Selenium Как несколько раз ждать один и тот же WebElement с другим текстом - PullRequest
0 голосов
/ 09 октября 2019

Я пытаюсь подождать, пока WebElement не изменится с пустого на сообщение 1, затем сообщение 2. Проблема в том, что я нахожу первое сообщение каждый раз, но не могу дождаться второго (время ожидания истекло). ищу текст)

Я пытался разделить объекты ожидания, которые не работали. Я попробовал несколько методов ожидаемого условия (textToBePresent *), которые после некоторого прочтения (я нашел об обновленном EC) безрезультатно.

@FindBy(xpath="//p[@class='statusText']")
WebElement statusMsg
public WebElement statusMsg(){

    String msg1="Logging in, please wait."
    String msg2="Login successful, please wait."
    String msg3="Login attempt exception, error code: "
    if(statusMsg.getText().contains(msg3)){
        log.error(statusMsg.getText())
        log.error("Something happened in the frontend")
        Assert.fail(statusMsg.getText())
    }else{
        log.info(statusMsg.getText())
    }
    WebDriverWait wait = new WebDriverWait(driver,45)
    wait.until(ExpectedConditions.textToBe(By.xpath("//p[@class='statusText']"), msg1))
    if(statusMsg.getText().contains(msg3)){
        log.error(statusMsg.getText())
        log.error("Something happened in the backend")
        Assert.fail(statusMsg.getText())
    }else{
        log.info(statusMsg.getText())
    }
    wait.until(ExpectedConditions.refreshed(ExpectedConditions.textToBe(By.xpath("//p[@class='statusText']"), msg2)))
    log.info("Found: "+msg2)
    return statusMsg
}

В результате testNG провалил мой тест, сказав:

org.openqa.selenium.TimeoutException: ожидаемое условие не выполнено: ожидание условия (элемент, найденный By.xpath: // p [@ class = 'statusText'] имеет текст «Вход в систему выполнен успешно, пожалуйста, подождите». ". Текущий текст:" Войдите в систему, пожалуйста, подождите. ")

И все же я вижу msg2 во время выполнения теста. Это нужно сделать, потому что я уже инициализировал объекты страницы через PageFactory.initElements(driver, this)?

1 Ответ

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

Вот код, который вы можете использовать для последовательной проверки сообщений об ошибках и успехах. Логика:

  1. Поместить ожидаемые сообщения в список expectedMessages
  2. Использовать свободное ожидание для проверки пользовательских условий
  3. Установить опрос каждые 50 миллисекунд, чтобы можно было перехватывать сообщения
  4. Проверьте, виден ли элемент сообщения о состоянии, если это так, получите текст
  5. Сбой, если сообщение о фактическом состоянии "ошибка"
  6. Проверьте, что сообщение о фактическом состоянии содержит первый текст в expectedMessages, если это так, удалите первый текст из expectedMessages
  7. Повторяйте шаг 6, пока не останется ничего, если expectedMessages


WebDriverWait wait = new WebDriverWait(driver, 20);

String errorMessage = "Login attempt exception, error code:";
List<String> expectedMessages = Arrays.asList(
        "Logging in, please wait.",
        "Login successful, please wait.");

wait.pollingEvery(Duration.ofMillis(50))
        .withMessage(String.format("Expecting %s login messages", expectedMessages))
        .until(d -> {
            if (!d.findElement(By.xpath("//p[@class='statusText']")).isDisplayed())
                    return false;

            String actualMessage = d.findElement(By.xpath("//p[@class='statusText']")).getText();
            if (actualMessage.contains(errorMessage))
                Assert.fail(actualMessage);

            String expectedMessage = expectedMessages.get(0);
            if (expectedMessage.contains(actualMessage)) {
                log.info(String.format("Message \"%s\" found", actualMessage));
                expectedMessages.remove(expectedMessage);
            }
            return expectedMessages.size() == 0;
        });

Второе решение состоит в том, чтобы получать все сообщения и после проверки.

Используйте код ниже, чтобы получить все сообщения и проверить, что вы получаете с веб-сайта:

JavascriptExecutor js = (JavascriptExecutor) driver;
List<String> actualMessages = new ArrayList<>();
for (int i = 0; i < 30000; i++) {
    actualMessages.addAll(
            (ArrayList<String>) js.executeScript("return [...document.querySelectorAll('p.statusText')].map(e=>{return e.textContent})")
    );

    Thread.sleep(10);
}
// debug here to check message collected
System.out.println(actualMessages);
...