How to locate and click the textarea element using Selenium and Python - python

I'm using Selenium with python and have been trying to click a text box, and input a message.
The text box's HTML looks like this:
<div class="tw-block tw-border-radius-large tw-pd-0">
<div class="tw-relative">
<div class="chat-input__textarea">
<textarea data-a-target="chat-input" data-test-selector="chat-input" class="tw-block tw-
border-radius-medium tw-font-size-6 tw-full-width tw-textarea tw-textarea--no-resize"
autocomplete="Messenger-chat" maxlength="500" placeholder="Send a message" rows="1"
style="padding-right: 3.5rem;"></textarea>
</div>
</div>
</div>
I have been trying to select it by css selector with this code:
time.sleep(3)
input_box = browser.find_element_by_css_selector(".textarea")
input_box.click()
for ch in message:
input_box.send_keys(ch)
input_box.send_keys(Keys.ENTER)
It keeps giving me a NoSuchElement. As you can see I don't really know what I am really doing- please help thanks :)

.texarea is not going to find any element:
. indicates that the selector should look for the proceeding value in the className of an element.
So, you are telling the selector to look for an element with className textarea.
You are confusing className selector with a tagname selector. If you want to get it by tagname, you just use the tagname without any dot(.), so:
find_element_by_css_selector("textarea")
This would return the first textarea element it finds, which may or may not be what you want. To make it more precise you can do:
find_element_by_css_selector("textarea.tw-block.tw-
border-radius-medium.tw-font-size-6.tw-full-width.tw-textarea.tw-textarea--no-resize")
Notice how in the second version there are multiple dots(.) in the selector, telling the engine to search for an element of tagname textarea with classNames: tw-block tw-
border-radius-medium tw-font-size-6 tw-full-width tw-textarea tw-textarea--no-resize. Each individual className is seperated by a space in the Html markup, so you use a dot(.) to tell the selector to chain those classNames together.
If by chance you have multiple textarea's with all the same classNames as above, you'd need to find some kind of unique identifier for the textarea you want. So the selector provided by KunduK is a good example of that.
Perhaps this link will help you to learn more about css selectors: (https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors)

As per the HTML the element is a <textarea> element. So to identify the element the relevant code would have been either of the following:
browser.find_element_by_tag_name("textarea")
browser.find_element_by_css_selector("textarea[attribute_name='attribute_value']")
Solution
Ideally, to identify and click within the desired element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
input_box = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "textarea[data-a-target='chat-input'][data-test-selector='chat-input'][placeholder='Send a message']")))
input_box.click()
Using XPATH:
input_box = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//textarea[#data-a-target='chat-input' and #data-test-selector='chat-input'][#placeholder='Send a message']")))
input_box.click()
Note : You have to add the following imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Your css selector is wrong .textarea in css selector identify the class name.
Try below css selector.
input_box = browser.find_element_by_css_selector("textarea[data-a-target='chat-input']")

Related

Unable to Locate Element with Selenium Python despite xPath

I can't locate element on website and insert numerical value inside using Selenium on Firefox with Python.
I am using firefox add-in to get the xPath for the input field, I receive:
/html/body/div1/section/div/div/div/div/form/div1/div/div[4]/div2/div/div/div/div1/div1/table/tbody/tr1/td3/div/input
however with Python code objDriver.find_element_by_xpath("...") - I receive "Unable to locate element:" -> like xpath is wrong
If I use it on the let's say border of the input field, I get following xPath:
/html/body/div1/section/div/div/div/div/form/div1/div/div[4]/div2/div/div/div/div1/div1/table/tbody/tr1/td3
This element I can allocate using objDriver.find_element_by_xpath("...") but it is not input field, so I can't insert value
If I click "Inspect" in Firefox, I get:
CSS Path:
html body div.main-content section.section div.block-one_col_1 div.container-fluid.wrapper div.row div.col-12 form#id_form-process.form-horizontal.formfactory div.row div.col-md div#fieldgroup_variants.fieldset div#fieldgroup_variants__fields.fieldset__content div.form-group.row.formfield_variantsCalculator.fieldpk_2533.mb-0.is-valid div.col-md-6.col-12 div.d-flex.flex-row div.w-100 div.table-scroll table.table.table--step tbody#tableContent.table tr.table-row.table-row--count td div.form-group.group1 input.form-control.variant-value.variant1.touched
xPath:
/html/body/div/section/div/div/div/div/form/div[1]/div/div[4]/div[2]/div/div/div/div[1]/div[1]/table/tbody/tr[1]/td[3]/div/input
HTML part I am interested in:
<td data-risk="6.1"><div class="form-group group1" data-excluded="false" data-risk="6.1"><input name="1" class="form-control variant-value variant1 touched" data-editable="true" data-risk="6.1" data-visible-sum="true" data-dynamic="false"></div></td>
Do you have any idea how can I locate the field I need?
General view of Input field:
When getting xPath of the border:
When getting xPath of the Input field:
Can you try with the below xpath with Explicit waits :
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#name= '1' and contains(#class, 'variant-value')]"))).send_keys('10000')
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Try with xPath = //input[#class="form-control variant-value variant1 touched"][#id="1"]

Trouble selecting google one box tab in selenium

going to https://www.google.com/search?q=tennis a google one box comes up for scores, I'm trying to click on the tabs and (Women's Singles, Men's Doubles etc) and having no luck. I've tried all methods, xpath, classname, partial link text, css selector.
any help would be appreciated!!!
The desired element is a JavaScript enabled element, so ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Clicking Women's Singles:
driver.get('https://www.google.com/search?q=tennis')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#jsslot]//span//span[contains(., 'Women') and contains(., 'Singles')]"))).click()
Clicking Men's Doubles:
driver.get('https://www.google.com/search?q=tennis')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#jsslot]//span//span[contains(., 'Men') and contains(., 'Doubles')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
I always use this method to set the XPath in Selenium based Python projects.
Click F12 after opening the link
In Elements, Click Ctrl + F. Now search some unique term in the page. I gave Men's Singles and this snippet came up.
<div class="SVWlSe FZzi2e" jsslot="">
<span jsslot="">
<div aria-controls="_dtAkYIqaMLraz7sPnrW54A435_0"
id="_dtAkYIqaMLraz7sPnrW54A434_0">
<span>
<span>Men's Singles</span>
</span>
</div>
</span>
</div>
Now right-click the snippet to get the XPath format or use the XPath Syntax. Here, the XPath is //div[#class='SVWlSe FZzi2e']. To find whether the attribute value is unique, I would suggest you to search within elements again with the value.
Notice that I used the class attribute instead of the aria-controls and id attributes since id and aria-controls changed over time.

How to locate a tag by text in its child tag

I am new to Webelement and selenium, can anyone help me on how to locate element below , using text "Hotel Wahington":
<a class="hotel_name_link url" href="/hotel/nl/washington.html?label=gen173nr-1FCAEoggI46AdIM1gEaFCIAQGYATG4ARjIAQzYAQHoAQH4AQKIAgGoAgS4Apyz__EFwAIB&sid=1b691d9ad57ac7ee7c3d40dac2f7f488&dest_id=-2140479&dest_type=city&group_adults=2&group_children=0&hapos=1&hpos=1&no_rooms=1&sr_order=popularity&srepoch=1581242789&srpvid=87de4712b9a90095&ucfs=1&from=searchresults;highlight_room=#hotelTmpl" target="_blank" rel="noopener">
<span class="sr-hotel__name" data-et-click=" ">Hotel Washington</span>
<span class="invisible_spoken">Opens in new window</span>
</a>
Adding the original link below :
https://www.booking.com/searchresults.html?label=gen173nr-1FCAEoggI46AdIM1gEaFCIAQGYATG4ARjIAQzYAQHoAQH4AQKIAgGoAgS4ApSSgPIFwAIB&sid=dcd3ff4c30abfd0bc264d5ae4a4c1d7a&sb=1&sb_lp=1&src=index&src_elem=sb&error_url=https%3A%2F%2Fwww.booking.com%2Findex.html%3Flabel%3Dgen173nr-1FCAEoggI46AdIM1gEaFCIAQGYATG4ARjIAQzYAQHoAQH4AQKIAgGoAgS4ApSSgPIFwAIB%3Bsid%3Ddcd3ff4c30abfd0bc264d5ae4a4c1d7a%3Bsb_price_type%3Dtotal%26%3B&sr_autoscroll=1&ss=hotel+washington&is_ski_area=0&checkin_year=&checkin_month=&checkout_year=&checkout_month=&group_adults=2&group_children=0&no_rooms=1&b_h4u_keep_filters=&from_sf=1
To select anchor tag based on text "Hotel Wahington" use the following xpath.
Use following Xpath
driver.find_element_by_xpath("//a[#class='hotel_name_link url' and contains(.,'Hotel Washington')]").click()
Or following css selector.
driver.find_element_by_css_selector("a.hotel_name_link.url[href*='/hotel/nl/washington']").click()
Or partial link text.
driver.find_element_by_partial_link_text("Hotel Washington").click()
Tryout this xpath:
//span[text()='Hotel Washington']/parent::a
Also note that the method "find_element_by_xpath()" in the answers is from version 4 of Selenium which is still in Alpha testing phase. You will be most likely using Selenium version 3. The valid code for version 3 would be:
driver.findElement(By.xpath("//span[text()='Hotel Washington']/parent::a")),click();
Using xpath you can go to parent element with ..
driver.find_element_by_xpath('//span[.="Hotel Washington"]/..')
Or locate an element which has specific text
driver.find_element_by_xpath('//a[span[.="Hotel Washington"]]')
Use the
xPath = //*[contains(#text(),'Hotel Wahington')]
OR
//a[#class='hotel_name_link url']//*[contains(#text(),'Hotel Wahington')]
You can locate an element using text only. You can try below solution:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.XPATH, "//span[contains(., 'Hotel Washington')]")))
element.click()

Selenium, select based on "onclick" value

With Selenium, I'm trying to find the following checkbox on webpage.
<input type="checkbox" value="1" onclick=" document.getElementById('lastCheminClicked').value='123'; createInputsBinaireCell(25,'colonne5',1,0789,1,1,0,this.checked, this);">
The distinctive part is the '123' value in the "onclick", this is what selenium should look for.
Any way to find it on page? I have tried with xpath with no sucess.
As you mentioned the partial value 123 is distinct within the onclick event so to locate the element you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[type='checkbox'][onclick*='123']")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#type='checkbox' and contains(#onclick,'123')]")))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
XPath selectors allow using contains() function which can be used for partial match on the attribute or text value of the DOM element.
The relevant selector would be something like:
//input[contains(#onlclick, '123')]
Demo:
More information:
XPath Tutorial
XPath Axes
XPath Operators & Functions
You might try finding all input tags, and then iterate through each looking at the onclick attribute. For example:
from selenium.webdriver.common.by import By
input_tags = driver.find_elements(By.TAG_NAME, 'input')
found_tag = None
for input_tag in input_tags:
onclick_attribute = input_tag.get_attribute('onclick')
if ".value='123'" in onclick_attribute:
found_tag = input_tag
break
You'll probably need exception handling around the get_attribute call.

How to locate and click the element when the innerText contains leading and trailing white-space characters using Selenium and Python

I want to locate (and click) the "Reoni" element, but I do not know what function to use it for
I tried with
driver.find_element_by_class_name("oe_menu_leaf")
and
driver.find_element_by_class_name("oe_menu_text")
but then selenium raise an error element cant be located,
and I tried
driver.find_element_by_link_text("Reoni")
This is the element I want to locate:
<a href="/web#menu_id=86&action=99" class="oe_menu_leaf" data-menu="86" data-action-model="ir.actions.act_window" data-action-id="99">
<span class="oe_menu_text">
Reoni
</span>
</a>
and full html:
If I was not clear enough or if you needed my code, please let me know.
As the desired element is a dynamic element you need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.oe_menu_leaf[href*='/web#menu_id=']>span.oe_menu_text"))).click()
Using XPATH and text():
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='oe_menu_leaf' and starts-with(#href,'/web#menu_id=')]/span[#class='oe_menu_text' and text()='Reoni']"))).click()
Using XPATH and normalize-space():
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='oe_menu_leaf' and contains(#href,'/web#menu_id=')]/span[#class='oe_menu_text' and normalize-space()='Reoni']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a relevant detailed discussion in:
Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome
Try something like this:
Clicking the button
From Chrome :
Right click "inspect" on the item you are trying to find the xpath.
Right click on the highlighted area on the console.
Go to Copy xpath
selectElem=browser.find_element_by_xpath('x-path-here').click()
Reading Values Only
from bs4 import BeautifulSoup
innerHTML = browser.execute_script("return document.body.innerHTML")
soup = BeautifulSoup(str(innerHTML.encode('utf-8').strip()), 'lxml')
value = soup.find('span', attrs={'class':'fxst-calendarpro fxst-table-s1'}).text

Categories