【问题标题】:WebDriverWait times out when run through Continuous Integration通过持续集成运行时 WebDriverWait 超时
【发布时间】:2019-06-18 09:14:46
【问题描述】:

在与自动化测试交互之前,我使用以下代码检查某个元素是否对我的自动化测试可见(Selenium/C#)。

        public bool ElementVisible(IWebDriver driver, IWebElement element, int secondsToWait = 30, bool doNotFailTest = false)
    {
        try
        {
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(secondsToWait));
            wait.Until<IWebElement>(d =>
            {
                if (element.GetCssValue("display") != "none" && element.Size.Height > 0 && element.Size.Width > 0)
                {
                    return element;
                }

                return null;
            });

            return true;
        }
        catch (Exception)
        {
            if (!doNotFailTest)
            {
                throw;
            }

            return false;
        }
    }

当我在我的 PC 上运行测试时,使用此方法的测试每次都有效。但是,当我从 TFS 的持续集成触发测试在我们的构建机器上运行时,只有当我的测试调用此方法时才会超时。可能值得注意的另一点是:此方法适用于我们测试的其他网站(本地和通过 CI)。只是因为某种原因不是这个网站...

我试过了:

  1. 在构建机器上本地运行测试,切断 CI = 没问题。
  2. 将超时时间增加数倍至更大的值 = 方法在更大的值处超时。
  3. 在上面的 try/catch 块之前添加了 Thread.Sleep 等待(我对此的推理源于我在 Browserstack 上发现的一个问题,即如果不先在 WebDriverWait 之前添加任意等待,则仅通过此方法无法找到 AJAX 注入元素...这对我来说没有意义,因为 WebDriverWait 显然是我唯一需要用来查找 AJAX 注入元素的东西(无论如何我都读过)。

顺便说一句,我将此方法设为 bool 的原因是,如果未找到某些元素,并非所有测试都会失败。例如,我们的网站很少更新条款和条件。当它出现时,登录时会向用户显示一个模式。我们将其保留为手动测试,但为了防止此模式破坏日常运行,我们会查找它并接受条款(如果存在)(抑制异常)。

这个超时错误与我们真正想要找到的测试元素有关,它是通过在我们的网站上找到一个仅在登录时才存在的元素来通过我们的 LogIn 测试的条件。这个元素注入了 AJAX .

CI 比我优秀的同事无法确定为什么会出现此问题。从理论上讲,CI 的触发器只是启动测试运行——它与测试的运行没有其他关系......?

我观察到,当触发从 CI 到构建机器的测试运行时,当我通过 VPN 连接到构建机器时,我希望看到浏览器加载并进行测试,但事实并非如此。也许这是一个因素?也许我错了,但这种行为似乎是在无头浏览器上运行测试?然而,我们还没有指定任何设置来使用无头版本的 Chrome (v75)。

如果通过无头浏览器进行测试会引发与 AJAX 元素相关的超时错误,则其他测试在登录后已通过 - 使用其他 AJAX 注入元素。只有当任何测试调用此方法时,才会在此特定网站上从 CI 触发运行时超时。

非常混乱!

【问题讨论】:

  • 你能添加完整的错误ElementNotInteractableException吗?

标签: selenium timeout integration webdriverwait continuous


【解决方案1】:

我创建了 WebDriverWait 的 JavaScript 版本,添加了一些调试 (Console.Error.WriteLine()) 以输出元素的计算样式。显示属性是“无”......但是,当我手动登录时,在 Chrome 的开发人员工具中,它是“阻止”。很奇怪。

我正在寻找的元素是一个具有“loggedin”类的 DIV 容器。相反,我通过了这个容器内的一个元素,该元素也只会在登录时显示(一段文本)。这行得通。

我的 WebDriverWait 不适用于这两个元素,所以我必须坚持使用这个 JavaScript 替代方案。然而,需要注意的一点是元素属性的评估需要 5 秒,因此我省略了设置检查之间的时间间隔。

    public bool ElementVisible(IWebDriver driver, By locator, int numberOfPolls = 10, bool doNotFailTest = false)
    {
        bool elementVisible = false;
        int pollCount = numberOfPolls;

Thread.Sleep(1000);

        while (!elementVisible && pollCount > 0)
        {
            try
            {
                // Takes 5 seconds to compute, bear this in mind when setting an interval or increasing the pollCount
                elementVisible = (bool)js.ExecuteScript("var display = window.getComputedStyle(arguments[0]).display; var height = window.getComputedStyle(arguments[0]).height; var width = window.getComputedStyle(arguments[0]).width; return (display != 'none' && height != 0 && width != 0);", driver.FindElement(locator));
            }
            catch (Exception)
            {
            }

            if (elementVisible)
            {
                break;
            }

            pollCount--;
        }

        if (!elementVisible)
        {
            if (!doNotFailTest)
            {
                throw new Exception("ElementVisible(): - element not visible.");
            }
        }

        return elementVisible;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多