Internet Explorer 8-10 中的 Selenium WebDriver 窗口切换问题

Posted

技术标签:

【中文标题】Internet Explorer 8-10 中的 Selenium WebDriver 窗口切换问题【英文标题】:Selenium WebDriver windows switching issue in Internet Explorer 8-10 【发布时间】:2011-11-07 14:44:11 【问题描述】:

我在尝试使用 Selenium WebDriver 测试我们的应用程序时发现了一个问题。问题在于 IE9 中的不稳定弹出窗口。它并不总是可重现的,它发生在大约 20% 的窗口切换中,但几乎不可能在 IE 上进行测试。在 FireFox 中一切正常。

    我尝试增加超时时间:

TimeSpan interval = new TimeSpan(0, 0, 10); driver.Manage().Timeouts().ImplicitlyWait(interval);

    创建自己的对象查找方法:

               for (int x = 0; x <= waitTimeOut; x++)
                
                    try
                    
                        element = (IWebElement)driver.FindElement(By.XPath(obj.Xpath));
                        return element;
                    
    
                    catch
                
    

    尝试使用 CssSelecotrs

    尝试在找到元素之前进行一些重新切换:

    driver.SwitchTo().Window(GetWindowHandle(2, 1)); driver.SwitchTo().Window(GetWindowHandle(0, 1)); driver.SwitchTo().Window(GetWindowHandle(2, 1));

如果出现问题,它总是只发生在我尝试在页面上找到的第一个元素上。如果找到该元素,则在此页面上查找其他元素没有任何问题。所以我认为问题在于专注。

调试器中的 Windows 句柄正确显示。例如,如果我切换到第三个窗口, driver.CurrentWindowHandle 会给我第三个窗口的正确句柄。但是,如果我尝试查找任何元素,FindElement() 会抛出异常。页面已加载,我可以手动单击元素但 FindElement() 找不到它。如果我重新运行测试,这一步可以毫无问题地通过,并且只会在下一次切换或更长时间时失败。这是不可预测的。

出现这种问题的原因是什么?

【问题讨论】:

您使用的是什么版本的 Selenium?我曾经只在 IE 上遇到过类似的问题,我必须通过在 SwitchTo 命令后添加 1000-5000 毫秒的睡眠来解决此问题。 【参考方案1】:

使用 IE 驱动程序,不能保证窗口在集合中出现的顺序。也就是说,集合中的第 0 个窗口不一定是会话打开的第一个窗口。鉴于这种情况,您需要执行以下操作:

private string FindNewWindowHandle(IWebDriver driver, IList<string> existingHandles, int timeout)

    string foundHandle = string.Empty;
    DateTime endTime = DateTime.Now.Add(TimeSpan.FromSeconds(timeout));
    while (string.IsNullOrEmpty(foundHandle) && DateTime.Now < endTime)
    
        IList<string> currentHandles = driver.WindowHandles;
        if (currentHandles.Count != existingHandles.Count)
        
            foreach (string currentHandle in currentHandles)
            
                if (!existingHandles.Contains(currentHandle))
                
                    foundHandle = currentHandle;
                    break;
                
            
        

        if (string.IsNullOrEmpty(foundHandle))
        
            System.Threading.Thread.Sleep(250);
        
     

     // Note: could optionally check for handle found here and throw
     // an exception if no window was found.
     return foundHandle;

上述函数的用法如下:

IList<string> handles = driver.WindowHandles;
// do whatever you have to do to invoke the popup
element.Click();
string popupHandle = FindNewWindowHandle(driver, handles, 10);
if (!string.IsNullOrEmpty(popupHandle))

    driver.SwitchTo().Window(popupHandle);

【讨论】:

谢谢,我将它转换为 Java,它对我有用。你真棒。 这解释了一些事情..我一直在根据索引切换 IE,假设窗口句柄将按照它们打开的顺序。 @djangofan :你能把转换后的 java 代码放在这里吗?我正在尝试同样的事情,但对我来说没有成功。【参考方案2】:

如果是 IE11,修改 HKLM_CURRENT_USER\Software\Microsoft\Internet Explorer\Main 路径应包含键 TabProcGrowth 值为 0。

【讨论】:

【参考方案3】:
String currentWindowHandle = driver.getWindowHandle();
        driver.findElement(By.cssSelector(locator)).click();
        Set<String> windows = driver.getWindowHandles();
        for (String window : windows) 
            if (!window.equals(currentWindowHandle)) 
                driver.switchTo().window(window);
                driver.close();
            
        
        driver.switchTo().window(currentWindowHandle);

【讨论】:

你应该解释你的答案。

以上是关于Internet Explorer 8-10 中的 Selenium WebDriver 窗口切换问题的主要内容,如果未能解决你的问题,请参考以下文章

Internet Explorer中的Imagenes PHP透明

CSS Internet Explorer 5.5 - 6中的PNG支持,带有工作链接

Internet Explorer 9 中的渐变

Internet Explorer 中的 CSS“未设置”/“初始”

Internet Explorer 中的 JQuery 选择器问题

Internet Explorer 忽略 URL 中的 Hashtag