Java Selenium如何多次等待具有不同文本的相同WebElement

Java Selenium如何多次等待具有不同文本的相同WebElement,java,selenium,selenium-webdriver,groovy,page-factory,Java,Selenium,Selenium Webdriver,Groovy,Page Factory,我正在尝试等待WebElement从空白变为消息1,然后变为消息2。问题是我每次都能找到第一条消息,但我似乎总是等不及第二条(寻找文本时超时) 我试过让等待对象分开,但没有成功。我尝试了一些预期条件方法(textToBePresent*),但经过一些阅读(我发现有关刷新的EC)后,这些方法都没有用 @FindBy(xpath="//p[@class='statusText']") WebElement statusMsg public WebElement statusMsg(){ S

我正在尝试等待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:预期条件失败: 正在等待条件(由.xpath找到的元素: //p[@class='statusText']要使text“登录成功,请 等待。“。当前文本:“登录,请稍候。”)


然而,在测试运行时,我可以看到
msg2
。是否必须这样做,因为我已经通过
PageFactory.initElements(驱动程序,this)
初始化了页面对象?

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

  • 将预期消息放入
    expectedMessages
    列表
  • 使用Fluent Wait检查自定义条件
  • 设置每50毫秒轮询一次以捕获消息
  • 检查状态消息元素是否可见,如果可见,则获取文本
  • 如果实际状态消息为“错误”,则失败
  • 检查实际状态消息是否包含
    expectedMessages
    中的第一个文本,如果是,请从
    expectedMessages
  • 如果
    expectedMessages

  • WebDriverWait wait=newwebdriverwait(驱动程序,20);
    String errorMessage=“登录尝试异常,错误代码:”;
    List expectedMessages=Arrays.asList(
    “正在登录,请稍候。”,
    “登录成功,请稍候。”);
    等待.轮询间隔(持续时间.百万(50))
    .withMessage(String.format(“应为%s登录消息”,应为消息))
    .直到(d->{
    如果(!d.findelelement(By.xpath(//p[@class='statusText'])).isDisplayed())
    返回false;
    字符串actualMessage=d.findElement(By.xpath(“//p[@class='statusText'])).getText();
    if(实际消息包含(错误消息))
    断言失败(实际消息);
    字符串expectedMessage=expectedMessages.get(0);
    if(expectedMessage.contains(actualMessage)){
    log.info(String.format(“找到消息\%s\”,实际消息));
    expectedMessages。删除(expectedMessage);
    }
    返回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);
    
    JavascriptExecutor js=(JavascriptExecutor)驱动程序;
    List actualMessages=new ArrayList();
    对于(int i=0;i<30000;i++){
    actualMessages.addAll(
    (ArrayList)js.executeScript(“return[…document.querySelectorAll('p.statusText'))].map(e=>{return e.textContent}”)
    );
    睡眠(10);
    }
    //在此处调试以检查收集的消息
    系统输出打印项次(实际信息);
    
    共享您的HTML代码<代码>登录尝试异常,错误代码:应该出现在错误的凭据尝试之后。不确定您所指的HTML是什么?登录豁免字符串不是问题所在,而是行
    wait.until(ExpectedConditions.refresh(ExpectedConditions.textToBe(By.xpath(“//p[@class='statusText']),msg2)))
    可能您的页面上有消息
    登录成功
    ,但您的xpath搜索错误。我确实想到了这一点,但如果禁用第一次等待,我会找到它。这部分测试实际上通过了,但我需要能够报告第一条消息和第二条消息。因此,如果我这样做而不是上面写的wait.until(ExpectedConditions.textToBe(By.xpath(“//p[@class='statusText']”,msg2))则在注释了
    wait.until(ExpectedConditions.textToBe(By.xpath(“//p[@class='statusText']”,msg1))
    时工作out@MistaWizard如果这个答案或任何其他答案解决了你的问题,您可以将答案向上投票并将其标记为已接受,谢谢,我已经尝试过这种流畅的等待方法,但不幸的是,它在我的情况下不起作用。再一次,我只收到了第一条信息。起初我认为可能是民意测验,所以我把它设为1毫秒。。。我可以直观地看到该领域的变化(借助chrome devtools,我看到它仍然是正确的元素)它花了一点时间进行测试(我正在groovy 2.5和3.0以及java 8/11中尝试)可能还有一个解决方案可以尝试。我将很快在答案中分享代码。你能解释一下fluent wait到底有什么不起作用吗?@MistaWizard在答案中尝试新代码来收集所有消息
    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);