我需要实现和修改我当前的方法来完成这两件事:
- 等待可见元素 - (当前已实现,但它仍然使用已过时且可能更改的预期条件(
- 等待可点击的元素 - (当我的测试运行时,它面临"加载圆圈"的问题,我按下按钮,在加载窗口之前有加载器,需要 1 到 4 秒,然后它消失了。我的目标是迫使硒等待"XXX"时间,当加载完成时,然后继续处理。
当前代码:
public static IWebElement WaitForElementVisible(this IWebDriver driver, By by, int timeoutInSeconds = 6)
{
IWebElement element;
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(0);
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
element = wait.Until(ExpectedConditions.ElementIsVisible(by));
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(Configuration.ElementTimeout);
return element;
}
catch (WebDriverTimeoutException e)
{
Console.WriteLine(e.ToString());
}
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(Configuration.ElementTimeout);
return null;
}
基于不同的主题,我已经开始写一些东西,但不幸的是它只是复制......
我宁愿做一个有价值的方法,目标是检查这两件事。您能否给我任何建议/提示,可以添加到该特定方法中?
//编辑
我正在添加该加载器代码的外观:
<div class="Loader__background" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 10;">
<div class="Loader__foreground" style="display: table; width: 100%; height: 100%; text-align: center; z-index: 20; color: white;">
<div class="Loader__message" style="display: table-cell; vertical-align: middle;">
<div mode="indeterminate" value="0" min="0" max="100" style="position: relative; display: inline-block; width: 280px; height: 280px;">
<div style="width: 280px; height: 280px; display: inline-block; transition: transform 10s linear 0ms; transform: rotate(1800deg);">
<svg viewBox="0 0 280 280" style="width: 280px; height: 280px; position: relative;">
<circle cx="140" cy="140" r="137.5" fill="none" stroke-width="5" stroke-miterlimit="20" style="stroke: rgb(0, 188, 212); stroke-linecap: round; transition: all 750ms ease-in-out 0ms; stroke-dasharray: 604.757, 863.938; stroke-dashoffset: -259.181;"></circle>
</svg>
</div>
</div>
</div>
</div>
</div>
我还@sers Java 建议转移到 C# 中:
public static IWebElement WaitForElementClickable(this IWebDriver driver, By by, int timeoutInSeconds)
{
new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)).Until(d =>
{
Boolean ajaxComplete;
Boolean jsReady;
Boolean loaderHidden = false;
IJavaScriptExecutor js = (IJavaScriptExecutor)d;
jsReady = (Boolean)js.ExecuteScript("return (document.readyState == "complete" || document.readyState == "interactive")"); ;
try
{
ajaxComplete = (Boolean)js.ExecuteScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
}
catch (Exception)
{
ajaxComplete = true;
}
try
{
loaderHidden = !d.FindElement(by).Displayed;
}
catch (Exception) { }
return ajaxComplete && jsReady && loaderHidden;
});
}
据我了解,在屏幕上加载元素但覆盖元素时,您的元素是可见且可点击的,也许您需要等待 javascript 完成才能成功单击。
您需要获取"加载圆圈"定位器。对于打开的chrome开发工具触发"加载圆圈"出现并按F8(暂停(,然后您可以找到加载元素的html。
等到加载元素消失:
var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(8));
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingElementLocator);
你也可以检查javascript是否完整:
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
bool jsLoaded = (bool)js.ExecuteScript("return (document.readyState == "complete" || document.readyState == "interactive")");
这里是Java示例:
new WebDriverWait(driver, timeoutSec).until(d ->
{
boolean ajaxComplete;
boolean jsReady;
boolean loaderHidden = false;
JavascriptExecutor js = (JavascriptExecutor) d;
jsReady = (boolean) js.executeScript("return (document.readyState == "complete" || document.readyState == "interactive")");;
try {
ajaxComplete = (boolean) js.executeScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
} catch (Exception ignored) {
ajaxComplete = true;
}
try {
loaderHidden = !d.findElement(loadElementLocator).isDisplayed();
} catch (Exception ignored) {}
return ajaxComplete && jsReady && loaderHidden;
});
这是您更新的代码:
public static void WaitForLoading(IWebDriver driver, int timeoutInSeconds)
{
new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)).Until(d =>
{
Boolean ajaxComplete;
Boolean jsReady;
Boolean loaderHidden = false;
IJavaScriptExecutor js = (IJavaScriptExecutor)d;
jsReady = (Boolean)js.ExecuteScript("return (document.readyState == "complete" || document.readyState == "interactive")"); ;
try
{
ajaxComplete = (Boolean)js.ExecuteScript("var result = true; try { result = (typeof jQuery != 'undefined') ? jQuery.active == 0 : true } catch (e) {}; return result;");
}
catch (Exception)
{
ajaxComplete = true;
}
try
{
loaderHidden = !d.FindElement(By.ClassName("Loader__background")).Displayed;
}
catch (Exception) { }
return ajaxComplete && jsReady && loaderHidden;
});
}
如何使用:
WaitForLoading(driver, 10);
myButton.Click();
.NET 绑定中的ExpectedConditions
已过时,但已移至DotNetSeleniumExtras
已过时:"预期条件" .NET 绑定中的实现已弃用,将被删除 在将来的版本中。这部分代码已迁移到 GitHub上的DotNetSeleniumExtras存储库 (https://github.com/DotNetSeleniumTools/DotNetSeleniumExtras('
从那里使用ExpectedConditions
,它将消除警告
using WaitHelpers = SeleniumExtras.WaitHelpers;
wait.Until(WaitHelpers.ExpectedConditions.ElementIsVisible(by));
您还可以使用ExpectedConditions
等待元素可单击
IWebElement webElement = wait.Until(WaitHelpers.ExpectedConditions.ElementToBeClickable(by));
webElement.Click();
另一种选择是等待加载程序出现,然后消失,然后继续
wait.Until(WaitHelpers.ExpectedConditions.ElementIsVisible(by));
wait.Until(WaitHelpers.ExpectedConditions.InvisibilityOfElementLocated(by));