【问题标题】:Check with Selenium if browser is open如果浏览器打开,请检查 Selenium
【发布时间】:2021-08-07 11:16:14
【问题描述】:

我正在使用 C#/Selenium 3 和 Microsoft Chromium Edge Webdriver 来抓取网页,然后将数据传送到另一个应用程序。我需要检查用户是否关闭了网络浏览器。有没有一种快速的方法来做到这一点?我想出了下面的代码,但问题是如果 Web 浏览器关闭,则 _webDriver.CurrentWindowHandle 需要 4 秒或更长时间才能引发异常。

public bool IsOpen
{
    get
    {
        if (!this._isDisposed)
        {
            try
            {
                _ = this._webDriver.CurrentWindowHandle;
                return true;
            }
            catch
            {
                // ignore.
            }
        }

        return false;
    }
}

【问题讨论】:

    标签: c# microsoft-edge selenium-edgedriver selenium3


    【解决方案1】:

    抛出异常需要几秒钟,因为当浏览器关闭时,驱动程序仍然会重试连接到浏览器。无法判断浏览器是手动关闭还是自动关闭。

    我需要检查用户是否关闭了网络浏览器

    自动化浏览器测试不应因人工干预而中断。这违反了所有最佳做法。 如果您手动关闭浏览器,WebDriver 将抛出 WebDriverException。因此,您还可以在WebDriverException 上使用try-catch 方法来检查浏览器是否可以访问。但是抛出异常也需要几秒钟的时间,原因与上述相同。

    如果你想阻止用户手动关闭浏览器,你可以在无头模式下使用 Edge,如下所示:

    edgeOptions.AddArguments("--headless");
    

    【讨论】:

    • 感谢您的回答。我很欣赏最佳实践,但我使用 Selenium 来抓取客户应用程序并将数据传递到客户端计算机上的另一个应用程序中。这不是测试过程的一部分。所以,在我的例子中,用户可以通过关闭浏览器来中断事情。
    【解决方案2】:

    最后我想出了以下解决方案:我使用扩展方法(如下所示)来获取 Web 浏览器的 .Net Process 对象。要检查浏览器是否仍然打开,我只需检查属性 process.HasExited。如果这是真的,那么用户已经关闭了浏览器。此方法不调用 Selenium,因此即使浏览器关闭,结果也几乎是即时的。

    /// <summary>
    /// Get the Web Drivers Browser process.
    /// </summary>
    /// <param name="webDriver">Instance of <see cref="IWebDriver"/>.</param>
    /// <returns>The <see cref="Process"/> object for the Web Browser.</returns>
    public static Process GetWebBrowserProcess(this IWebDriver webDriver)
    {
        // store the old browser window title and give it a unique title.
        string oldTitle = webDriver.Title;
        string newTitle = $"{Guid.NewGuid():n}";
    
        IJavaScriptExecutor js = (IJavaScriptExecutor)webDriver;
        js.ExecuteScript($"document.title = '{newTitle}'");
    
        // find the process that contains the unique title.
        Process process = Process.GetProcesses().First(p => p.MainWindowTitle.Contains(newTitle));
    
        // reset the browser window title.
        js.ExecuteScript($"document.title = '{oldTitle}'");
        return process;
    }
    

    【讨论】:

    • 感谢您发布此问题的解决方案。您可以将您的答案标记为已接受的答案。它可以在未来帮助其他社区成员解决类似的问题。感谢您的理解。
    最近更新 更多