'Python. Selenium. How to wait for new window opens?
I have a button with twitter, and after click new window opens, but before opening there is a timout in few seconds, so is there a way to wait for it? I mait in a bad way for now...
Ui.click_el(link.W9FormNodes.TWITTER_BUTTON)
# Wait for new window and switch to it
time.sleep(3)
aw = driver.window_handles
driver.switch_to_window(aw[1])
So I need something better, that will wait only that amount of seconds that needs.
I think I solve it in this way. But maybe someone will have comments how to do it better.
aw = Ui.click_and_wait_for_window(link.W9FormNodes.TWITTER_BUTTON)
driver.switch_to_window(aw[1])
And here is a method that click on button and wait for new window:
def click_and_wait_for_window(self, node):
current_value = old_value = self.driver.window_handles
self.click_el(node)
while len(current_value) == len(old_value):
time.sleep(0.05)
current_value = self.driver.window_handles
return current_value
Solution 1:[1]
As Surya mentioned, WebDriverWait
would be the way to wait for a change. You could have a context manager like this that only implements the wait logic and then use it for any kind of operation you care about:
@contextmanager
def wait_for_new_window(driver, timeout=10):
handles_before = driver.window_handles
yield
WebDriverWait(driver, timeout).until(
lambda driver: len(handles_before) != len(driver.window_handles))
Here's a full working example:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from contextlib import contextmanager
@contextmanager
def wait_for_new_window(driver, timeout=10):
handles_before = driver.window_handles
yield
WebDriverWait(driver, timeout).until(
lambda driver: len(handles_before) != len(driver.window_handles))
driver = webdriver.Chrome()
driver.get("http://www.google.com")
with wait_for_new_window(driver):
driver.execute_script("""
window.open("http://www.google.com", "_blank");
""")
with wait_for_new_window(driver, 2):
pass # This will obviously hit the timeout.
driver.quit()
Solution 2:[2]
Yes; your implementation looks fine. Only thing is you need to set the timeout, otherwise it will wait for ever, if new window doesn't open.
You can combine with WebDriverWait(driver, 10).until..
to set the timeout.
Hope this helps.
Solution 3:[3]
Now there has a function in the selenium.webdriver.support.expected_conditions
package. For example:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(web, 20).until(EC.new_window_is_opened(driver.window_handles))
It will wait for the new window opens.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Louis |
Solution 2 | Surya |
Solution 3 | Aruix |