新窗口句柄在IE中消失,无法切换到新窗口

时间:2013-10-24 19:40:37

标签: c# internet-explorer selenium

我在Internet Explorer 10中使用最新版本的Selenium(2.37.0)与C#(使用最新的32位InternetExplorerDriver,2.37.0)登录网页,点击一个打开新的按钮窗口,然后将焦点更改为新窗口。

最初我在Firefox中使用此代码,每次都可以使用:

// Get handle for original window
string parentHandle = driver.CurrentWindowHandle;

// Click on button for new window
driver.FindElement(By.Id("buttonForNewWindow")).Click();

// Get list of all window handles
ReadOnlyCollection<string> allWindowHandles = driver.WindowHandles;

// Loop over all handles and switch to new child window
foreach (string handle in allWindowHandles)
{
    if (handle != parentHandle)
    {
        driver.SwitchTo().Window(handle);
    }
}

但这在Internet Explorer中不起作用。

我已经确定了问题所在。在我打开新窗口之前,我使用driver.WindowHandles.Count来获取窗口句柄的数量,并且(如预期的那样)它告诉我只有一个窗口句柄。然后,当我单击新窗口的按钮时,它会(再次按预期)告诉我有两个窗口句柄。但是在代码到达driver.SwitchTo().Window(handle);的行之前,窗口句柄的数量已经下降到一个,即使两个窗口仍然可见

所以不知何故,其中一个窗口句柄迷路了。我已经确认(使用一堆Console.WriteLine语句)被删除的窗口句柄是新的。我还使用Stopwatch类来计算删除新窗口句柄所需的时间:

Stopwatch sw = new Stopwatch();

// Wait until the number of windows has changed from 1 to 2
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((_driver) => { return _driver.WindowHandles.Count != windowsBefore; });

// Start stopwatch
sw.Start();

int numberOfWindows = driver.WindowHandles.Count;

while (numberOfWindows == 2)
{
    numberOfWindows = driver.WindowHandles.Count;
}

sw.Stop();

Console.Write("\nTime elapsed: " + sw.ElapsedMilliseconds + " ms");

运行几次之后,我发现窗口句柄的数量通常会在不到50毫秒的时间内回落到 。然而,有一次窗户把手持续的时间更长;这是原始数字:

Time elapsed: 47 ms
Time elapsed: 31 ms
Time elapsed: 47 ms
Time elapsed: 2861 ms
Time elapsed: 30 ms

我还确认 Firefox中没有出现此问题。当我在Firefox中运行相同的代码时,我发现窗口句柄的数量从1变为2,并保持原样,就像它应该的那样。

似乎其他人也遇到此问题This person发现当他们打开一个新窗口并等待1000毫秒时,getWindowHandles()返回的值为1而不是2.而Selenium Google Group上的this person似乎也有同样的问题。< / p>

我的问题:鉴于新打开的窗口的句柄保持打开(通常)小于50毫秒,在Internet Explorer中切换到新窗口的最有效方法是什么10与硒?或者有什么我应该做的不同,以防止新的窗口句柄迷路?

2 个答案:

答案 0 :(得分:0)

只是想提供更新,以防其他人遇到同样的问题并找到此页面。我没有找到解决问题的方法,但我想出了一个解决方法。

最初,我点击了一个打开新窗口的链接,我无法将Selenium导航到新窗口。我所做的是挖掘页面的源代码,找到我点击的按钮,并找出该按钮所指向的位置。如果它是一个简单的超链接(www.whatever.com / ....),那将是最简单的,但它是一个Javascript函数。 Javascript函数使用一些固定的字符和一些变量来构建超链接;例如:

link(username, date) = "http://www.google.com/user=" + username + "?date=" + date;

因此,继续这个例子,我只是想出了什么变量被输入(用户名,日期等),自己构建了URL,并直接导航到它。因此,我根本不需要打开并导航到新窗口。

答案 1 :(得分:0)

这是由于Internet Explorer中的安全设置不正确。您需要清除“ Internet选项”对话框“安全性”选项卡中四个区域中每个区域的“启用保护模式”复选框。四个区域必须匹配。

enter image description here

手动方法:

  1. 打开Internet Explorer。
  2. 单击“工具”图标或按Alt-X。
  3. 单击Internet选项菜单项或Alt-o。
  4. 单击“安全性”选项卡。
  5. 单击Internet图标。
  6. 清除“启用保护模式”复选框。
  7. 单击本地Intranet图标。
  8. 清除“启用保护模式”复选框。
  9. 重复“受信任的站点”和“受限制的站点”。
  10. 单击“应用”按钮。
  11. 确认安全风险弹出,接受该风险。
  12. 关闭Internet Explorer。

现在,InternetExplorerDriver应该显示正确数量的窗口句柄,并且能够在窗口之间切换。

在我的情况下,手动更改仅持续到重新启动后才恢复,然后恢复了设置,因此,为了确保每次测试运行,我建议修改注册表。

使用注册表的C#示例:

            const string zonesPath =
                @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\";
            const string internetZonePath = zonesPath + "3";
            const string restrictedZonePath = zonesPath + "4";
            const string name = "2500";
            const int value = 3;
            Registry.SetValue(internetZonePath, name, value, RegistryValueKind.DWord);
            Registry.SetValue(restrictedZonePath, name, value, RegistryValueKind.DWord);

区域是:

  • 本地计算机:0
  • 内部网:1
  • 受信任的站点:2
  • 互联网:3
  • 受限制的站点:4

每个区域的路径为:“ HKEY_CURRENT_USER \ Software \ Microsoft \ Windows \ CurrentVersion \ Internet设置\区域\ {上面的区域编号}。

密钥的名称始终为“ 2500”。

要关闭保护模式的值是“ 3”。

要打开保护模式,请将值设置为“ 0”。

为了获得所有手柄,必须将所有区域设置为相同的值。