Selenium FireFox Driver stops responding after pop-up disappears - python

I would appreciate some thoughts on a problem at hand that I've been trying to solve for 1-2 days.
I am running a Python script with Selenium 2.53.6 on FireFox 49.0.1. The script is supposed to click a series of document-download links on a page (I have set the browser to automatically download these file types instead of opening them). Upon clicking, one of the following two events may unfold:
A pop-up window appears. A button on the pop-up window needs to be clicked to close it before the document is downloaded.
A blank pop-up appears momentarily before it disappears on its own when the document download begins.
Here's an excerpt of the script that is written to handle the events above:
file_link = tr.find_element_by_xpath('td[5]/a')
file_link.click()
time.sleep(7) # Allows the blank pop-up to disappear automatically under Event2
agree_button = None
# Checks for the pop-up window
try:
print "Step 1"
driver.switch_to.window(driver.window_handles[1])
print "Step 2" # SCRIPT STOPS RUNNING HERE
agree_button = driver.find_element_by_xpath('//input[#value="Agree and proceed"]')
print "Popup found"
except:
driver.switch_to.window(driver.window_handles[0])
# Clicks the button if the pop-up window is found
if agree_button is not None:
agree_button.click()
print "Button clicked"
The trouble surfaces when there's high latency in the network for Event 2. Under normal circumstances, the blank pop-up disappears almost instantaneously and the download begins immediately after. However, if the network is slow, the blank pop-up may persist beyond the allocated 7 seconds and that resulted in the script running into "Step 2" before the pop-up window disappears.
Strangely, at this point the script doesn't continue on to look for the agree_button. If it does, then that would have triggered the exception and I would be able to revert back to the original window to resume the steps. The script just stalls and does nothing it seems.
Thanks in advance for your time guys!

You need to keep on waiting until the pop-up disappears. One way you might do this is making below changes in your code:
file_link = tr.find_element_by_xpath('td[5]/a')
file_link.click()
time.sleep(7) # Allows the blank pop-up to disappear automatically under Event2
agree_button = None
# Checks for the pop-up window
try:
print "Step 1"
driver.switch_to.window(driver.window_handles[1])
print "Step 2" # SCRIPT STOPS RUNNING HERE
while True:
agree_button = driver.find_element_by_xpath('//input[#value="Agree and proceed"]')
if agree_button is not None:
break
else:
sleep(7)
print "Popup found"
except:
driver.switch_to.window(driver.window_handles[0])
# Clicks the button if the pop-up window is found
if agree_button is not None:
agree_button.click()
print "Button clicked"

Related

How to click random pop up during a loop?

in my scraping script in python I'm in a situation where, while collapsing multiple buttons on a page, randomically a couple of pop up appear in the page and automatically the script fails.
These two pop ups are already managed and the beginning of the script but the website in a non systematic way dedices to show these two.
This is the part of the script interested where the script sleeps for 3 secs between one click to the other:
collapes = driver.find_elements_by_css_selector('.suf-CompetitionMarketGroup suf-CompetitionMarketGroup-collapsed ')
for collapes in collapes:
collapes.click()
sleep(3)
These are the two lines of the scipt where I click on the pop ups at the beginning
wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div/div[2]/div[2]'))).click()
driver.find_element(By.XPATH, '/html/body/div[1]/div/div[4]/div[1]/div/div[3]/div[4]/div[3]/div').click()
DO you think there's a way to continue running the process being ready to click on these two without going on error?
You can try to close the popups every time your code in for loop fails:
def try_closing_popups():
try:
wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div/div[2]/div[2]'))).click()
driver.find_element(By.XPATH, '/html/body/div[1]/div/div[4]/div[1]/div/div[3]/div[4]/div[3]/div').click()
except:
pass
collapes = driver.find_elements_by_css_selector('.suf-CompetitionMarketGroup suf-CompetitionMarketGroup-collapsed ')
for collapes in collapes:
try:
collapes.click()
except:
try_closing_popups()
sleep(3)

How to go back to top of loop after finishing?

When visiting some websites with selenium there are times where the page doesn't load correctly. So I want to write a code that checks if the website loaded correctly by searching for a particular button. If it can't find the button it needs to refresh until it finds the button and if the code does find the button it needs to execute the rest of the code.
So for example: Button not there: >>> refresh >>> (checks again if button is not there) Button not there >>> refresh >>> (checks again if button is not there) Button is there >>> rest of code
The loop that I currently have looks like this but after refreshing the loop doesn't restart and runs the else: function.
So the question is how do I make a loop that restarts the loop after it refreshes.
while not (driver.find_elements(By.CLASS_NAME, "button")):
driver.refresh()
else:
Rest of code
Help would be much appreciated, thanks in advance
You can have an infinite while loop, and an if condition with find_elements, Please note that find_elements does not return any exception, it returns a list of web elements or either 0.
Code:
while True:
try:
if len(driver.find_elements(By.XPATH, "xpath of the button")) >0:
print("Button is present, since find elements list is non empty")
# execute the code, may be click on the button or whatever it is.
#make sure to exit from infinite loop as well
break
else:
driver.refresh()
#may be put some delay here to let button available to click again.
except:
print("There was some problem trying to find the button element, tearing it down")
break

Intermittent issues with pywinauto.type_keys() going out of focus

I have a piece of pywinauto code which attempts to delete an Item from an ItemList. Occasionally the type_keys() isn't working, as if the window is going out of focus. Interestingly enough, if I click on the Command Prompt window where the python code is running, this suddenly triggers the code to properly set focus on the application and continue running.
Here's an overview of the steps:
Opens an Open Diaglog window in certain application
(here its Tradestation's Development Environment)
Selects an item from the ItemList
Type DELETE key
(confirmation window pops up)
Select 'Yes' in the confirmation window
Most of the time this sequence works, except occasionally (maybe 1 out of every 5 or so tries) it fails where the DELETE key press isn't happening. The item is selected, but the window appears out of focus (or so it seems).
I've been chasing this issue for days/weeks, trying various different things, i.e. added delays, adjusted timeouts, adjusted pywinauto.Timings.fast/slow, tried setting focus in various places, etc... I also put the code into an infinite 'while' loop hoping that it would work on subsequent tries.
Interestingly enough, when it gets stuck, if I click on the Windows Command Prompt window where the python application is running, then suddenly the Open Diaglog box goes back into focus and continues to run successfully.
I'm looking for suggestions as to the root cause OR what else I could try.
Here's where the code has ended up:
strategy = self.window.child_window(title=name, control_type='ListItem')
Timings.slow()
while True:
# Issues where delete/confirm window not showing
# Try solving with SetFocus in case the open diag is going out of focus
_logger.info("Set focus")
handle = win32gui.FindWindow(None, OPEN_DLG_TITLE)
win32gui.SetForegroundWindow(handle)
# Highlight the strategy
_logger.info("Select Strategy")
strategy.select()
if strategy.is_selected() == 0:
time.sleep(2)
continue
_logger.info("Strategy selected")
# Delete it...
_logger.info("Type DELETE")
#strategy.type_keys('{DELETE}')
strategy.type_keys('{DELETE}', set_foreground=False)
# Delay in case return comes back too quickly
time.sleep(2)
# Click 'Yes' in Confirmation Window
_logger.info("Check confirmation window")
confirm_window = self.window.child_window(
title="Confirm file removal",
control_type="Window"
)
if confirm_window.exists() is False:
try:
_logger.info('... does not exist. Briefly wait 5 seconds')
confirm_window.wait('exists', timeout=5)
except pywinauto.timings.TimeoutError:
#breakpoint()
_logger.info('---- Retrying -----')
continue
assert confirm_window.exists() is True
break
Timings.fast()

Make Python script wait for button click ipywidgets

I'm sorry if this question has already been answered, but I couldn't find anything on here (except this one which hasn't been answered: link and one that doesn't quite answer the question i'm asking link
I'm creating a button with ipywidgets, but the script doesn't wait for the button to be clicked. Here's a sample of the code/what I'm trying to achieve:
button = widgets.Button(description = "Click")
output = widgets.Output()
display(button, output)
def on_button_clicked(b):
with output:
print("button clicked")
button.on_click(on_button_clicked)
print("Python is ignoring you")
If I run this, I'll just get "Python is ignoring you" before I click the button. I want it to display the button, wait for the person to click it, and only then execute the rest ("Python is ignoring you").
Does anyone have an idea of how I can make python wait for the button to be clicked?
Would appreciate any help! Thanks
I never used the ipywidgets, but the problem is on the last line
you're telling python to print "Python is ignoring you" and python is doing it.
It will not wait for the user to click the button,
because the print statement is out the function "on_button_clicked".(or any)
So just Put it in the function. (That print Statement)

Selenium not printing out the right URL

I'm practicing with selenium right now but I can't seem to get it to print the correct URL.
import time
from selenium import webdriver
driver = webdriver.Firefox()
home_page = ''
driver.get(home_page)
time.sleep(15)
for i in range(1,9):
listing_page = driver.find_element_by_xpath('//*[#id="m_property_lst_cnt_realtor_more_'+str(i)+'"]').click()
realtor_url = driver.find_element_by_xpath('//*[#id="lblMediaLinks"]/a').click()
print(driver.current_url)
driver.get(home_page)
time.sleep(5)
I need the URL of the webpage that opens up when selenium clicks on the element in realtor_url. It instead prints the URL of the first click from listing_page.
(Note: webpage that is opened from realtor_url is a completely different website, if that helps)
You need to switch to the newly opened window before printing the URL, then close the newly opened window and switch back to the original window.
// do the click that opens another window
WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) == 2)
driver.switch_to_window(driver.window_handles[1])
print(driver.current_url)
driver.close()
driver.switch_to_window(driver.window_handles[0])
A couple other things...
.click() returns void, i.e. nothing, so there's nothing ever stored in listing_page or realtor_url variables.
sleep() is a bad practice. Don't use it. Google it to find out the details why. Replace sleep() with a relevant WebDriverWait.
I believe you need to change the "focus"of the window in order to print the correct url. The current window handler may be pointing to the previous click and not changed focus to the new window.
Try and get to change the "window handler". Every new window opened has a handler.
I hope this helps. window_handles Or this Handle multiple window in Python
EDIT:
The below should bring you to the latest open window.
driver.switch_to_window(driver.window_handles[-1])

Categories

Resources