web-dev-qa-db-ja.com

Selenium Webドライバーは、新しいウィンドウがいつ開かれたかを知ることができ、実行を再開できますか

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);ステートメントを使用したくありません。ウィンドウを開くのに時間がかかるとコードが失敗し、ウィンドウがすぐに開くとテストが不必要に遅くなるためです。

ウィンドウが開いてからテストが実行を再開できるタイミングを知る方法はありますか?

24
Ozone

操作を行う前に、コントロールをポップアップウィンドウに切り替える必要があります。これを使用することにより、問題を解決できます。

ポップアップウィンドウを開く前に、メインウィンドウのハンドルを取得して保存します。

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);
    }
}
28
Santoshsarma

たとえば、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()
11
jfs

私はこれを使用して、ウィンドウが開くのを待ちます。

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);
1
DadoH

私は最終的に答えを見つけました、私は新しいウィンドウに切り替えるために以下の方法を使用しました、

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;
            }

これはウィンドウを切り替えるのに役立つと思います。

1
Prasanna

この質問にはすでに答えがありますが、新しいウィンドウを取得することに頼ることができないため、それらのどれも本当に役に立ちませんでした。 、誰かの役に立つことを願っています。

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);
0
HeD_pE