gpt4 book ai didi

java - Thread.sleep 可以工作,但隐式等待、webdriverwait 和流畅等待却不能?

转载 作者:行者123 更新时间:2023-11-30 07:53:46 24 4
gpt4 key购买 nike

driver.findElement(By.xpath(sOptionPath)).click();  //this option button changes contents of page   
Thread.sleep(4000);
WebElement combo=driver.findElement(By.xpath(sXpath));
Select dropdownvalue = new Select(combo);
dropdownvalue.selectByVisibleText(sText);

上面的代码工作正常,但如果我使用 wait 而不是 thread.sleep,我会得到 StaleElementReferenceException 异常。这是我使用的 Fluent wait :

    Wait<WebDriver> newwait=new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class);

WebElement combo=newwait.until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath(sXpath));
}

});

这找到了组合框,但再次对组合框执行任何操作都会给出 NoSuchElement 或 statestate 异常。所以我也尝试过从组合框中选择值:

    Wait<WebElement> elwait=new FluentWait<WebElement>(combo).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class,NoSuchElementException.class);

Boolean a=elwait.until(new Function<WebElement,Boolean>(){
@Override
public Boolean apply(WebElement arg0) {
Select dropdownvalue = new Select(arg0);
dropdownvalue.selectByVisibleText(sText);
return true;
}

});

这个超时并且不起作用!

我怎样才能让它工作,为什么它不工作而 thread.sleep 工作。为什么使用 Thread.sleep 是一种不好的做法?

最佳答案

我会尝试使用 ExpectedCondtions 类中的一些现有检查来验证我返回到“组合”的对象是否过时。

   Wait<WebDriver> newwait=new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class);

WebElement combo=newwait.until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver driver) {
WebElement found = driver.findElement(By.xpath(sXpath));
if (ExpectedConditions.stalenessOf(found).apply(driver)) {
return null;
}
return found;
}

});

我正在使用版本 2.47.2,当从委托(delegate)函数返回 null 时,FluentWait 似乎会重试,因此如果您否则会收到 StaleElementException,我希望重试。

 public <V> V until(Function<? super T, V> isTrue) {
long end = clock.laterBy(timeout.in(MILLISECONDS));
Throwable lastException = null;
while (true) {
try {
V value = isTrue.apply(input);
if (value != null && Boolean.class.equals(value.getClass())) {
if (Boolean.TRUE.equals(value)) {
return value;
}
} else if (value != null) {
return value;
}
} catch (Throwable e) {
lastException = propagateIfNotIngored(e);
}

// Check the timeout after evaluating the function to ensure conditions
// with a zero timeout can succeed.
if (!clock.isNowBefore(end)) {
String toAppend = message == null ?
" waiting for " + isTrue.toString() : ": " + message;

String timeoutMessage = String.format("Timed out after %d seconds%s",
timeout.in(SECONDS), toAppend);
throw timeoutException(timeoutMessage, lastException);
}

try {
sleeper.sleep(interval);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new WebDriverException(e);
}
}

我在一次测试中看到了类似的情况,花了我一段时间,但我最终得出结论,在我的例子中,这是 WebDriver 配置中的隐式等待和显式等待时间之间的竞争条件。我还没有进行测试来证明这种情况,但这是我目前的理论......

sleep

  1. 执行任务来刷新 dom
  2. sleep ——期间 dom 刷新
  3. 从刷新 dom 重新请求对象
  4. 测试按预期继续进行。

显式等待<=隐式等待

  1. 执行任务来刷新 dom
  2. 显式等待触发(10秒),抓取dom并尝试获取元素(隐式等待30秒)
  3. Dom 刷新
  4. 显式等待在 10 秒后结束。它只尝试一次根据原始 DOM 解析对象
  5. 测试失败

显式等待 > 隐式等待

  1. 执行任务来刷新 dom
  2. 显式等待触发(30秒),抓取dom并尝试获取元素(隐式等待10秒)
  3. Dom 刷新
  4. 10秒后第一个请求失败,dom刷新
  5. 显式等待尝试获取元素,并成功
  6. 测试继续。

根据这个假设,我最近没有看到这个问题。我使隐式等待值可供我的测试访问,现在我可以根据我想要执行的重试次数来计算时间范围。

private final WebElement explicitWait(int retries, Predicate<Boolean> test) {
WebDriverWait wait = new WebDriverWait(driver, retries * getImplicitWait());
return wait.until(test);
}

我完全同意 Vinoth 关于 Thread.sleep 的使用和可靠性的观点,它是不可靠的,如果它在大量测试中出现得太频繁,可能会造成浪费。最好有一种能够尽快响应并考虑类型正确且有意义的异常的机制。

祝你好运。

关于java - Thread.sleep 可以工作,但隐式等待、webdriverwait 和流畅等待却不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32977691/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com