【问题标题】:Selenium: switch tab in RemoteWebDriver with C#Selenium:使用 C# 在 RemoteWebDriver 中切换选项卡
【发布时间】:2017-09-14 17:58:35
【问题描述】:

目前,我正在尝试使用 Selenium Grid 和 RemoteWebDriver 在 Safari 上运行我的 Selenium 测试。这是我的设置:

  • Mac OS Sierra 10.12.6 作为运行测试的机器。
  • Selenium 服务器 3.5.3。
  • Safari 11.
  • C# Selenium WebDriver 和 Selenium 支持(最新版本)。

我在我的主机操作系统 (Windows 10) 上使用端口转发将请求转发到在我的虚拟机上运行的 Mac。在我的 Mac 上,我有 Selenium Grid 集线器,我像这样运行它:

java -jar selenium-server-standalone-3.5.3.jar -role hub -port 4723

还有一个节点:

java -jar selenium-server-standalone-3.5.3.jar -role node -hub http://10.0.2.15:4723/grid/register

在代码中,我这样启动我的驱动程序:

SafariOprions options = new SafariOptions();
IWebDriver driver = new RemoteWebDriver(new Uri(hubURL), options.ToCapabilities());

我的测试在当前设置下运行良好。但是,当点击属性为target='_blank' 的链接时,我开始面临一些麻烦。对于我在本地运行的其他驱动程序,我可以毫无问题地切换选项卡:在单击链接之前我得到driver.WindowHandles,然后单击链接并再次检索窗口句柄以与以前的句柄进行比较。之后我使用driver.SwitchTo().Window(newHandle),一切正常。

但是当谈到 RemoteWebDriver(或 Apple 的 SafariDriver,我不能更准确地说)时,我总是只得到一个窗口句柄,即使打开了新标签并且我可以看到它。

作为建议的解决方案之一,我试图避免使用“Command + T”切换选项卡,因为我的测试旨在在所有浏览器(Chrome、Firefox、Opera、Edge、Safari)上运行,这不起作用。

更新:我尝试通过 RemoteWebDriver 在 Selenium Grid 中运行 Chrome 和其他浏览器,我可以说这不是 RemoteWebDriver 的问题。接下来,我安装了 Visual Studio for Mac 并重写了一些东西以在没有 Selenium Grid 的情况下运行我的测试,只需使用以下代码:

//if memory serves, just like this
SafariOptions options = new SafariOptions();
SafariDriver driver = new SafariDriver(options);

但是,不幸的是,这没有帮助。驱动程序将我导航到该页面,单击链接并打开一个新选项卡,但没有任何开关。当我检查driver.WindowHandles 时,我只有一个,虽然有两个可见的选项卡。 driver.SwitchTo().ActiveElementdriver.SwitchTo().Frame(hardcoded_frame_name) 似乎都不起作用。相当长的等待(打开链接后等待 60 秒,然后再等待)也不起作用。现在我认为这确实是一个错误,我会尽快向 Apple 报告。

但是现在,也许有人对此有一个奇特的解决方法?

【问题讨论】:

  • 也可能是 Safaridriver 的一个错误,无法检测到新窗口
  • 你能提供一些等待(WebDriverWait)并重新检查吗?
  • @DebanjanB,是的,我提供了几次长支票,但都是徒劳的。我用网格上的其他浏览器检查了 RemoteWebDriver,一切都很好。所以我认为这个问题与我使用它启动 Selenium Grid 和 Safari 的方式有关。因为使用 nodeconfig.json 我根本没有得到任何句柄。将尝试直接在 Mac 上运行测试并发布任何更新。
  • 听起来不错。记得在收集 window_handles 之前放慢速度。有一次我确实在过去运行在 Firefox 浏览器之前犯了一个错误,并且不知道我在哪里着陆。
  • @DebanjanB 抱歉更新晚了,详情请参阅我编辑的帖子。

标签: c# selenium safari selenium-grid


【解决方案1】:

正如我们在 cmets 中所讨论的,这似乎是一个时间问题。所以我们会诱导 WebDriverWait 与尾随浏览器实例同步。我正在通过Selenium-Java 提供一个代码块作为解决方案,考虑在C# 中实现它,如果它适合你,请更新我。

    driver.get("http://www.google.com");
    System.out.println("Page Title is : "+driver.getTitle());
    String parent_window = driver.getWindowHandle();
    ((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
    WebDriverWait wait = new WebDriverWait(driver,3);
    wait.until(ExpectedConditions.numberOfWindowsToBe(2));
    Set<String> allWindows_1 = driver.getWindowHandles();
    ArrayList<String> tabs = new  ArrayList<>(allWindows_1);
    driver.switchTo().window(tabs.get(1));
    wait.until(ExpectedConditions.titleContains("Facebook"));
    System.out.println("First Child Handle : "+driver.getTitle());

【讨论】:

  • 很抱歉再次延迟回复,但正如我在帖子中所说 - 我使用了没有效果的等待。事实上,有几个等待时间相当长(我试过 10、30、60 秒)。从我的角度来看,这与 SafariDriver 有关。或者,如果您的解决方案对 Safari + Java 很有吸引力,那么我认为它与 .Net 绑定有关,因为与 Java 相比,它们有点过时了。
【解决方案2】:

Java 版本我可以帮你:

操作完成后,请执行以下操作。

//Store the parent window
        String parentWindow = driver.getWindowHandle();

        //Open a new Windows(Mailtrap)
        String a = "window.open('https://mailtrap.io/signin','_blank');";
        ((JavascriptExecutor)driver).executeScript(a);

        //This Thread.sleep is useful with Safari. Do not remove.
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //Take control over new browser
        for(String handle: driver.getWindowHandles()){
            driver.switchTo().window(handle);
        }

【讨论】:

    猜你喜欢
    • 2018-12-15
    • 1970-01-01
    • 2017-04-20
    • 2012-09-25
    • 2017-05-21
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多