Handle exception of Pop Up displayed during a Selenium-Python script - python

I was coding a script written in Py and Selenium that slides some slide and clicks a button of each slide, but sometimes, when the button is clicked, a popup is displayed, and other times the script should go regularly.
Can anybody explain me how to handle the ‘exception’ and How can write correctly the Code?
I'm sure to use Try and Exception, but I don't know how to recognize the Popup, so every attempt I tried failed.
try:
element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, “x”)))
element.click() #Click Slider Button
element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, “y”)))
element.click() #Click arrow to go to next slide
exception that, if popup is displayed, do this code
except driver.find_element_by_class_name(“z”).is_displayed():
element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, “f”)))#click to close popup
element.click()
element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, “y”)))
element.click() #click arrow to go to next slide

Try using some popups blocker extensions. If you use a chrome based navigator than this extension works perfectly and will block all possible popups.
Download the extension with this service and follow this question if you don't know how to use extensions with selenium.
This is not exactly the solution you want but it works.

Related

Python Selenium not clicking the correct button in a popup modal using CssSelector

I am using the selenium webdriver in Python to process through a website, but I am running into an issue with clicking a specific button that shows up in a popup modal. Currently, the behavior seems as though the click is being performed, but appears to be clicking the "No" button instead of "Yes."
Here is the snippet of code I am currently using. The first click will hit an "Apply" button, which then opens a popup confirmation modal that requires the user to select No or Yes to continue with applying the request.
driver.find_element(By.CSS_SELECTOR, xpaths['planRangeApply']).click()
time.sleep(2)
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.modal-footer:nth-child(3) > jv-button:nth-child(2)'))).click()
For comparison, here is the CSS_SELECTOR for the "No" button:
div.modal-footer:nth-child(3) > jv-button:nth-child(1)
From what I have researched so far, I am properly waiting for the modal to appear and the proceed to find the Yes button element. Am I misunderstanding this process or is my CSS_SELECTOR path simply incorrect? I have tried utilizing XPATH instead of CSS_SELECTOR, but I get the exact same result.
Here is a screenshot of the page inspector with the correct button highlighted:
The CSS_SELECTOR is slightly off.
The parent tag is <div class="modal-footer">
The desired element is the second <jv-button> child of it's parent.
Solution
The effective CSS_SELECTOR would be:
div.modal-footer jv-button:nth-child(2)

How to click on a button that does not appear on page source?

I'm trying to click on a button using Selenium with Python, however the button does not appear on Page Source and thus, the instantiated driver cannot find it. Here is the link I am accessing: https://data.ntsb.gov/carol-main-public/query-builder?month=6&year=2021
And the button I want to click is "Download Summary (CSV)", which is located at the end of the page.
I have already googled this kind of trouble but I haven't found a possible solution so far.
My attempt was to find the button directly by using the following commands, but it returns a NoSuchElementException:
element = driver.find_element_by_id('exportSummaryButton')
element.click()
This exception triggered me the intuition that the page source differs from what I see on Devtools and this is exactly what happens.
Thanks in advance!

Why Selenium couldn't find any element on page before I used time.sleep()?

I came across this problem while automating task with Selenium.
What was the code execution process?
So first of all there're two functions inside seleniumtest.py :
getGateway() and restartRouter().
Let's focus on restartRouter() function as it contains code related to selenium, and getGateway() function was just function that I used in restartRouter() just like this: driver.get(getGateway()).
First of all, what was happening is following:
Start browser and open provided url;
Find elements username and password
Enter username and password;
Find Login element
Click Login;
Find another button
Click on another button
...
What is the problem?
So, the problem start occuring on step 6, just after clicking Login button (See code execution process, step 6).
After it clicks on login button, it loads new page (it doesn't open it in new tab), and after that it didn't want to work.
What have you tried to do to solve the problem
First thing that came up to mine mind was to use driver.wait(5) just after clicking on login, which didn't work.
I've also tried to check if any other element on that page will result in action .click()
After that, I've tried Waits - SELENIUM WAITS ; which also didn't work. I tried two possible options: driver.implicitly_wait(10) and WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,"//*[#id=\"mmManagDiag\"]")). It also gave me errors how my USB Device isn't working while using explicit waits.
None of these worked.
What worked for me?
After working around it came up to my mind to try with time.sleep(3) and suddenly it worked.
My final question
So, I am wondering why Selenium couldn't find any element on that page before I used time.sleep()?
And isn't selenium waits and time.sleep() almost the same thing?
Code
driver = webdriver.Chrome('./chromedriver')
driver.get(getGateway())
#Frm_Username
username = driver.find_element(By.NAME,'Frm_Username')
username.clear()
username.send_keys("user")
#Frm_Password
passwrd = driver.find_element(By.NAME,"Frm_Password")
passwrd.clear()
passwrd.send_keys("user")
#passwrd.send_keys(Keys.RETURN)
driver.find_element(By.XPATH,"//*[#id=\"LoginId\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"mmManagDiag\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"mmManagDevice\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"Btn_restart\"]").click()
time.sleep(3)
driver.find_element(By.XPATH,"//*[#id=\"confirmOK\"]").click()
driver.quit()
Waiting for the elements presence might be not enough to click on it.
Try to wait for element to be clickable.
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "your xpath value"))
).click()

Locate "file upload" button with Selenium

I have the button shown below (image and HTML) and am trying to click it.
Selenium is unable to locate it - I have tried locating by both xpath and by ID.
<input id="wsUpload1" type="file" name="file">
XPATH:
element = driver.find_element_by_xpath('//input[#id="wsUpload1"]')
element.click()
Where am I going wrong?
EDIT: Here is the exception thrown by Selenium:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//input[#id="wsUpload1"]"}
Possibilities
Duplicate web element with same id in the page.
Element may be in frame. You need to switch to frame
Trying to access the web element before page is loading.Give some wait time.
Not sure why your button wasn't found, maybe it's because of quotes (although it should show you error in that case), try with driver.find_element_by_xpath(".//input[#id='wsUpload1']") and see if it works. I'm not sure is your button already rendered on the page or you trigger it somehow so it's not there yet?
NoSuchElementException is thrown because your targeted element couldn't be found on that page, it could be that you are on the wrong page, element is not rendered yet so you should wait for it to appear, element could be in some iframe etc etc, it's hard to say when I don't know how your page works.
But if you are trying to upload something you should perform sendKeys() on that button (with path of file which are you trying to upload), not click() on it. This is how selenium upload works.
I have solved it - the driver opens a tab on a side panel and the button is in the tab. There seems to be a few ms delay between clicking the tab and the button appearing so I added a wait until element is clickable and that seems to work.
wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#id='wsUpload1']"))).click()

Expected condition: wait until one element clickable while other- dissapeared

I face the following issue: there is a page (unfortunately it's not public) with a Register request and a Approve request button. Clicking on a button leads to opening a transparent div with a pop-up.
Algorithm is as following:
1) Click Register;
2) Fill form in raised pop-up;
3) Click Submit to confirm registration (to close pop-up);
4) Click Approve
So I use the following code:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//button[#id="RegisterButton"]'))).click()
# ...Filling Register form...
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//button[#id="SubmitButton"]'))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//button[#id="ApproveButton"]'))).click()
But despite using EC.element_to_be_clickable() I get the following error:
WebDriverException: Message: unknown error:
Element is not clickable at point (338, 167).
Other element would receive the click: <div class="modal fade" id="confirmWindow" style="display: block;">...</div>
Seems that the driver considers Approve being already clickable and tries to click on it while the transparent div is still displayed.
So I need an Expected Conditions statement to catch the state when the div is already selected and Approve if the button is clickable
P.S. I'm using time.sleep() to do this, but seems to be a rough approach
UPDATED
I try to use JavaScript:
driver.execute_script('document.getElementById("ApproveButton").click();')
and so far it works... I wonder if it really a better way to click on button or there could be some obstacles also?
Understandably using a time.sleep() is something you want to avoid. Since it clicks on the modal I am assuming the button is considered clickable even though the modal isn't fully disappeared yet. In this case I would add another wait that waits till the modal is no longer visible.
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, '//button[#id="RegisterButton"]'))).click()
# ...Filling Register form...
wait.until(EC.element_to_be_clickable((By.XPATH, '//button[#id="SubmitButton"]'))).click()
# Wait till the modal is no longer visible
wait.until_not(EC.visibility_of_element_located((By.ID, 'confirmWindow')))
wait.until(EC.element_to_be_clickable((By.XPATH, '//button[#id="ApproveButton"]'))).click()
Note: I've also created a single instance of WebDriverWait instead of making a new one for each wait like you did in your example. There is no need to create a new instance all the time.

Categories