I want to click on a button that is either not yet clickable or has another element on top of it.
But as soon as it is clickable, I want to press it.
I tried this:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, "likeClick")))
button.click()
But it doesnt work because I still get the error
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <a class="likeClick"> is not clickable at point (400,553) because another element <div class="delete-overlay"> obscures it```
This error message...
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <a class="likeClick"> is not clickable at point (400,553) because another element <div class="delete-overlay"> obscures it
...implies that the click to the <a> element failed as the element was obscured the <div> element which seems to be an temporary overlay .
Solution
To click on the desired element you need to induce WebDriverWait for the invisibility_of_element_located() of the overlay and then induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 30).until(EC.invisibility_of_element_located((By.CSS_SELECTOR, "div.delete-overlay")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.likeClick"))).click()
Using XPATH:
WebDriverWait(driver, 30).until(EC.invisibility_of_element_located((By.XPATH, "//div[#class='delete-overlay']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='likeClick']"))).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
Related
I am trying to pull some quotes on a website. To get the quote you have to click the Javascript button below:
Below is my python code to click the button:
driver = webdriver.Edge()
driver.get("http://generatorland.com/glgenerator.aspx?id=86")
driver.find_element(By.XPATH,"//a[#href='JavaScript:void(0);']").click()
However, when I run the code to test the button press, it throws an error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//a[#href='JavaScript:void(0);']"}
(Session info: MicrosoftEdge=110.0.1587.46)
Why can't it find the button, even when I specify the href sample for the XPATH to find?
You can move a step deeper and use the <img> tag.
Solution
The desired element is a dynamic element, so to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a > img[alt='Confucius']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a/img[#alt='Confucius']"))).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 am trying to make selenium click the add to trolley button but there is an error the code which I am using is:
trolley = driver.find_element_by_xpath("//button[#role='button']")
trolley.click()
The inspect element of the button is:
<button class="Buttonstyles__Button-pv6mx8-2 SczzF" data-test="add-to-trolley-button-button" kind="primary" role="button" tabindex="0" type="button" xpath="1" style=""><span><span>Add<span class="sr-only"> </span> to trolley</span></span></button>
I was able to find a pythonspot article on clicking a button using selenium (https://pythonspot.com/selenium-click-button/) and they used the function:
trolley = driver.find_elements_by_xpath(`xpath here`)
trolley.click()
The difference between them is this one returns a list over a single element, im not sure why this might work over your method but this is what ive found. Just change that element to elements
To locate the element you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.find_element(By.CSS_SELECTOR, "button[class^='Buttonstyles__Button'][data-test='add-to-trolley-button-button'] > span > span").click()
Using XPATH:
driver.find_element(By.XPATH, "//button[starts-with(#class, 'Buttonstyles__Button') and #data-test='add-to-trolley-button-button']/span/span").click()
Ideally, to locate the clickable element you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[class^='Buttonstyles__Button'][data-test='add-to-trolley-button-button'] > span > span"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[starts-with(#class, 'Buttonstyles__Button') and #data-test='add-to-trolley-button-button']/span/span"))).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 was making a webscraper to get gpu stocks from https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us to get my hands on a 30 series card, I am using python with bs4 and selenium for this.
I want to load more shopping items, on the website it has this load more button. So I grabbed its class and made it so selenium clicks it:
driver.find_element_by_class_name("buy-link").click()
but it says that the element in non interactiable, HTML for the button
The exact error it gives me is:
Message: element click intercepted: Element <span class="extra_style buy-link" data-color="#76b900" data-secondary-color="#fff" style="visibility: visible; cursor: pointer;" data-mpn-code="NVGFT070">...</span> is not clickable at point (657, 594). Other element would receive the click: <div class="popBg" id="nv-buy-now-model" style="display: block;">...</div>
I don't know much HTML, how can I achieve clicking this button
The LOAD MORE element is a Angular element so to click on it you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#cookiePolicy-btn-close>span"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.buy-link.load-more-btn[value='LOAD MORE']"))).click()
Using XPATH:
driver.get("https://www.nvidia.com/en-us/shop/geforce/?page=1&limit=9&locale=en-us")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='cookiePolicy-btn-close']/span"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='buy-link load-more-btn' and #value='LOAD MORE']"))).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
Browser Snapshot:
The problem is that there are some 20 elements on that page that match your first locator, .find_element_by_class_name("buy-link"). In this case, if you make your locator more specific, you can isolate it down to just the "LOAD MORE" INPUT button.
Try this instead
driver.find_element_by_css_selector("input.buy-link").click()
It's generally a good practice to add a wait unless you are sure you won't ever need it.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='CLOSE']")).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.buy-link")).click()
See the docs for more info and details.
I am using the code below to click on the highlighted tab that you see on the attached screenshot with the corresponding HTML code. The tab is always visible on the bottom of the script so there is no need to scroll down to it.
element = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, "tab-button-settings")))
element.click()
The error that I get is below. What am I doing wrong?
Message: unknown error: Element <a class="tab-button has-icon icon-only" href="#" role="tab" ng-
reflect-tab="[object Object]" id="tab-button-settings" aria-controls="tabpanel-t0-1" aria-
selected="false">...</a> is not clickable at point (1440, 1017). Other element would receive the
click: <div class="click-block click-block-enabled click-block-active"></div>
(Session info: chrome=78.0.3904.108)
you can use action class to avoid above issue
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
element = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, "tab-button-settings"))
ActionChains(driver).move_to_element(element).click().perform()
Another way alternative to javascript is to use touch actions
from selenium.webdriver.common.touch_actions import TouchActions
element = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, "tab-button-settings")))
touchactions = TouchActions(driver)
touchactions.tap(element).perform()
The desired element is an Angular element so to locate and click() on the 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:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.tab-button.has-icon.icon-only#tab-button-settings"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='tab-button has-icon icon-only' and #id='tab-button-settings']"))).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
In case the unknown error still occurs you may have to induce WebDriverWait additionally for the invisibility_of_element_located() and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.invisibility_of_element_located((By.CSS_SELECTOR, "div.click-block.click-block-enabled.click-block-active")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.tab-button.has-icon.icon-only#tab-button-settings"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.invisibility_of_element_located((By.XPATH, "//div[#class='click-block click-block-enabled click-block-active']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='tab-button has-icon icon-only' and #id='tab-button-settings']"))).click()
References
You can find a couple of relevant discussions in:
Selenium Web Driver & Java. Element is not clickable at point (x, y). Other element would receive the click
Element MyElement is not clickable at point (x, y)… Other element would receive the click
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element is not clickable with Selenium and Python
I try to click on html a tag with selenium but I get an error.
How can I get selenium to click on such tag?
I've tried this code but I get an error:
driver.find_element_by_id("btnCreateJE").click()
HTML code:
<a id="btnCreateJE" data-permission="true" onclick="NewManualJE()" href="#" class="btn waves-effect waves-light"> New </a>
Python selenium code:
driver.find_element_by_id("btnCreateJE").click()
I get that error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="btnCreateJE"]"}
(Session info: chrome=75.0.3770.142)
Make sure that the element doesn't belong to the iframe, if this is the case - you will need to switch_to_frame first
Make sure that the element doesn't belong to the Shadow DOM, if this is the case - you will have to find the relevant ShadowRoot and locate your element relatively
It might be the case the link is not immediately present in DOM, i.e. it's being added later as a result of an AJAX call. If this is the case - consider adding Explicit Wait like:
WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located((By.ID, "btnCreateJE"))).click()
The desired element is a JavaScript enabled element so to click() on the element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using PARTIAL_LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "New"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.waves-effect.waves-light#btnCreateJE[onclick^='NewManualJE']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn waves-effect waves-light' and #id='btnCreateJE'][starts-with(#onclick, 'NewManualJE')]"))).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