Selenium Automation - 如何定期单击特定按钮直到获得另一个元素的更新文本值?

Selenium Automation - How to click on particular button periodically until getting another element's updated text value?

在我的网页中,我有一个刷新按钮和一个文本字段, 当我登陆该页面时,最初该文本字段值将是 processing(在后端有一个正在处理的功能,为了通知用户,文本字段值正在 UI 中处理),然后功能完成后,文本字段将是 completed

现在来谈谈这个问题, 只有点击刷新按钮,我们才会知道Text Field的更新值,

有没有办法让 WebElement 等到文本字段的值为 completed?我们还需要定期单击该特定刷新按钮以检查文本字段值是否变为 completed 或未变为

我在ExpectedConditions中找到了一个叫做textToBePresentInElement的方法,但是使用这个方法,我们不能定期刷新按钮, selenium webdriver 是否提供其他解决方案?

您需要写一个自定义的方法来等待一段时间然后执行点击操作。您可以看到下面的示例代码,

代码:

创建一个re-usable方法,并写下方法内部的逻辑,在给定的显式间隔时间进行点击操作和元素值检查。

public static void clickUntilStatusIsChanged(By element1, By element2, String expectedStatus, int timeOutSeconds) {
    WebDriverWait wait = new WebDriverWait(driver, 5);

    /* The purpose of this loop is to wait for maximum of 50 seconds */
    for (int i = 0; i < timeOutSeconds / 10; i++) {
        if (wait.until(ExpectedConditions.textToBePresentInElementLocated(element2, expectedStatus))) {
            break;
        } else {
            /* Waits for 10 seconds and performs click operation */
            waitForTime(timeOutSeconds / 5);
            driver.findElement(element1).click();
        }
    }
}

public static void waitForTime(int interval) {
    int waitTillSeconds = interval;
    long waitTillTime = Instant.now().getEpochSecond() + waitTillSeconds;
    while (Instant.now().getEpochSecond() < waitTillTime) {
        // Do nothing...
    }
}

将参数传递给re-usable方法:

clickUntilStatusIsChanged(By.xpath("Element#1"), By.xpath("Element#2"), "completed", 50);

可以实现自定义预期条件:

import org.openqa.selenium.support.ui.ExpectedCondition

public static ExpectedCondition<Boolean> textToBePresentForElementWithRefreshByClick(By originalElement, Strint expectedText, By refreshElement) {
    return new ExpectedCondition<Boolean>() {
        private boolean hasText = false;
        private String currentText = "";

        @Override
        public Boolean apply(WebDriver driver) {
            currentText = driver.findElement(originalElement).getText();
            hasText = currentText == expectedText;
            if(!hasText) {
                driver.findElement(refreshElement).click();
                // Optionally some sleep might be added here, like Thread.sleep(1000);
            }
            return hasText;
        }

        @Override
        public String toString() {
            return String.format("element \"%s\" should have text \"%s\", found text: \"%s\"", originalElement.toString(), expectedText, currentText);
        }
    };
}

用法:

By originalElement = ...;
By refreshElement = ...;

new WebDriverWait(driver, Duration.ofSeconds(10)).until(
    textToBePresentForElementWithRefreshByClick(originalElement, "completed", refreshElement)
)