I'm trying to click on the tab with text as Python
within the Selenium documentation website.
HTML:
<input type="radio" name="tabsetcode2" id="tab1code2" aria-controls="pythoncode2">
But I'm facing TimeoutException
:
selenium.common.exceptions.TimeoutException: Message:
Code trials:
driver.get('https://www.selenium.dev/documentation/en/')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[aria-controls='pythoncode2']"))).click()
Can anyone help me out to click on the Python
tab?
Try waiting by xpath
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '*//div[@class="tabset"]/label[2]'))).click()
If still doesn't work, try waiting till visible
WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, '*//div[@class="tabset"]/label[2]'))).click()
Firstly, there is a preference to use Id > Css selector > XPaths. So the example code could have been (By.CSS_SELECTOR, "#pythoncode2")
or better (By.ID, "pythoncode2")
.
However, that is not a clickable the element anyway, so despite waiting 20 seconds, it would always reach timeout waiting for it to become 'clickable'. (the circle of the radio button has the styling of left -1704px
which is off the screen if you go into "developer mode" on the browser via F12 and select that tab. The driver consider anything outside its viewport as unclickable)
The clickable element is the target label; there is no Id, but you can find it by CSS: (By.CSS_SELECTOR, "label[for=tab1code2]")
Here's my working code to prove it working:
from selenium import webdriver
if __name__ == '__main__':
driver = webdriver.Chrome("./chromedriver")
driver.get('https://www.selenium.dev/documentation/en/')
driver.find_element_by_css_selector("label[for=tab1code2]").click()
You can click on the label instead and it works.
driver.get('https://www.selenium.dev/documentation/en/')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[@for='tab1code2']"))).click()
The element is indeed clickable. But it is bounded with a label tag.
For more information, about binding label and infohere
Using EC.element_to_be_clickable
also ensure that the element is visible which is not the case.
class element_to_be_clickable(object):
""" An Expectation for checking an element is visible and enabled such that
you can click it."""
You can confirm that it is clickable by calling is_enabled
. This method only validate that the attribute disabled
is not false.
driver.find_element_by_css_selector("input[aria-controls='pythoncode2']").is_enabled()
Or
driver.find_element_by_css_selector("input[aria-controls='pythoncode2']").get_attribute('disabled') != "true"
Result:
True
But the EC.element_to_be_clickable
also calls to is_displayed
to determine if the element is visible as well
driver.find_element_by_css_selector("input[aria-controls='pythoncode2']").is_displayed()
Result:
False
This is why, no matter how long you wait, it will never become true.
To click on the input element, you might target the label element instead. They are bound together with the attribute for=id
In your case
driver.find_element_by_css_selector('[for="tab1code2"]')
Also:
driver.find_element_by_css_selector('[for="tab1code2"]').is_enabled()
driver.find_element_by_css_selector('[for="tab1code2"]').is_displayed()
Both returns: True
If you try to click the element with the css selector you've chosen, the following exception is thrown:
ElementNotInteractableException: Message: element not interactable"
The reason why, is the fact the type="radio"
attribute.
Instead of that, you should try to click the label element underneath with the following css selector:
("label[for=tab1code2]")
So, your code should look like:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "label[for=tab1code2]"))).click()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.