我创建了一个自定义单击方法,在单击元素之前等待元素可单击。该方法运行良好,但我需要添加更多wait.Until
以使click方法更稳定。
这就是我所拥有的。
public static void WaitAndJsClick(this Browser browser, IWebElement element, int seconds = 30)
{
var LoadingProgressBar = "(//*[@class='progress-bar'])[2]";
var loading = "loading";
var spinner = "spinner";
var wait = new WebDriverWait(browser.Driver, new TimeSpan(0, 0, seconds));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName(loading)));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName(spinner)));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.XPath(LoadingProgressBar)));
wait.Until(ExpectedConditions.ElementToBeClickable(element));
element.JsClick(browser); // Click
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName(loading)));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName(spinner)));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.XPath(LoadingProgressBar)));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
}
现在你可以看到,我等待三个元素是"隐形"在点击之前,点击之后它再次等待元素"隐形"
我的问题是,我怎么能改善这个?这是一个很好的解决方案吗? 它看起来像一团糟,但工作得非常好。
答案 0 :(得分:1)
我遇到了类似的问题,这就是我为确保此类案件的稳定所做的工作。
private const int RetryIntervalInMilliSeconds = 2000;
private const int AjaxReqTimeoutInMilliSeconds = 20000;
public void WaitForAjax()
{
var stopwatch = Stopwatch.StartNew();
while (stopwatch.ElapsedMilliseconds < AjaxReqTimeoutInMilliSeconds)
{
try
{
Thread.Sleep(RetryIntervalInMilliSeconds);
var ajaxIsComplete = (bool)browser.ExecuteJavascript("return window.jQuery && jQuery.active == 0");
if (ajaxIsComplete)
{
break;
}
}
catch
{
return;
}
}
}
然后我用调用WaitForAjax()替换了所有等待旋转器和进度条的调用。
您可以在技术上删除睡眠,只需在expectedCondition中使用javascript ajaxComplete即可返回true。
希望这有帮助
答案 1 :(得分:1)
我不是等待一堆东西的通用方法的忠实粉丝。我认为当出现问题时,它会使事情变得更加混乱和难以调试。我会为每个&#34;事情写一个函数&#34;你需要等待......进度条,微调器,加载信息等,然后在需要时调用它们。
public static void WaitForLoading(this Browser browser)
{
new WebDriverWait(browser.Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName("loading")));
}
public static void WaitForProgressBar(this Browser browser)
{
new WebDriverWait(browser.Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.XPath("(//*[@class='progress-bar'])[2]")));
}
public static void WaitForSpinner(this Browser browser)
{
new WebDriverWait(browser.Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName("spinner")));
}
然后,当您需要在单击元素后等待进度条时,您可以执行类似这样的操作
element.JsClick(browser);
WaitForProgressBar(browser);
现在你的代码等待每个&#34;事情&#34;只存在于一个地方(跟DRY principle之后)并且更容易维护。
答案 2 :(得分:0)
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
在这里毫无意义。如果您确实要忽略某些异常,请在实例化此新Wait对象后立即执行此方法