【问题标题】:Selenium How to wait multiple times for the same WebElement with different textSelenium 如何多次等待具有不同文本的同一个 WebElement
【发布时间】:2020-02-06 09:07:26
【问题描述】:

我正在尝试等待 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)初始化了页面对象吗?

【问题讨论】:

  • 分享您的 HTML 代码。 Login attempt exception, error code: 应该出现在错误的凭据尝试之后。
  • 不确定您指的是什么 HTML?登录豁免字符串不是有问题的问题,它是行 wait.until(ExpectedConditions.refreshed(ExpectedConditions.textToBe(By.xpath("//p[@class='statusText']"), msg2)))
  • 也许Login successful 的消息在您的页面上,但您的搜索路径错误。
  • 我确实想到了这一点,但如果我禁用第一次等待,我确实会找到它。这部分测试实际上通过了,但我需要能够报告第一条消息和第二条消息。因此,如果我这样做而不是上面写的 wait.until(ExpectedConditions.textToBe(By.xpath("//p[@class='statusText']"),msg2)) 它会在 wait.until(ExpectedConditions.textToBe(By.xpath("//p[@class='statusText']"), msg1)) 被注释掉时起作用

标签: java selenium selenium-webdriver groovy page-factory


【解决方案1】:

以下代码可用于按顺序检查错误和成功消息。 逻辑:

  1. 将预期消息放入expectedMessages 列表
  2. 使用 Fluent Wait 检查自定义条件
  3. 设置每 50 毫秒轮询一次,以便能够捕获消息
  4. 检查状态消息元素是否可见,如果可见则获取文本
  5. 如果实际状态消息为“错误”则失败
  6. 检查实际状态消息是否包含expectedMessages 中的第一个文本,如果是,请从expectedMessages 中删除第一个文本
  7. 如果expectedMessages,重复第6步直到没有剩余物品


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);

【讨论】:

  • @MistaWizard 如果此答案或任何其他答案解决了您的问题,您可以投票并标记为已接受,how to accept the answer
  • 谢谢,我已经尝试过这种流畅的等待方法,不幸的是它不适用于我的情况。同样,我只接收第一条消息。起初我认为这可能是民意调查,所以我将其设置为 1 毫秒......我可以直观地看到该领域的变化(借助 chrome devtools,我看到它仍然是正确的元素)
  • 测试需要一点时间(我正在尝试 groovy 2.5 和 3.0 以及 java 8/11)
  • 可能还有另一种解决方案可以尝试。我将很快在答案中分享代码。你能解释一下 fluent wait 到底是什么不工作吗?
  • @MistaWizard 在答案中尝试新代码以收集所有消息
猜你喜欢
  • 2020-12-08
  • 2013-06-16
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
相关资源
最近更新 更多