C# 自定义单击中的多个wait.untill
我创建了一个自定义的click方法,它在单击元素之前会一直等到元素可单击为止。该方法运行良好,但我需要添加更多的C# 自定义单击中的多个wait.untill,c#,selenium,xunit,C#,Selenium,Xunit,我创建了一个自定义的click方法,它在单击元素之前会一直等到元素可单击为止。该方法运行良好,但我需要添加更多的wait.Until,以使click方法更稳定 这就是我所拥有的 public static void WaitAndJsClick(this Browser browser, IWebElement element, int seconds = 30) { var LoadingProgressBar = "(//*[@class='progress-bar'])[2]";
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));
}
现在,正如您所看到的,我在单击之前等待三个元素“不可见”,单击之后,它再次等待元素“不可见”
我的问题是,我该如何改进这一点?这是一个好的解决方案吗?
它看起来很混乱,但工作非常好。等等。忽略异常类型(typeof(NoSuchElementException))代码>在这里没有意义。如果确实要忽略某些异常,请在实例化此新Wait对象之后立即执行此方法代码>在这里没有意义。如果您真的想忽略一些异常,请在实例化这个新的Wait对象之后立即执行此方法。我遇到了一个类似的问题,这就是我为确保这种情况下的稳定性所做的
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;
}
}
}
private const int retryintervalinMillingSeconds=2000;
私有常量int ajaxreqtimeoutinems=20000;
public void WaitForAjax()
{
var stopwatch=stopwatch.StartNew();
while(stopwatch.elapsedmillesons
然后,我用WaitForAjax()调用替换了所有等待微调器和进度条的调用
从技术上讲,您可以删除休眠,只需在预期条件下使用javascript ajaxComplete即可返回true
希望这有帮助我也遇到过类似的问题,这就是我为确保此类情况的稳定性所做的
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;
}
}
}
private const int retryintervalinMillingSeconds=2000;
私有常量int ajaxreqtimeoutinems=20000;
public void WaitForAjax()
{
var stopwatch=stopwatch.StartNew();
while(stopwatch.elapsedmillesons
然后,我用WaitForAjax()调用替换了所有等待微调器和进度条的调用
从技术上讲,您可以删除休眠,只需在预期条件下使用javascript ajaxComplete即可返回true
希望这有帮助我不太喜欢等待一大堆东西的通用方法。我认为当事情出错时,它会使事情变得更加混乱和难以调试。我会为你需要等待的每个“东西”写一个函数。。。进度条、微调器、加载消息等,然后在需要时调用它们
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);
现在,等待每件“事情”的代码只存在于一个地方(如下所示),并且更易于维护。我不太喜欢等待一堆东西的通用方法。我认为当事情出错时,它会使事情变得更加混乱和难以调试。我会为你需要等待的每个“东西”写一个函数。。。进度条、微调器、加载消息等,然后在需要时调用它们
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);
现在,等待每件“事情”的代码只存在于一个地方(如下所示),并且更易于维护。谢谢,Ajax加载实际上是我最大的问题。我现在就试试看没问题。让我知道进展如何。谢谢,Ajax加载实际上是我最大的问题。我现在就试试看没问题。让我知道它是如何进行的。也许你不必等待加载微调器不可见,而可以等待元素可单击?@NicolasG.Duvivier是的。我已经有这种情况了。问题是,在加载微调器消失之前,元素可单击,因此Selenium无法“获取”按钮:(对不起,我没有注意到你的代码。当SPENE已经存在时,它是否认为元素是可点击的,或者是因为自旋者出现了一点滞后,然后等待已经被执行了?)NeOLasas.Duvivier-Yes,这就是问题所在,也是我需要等待三个元素先消失的原因。这是一种仅在需要微调器时才使用的方法吗?也许您可以不等待加载微调器不可见,而只等待元素可单击?@NicolasG.Duvivier是的。我已经有了这种情况。问题是,在加载微调器消失之前元素可单击,因此Selenium无法“获取”按钮:(对不起,我没有注意到你的代码。当SPENE已经存在时,它是否认为元素是可点击的,或者是因为自旋者出现了一点滞后,然后等待已经被执行了?)NeOLasas.Duvivier-Yes,这就是问题所在,也是我需要等待三个元素先消失的原因。这是一种你只在期待一个微调器时才使用的方法吗?完全同意!这是我第一次这样做的,不幸的是,负责框架的人说,阅读这个微调器会变得一团糟