Selenium c # Ожидание выполнения JavaScript - PullRequest
0 голосов
/ 08 октября 2019

Я работаю над некоторым модульным тестированием с использованием Selenium с Nunit в c #.

Теоретически это довольно просто, у меня есть элемент, который я хочу щелкнуть, чтобы перейти на другую страницу. У меня проблема в том, что та часть, которая делает его кликабельной, загружается позже, чем фактический элемент. Это означает, что если я просто подожду, пока элемент загрузится, нажатие на него все равно ничего не даст. Я также пытался подождать, пока он станет активным, но он все еще не работает.

Есть ли способ обойти это, кроме статической задержки?

Спасибо

Ответы [ 3 ]

0 голосов
/ 08 октября 2019

Итак, есть несколько подходов:

  1. Ожидание выполнения ajax. Если элементы загружаются с помощью ajax, вы можете использовать этот код:
    public void WaitForAjax(){
         var miliSecondsToWait = 15000;
         bool ajaxIsComplete = false;
         while (!ajaxIsComplete && miliSecondsToWait > 0) // Handle timeout somewhere
        {
             ajaxIsComplete = (bool)(Driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
             Thread.Sleep(200);
             miliSecondsToWait -= 200;
        }
     }
Самое простое решение, но это не рекомендуемый метод: просто переведите вашу ветку в спящий режим:
     Thread.Sleep(10000). 

Ожидание в течение 10 секунд (не рекомендуемый метод) Не забудьте импортировать систему. Нарезание резьбы;

Напишите пользовательскую функцию для ожидания, когда можно щелкнуть элемент, например:
     protected Func<IWebDriver, bool> ButtonToBeSuccessfullyClicked(IWebDriver driver, By locator)
           {
               Func<IWebDriver, bool> func = (_driver) =>
               {
                   if (E(locator).Displayed)
                   {
                       E(_continueButton).Click();
                       return false;
                   }
                   else
                   {
                       return true;
                   }

               };
              return func;
     }

с подходом, вы можете вызвать эту функцию в ожидаемых условиях

     Driver.Until(ButtonToBeSuccessfullyClicked(Driver, _continueButton)); 

Обратите внимание, если вы используете SeleniumExtras.WaitHelpers.ExpectedConditions, функция не будет работать, вам придется написать собственную реализацию.

Это мой предпочтительный способ. Если во время клика выдается исключение, вы можете заключить клик в try-catch. поэтому результат будет выглядеть следующим образом:

     protected Func<IWebDriver, bool> ButtonToBeSuccessfullyClicked(IWebDriver driver, By locator)
           {
               Func<IWebDriver, bool> func = (_driver) =>
               {
                   if (E(locator).Displayed)
                   {
                       try {
                            E(_continueButton).Click();
                            return false;
                       } catch ()
                       {
                           return true;
                       }

                   }
                   else
                   {
                       return true;
                   }

               };
              return func;
     }

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

Как уже упоминалось в вопросе и немного грубо напомнил мне пользователь =). У вас не было никаких исключений при нажатии на элемент. Другое решение - сравнить HTML полностью работающего элемента, когда он работает (кликабелен), и того же элемента, но в начале, когда он не работает (не кликабелен). Если элемент имеет какие-либо различия в HTLM, имени класса css, стиле css и т. Д., Вы можете дождаться этого изменения в своем тестовом коде.
0 голосов
/ 11 октября 2019

Я предлагаю вам создать метод, который ожидает ajax / jquery:

public void WaitForJqueryAjax() {
    int delay = MaxdelaySeconds;
    while(delay > 0) {
        Thread.Sleep(1000);
        var jquery = (bool)(this.driver as IJavaScriptExecutor)
            .ExecuteScript("return window.jQuery == undefined");
        if(jquery) {
            break;
        }
        var ajaxIsComplete = (bool)(this.driver as IJavaScriptExecutor)
            .ExecuteScript("return window.jQuery.active == 0");
        if(ajaxIsComplete) {
            break;
        }
        delay--;
    }
}

В моей реализации int delay = MaxdelaySeconds; имеет то же значение, что и время неявного ожидания моих драйверов.

(При необходимости измените приведенный выше метод, чтобы он использовал ваш драйвер в качестве параметра)

0 голосов
/ 08 октября 2019

Может быть, вам нужно выполнить код JavaScript или Jquery

Например:

            driver.ExecuteJavaScript("$(\"#CategorylId\").CascadingDropDown(\"#WareId\", \'/store/log/AsyncWare\');");
            WaitUntilLoad(driver, "WareId", 5000);
            page = driver.PageSource;

Для получения дополнительной информации эта ссылка может быть полезной

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...