为什么 Selenium WebDriver 无法在 catch 子句中找到我的元素

Why can't Selenium WebDriver find my element in a catch clause

我正在尝试开发一种使用 Internet Explorer 单击内容的 hack。我的目标是拥有一种我可以使用的方法,首先尝试正常的 Click(),如果失败,将执行 SendKeys("\n"),这似乎是公认的解决方法。

这是我的尝试

public void ClickByCssSelectorIeSafe(string cssSelector)
{
    try
    {
        _driver.FindElement(By.CssSelector(cssSelector)).Click();
    }
    catch (WebDriverException)
    {
        _driver.FindElement(By.CssSelector(cssSelector)).SendKeys("\n");
    }
}

当点击成功时,一切正常,但是当我在 try 子句中得到 WebDriverException 时,即使在 try 子句中成功,catch 子句中的 FindElement 也会失败。为什么?

另一个有趣的地方是,在某些情况下,我可以看到 Click() 在浏览器中成功,但它仍然抛出异常并在 catch 子句中结束。

我想要这个,因为我们 运行 我们在 Chrome、Firefox 和 IE 中进行测试,我不希望 IE hack 应用到所有地方。

catch 子句中失败的 FindElement 的异常消息如下所示

A first chance exception of type 'OpenQA.Selenium.WebDriverException' occurred in WebDriver.dll

Additional information: The HTTP request to the remote WebDriver server for URL 
http://localhost:58124/session/21337088-7630-4709-a902-0a5d1bc7a669/element timed out after 60 seconds.

try 子句中点击失败的异常消息如下所示

A first chance exception of type 'OpenQA.Selenium.WebDriverException' 
occurred in WebDriver.dll

Additional information: The HTTP request to the remote WebDriver server for URL 
http://localhost:58124/session/21337088-7630-4709-a902-0a5d1bc7a669/element/bcee1534-00e6-4155-b4cc-7171db39f112/click timed out after 60 seconds.

尝试将您的代码更改为以下代码以找出问题所在。

public void ClickByCssSelectorIeSafe(string cssSelector)
{
    IWebElement element = null;
    try
    {
        element = _driver.FindElement(By.CssSelector(cssSelector));
        element.Click();
    }
    catch (NoSuchElementException e)
    {
        Console.WriteLine("element not found. {0}", e.Message);
        //do something here when your element is not found
    }
    catch (WebDriverException e)
    {
        if (element != null) element.SendKeys("\n");
    }
}

现在您将知道在查找元素或单击元素时是否抛出异常并且仍然​​能够处理这两种情况。

但是,您似乎在这两种情况下都遇到了超时问题,这表明 browser/AUT 正在 hung/not 响应。检查 selenium 服务器和节点日志以获取更多信息,以找出在抛出异常之前发生了什么。

我最终在日志中找到了这个:D 2015-04-27 14:01:08:497 Browser.cpp(379) Browser busy property is true. 这让我朝着正确的方向前进。

我遇到的问题似乎是该页面很忙,不允许我与之交互。我找到了一个建议 here 来设置 页面加载超时并在发生这种情况时处理(吞下)异常。那奏效了。

换句话说,如果页面很忙,我只是吞下异常,如果由于其他原因导致点击失败,我会进行 SendKeys("\n") hack。

因此,当我初始化我的驱动程序时,我会这样做:

driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5));

我的扩展方法现在看起来像这样:

    public static void ClickWithIeHackFailover(this IWebElement element)
    {
        try
        {
            element.Click();
        }
        catch (WebDriverException e)
        {
            if (e.Message != "Timed out waiting for page to load.")
            {
                element.SendKeys("\n");
            }
        }
    }

感谢@user903039 帮我找到问题