Как веб-драйвер селена узнает, когда откроется новое окно, а затем возобновит его выполнение
Я столкнулся с проблемой автоматизации веб-приложения с помощью веб-драйвера селена.
На веб-странице есть кнопка, которая при нажатии открывается в новом окне. Когда я использую следующий код, он бросает OpenQA.Selenium.NoSuchWindowException: No window found
WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();
Чтобы решить вышеупомянутую проблему, я добавляю Thread.Sleep(50000);
между нажатиями кнопок и SwitchTo
.
WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
Thread.Sleep(50000); //wait
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();
Он решил проблему, но я не хочу использовать оператор Thread.Sleep(50000);
, потому что если в окне требуется больше времени для открытия, код может выйти из строя, и если окно будет открыто быстро, это сделает тест медленным без необходимости.
Есть ли способ узнать, когда окно открылось, а затем тест может возобновить выполнение?
Ответы
Ответ 1
Вам нужно переключить элемент управления во всплывающее окно перед выполнением каких-либо операций. Используя это, вы можете решить свою проблему.
Перед тем, как открыть всплывающее окно, вы получите дескриптор главного окна и сохраните его.
String mwh=driver.getWindowHandle();
Теперь попробуйте открыть всплывающее окно, выполнив какое-то действие:
driver.findElement(By.xpath("")).click();
Set s=driver.getWindowHandles(); //this method will gives you the handles of all opened windows
Iterator ite=s.iterator();
while(ite.hasNext())
{
String popupHandle=ite.next().toString();
if(!popupHandle.contains(mwh))
{
driver.switchTo().window(popupHandle);
/**/here you can perform operation in pop-up window**
//After finished your operation in pop-up just select the main window again
driver.switchTo().window(mwh);
}
}
Ответ 2
Вы можете подождать, пока операция не завершится успешно, например, в Python:
from selenium.common.exceptions import NoSuchWindowException
from selenium.webdriver.support.ui import WebDriverWait
def found_window(name):
def predicate(driver):
try: driver.switch_to_window(name)
except NoSuchWindowException:
return False
else:
return True # found window
return predicate
driver.find_element_by_id("id of the button that opens new window").click()
WebDriverWait(driver, timeout=50).until(found_window("new window name"))
WebDriverWait(driver, timeout=10).until( # wait until the button is available
lambda x: x.find_element_by_id("id of button present on newly opened window"))\
.click()
Ответ 3
Наконец-то я нашел ответ,
Я использовал метод ниже, чтобы перейти в новое окно,
public String switchwindow(String object, String data){
try {
String winHandleBefore = driver.getWindowHandle();
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
}catch(Exception e){
return Constants.KEYWORD_FAIL+ "Unable to Switch Window" + e.getMessage();
}
return Constants.KEYWORD_PASS;
}
Чтобы перейти к родительскому окну, я использовал следующий код,
public String switchwindowback(String object, String data){
try {
String winHandleBefore = driver.getWindowHandle();
driver.close();
//Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
//continue with original browser (first window)
}catch(Exception e){
return Constants.KEYWORD_FAIL+ "Unable to Switch to main window" + e.getMessage();
}
return Constants.KEYWORD_PASS;
}
Я думаю, это поможет вам переключаться между окнами.
Ответ 4
Я использую это, чтобы ждать открытия окна, и он работает для меня.
Код С#:
public static void WaitUntilNewWindowIsOpened(this RemoteWebDriver driver, int expectedNumberOfWindows, int maxRetryCount = 100)
{
int returnValue;
bool boolReturnValue;
for (var i = 0; i < maxRetryCount; Thread.Sleep(100), i++)
{
returnValue = driver.WindowHandles.Count;
boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
if (boolReturnValue)
{
return;
}
}
//try one last time to check for window
returnValue = driver.WindowHandles.Count;
boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
if (!boolReturnValue)
{
throw new ApplicationException("New window did not open.");
}
}
И затем я вызываю этот метод в коде
Extensions.WaitUntilNewWindowIsOpened(driver, 2);