How to get rid of Cannot focus element exception - python

I faced with following issue with chromedriver: I have a text input field and a texarea. I can successfully send text to both elements with follow code
input = driver.find_element_by_xpath('//input[#type="text"]')
input.send_keys('test')
textarea = driver.find_element_by_xpath('//textarea[not(#readonly)]')
textarea.send_keys('test')
But if to try this code
text_fields = driver.find_elements_by_xpath('//*[input[#type="text"] or textarea[not(#readonly)]]')
for field in text_fields:
field.send_keys('test')
I get selenium.common.exceptions.WebDriverException: Message: unknown error: cannot focus element
P.S. Adding field.click() before sending text or using ActionChains failed to solve issue. Also len(text_fields) return 2, so both elements correctly matched with XPath

The second expression will return the parent element of the input or textarea. If you wish to get both in a single XPath then:
text_fields = driver.find_elements_by_xpath("//input[#type='text'] | //textarea[not(#readonly)]")
for field in text_fields:
field.send_keys('test')
Or with a CSS selector :
text_fields = driver.find_elements_by_css_selector("input[type='text'] , textarea:not([readonly])")
for field in text_fields:
field.send_keys('test')

Related

Python Selenium - element is not attached to the page document - once button is clicked

When I click on an item inside a dropdown list, the item is correctly clicked but the error: "stale element is not attached to the page document" is raised.
I guess this error is raised because of an element I use as changed inside the DOM or has been refreshed, but I didn't find any solutions for now. Here's my code:
exam_question_type = self.driver.find_element(By.XPATH, f"//*[name()='svg'][#class='css-19bqh2r']")
exam_question_type.click()
WebDriverWait(self.driver).until(ec.visibility_of_element_located((By.CSS_SELECTOR, 'class=" css-b02ejv-menu"'))
select_question_type = self.driver.find_elements(By.CSS_SELECTOR, 'class="CustomOptionMenu_button__2GnMd"')
for type in select_question_type:
if type.text == "QCM grid":
try:
ActionChains(self.driver).click(type).perform()
except StaleElementReferenceException:
pass
What i'm doing wrong?
Since by clicking on elements inside the dropdown list the page is changing and elements are refreshed you have to grab select_question_type elements again after the refreshing. Something like this:
exam_question_type = self.driver.find_element(By.XPATH, f"//*[name()='svg'][#class='css-19bqh2r']")
exam_question_type.click()
WebDriverWait(self.driver).until(ec.visibility_of_element_located((By.CSS_SELECTOR, 'class=" css-b02ejv-menu"'))
select_question_type = self.driver.find_elements(By.CSS_SELECTOR, 'class="CustomOptionMenu_button__2GnMd"')
for index, type_el in enumerate(select_question_type):
type_el = select_question_type[index]
if type_el.text == "QCM grid":
ActionChains(self.driver).click(type_el).perform()
WebDriverWait(self.driver).until(ec.visibility_of_element_located((By.CSS_SELECTOR, 'class=" css-b02ejv-menu"'))
select_question_type = self.driver.find_elements(By.CSS_SELECTOR, 'class="CustomOptionMenu_button__2GnMd"')
Also, I've changed the element name from type to type_el since type is a keyword that should not be used for naming of variables.

SyntaxError: Failed to execute 'evaluate' on 'Document': xpath

Element:
XPATH:
//*[#id="autocomplete_code"]
I am getting syntax error for below statement, what is not correct in this xpath? I tried just with id and both id & class.
account = driver.find_element(By.XPATH,"//*input[#id='autocomplete_code' and #class = 'account_code_ac inputSearch ui-autocomplete-input']")
changing code as below fixed the syntax error, but still not able to select the search result value with arrow down key
account = driver.find_element(By.XPATH,"//*[#id='autocomplete_code']")
account.send_keys("1100-1200-200167-620038")
account.send_keys(Keys.ARROW_DOWN)
account.send_keys(Keys.RETURN)
changing code as below works fine:
account =driver.find_element(By.XPATH,"//*[#aria-label='Search an Account']").click()
account = driver.find_element(By.XPATH,"//*[#id='autocomplete_code']")
account.send_keys("1100-1200-200167-620038")
element = wait.until(EC.visibility_of_element_located((By.XPATH, '//a[contains(#aria-label, "1100-1200-200167-620038")]')))
account.send_keys(Keys.ARROW_DOWN)
account.send_keys(Keys.RETURN)

How to verify an option is selected with Selenium with Python

I have a Select tag with several options (pictured below). I want to write a selenium test where I verify that the option with the 18 value is selected.
I have tried this but it doesn't work:
`age_min = self.browser.find_element_by_css_selector('select#age-min > option[value="18"]')
age_min_selected = is_attribtue_present(age_min, 'selected')
self.assertTrue(age_min_selected)`
I get this error: NameError: name 'is_attribtue_present' is not defined
I've also tried this:
`age_min = self.browser.find_element_by_css_selector('select#age-min > option[value="18"]["selected"]')`
error: Message: invalid selector: An invalid or illegal selector was specified
You could check the "selected" attribute on the option as such:
options = driver.find_elements_by_xpath("//option")
for option in options:
is_selected = option.is_selected()
print(str(is_selected))
Based on this documentation:
https://selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webelement.html?highlight=is_selected#selenium.webdriver.remote.webelement.WebElement.is_selected

How to extract text from element where the parent element is having attribute style="display:none" using Selenium

I want to extract Phone number from this div. This div has style="display:none"
So I can not access the children of this div. Please help me out in getting the phone number from the div.
I guess We need to change that display:none; to visibility:visible. How can I do this in Python Selenuim
Edit
I have tried the code below, as suggested in the first answer but it throws the following error:
email_div = browser.find_element_by_class_name("returnemail")
email_div_contents = browser.execute_script('return arguments[0].innerHTML', email_div)
telephone = email_div_contents.find_element_by_class_name('reply-tel-number').get_attribute('textContent')
AttributeError: 'str' object has no attribute
'find_element_by_class_name
'
As per the documentation execute_script() returns:
The command's JSON response loaded into a dictionary object.
Hence, moving forward when you attempted to invoke find_element_by_class_name() method on the dictionary object as follows:
email_div_contents.find_element_by_class_name('reply-tel-number').get_attribute('textContent')
The following error is raised:
AttributeError: 'str' object has no attribute 'find_element_by_class_name'
To remove the attribute style="display:none" from the desired element and extract the phone number you can use the following solution:
element = driver.find_element_by_xpath("//div[#class='returnemail js-only']")
driver.execute_script("arguments[0].removeAttribute('style')", element)
tel_number = element.find_element_by_xpath("./aside/ul//li//p[#class='reply-tel-number']").get_attribute("innerHTML")
Your code has incorrect place:
email_div = browser.find_element_by_class_name("returnemail")
email_div_contents = browser.execute_script('return arguments[0].innerHTML', email_div)
email_div_contents.find_element_by_class_name()
email_div_contents is a string represents the HTML code of the email_div, not a web element,
You can't call find_element_by_class_name() on a string.
That's why you got error:
'str' object has no attribute 'find_element_by_class_name'
You can always call get_attribute() to fetch attribute value on visible and invisible element.
To get the text content of invisible element you can use get_attribute('innerText').
phone_number = driver.find_element_by_css_selector("div.returnemail .reply-tel-number")
.get_attribute('innerText')
Actually, element.text call element.get_attribute('innerText') inside, but element.text will respect user experience: If user can't see the element from page, element.text will return empty string as user see. (Even element.get_attribute('innerText') return non-empty string)
#property
text:
if ( element is visible ):
return element.get_attribute('innerText')
else:
return ''

How can I click in link but without "a href" [Selenium + Python]

I don't know how can I click on "Utwórz konto" on https://www.morele.net/login.
I tried:
link_registration = driver.find_element_by_class_name("//li[#class = 'el-login-nav register']")
link_registration.click()
but I get error:
selenium.common.exceptions.InvalidSelectorException: Message: Given
css selector expression ".//li[#class = 'el-login-nav register']" is
invalid: InvalidSelectorError: './/li[#class = 'el-login-nav
register']' is not a valid selector: ".//li[#class = 'el-login-nav
register']"
You are trying to pass an XPath expression to the "by class name" locator - no wonder it fails.
I would use a CSS selector instead:
register = driver.find_element_by_css_selector(".autorization-form .register")
register.click()
.autorization-form .register would match an element having a register class somewhere (at any depth level) inside an element having an autorization-form class. Space here means parent-child relationship - but the child can be at any level inside the parent.
You are getting that error because you used the find_element_by_class_name() command but passed in an xpath. You need to either use find_elements_by_xpath() or a different locator function. Either of these should work:
driver.find_element_by_xpath("//li[#class = 'el-login-nav register']");
driver.find_element_by_css_selector("li.register")

Categories

Resources