【发布时间】:2019-09-09 20:54:31
【问题描述】:
一段时间后,我使用WebDriverWait 获取WebElement 的值,但如果它没有改变,我不希望它失败,只需获取当前值并继续使用执行。
我正在 Web 中运行一个进程,该进程有一个“进程已完成”标签,我用它来检查它是否已完成。在同一屏幕上,我需要阅读该进程的“经过时间”,以报告运行该进程所需的时间。 问题是,即使出现“进程完成”标签,后端进程仍在运行,并且时间得到更新。我不知道这个“后端更新”需要多长时间,我不知道在快乐运行中它是否会出现在提到的标签之前,目前,从我的测试来看,它从 10 秒到 40 秒(60 到确定)。
我们有一个Waits 类来处理这类东西,但是我们没有这个文本更改验证的方法,所以我想出了这个:
private static WebDriverWait _customWait(int value) => new WebDriverWait(
clock,
Driver.Instance,
TimeSpan.FromSeconds(value),
TimeSpan.FromMilliseconds(Settings.Timeouts.SleepIntervalInMillis));
public static void WaitForTextElementToChange(Func<IWebDriver, IWebElement> elementFinder, IWebDriver driver, int time)
{
string oldValue = elementFinder.Invoke(driver).Read();
_customWait(time).Until(drv =>
{
try
{
return !elementFinder.Invoke(driver).Read().Contains(oldValue);
}
catch (NotFoundException)
{
return true;
}
catch (StaleElementReferenceException)
{
return true;
}
});
}
这行得通。我之所以评论它,是因为我还不完全理解 Until 方法背后的语法和逻辑,我知道它提供了一个 WebDriverTimeoutException,我将其留作框架的附加方法。
所以,如果值发生变化,它就会出来并继续运行,但在这种特殊情况下,如果它没有变化,我不需要它来抛出那个异常,所以我在 try/catch 中调用它。
Waits.WaitForProcessToFinish(drv => processCompleteLabel); //<- context code
try
{
//If value changes before 60 secs everything is fine
Waits.WaitForTextElementToChange(drv => timeElement, someDriverObject, 60);
//60 is a hardcoded int value just for testing
}
catch (WebDriverTimeoutException)
{
//But if it doesn't change just do nothing
}
string timeElapsed = timeElement.Read(); //<- context code
我的问题是,这样可以吗? 你会怎么做?
【问题讨论】:
-
StaleElement 如果元素发生变化应该被抛出,所以你可以在原始元素上检查它并在它被抛出后确认预期的文本。
-
我一直在玩一些代码,尽管元素改变了它的值,但它并没有抛出那个异常。这是 html 代码,在检查模式下查看它时,
div和Time Elapsed : ##:##文本闪烁并且值得到更新。我猜是正常行为。<div class="time-elapsed-heading">Time Elapsed : 00:10</div>但我看不出我应该在哪里做出改变来尝试你的想法。能给我一个提示吗? -
不太确定,但 element.getText() 似乎如果“时间已过”文本已更新,它会抛出陈旧的元素。在进程完成标签出现后尝试获取元素,然后休眠 60 秒。尝试从同一元素中获取文本,然后查看是否引发异常。如果是这样,它已被更新。 (显然最好在服务器端放置一个断言......如果标签在后端进程仍在运行时更新,则断言)
标签: c# selenium webdriverwait