Селен чекайте, поки документ буде готовий


133

Чи може хтось дозволити мені, як я можу змусити селен чекати до моменту завантаження сторінки повністю? Я хочу щось загальне, я знаю, що можу налаштувати WebDriverWait і викликати щось на кшталт "знайти", щоб змусити його чекати, але я не заходжу так далеко. Мені просто потрібно перевірити, що сторінка успішно завантажується, і перейти до наступної сторінки для тестування.

Я знайшов щось у .net, але не зміг змусити його працювати в Java ...

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Хтось думає?


Чому ви цього не хочете використовувати?
Емей

7
Ви маєте на увазі явне очікування? Це забирає багато часу, я тестую кілька сторінок на 10 к.
Гіріш

2
Я маю на увазі, додавання очікування виправлення може бути не дуже хорошою ідеєю, якщо я тестую велику кількість посилань, правда?
Гіріш

10
Очікувати фіксовану кількість секунд не приносить користі. Це здогадки.
Андерс Лінден

Зважаючи на те, що javascript на сторінці може запускати будь-який загальний код, написання програми чекати її завершення неможливо. Це форма проблеми зупинки ( en.wikipedia.org/wiki/Halting_problem ). Будь-яке рішення тут повинно йти на компроміси або базуватися на припущеннях, що лежать в основі веб-сторінки.
швидкісний літак

Відповіді:


83

Спробуйте цей код:

  driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

Вищевказаний код зачекає до 10 секунд для завантаження сторінки. Якщо завантаження сторінки перевищує час, воно перекине TimeoutException. Ви ловите виняток і виконуєте свої потреби. Я не впевнений, чи закриває він завантаження сторінки після викинутого винятку. я ще не пробував цей код. Хочете просто спробувати.

Це неявне очікування. Якщо встановити це один раз, він буде мати область, поки екземпляр веб-драйвера не знищить.

Для отримання додаткової інформації див. ДокументаціюWebDriver.Timeouts .


3
Дякую, так що ж тут відбувається, якщо сторінка завантажується до 10 секунд, чи буде вона ще чекати 10 секунд, щоб виконати наступний рядок після завантаження?
Гіріш

Ні, якщо ваша сторінка завантажується до 10 секунд, це означає, що вона припинить умову очікування та виконає попередній рядок.
Манігандан

3
Це використовується для того, коли ви очікуєте, що завантаження сторінок займає занадто тривалий час, щоб затримати час та викидати винятки. Це не відразу чекає завантаження сторінки або встановлення кращої політики завантаження. Він за замовчуванням нескінченний час, тому завантаження вашої сторінки ніколи не викидає винятків, і Selenium завжди намагається чекати повного завантаження.
Петро Янечек

19
Проблема цього методу полягає в тому, що можливо, домен DOM не є повністю доступним, навіть незважаючи на те, що неявне очікування раніше успішно повернуло об’єкт WebElement. Потім, якщо ви спробуєте натиснути на елемент, ви отримаєте застарілий виняток. Отже, ця відповідь не зовсім безпечна.
djangofan

3
Як цей час очікування пов'язаний з очікуванням завантаження документа?
Андерс Лінден

90

Пропоноване рішення лише чекає, коли DOM надійдеreadyState на сигнал complete. Але Selenium за замовчуванням намагається зачекати тих (і трохи більше) на завантаженні сторінки за допомогою driver.get()і element.click()методів. Вони вже блокуються, вони чекають, коли сторінка повністю завантажиться, і ті повинні працювати нормально.

Очевидно, що проблема полягає в переадресації через AJAX-запити та запущені сценарії - ті, які не можуть бути впіймані Selenium, не чекають, коли вони закінчать. Крім того, ви не можете надійно їх зафіксувати readyState- він чекає трохи, що може бути корисним, але воно подасть сигнал completeзадовго до завантаження всього вмісту AJAX.

Не існує загального рішення, яке працювало б скрізь і для кожного, тому важко, і кожен використовує щось трохи інше.

Загальне правило - покладатися на WebDriver, щоб виконати свою роль, потім використовувати неявні очікування, потім використовувати явні очікування для елементів, які ви хочете стверджувати на сторінці, але є набагато більше прийомів, які можна зробити. Виберіть один із них (або їх комбінацію з декількох), який найкраще працює у вашому випадку, на тестованій сторінці.

Дивіться дві мої відповіді щодо цього для отримання додаткової інформації:


20
Це неточно, Selenium не чекає і не блокує element.click()дзвінки.
hwjp

3
@hwjp Хочете розробити більше? JavaDocs говорять інакше : "Якщо це спричинить завантаження нової сторінки, цей метод буде намагатися блокувати, поки сторінка не завантажиться."
Петро Янечек

5
cf деякі розмови, які я мав у списку розсилки, здається, це неточно. selenium може блокувати дзвінки .get, де ви прямо запитуєте URL-адресу, але це не робить нічого особливого при викликах натискання, оскільки він не може визначити, натиснули ви на "справжню" гіперпосилання або на ту, яку перехопить javascript. ..
hwjp

4
Я посилаюся на помилку на початку обговорення списку розсилки. Навіть документи довіряють: "Якщо click () [...] робиться шляхом надсилання нативної події, тоді метод буде * не * чекати"
hwjp

4
Отже, все вмикається, чи браузер використовує "рідні події". І, схоже, більшість із них за замовчуванням: code.google.com/p/selenium/wiki/… (тому я б сказав, що ці документи в кращому випадку вводять в оману. Надішліть список розсилки).
hwjp

61

Це працююча версія Java з прикладу, який ви подали:

void waitForLoad(WebDriver driver) {
    new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

Приклад для c #:

public static void WaitForLoad(IWebDriver driver, int timeoutSec = 15)
{
  IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
  WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
  wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}

1
Чувак, я копіюю та вставляю це. Цей фрагмент просто геніальний. Чому я не думав про це? Правда, що більше однієї пари очних яблук завжди призводять до хорошого рішення. Дякую.
luis.espinal

2
Чи можете ви помістити це у версію java 1.7, порівнянну, оскільки лямбда-вирази не підтримують
vkrams

3
Версія Java 1.7: wait.until (новий Predicate <WebDriver> () {public boolean apply (драйвер WebDriver) {return ((JavascriptExecutor) driver) .executeScript ("return document.readyState"). Equals ("complete");} });
luQ

1
Якщо хтось хоче використовувати рішення від @IuQ, Predicate має імпортimport com.google.common.base.Predicate
Knu8

Я спробував цю ідею в тестовому додатку VB. Працює більшу частину часу. Я інколи отримую цю помилку: System.InvalidOperationException: Помилка JavaScript (UnexpectedJavaScriptError) на OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError (Response errorResponse) Тест-додаток натискає на посилання меню 2 рівня, а потім дзвонить на WaitObast (Fun) (() D, InternetExplorerDriver) .ExecuteScript ("повернути документ.readyState") = "завершено"). Я думаю, що помилка викликана тим, що браузер вивантажує поточну сторінку і не є об'єктом документа. Можливо, зачекайте 1/2 секунди, перш ніж зробити "повернути document.readystate? Ідеї"
CoolBreeze

12

Ось моя спроба цілком загального рішення в Python:

По-перше, загальна функція "зачекати" (використовуйте WebDriverWait, якщо вам подобається, я вважаю їх некрасивими):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Далі, рішення покладається на те, що селен записує (внутрішній) ідентифікаційний номер для всіх елементів сторінки, включаючи <html>елемент верхнього рівня . Коли сторінка оновлюється або завантажується, вона отримує новий html-елемент з новим ідентифікатором.

Отже, якщо припустити, що ви хочете натиснути на посилання з текстом "моє посилання", наприклад:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

Для отримання більш пітонічного, багаторазового використання, загального помічника, ви можете створити контекстний менеджер:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

І тоді ви можете використовувати його майже на будь-якій взаємодії з селеном:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

Я вважаю, що це куленепробивна! Що ти думаєш?

Більше інформації в публікації блогу тут


Дуже цікавий підхід. Одне із завдань - чи може це працювати при початковому завантаженні сторінки після першого запуску браузера. Немає гарантії, що в початковий стан браузера завантажена будь-яка сторінка. Крім того, у Java я не бачу, що у нас на об’єкті є "id" - я припускаю, що ви не маєте на увазі, що селен вставляє атрибут html id. Я додам більше до цієї відповіді, як тільки я більше вивчую цей варіант. Дякую за пост!
Лукус

@hwjp Я використовую це рішення багато разів з відмінними результатами, але схоже, що воно не працює в одному випадку. Повне пояснення питання stackoverflow.com/q/31985739/4249707
El Ruso

7

У мене була подібна проблема. Мені потрібно було почекати, поки мій документ не буде готовий, але також, поки всі дзвінки Ajax завершиться. Друга умова виявилася важкою для виявлення. Врешті-решт я перевірив на активні дзвінки Ajax, і це спрацювало.

Javascript:

return (document.readyState == 'complete' && jQuery.active == 0)

Повний метод C #:

private void WaitUntilDocumentIsReady(TimeSpan timeout)
{
    var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
    var wait = new WebDriverWait(WebDriver, timeout);            

    // Check if document is ready
    Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
        .ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
    wait.Until(readyCondition);
}

Чи є щось на кшталт document.readyState == 'complete' && jQuery.active == 0React?
Дощ9333

7
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));

4

Для C # NUnit вам потрібно перетворити WebDriver в JSExecuter і виконати сценарій, щоб перевірити, чи стан документа вже готовий чи ні. Перевірте код нижче для довідок:

 public static void WaitForLoad(IWebDriver driver)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        int timeoutSec = 15;
        WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
        wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
    }

Це зачекає, поки умова буде виконана або час очікується.


3

Для початкового завантаження сторінки я помітив, що "Максимізація" вікна браузера практично чекає, поки завантаження сторінки не завершиться (включаючи джерела)

Замінити:

AppDriver.Navigate().GoToUrl(url);

З:

public void OpenURL(IWebDriver AppDriver, string Url)
            {
                try
                {
                    AppDriver.Navigate().GoToUrl(Url);
                    AppDriver.Manage().Window.Maximize();
                    AppDriver.SwitchTo().ActiveElement();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
                    throw;
                }
            }

ніж використання:

OpenURL(myDriver, myUrl);

Це завантажить сторінку, дочекається її завершення, максимізує її і зосередиться на ній. Я не знаю, чому це так, але це працює.

Якщо ви хочете дочекатися завантаження сторінки після натискання на наступну або будь-яку іншу триггер навігації по сторінці інше, ніж "Navigate ()", відповідь Бен Дайєра (у цій темі) зробить роботу.


1

Погляньте на веб-рамки гобеленів . Ви можете завантажити вихідний код туди.

Ідея полягає в тому, щоб сигналізувати, що сторінка готова html-атрибутом body. Ви можете використовувати цю ідею, ігноруючи складні справи про позов.

<html>
<head>
</head>
<body data-page-initialized="false">
    <p>Write you page here</p>

    <script>
    $(document).ready(function () {
        $(document.body).attr('data-page-initialized', 'true');
    });
    </script>  
</body>
</html>

А потім створити розширення веб-драйвера Selenium (відповідно до рамки гобелену)

public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
    //wait a bit for the page to start loading
    Thread.Sleep(100);

    //// In a limited number of cases, a "page" is an container error page or raw HTML content
    // that does not include the body element and data-page-initialized element. In those cases,
    // there will never be page initialization in the Tapestry sense and we return immediately.
    if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
    {                
        return;
    }

    Stopwatch stopwatch = Stopwatch.StartNew();

    int sleepTime = 20;

    while(true)
    {
        if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
        {
            return;
        }

        if (stopwatch.ElapsedMilliseconds > 30000)
        {
            throw new Exception("Page did not finish initializing after 30 seconds.");
        }

        Thread.Sleep(sleepTime);
        sleepTime *= 2; // geometric row of sleep time
    }          
}

Використовуйте розширення ElementIsDisplayed написано Alister Scott .

public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
    try
    {
        return driver.FindElement(By.XPath(xpath)).Displayed;
    }
    catch(NoSuchElementException)
    {
        return false;
    }
}

І нарешті створіть тест:

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();

1

Відповідь Бен Суйера не склався на моїй машині ("The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait" ).

Робоча версія Java 8:

Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
        "return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);

Версія Java 7:

Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver input) {
            return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
        }

};
new FluentWait<WebDriver>(driver).until(pageLoaded);

1

Я спробував цей код, і він працює для мене. Я викликаю цю функцію щоразу, коли переходжу на іншу сторінку

public static void waitForPageToBeReady() 
{
    JavascriptExecutor js = (JavascriptExecutor)driver;

    //This loop will rotate for 100 times to check If page Is ready after every 1 second.
    //You can replace your if you wants to Increase or decrease wait time.
    for (int i=0; i<400; i++)
    { 
        try 
        {
            Thread.sleep(1000);
        }catch (InterruptedException e) {} 
        //To check page ready state.

        if (js.executeScript("return document.readyState").toString().equals("complete"))
        { 
            break; 
        }   
      }
 }

1

У Nodejs ви можете отримати це за допомогою обіцянок ...

Якщо ви пишете цей код, ви можете бути впевнені, що сторінка повністю завантажена, коли ви дістанетесь до тогочасного ...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Якщо ви напишете цей код, ви перейдете, а селен чекатиме 3 секунди ...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

З документації Селен:

this.get (URL) → Thenable

Запланує команду для переходу до вказаної URL-адреси.

Повертає обіцянку, яка буде вирішена після завершення завантаження документа .

Документація селену (Nodejs)


1

Очікування події document.ready не є повним виправленням цієї проблеми, оскільки цей код все ще знаходиться у гоночному стані: Іноді цей код запускається перед обробкою події клацання, тому це безпосередньо повертається, оскільки браузер не запускається завантаження нової сторінки ще.

Після деяких пошуків я знайшов публікацію на Obay тестувальній козі , яка має вирішення цієї проблеми. Код c # для цього рішення є приблизно таким:

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}

`Я запускаю цей метод безпосередньо після driver.navigate.gotourl, щоб він якомога швидше отримав посилання на сторінку. Повеселіться!


1

нормально, коли селен відкриє нову сторінку з клацання або подання або отримання методів, він буде чекати, коли розблокувати сторінку завантажується, але проблеми в тому випадку, коли на сторінці з'явиться виклик xhr (ajax), він ніколи не чекатиме завантаження xhr, так створення нового методу для моніторингу ххр і чекання на них, це буде добре.

public boolean waitForJSandJQueryToLoad() {
    WebDriverWait wait = new WebDriverWait(webDriver, 30);
    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
            Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
            return r == 0;
        } catch (Exception e) {
            LOG.info("no jquery present");
            return true;
        }
      }
    };

    // wait for Javascript to load
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor)driver).executeScript("return document.readyState")
        .toString().equals("complete");
      }
    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);
}

if $.active == 0значить, немає активних викликів xhrs (які працюють лише з jQuery). для виклику jaja ajax потрібно створити змінну у своєму проекті та імітувати її.


0

Ви можете написати певну логіку, щоб вирішити це. У мене є метод, який поверне WebElementі цей метод буде викликаний три рази, або ви можете збільшити час і додати нульову перевірку. WebElementОсь приклад

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.crowdanalytix.com/#home");
        WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
        int i = 1;
        while (webElement == null && i < 4) {
            webElement = getWebElement(driver, "homessssssssssss");
            System.out.println("calling");
            i++;
        }
        System.out.println(webElement.getTagName());
        System.out.println("End");
        driver.close();
    }

    public static WebElement getWebElement(WebDriver driver, String id) {
        WebElement myDynamicElement = null;
        try {
            myDynamicElement = (new WebDriverWait(driver, 10))
                    .until(ExpectedConditions.presenceOfElementLocated(By
                            .id(id)));
            return myDynamicElement;
        } catch (TimeoutException ex) {
            return null;
        }
    }

0

Я виконав код JavaScript, щоб перевірити, чи готовий документ. Заощадило мені багато часу на налагодженні тестів селену для сайтів, на яких відображається клієнт.

public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
    Thread.sleep(100)
    def ready = isDOMReady(driver);
    if (ready) {
        break;
    }
}

}

public static boolean isDOMReady(WebDriver driver){
    return driver.executeScript("return document.readyState");
}

0
public boolean waitForElement(String zoneName, String element, int index, int timeout) {
        WebDriverWait wait = new WebDriverWait(appiumDriver, timeout/1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(element)));
        return true;
    }

0

Як Рубанов писав для C #, так і я пишу для Java, і це:

    public void waitForPageLoaded() {
    ExpectedCondition<Boolean> expectation = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return (((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete")&&((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")));
                }
            };
    try {
        Thread.sleep(100);
        WebDriverWait waitForLoad = new WebDriverWait(driver, 30);
        waitForLoad.until(expectation);
    } catch (Throwable error) {
        Assert.fail("Timeout waiting for Page Load Request to complete.");
    }
}

0

На Java це сподобається нижче: -

  private static boolean isloadComplete(WebDriver driver)
    {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    }

1
Було б краще поєднати команди JS в одну, щоб вам не довелося двічі return document.readyState == 'loaded' || return document.readyState == 'complete'
переходити

0

Наступний код, ймовірно, повинен працювати:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfAllElementsLocated(By.xpath("//*")));

0

Якщо у вас повільна сторінка або мережеве з'єднання, швидше за все, нічого з перерахованого вище не працюватиме. Я перепробував їх усіх, і єдине, що працювало для мене, - це дочекатися останнього видимого елемента на цій сторінці. Візьмемо для прикладу веб-сторінку Bing. Вони розмістили піктограму CAMERA (пошук за кнопкою зображення) поруч із головною кнопкою пошуку, яку можна побачити лише після завантаження повної сторінки. Якщо всі це зробили, то все, що нам потрібно зробити, - це скористатися явним очікуванням, як у наведених вище прикладах.


-1
public void waitForPageToLoad()
  {
(new WebDriverWait(driver, DEFAULT_WAIT_TIME)).until(new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver d) {
        return (((org.openqa.selenium.JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
      }
    });//Here DEFAULT_WAIT_TIME is a integer correspond to wait time in seconds

-1

Ось щось подібне, в Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }

Ваш код для мене не працює. Як переключити робити iframe і чекати onload = "javascript: pageload (); funkcionalPageLoad ();" перезавантажити сторінку в Ruby? Я виявляю, що я відкриваю iframe всередині сторінки, у мене є доступ до неї, потім сторінка перезавантажується, і я більше не можу отримати доступ до кадру. Я прочитав багато відповідей щодо очікування, сну, часу, переходу на кадр, потім до батьківського, але не можу досягти своєї мети.
Аманда Кавалларо

1
Здається, що ваше питання полягає в першу чергу про те, як перейти на iFrame, а не про очікування завантаження документа. Можливо, буде краще почати нове запитання, якщо ви не можете знайти рішення в питанні про роботу з iFrames.
наждак

-1

Ви можете заснути потоки, поки сторінка не буде завантажена. Це не найкраще рішення, оскільки вам потрібно мати оцінку, скільки часу потрібна сторінка для завантаження.

driver.get(homeUrl); 
Thread.sleep(5000);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(userName);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(passWord);
driver.findElement(By.xpath("Your_Xpath_here")).click();

Я вважаю, що Thread.sleep (5000) часто є єдиним методом, який працює в тесті, незважаючи на всі рекомендації щодо його використання. Жодна комбінація очікування елемента не працює для мене, тим більше, що багато елементів не можуть бути ідентифіковані, поки вони фактично не знайдені.
Стів Стейпл

-1

Я Перевірено завантаження сторінки завершено, працюйте в Selenium 3.14.0

    public static void UntilPageLoadComplete(IWebDriver driver, long timeoutInSeconds)
    {
        Until(driver, (d) =>
        {
            Boolean isPageLoaded = (Boolean)((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete");
            if (!isPageLoaded) Console.WriteLine("Document is loading");
            return isPageLoaded;
        }, timeoutInSeconds);
    }

    public static void Until(IWebDriver driver, Func<IWebDriver, Boolean> waitCondition, long timeoutInSeconds)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
        webDriverWait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
        try
        {
            webDriverWait.Until(waitCondition);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

-1

Для людей, яким потрібно дочекатися появи конкретного елемента. (використано c #)

public static void WaitForElement(IWebDriver driver, By element)
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    wait.Until(ExpectedConditions.ElementIsVisible(element));
}

Тоді, якщо ви хочете зачекати, наприклад, якщо у DOM існує клас = "повідомлення про помилку", ви просто зробите:

WaitForElement(driver, By.ClassName("error-message"));

Для ід, це буде потім

WaitForElement(driver, By.Id("yourid"));


-3

Ви використовуєте Angular? Якщо ви є, можливо, webdriver не визнає, що виклики асинхронізації закінчилися.

Рекомендую подивитися на Пола Хаманта ngWebDriver . Метод waitForAngularRequestsToFinish () може стати в нагоді.


Він дуже не користувався Angular. Ця відповідь була оскаржена, оскільки, здається, ви не уважно прочитали оригінальне запитання.
zelusp

Але не підводьте голоси, що виводять вас із форми. Люди тут добре означають. А критика - це фактично форма любові (адже якщо хтось потребує часу, щоб когось виправити, це тому, що їм все одно). Оформити замовлення Як задавати питання розумним способом - ці ідеї також застосовуються до відповідей на запитання розумним чином.
zelusp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.