Время ожидания WebDriverWait при запуске через непрерывную интеграцию - PullRequest
0 голосов
/ 18 июня 2019

Я использую следующий код, чтобы проверить, видим ли элемент для моих автоматических тестов, прежде чем взаимодействовать с ними (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;
        }
    }

Тесты, использующие этот метод, работают каждый раз, когда я запускаю тесты на моем ПК. Однако, когда я запускаю тесты на нашей сборочной машине из TFS Continuous Integration, только тогда этот метод истекает при вызове моих тестов. Еще один момент, на который стоит обратить внимание: этот метод работает на других веб-сайтах, которые мы тестируем (как локально, так и через CI). Просто не этот сайт по какой-то причине ...

Я пробовал:

  1. Выполнение тестов локально на сборочной машине, исключая CI = нет проблем.
  2. Увеличено время ожидания в несколько раз до больших значений = время ожидания метода при больших значениях.
  3. Добавлено ожидание Thread.Sleep перед приведенным выше блоком try / catch (мои соображения по этому поводу связаны с обнаруженной мной проблемой в Browserstack, из-за которой внедренный элемент AJAX не может быть найден одним только этим методом без предварительного добавления произвольного ожидания перед WebDriverWait. ... что не имеет смысла для меня, потому что WebDriverWait, очевидно, является единственной вещью, которую мне нужно использовать, чтобы найти элементы с инжекцией AJAX (из того, что я прочитал в любом случае)).

Кроме того, причина, по которой я сделал этот метод глупым, заключается в том, что не все мои тесты должны провалиться, если определенные элементы не найдены. Например, на нашем сайте редко обновляются условия. Когда это происходит, пользователю предоставляется модальное имя при входе в систему. Мы оставили это как ручной тест, но чтобы этот мод не нарушал ежедневные циклы, мы ищем его и принимаем условия, если они есть (исключая исключения ).

Эта ошибка времени ожидания относится к элементу теста, который мы действительно хотим найти, это условие, чтобы пройти наш тест входа в систему, найдя на нашем сайте элемент, который присутствует только при входе в систему. Этот элемент внедряется с помощью AJAX .

Лучшие коллеги, чем я в CI, не могут точно определить причину возникновения этой проблемы. Теоретически, триггер от CI просто инициирует тестовый запуск - он не имеет никакого другого участия в выполнении тестов ...?

Я заметил, что при запуске тестового прогона от CI до компьютера сборки, когда я подключаюсь VPN к компьютеру сборки, я ожидаю увидеть загрузку браузера и проведение тестов, но это не так. Может быть, это фактор? Возможно, я ошибаюсь, но такое поведение похоже на то, что тесты выполняются на безголовом браузере? Тем не менее, мы не указали никаких настроек для использования безголовой версии Chrome (v75).

Если в ходе тестирования через браузер без монитора выбрасывались ошибки тайм-аута, связанные с элементами AJAX, после входа в систему выполнялись другие тесты с использованием других внедренных элементов AJAX. Только когда какой-либо тест вызывает этот метод, происходит ли тайм-аут, когда запуск запускается из CI на этом конкретном веб-сайте.

Очень запутанно!

1 Ответ

0 голосов
/ 19 июня 2019

Я создал JavaScript-версию WebDriverWait, добавил некоторую отладку (Console.Error.WriteLine ()) для вывода вычисленных стилей элемента.Свойство display было 'none' ... однако, когда я вхожу вручную, в инструментах разработчика Chrome это 'block'.Странно.

Элемент, который я искал, был контейнером DIV, который имеет класс 'loggedin'.Вместо этого я пропустил элемент внутри этого контейнера, который также будет отображаться только при входе в систему (фрагмент текста).Это сработало.

Мой 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;
    }
...