I have an element that clears a query after the query is made, but I can't get selenium to locate it.
Here is the xpath for the element:
/html/body/main/div/section[1]/div/a[2]
This is the html for the element:
<a onclick="onClearClicked()" class="btn btn--secondary btn--sm">clear</a>
Things that I have tried:
Finding by using the whole xpath, css selector, class name, text
Using css to find all buttons on the page and iterating over them until I find the right one (it doesn't find any buttons with text)
buttons = mydriver.find_elements_by_css_selector("button")
for button in buttons:
print(button.text)
if button.text.strip() == "clear":
button.click()```
Exiting the iframe I was in before and using the full xpath
driver.switch_to().defaultContent()
I have a work around that involves quitting the driver and reopening it for every query, but this would involve logging in and navigating to the right page every time and I'd much rather be able to just use the clear button.
Your html doesn't have any "button" element; it's an "a" (hyperlink) element. So, you should do:-
buttons = mydriver.find_elements_by_css_selector("a")
Using full xpath not a good way , so try the following code:
buttons =driver.find_elements_by_css_selector("[class='btn btn--secondary btn--sm']")
for button in buttons:
print(button.text)
if button.text.strip() == "clear":
button.click()
driver.find_element(By.XPATH,"//a[.='clear']").click()
If you want to click the element with the text clear you can just look for an a tag with that text.
The element is a <a> tag which have the innerText as clear
<a onclick="onClearClicked()" class="btn btn--secondary btn--sm">clear</a>
Solution
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 LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "clear"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.btn--secondary.btn--sm[onclick^='onClearClicked']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn btn--secondary btn--sm' and starts-with(#onclick, 'onClearClicked')]"))).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 want to use the click() function of selenium on these buttons in the following manner(the first two clicks):
For reference the 1st button I want to click and its code:
2nd button with its code:
I tried using
driver.find_element(By.XPATH,"//button[contains(#type,\"button\")]").click()
on the first button (the "X" mark) but it didn't work and got this error:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <button type="button" class="el-button yellowBtn el-button--default">...</button> is not clickable at point (606, 507). Other element would receive the click: <img src="https://d2g38dx0j6xqav.cloudfront.net/online/img/app-inner/popup.png" alt="" style="width: 100%;">
If I somehow get it to click the first button then getting it to click the second button will be much easier.
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted
Above exception implies that the element you are trying to action upon isn't clickable, as some other element is overshadowing it.
Try by inducing wait(see below):
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH,"Your XPath expression here"))).click()
if the above doesn't work, try using execute_script() method(see below):
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "Your XPath expression here"))))
Required imports statements:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
I think you should wait until the element is visible in the modal dialog box. U can use both the Explicit and Implicit waits methods for the above problem.
Always read exception and/or error messages carefully to see what you can learn about the problem. In this case, it tells you exactly what happened. I reformatted and shortened it to make it more readable.
ElementClickInterceptedException:
Message: element click intercepted: Element <button...> is not clickable.
Other element would receive the click: <img...>
Selenium is telling you that it tried to click the BUTTON but the click was intercepted (it never got clicked because there was another element covering it). The element that got clicked instead was an IMG.
Without seeing the full HTML of the page it's hard to say but your BUTTON locator looks pretty generic and there's a good chance that you clicked a different BUTTON than you intended. I would use the locator below instead to click on the I tag.
wait = WebDriverWait(driver, 10)
close_icon = (By.CSS_SELECTOR, "i.el-dialog__close")
wait.until(EC.element_to_be_clickable(close_icon)).click() # click the close icon
wait.until(EC.invisibility_of_element_located(close_icon)) # wait for the close icon to disappear indicating the dialog is fully closed
# continue script
If that still doesn't work, you will probably need to use a JS click. If you are writing UI tests, then you should avoid JS clicks unless no other solution can be found because it allows the script to do things that a user can't. If you aren't writing tests, then it likely doesn't matter.
wait = WebDriverWait(driver, 10)
close_icon = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "i.el-dialog__close")))
driver.execute_script("arguments[0].click()", close_icon)
# continue script
You desired element is:
But your line of code:
driver.find_element(By.XPATH,"//button[contains(#type,\"button\")]").click()
is attempting to click on:
<button type="button" class="el-button yellowBtn el-button--default">...</button>
which isn't the desired element and still the click attempt is intercepted by:
<img src="https://d2g38dx0j6xqav.cloudfront.net/online/img/app-inner/popup.png" alt="" style="width: 100%;">
Solution
To click 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, "button.el-dialog__headerbtn[aria-label='Close'] > i.el-dialog__close.el-icon.el-icon-close"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='el-dialog__headerbtn' and #aria-label='Close']/i[#class='el-dialog__close el-icon el-icon-close']"))).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 create an automated download event for one ERP platform using Selenium in python. This is a bit tricky for this part as there is no specific element to find and click.
Multiple buttons have the same class and no id for the highlighted button (DATABASE/BACKUP)
Can anyone help me with the same?
event flow >>
Login page > click "administration button" > click "database / backup"
thanks
As per Selenium documentation https://selenium-python.readthedocs.io/locating-elements.html you can find all of the elements by their class name and then access them by index ([index_number]).
all_buttons = driver.find_elements_by_class_name("your_class_name")
then you can do something like:
button_to_click = all_buttons[3] # The 4th button which has index 3 in all the retrieved buttons by class name
driver.find_element(By.XPATH,"//a[contains(text(),'Database / Backup')]").click()
Simply click the a tag which contains the text.
To click on the element with text as DATABASE/BACKUP you can use either of the following Locator Strategies:
Using xpath:
driver.find_element(By.XPATH, "//a[#class='menui' and contains(., 'DATABASE/BACKUP')]").click()
Using xpath:
driver.find_element(By.XPATH, "//a[text()[contains(., 'DATABASE/BACKUP')]]").click()
The desired element is a dynamic element, ideally to click on a clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='menui' and contains(., 'DATABASE/BACKUP')]"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[text()[contains(., 'DATABASE/BACKUP')]]"))).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 have been trying to make this clickable and I just cannot understand what I am doing wrong.
I am also trying to induce webdriverwait, so that it is clicked when it appears.
This is my code so far:
def order(k):
driver = webdriver.Chrome(os.getcwd()+"\\webdriver\\chromedriver.exe")
driver.get("website.com/login-to-checkout")
driver.find_element_by_id('i0116').send_keys(k["email"])
driver.find_element_by_id('i0118').send_keys(k["password"])
driver.find_element_by_id('idSIButton9').click()
delay()
#sign in button
driver.find_element_by_id('idSIButton9').click()
#Button below I cant get to be clicked
with webdriver.Chrome() as driver:
wait = WebDriverWait(driver, 7)
wait.until(presence_of_element_located((By.CSS_SELECTOR, "#ember1053")))
driver.find_element(By.id, "ember1053").click()
this is the source code for the button that I am trying to make clickable:
<div id="ember1037" class="btn-group m-b-lg m-t-lg order-call-to-action ember-view"><!----> <!--biBehavior 80 means place order Place Order-->
<button aria-live="polite" type="button" tabindex="0" data-m="{"aN":"shoppingCart","cN":"PlaceOrder","bhvr":80}" id="ember1053" class="btn theme-default btn-primary cli-purchase ember-view"><!----> Place order
</button></div>
The desired element is an Ember.js element and the value of the id attribute of the <button> will keep changing dynamically, every time you access the AUT(Application Under Test). Hence to 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, "button.btn.theme-default.btn-primary.cli-purchase.ember-view[id^='ember'][type='button'][aria-live='polite']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn theme-default btn-primary cli-purchase ember-view' and starts-with(#id,'ember')][contains(., 'Place order') and #aria-live='polite']"))).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
References
You can find a couple of relevant detailed discussions in:
Selenium - Finding element based on ember
Ember dropdown selenium xpath
This may help but I've had issues with webdriver not clicking on a button when I use the id to find it.
The work around I've found is using the xpath instead of the id.
Like this, it's worth a try.
driver.find_element_by_xpath("""//*[#id="submit-button"]""").click()
I was making a bot with selenium but I can not click here:
There are many classes and I can not find which one I should use , because I tried something but didn't do it.
For example, button name is OTURUM AÇ and I wrote like this , but it does not work.
browser = driver.find_elements_by_xpath('//button[text()="OTURUM AÇ"]').click()
Update from comments: https://dlive.tv/ I wanna log in there. But I can't.
This should work for you
btn = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//span[text()='OTURUM AÇ']")))
driver.execute_script('arguments[0].click();', btn)
It doesn't work because you are trying to find a button which has a text 'OTURUM AÇ' inside of it. In html which you add to question, there is no <button> tag so you need to search this element with <span>.
login = driver.find_element_by_xpath('//span[text()="OTURUM AÇ"]')
driver.execute_script('arguments[0].click();', login)
In html, it is not mandatory to use a <button> tag to place a button on page so make sure you check the tags.
You use wrong locator. There is login button with span tag, not button.
Locotor will be:
//span[text()="OTURUM AÇ"]
But using text in locators is not good practice. You can rewrite it using css:
.sign-register-buttons .btnA span
or the same xpath locator:
//*[contains(#class, 'sign-register-buttons')]//*[contains(#class, 'btnA')]//span
They will work for any site language.
To click on the element with text as OTURUM AÇ you can use the following xpath based Locator Strategies:
browser.find_element_by_xpath("//div[#class='sign-register-buttons flex-align-center']//span[text()='OTURUM AÇ']").click()
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:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='sign-register-buttons flex-align-center']//span[text()='OTURUM AÇ']"))).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 facing some difficulties scraping a website which uses react.js and not sure why this is happening.
This is the html of the website:
What I wish to do is click on the button with the class: play-pause-button btn btn -naked. However, when I load the page with the Mozilla gecko webdriver there is an exception thrown saying
Message: Unable to locate element: .play-pause-button btn btn-naked
which makes me think that maybe I should do something else to get this element?
This is my code so far:
driver.get("https://drawittoknowit.com/course/neurological-system/anatomy/peripheral-nervous-system/1332/brachial-plexus---essentials")
# execute script to scroll down the page
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);var lenOfPage=document.body.scrollHeight;return lenOfPage;")
time.sleep(10)
soup = BeautifulSoup(driver.page_source, 'lxml')
print(driver.page_source)
play_button = driver.find_element_by_class_name("play-pause-button btn btn-naked").click()
print(play_button)
Does anyone have an idea as to how I could go about solving this? Any help is much appreciated
Seems you were close. While using find_element_by_class_name() you can't pass multiple classes and you are allowed to pass only one classname, i.e. only only one among either of the following:
play-pause-button
btn
btn-naked
On passing multiple classes through find_element_by_class_name() you will face Message: invalid selector: Compound class names not permitted
Solution
As an alternative, as the element is an Angular element, to click() on the element you have to induce WebDriverWait for the element_to_be_clickable() and you 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.play-pause-button.btn.btn-naked")))click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='play-pause-button btn btn-naked']")))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