Используйте Selenium, чтобы дождаться индикатора прогресса - PullRequest
0 голосов
/ 21 марта 2020

Я пытаюсь использовать Selenium, чтобы дождаться появления и исчезновения индикатора выполнения, что указывает на то, что результат поиска запущен, а затем выполнен.

Когда индикатор выполнения отсутствует, документ выглядит что-то вроде этого:

<html lang="en-US">
    <body class="appian-body">
        <a id="skip-to-content"></a>
        <div id="aDiv"></div>
        <div id="anotherOne"></div>
        <div id="OneMore"></div>
        ...
    </body>
</html>

Когда начинается поисковый вызов, он выглядит следующим образом:

<html lang="en-US">
    <body class="appian-body">
        <a id="skip-to-content"></a>
        <div id="aDiv"></div>
        <div id="anotherOne"></div>
        <div id="OneMore"></div>
        ...
        <div id="appian-working-indicator-hidden" style="display: none;"></div>
    </body>
</html>

Обратите внимание, что появился <div id="appian-working-indicator-hidden" style="display: none;"></div>, что также происходит, когда появляется индикатор выполнения. Конечно, когда поиск будет завершен, он исчезнет, ​​и мы вернемся к исходному документу.

Вот некоторые попытки, которые я предпринял для ожидания этого элемента:

Попытка 1

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[4]")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("/html/body/div[4]")));

Результат: Исключение тайм-аута на visibilityOfElementLocated (то есть оно никогда не отображается).

Попытка 2

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div[4]")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("/html/body/div[4]")));

Результат: Выполнение проходит через presenceOfElementLocated и invisibilityOfElementLocated без ожидания вообще.

Итак, что еще можно сделать, чтобы этот элемент появился и исчез?

Обновление

Я создал следующие рекурсивные методы:

public void waitForProgressBarToStart() {
    List<WebElement> progressBarList = driver.findElements(By.xpath("//div[@id='appian-working-indicator-hidden']"));
    if(progressBarList.size() == 0) {
        waitForProgressBarToStart();
    } else {
        //for timestamping when the element is found
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        System.out.println(String.format("%s: Progress Bar started", dateFormat.format(date)));
    }
}
public void waitForProgressBarToFinish() {
    List<WebElement> progressBarList = driver.findElements(By.xpath("//div[@id='appian-working-indicator-hidden']"));
    if(progressBarList.size() > 0) {
        waitForProgressBarToFinish();
    } else {
        //for timestamping when the element is gone
        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date();
        System.out.println(String.format("%s: Progress Bar done", dateFormat.format(date)));
    }
}
public void waitForResults(){
    waitForProgressBarToStart();
    waitForProgressBarToFinish();
}

После использования временных меток в методах я вижу, что метод waitForProgressBarToFinish занимает на 10-13 секунд больше, чем фактический прогресс бар. Однако waitForProgressBarToStart, похоже, находит элемент в нужное время.

Почему waitForProgressBarToFinish займет больше времени и как это исправить?

Ответы [ 2 ]

1 голос
/ 21 марта 2020

Вы можете получить список этого веб-элемента, когда элемент виден на странице, размер списка будет равен 1, а когда он не виден, размер будет равен 0. Таким образом, вы можете проверить размер элемент для проверки, если он виден или нет.

И я использую относительный xpath для вашего элемента вместо абсолютного xpath, который вы используете, потому что абсолютные xpath очень изменчивы, и любое незначительное изменение в структуре html может оказать влияние на ваш скрипт.

Ваш код должен быть таким:

List<WebElement> progressBarList = driver.findElements(By.xpath("//div[@id='appian-working-indicator-hidden']"));
if(progressBarList.size()>0){
    System.out.println("Element is present");
}
else{
    System.out.println("Element is not present");
}
1 голос
/ 21 марта 2020

Поскольку вы знаете, что конкретно ищете элемент <div> со значением идентификатора appian-working-indicator-hidden, вы должны использовать более конкретный c xpath-запрос, чтобы найти его. Я ожидаю, что ваше выполнение «Попытка 2» прошло немедленно, потому что WebDriver расположен на 4-й <div> на странице, которая, вероятно, не была div#appian-working-indicator-hidden, которую вы ищете.

Вы можете запросить для <div> с определенным значением идентификатора с использованием функции contains() xpath .

Вы можете переписать свою «Попытку 2», чтобы она выглядела примерно так:

String xpathQuery = "//div[contains(@id,'appian-working-indicator-hidden')]"

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(xpathQuery)));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(xpathQuery)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...