Selenium Webドライバーを使用してWebアプリケーションを自動化する際に問題に直面しています。
Webページにはボタンがあり、クリックすると新しいウィンドウが開きます。次のコードを使用すると、_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();
_
上記の問題を解決するために、ボタンクリックとSwitchTo
ステートメントの間にThread.Sleep(50000);
を追加します。
_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);
ステートメントを使用したくありません。ウィンドウを開くのに時間がかかるとコードが失敗し、ウィンドウがすぐに開くとテストが不必要に遅くなるためです。
ウィンドウが開いてからテストが実行を再開できるタイミングを知る方法はありますか?
操作を行う前に、コントロールをポップアップウィンドウに切り替える必要があります。これを使用することにより、問題を解決できます。
ポップアップウィンドウを開く前に、メインウィンドウのハンドルを取得して保存します。
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);
}
}
たとえば、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()
私はこれを使用して、ウィンドウが開くのを待ちます。
C#コード:
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);
私は最終的に答えを見つけました、私は新しいウィンドウに切り替えるために以下の方法を使用しました、
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;
}
これはウィンドウを切り替えるのに役立つと思います。
この質問にはすでに答えがありますが、新しいウィンドウを取得することに頼ることができないため、それらのどれも本当に役に立ちませんでした。 、誰かの役に立つことを願っています。
public async Task<string> WaitUntilNewWindowIsOpen(string expectedWindowTitle, bool switchToWindow, int maxRetryCount = 100)
{
string newWindowHandle = await Task.Run(() =>
{
string previousWindowHandle = _driver.CurrentWindowHandle;
int retries = 0;
while (retries < maxRetryCount)
{
foreach (string handle in _driver.WindowHandles)
{
_driver.SwitchTo().Window(handle);
string title = _driver.Title;
if (title.Equals(expectedWindowTitle))
{
if(!switchToWindow)
_driver.SwitchTo().Window(previousWindowHandle);
return handle;
}
}
retries++;
Thread.Sleep(100);
}
return string.Empty;
});
return newWindowHandle;
}
そのため、このソリューションでは、すべてのウィンドウをループし、新しいウィンドウタイトルを比較する関数の引数として予想されるウィンドウタイトルを渡すことを選択しました。これにより、正しいウィンドウを返すことが保証されます。このメソッドの呼び出し例を次に示します。
await WaitUntilNewWindowIsOpen("newWindowTitle", true);