How to click on this button with Selenium? - python

Here are all the parts of the element I am trying to click according to 'Inspect':
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
::before
<div class="ui-dialog-buttonset">
<button type="button" class="done ui-button ui-corner-all ui-widget">
Done</button>
</div>
::after
</div>
When I want to click it, I assume it is on the ::before part as it is showing and clickable. In the code, I make sure to scroll and wait two seconds before clicking to make sure that the button is visible and yet I get:
selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable
But I don't understand how it's not interactable. When I hover over it in the inspector, everything in <button>...</button> highlights, so the button I want to click must be in there, right?
Here are few things that I have tried:
browser.find_element_by_css_selector('button[type=button]').click()
browser.find_elements_by_xpath("//*[contains(text(), 'Done')]").click()
# The above returns a list for some reason?
browser.find_elements_by_css_selector('done.ui-button.ui-corner-all.ui-widget')
I wish I could remember all that I tried, but regardless I hope someone can help me.

To click on the element as the desired element is a dynamic element you have to induce WebDriverWait for the 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, "div.ui-dialog-buttonpane.ui-widget-content.ui-helper-clearfix"))).click()
Using XPATH:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='ui-dialog-buttonpane ui-widget-content ui-helper-clearfix']"))).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
You can find a detailed discussion in selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable using Selenium

When you use .find_elements (note the plural) it will return a list instead of a single element like .find_element (singular) does. Have you tried
browser.find_element_by_xpath("//button[.='Done']")
If you get a len() on these .find_elements calls... is it 1? I'm wondering if there isn't more than one button that matches the locators you are using and the first isn't visible but you want the second or third, etc.

You can use ActionChains to move to element
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_elements_by_css_selector("div.ui-dialog-buttonpane.ui-widget-content.ui-helper-clearfix")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
or u can scroll till element is in view using scrollIntoView():
driver.execute_script("arguments[0].scrollIntoView();", element)

Related

How to use click() function of selenium in case of "button" attribute in HTML?

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

Selenium unable to locate xpath however the xpath is there in the browser

Im not sure if that was quite the best title but Im not sure how else to describe it, I am trying to use selenium to automate 2fa on a website so all I need to do is anwser the phone call and the script will take care of the rest however the button I am trying to get selenium to click keeps showing up as unable to locate even though its always in the same place and never changes here is my code in python
callMe = driver.find_element('xpath', '//*[#id="auth_methods"]/fieldset/div[2]/button')
callMe.click()
sleep(25)
this is one of three buttons that all have the same element information besides the xpaths here are all 3 button elements I am trying to grab the second one
<button tabindex="2" type="submit" class="positive auth-button"><!-- -->Send Me a Push </button>
<button tabindex="2" type="submit" class="positive auth-button"><!-- -->Call Me </button>
<button tabindex="2" type="submit" class="positive auth-button"><!-- -->Text Me </button>
I am not sure how else I can locate the second button besides using the xpath but that is not working and I dont know if I can or how I can search for the button based off the text that is inside it.
Did you try with By ?
from selenium.webdriver.common.by import By
callMe = driver.find_element(By.XPATH, '//*[#id="auth_methods"]/fieldset/div[2]/button')
Try using By.cssselector, get the css selector of the main body html for the button you want.
callMe = driver.find_element(By.css_selector, 'selectorofbodyhtml')
callme.click()
Try below xpath
//button[starts-with(text(),'Call Me')]
The desired element Call Me is a dynamic 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 XPATH and contains():
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(., 'Call Me')]"))).click()
Using XPATH and starts-with():
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[starts-with(., 'Call Me')]"))).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

Python Selenium - clicking Send button 'not clickable

I have a python script where I need to click a button. My function is as follows:
def inviteuser():
invitebutton.click()
time.sleep(2.5)
addressbox = driver.find_element_by_xpath('/html/body/div[9]/div/div/div[2]/div/div[1]/div/div/div/div/div[3]/div/div/div[1]')
time.sleep(2.5)
addressbox.send_keys(email)
time.sleep(2.5)
sendbutton = driver.find_element_by_xpath('/html/body/div[8]/div/div/div[3]/div[2]')
sendbutton.click()
When running the script at the button clicking part, I get this message:
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <div class="c-sk-modal_footer_actions"> is not clickable at point (834,677) because another element <div class="ReactModal__Overlay ReactModal__Overlay--after-open c-popover c-popover--z_above_fs c-popover--fade"> obscures it
I tried searching for that div, but the search in the browser could not find it.
I also tried
driver.find_element_by_css_selector('.c-button .c-button--primary .c-button--medium').click()
HTML code of the items
<div class="c-sk-modal_footer_actions">
<button class="c-button c-button--primary c-button--medium c-button--disabled" data-qa="invite-to-workspace-modal-invite-form-send-button" type="button" aria-disabled="true">
"Send"
::after
</button>
</div>
If it helps at all, this is for the invite people box in slack admin portal
EDIT:
So I basically figured out the issue but can't figure out how to fix the issue...
So just using the variable sys.argv[1] puts in the email address, but I need to either press space bar , comma, or enter key after. I can get it to work if I specify what the variable email is (email = "test#test.com" then confirm = " ") and adding a second line addressbox.send_keys(confirm) but if I make the variable what I need it to be so it's called from powershell (sys.argv[1]) It doesn't work. It's like it removes what I entered and only puts what's in the variable "confirm"
Try the execute script method which can have a better chance when getting that error. Also you could use implicitly wait instead of time waits to be more effecient.
driver.implicitly_wait(5)
addressbox = driver.find_element_by_xpath('/html/body/div[9]/div/div/div[2]/div/div[1]/div/div/div/div/div[3]/div/div/div[1]')
driver.execute_script("arguments[0].click();", addressbox)
Generally <div> elements aren't clickable. Presumably you need to crosscheck if the following element is your desired element:
<div class="c-sk-modal_footer_actions">
Where as, the element from your second attempt:
<div class="c-button c-button--primary c-button--medium...">
looks as a perfect clickable candidate.
Solution
The desired element is a React element, so 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:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".c-button.c-button--primary.c-button--medium"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[#class='c-button c-button--primary c-button--medium']"))).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

How to click on the ember.js enabled button using Selenium and Python

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()

How to click on the angular based checkbox as per the HTML provided through Selenium and Python?

I am trying to click on a checkbox using selenium python. I tried
buttons = driver.find_element_by_xpath("//*[contains(text(), 'Exact')]"); buttons.click()
I keep getting
"ElementNotVisibleException:"
<button type="button" data-ng-class="{iconCheck: event.locationExactness.isExact, inputBox:!event.locationExactness.isExact}" class="link icon locationButton inputBox" data-sfs-callout-visible="relativeExactnesses.length > 1" data-sfs-callout="sfs_-sfsLocationExactness-1-place-callout" data-sfs-callout-focus="sfs_-sfsLocationExactness-1-exact" data-ng-click="updateIsExact(relativeExactnesses.length > 1 ? true : !event.locationExactness.isExact)" data-autoname="NameAPlace_msypn_LocationExactButton"><!--
--><span class="locationLabel ng-binding">Exact</span><!--
--></button>
<<pseudo:before>></<pseudo:before>>
<!--
-->
<span class="locationLabel ng-binding">Exact</span>
<!--
-->
First of all you are locating one element, but are giving it plural name buttons. I would use singular name button.
Second thing is even in your code snippet there is two span which contain Exact. You have to change your locator so, that only one element(which you want to interact with) will be selected via selector.
For example, if you want the first Exact in your code snippet, you can use this xPath:
//button[#data-sfs-callout = 'sfs_-sfsLocationExactness-1-place-callout']/span
Note: as #RajKamal already mentioned, there can be multiple elements on the page with text Exact. You can check this in dev tools by pressing F12.
As per the HTML you have shared the element with text as Exact is a Angular element so to invoke click() on the desired element you have to induce WebDriverWait for the element to be clickable and you can use the following solution:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='link icon locationButton inputBox' and #data-autoname='NameAPlace_msypn_LocationExactButton']//span[#class='locationLabel ng-binding'][contains(.,'Exact')]"))).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

Categories

Resources