Python Selenium Wait for user to click a button
Asked Answered
C

3

8

Context:

  1. My script launch to a website using selenium webdriver
  2. The user fills in some stuff on the website
  3. The user will click a button which will popup a confirm()dialog box asking the user "Do you want to submit the data"

My intention:

My script would wait till the user click the button. Once it detects that the user clicked the button, my script would get a value of an element and then (somehow) click OK on the dialog box.


Question:

How do wait for the user to click the button?

How do I then click OK on the dialog box?


Additional Notes:

Using: chromedriver, Python 2.7

The button: <input id="submitID" type="button" class="medium" value="Submit filled Data">


[EDIT] Some code snippet:

The dialog popup is javascript popup:

    if (window.confirm("Are you sure you want to submit the data?")) {
        this.SaveData();
    }

My code (simplified & modified for this question):

from selenium import webdriver
from selenium.common.exceptions import WebDriverException

PATH_TO_CHROMEDRIVER = 'path/to/chromedriver'
URL = 'https://website-asking-user-to-fill-in-stuff.com'

driver = webdriver.Chrome(PATH_TO_CHROMEDRIVER)
driver.get(URL)

while True:
    # loop until user close the chrome.
    # If anyone has any better idea to
    # WAIT TILL USER CLOSE THE WEBDRIVER, PLEASE SHARE IT HERE

    try:
        # --- main part of the code ---

        waitForUserToClickButton() # this is what I need help with

        driver.find_element_by_id('elementID').text

        confirmJavascriptPopup() # this is also what I need help with

    except WebDriverException:
        print 'User closed the browser'
        exit()
Capillary answered 3/8, 2018 at 23:50 Comment(3)
Is it a javascript or html popup? Also, you should share some code snippet for what have you tried so far and html for the alert if its an html popupAcquittance
It's very interesting question but I think it's not possible via Selenium.Helgahelge
@Acquittance It's a javascript popup.Capillary
M
5

Q: How do wait for the user to click the button?

In this case , you can introduce WebDriverWait which is explicit wait in selenium.

You can try with this code :

from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'submitID')))  

Q. How do I then click OK on the dialog box?

In this case first you would have to switch the focus of your web driver to the alert and then you can click on it.

    alert = browser.switch_to.alert
    alert.accept()
    print("alert accepted")  

UPDATE 1:

When you are performing the click operation then there is one alert gets popped up. You can extract the text from the alert using this code :

alert = browser.switch_to.alert
msg_from_alert = alert.text  
alert.accept() 

Now You can simply match it with your expected message which is already known to you.

expected_msg = "some msg from alert"  

from collections import Counter
Counter(msg_from_alert) == Counter(expected_msg)
True
Mama answered 4/8, 2018 at 10:19 Comment(14)
EC.element_to_be_clickable will wait until the button will be clickable and unfortunately, the button is clickable all the time. But as for the second answer, it worked.Capillary
Element to be clickable checks for visibilty of web element and whether web element is enable or not. By combining these two conditions we assume that element should be in a state of clicking. Now if there is any problem with overlying that has to be handled by script writer.Mama
Oh, I think you misunderstood my problem. I want the script to wait/detect when the user clicks or clicked the button and not when the button is clickable.Capillary
Ok what happens manually when you perform click operation ? I guess alert appeared after that ?Mama
Yes, if you are thinking to use WebDriverWait(driver, 10).until(EC.alert_is_present()) then I already thought about it. (check my latest edit)Capillary
Once I click on button then I know that a JS alert will pop up, now I would simply extract the data which is present in alert and match it with my expected text. If both strings are same then my script will get to know that I have clicked on the right button.Mama
Actually that is not a bad idea! Please edit your answer for the first question and I will accept that. It's a pity that the solution only works if the button will cause an alert box to pop up. Other people with similar situation might not be able to apply the solution.Capillary
@ProgramerBeginner : Updated the answer though.Mama
just curious: any reason why you use Counter()? why not expected_msg == msg_from_alert?Capillary
There are n number of ways you can verify it. using this expected_msg == msg_from_alert will check for length of string , Counter() would check for character , So IMO, that makes more sense. As a first layer of verification you can use expected_msg == msg_from_alert . and one more way would be : if expected_msg in msg_from_alert: then print true.Mama
my submit button does not has an ID how should I do it?Generation
this will not work if the button is always clickable, i believe. are there any other solutions?Glassco
@Glassco : Please feel free to create a new ticket if this does not solve your problemMama
posted a question over here. your input/knowledge would be appreciatedGlassco
G
1

Here is a solution I devised that may not work for everybody. Poll the URL...

poll_rate = 1
current_url = driver.current_url
while driver.current_url == current_url:
  time.sleep(poll_rate)

Can anybody come up with a better solution?!

I am shocked that it is almost impossible to detect user input in a practical manner.

Glassco answered 22/7, 2021 at 19:56 Comment(0)
W
0

Just a slight modification to the above answer for my use case. I put a 30 seconds window for the user to enter his password. The while loop is not necessary for my scenario.

poll_rate = 30
current_url = driver.current_url
time.sleep(poll_rate)
driver.find_element(By.NAME, "verifyPassword").click()
Willette answered 1/5, 2022 at 12:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.