Selenium Web 驱动程序如何知道新窗口何时打开,然后恢复执行

发布于 2025-01-03 20:59:27 字数 1107 浏览 4 评论 0原文

我在使用 Selenium 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();

为了解决上述问题,我在按钮单击之间添加 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); 语句,因为如果窗口需要更多时间打开,代码可能会失败,如果窗口打开很快,那么它会使测试速度不必要地变慢。

有什么方法可以知道窗口何时打开然后测试可以恢复执行?

I am facing an issue in automating a web application using selenium web driver.

The webpage has a button which when clicked opens a new window. When I use the following code, it throws 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();

To solve the above issue I add Thread.Sleep(50000); between the button click and SwitchTo statements.

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();

It solved the issue, but I do not want to use the Thread.Sleep(50000); statement because if the window takes more time to open, code can fail and if window opens quickly then it makes the test slow unnecessarily.

Is there any way to know when the window has opened and then the test can resume its execution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

硪扪都還晓 2025-01-10 20:59:27

在进行任何操作之前,您需要将控件切换到弹出窗口。通过使用这个你可以解决你的问题。

在打开弹出窗口之前获取主窗口的句柄并保存它。

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

You need to switch the control to pop-up window before doing any operations in it. By using this you can solve your problem.

Before opening the popup window get the handle of main window and save it.

String mwh=driver.getWindowHandle();

Now try to open the popup window by performing some action:

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);
    }
}
放赐 2025-01-10 20:59:27

您可以等到操作成功,例如在 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()

You could wait until the operation succeeds e.g., in 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()
梓梦 2025-01-10 20:59:27

我终于找到答案了
我使用下面的方法切换到新窗口,

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

我认为这将帮助您在窗口之间切换。

I finally found the answer,
I used the below method to switch to the new window,

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

To move to parent window, i used the following code,

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

I think this will help u to switch between the windows.

Saygoodbye 2025-01-10 20:59:27

我用它来等待窗口打开,它对我有用。

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

I use this to wait for window to be opened and it works for me.

C# code:

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.");
        }
    }

And then i call this method in the code

Extensions.WaitUntilNewWindowIsOpened(driver, 2);
夜司空 2025-01-10 20:59:27

您可以使用 WebDriverWait 等待另一个窗口弹出。
首先,您必须保存所有打开的窗口的当前句柄:

private Set<String> windowHandlersSet = driver.getWindowHandles();

然后单击按钮打开一个新窗口并等待它弹出:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(driver -> !driver.getWindowHandles().equals(windowHandlersSet));

这会检查当前窗口句柄集与保存的窗口句柄集相比是否有更改。我使用这个解决方案在 Internet Explorer 下编写测试,打开新窗口总是需要几秒钟的时间。

You can wait for another window to pop using WebDriverWait.
First you have to save current handles of all opened windows:

private Set<String> windowHandlersSet = driver.getWindowHandles();

Then you click a button to open a new window and wait for it to pop with:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(driver -> !driver.getWindowHandles().equals(windowHandlersSet));

Which checks if there is a change to current window handles set comparing to saved one. I used this solutnion writing tests under Internet Explorer where it always takes few seconds to open new window.

只等公子 2025-01-10 20:59:27
    WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(max duration you want it to check for new window));
    wait.until(ExpectedConditions.numberOfWindowsToBe(2));//here 2 represents the current window and the new window to be opened
    WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(max duration you want it to check for new window));
    wait.until(ExpectedConditions.numberOfWindowsToBe(2));//here 2 represents the current window and the new window to be opened
情绪少女 2025-01-10 20:59:27

虽然这个问题已经有了答案,但它们对我来说都没有真正的用处,因为我不能依赖获得任何新窗口,我需要过滤更多,所以我开始使用 Dadoh 的解决方案,但对其进行了调整,直到我想出这个解决方案,希望对某人有用。

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

Although this question already has answers, none of them was useful to me really since I can't rely on getting any new window, I needed to filter even more, so I started using Dadoh's solution but tweaked it until I came up with this solution, hope it will be of some use to someone.

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

So in this solution I opted to pass the expected window title as an argument for the function to loop all windows and compare the new window title, this way, it's guaranteed to return the correct window. Here is an example call to this method:

await WaitUntilNewWindowIsOpen("newWindowTitle", true);
聽兲甴掵 2025-01-10 20:59:27

下面的函数可以等待给定的最长时间,直到您的新窗口打开

public static void waitForWindow(int max_sec_toWait, int noOfExpectedWindow) {
    FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
    wait.pollingEvery(Duration.ofMillis(200));
    wait.withTimeout(Duration.ofSeconds(max_sec_toWait));
    wait.ignoring(NoSuchWindowException.class);
    Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>(){
        @Override
        public Boolean apply(WebDriver driver) {
            Set<String> handel = driver.getWindowHandles();
            if(handel.size() == noOfExpectedWindow) 
                return true;
            else 
                return false;
            }
    };      
    wait.until(function);
}

Below function can wait for given max time until your new window is open

public static void waitForWindow(int max_sec_toWait, int noOfExpectedWindow) {
    FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
    wait.pollingEvery(Duration.ofMillis(200));
    wait.withTimeout(Duration.ofSeconds(max_sec_toWait));
    wait.ignoring(NoSuchWindowException.class);
    Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>(){
        @Override
        public Boolean apply(WebDriver driver) {
            Set<String> handel = driver.getWindowHandles();
            if(handel.size() == noOfExpectedWindow) 
                return true;
            else 
                return false;
            }
    };      
    wait.until(function);
}
蓝戈者 2025-01-10 20:59:27

js代码

     await firstPage.clickOnLink();
        let tabs = await driver.getAllWindowHandles();
        await driver.switchTo().window(tabs[1]);
        await driver.wait(await until.titleContains('myString'), 2000);

Js code

     await firstPage.clickOnLink();
        let tabs = await driver.getAllWindowHandles();
        await driver.switchTo().window(tabs[1]);
        await driver.wait(await until.titleContains('myString'), 2000);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文