1

我在 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用来获取窗口句柄的数量,并且(如预期的那样)它告诉我只有一个窗口句柄。然后,当我单击新窗口的按钮时,它告诉我(再次,正如预期的那样)有两个窗口句柄。但是在代码到达 for 行之前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,并保持不变

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

我的问题:鉴于新打开窗口的句柄保持打开状态(通常)少于 50 毫秒,在 Internet Explorer 10 中使用 Selenium 切换到新窗口的最有效方法是什么?还是我应该做些不同的事情来防止新的窗口句柄丢失?

4

2 回答 2

0

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

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

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

因此,随着这个示例的进行,我只是弄清楚输入了哪些变量(用户名、日期等),自己构建了 URL,然后直接导航到它。因此,我什至根本不必打开并导航到新窗口。

于 2013-10-28T19:09:46.343 回答
0

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

在此处输入图像描述

手动方法:

  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 Settings\Zones\{上面的区域编号}。

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

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

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

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

于 2020-06-17T21:08:13.237 回答