public static void WaitUntil(this IWebDriver driver, Func<bool> Condition, float timeout = 10f) { float timer = timeout; while (!Condition.Invoke() && timer > 0f) { System.Threading.Thread.Sleep(500); timer -= 0.5f; } System.Threading.Thread.Sleep(500); } driver.WaitUntil(() => driver.FindElements(By.XPath(".//*[contains(@class, 'block-ui-wrapper')]").Length == 0);
我有一类扩展,我做了一堆自定义的Selenium操作。我发现隐性等待给我带来的麻烦比它值得多。而且我发现明确的selenium等待可能会有点冗长,而且它并没有涵盖我在框架中需要的所有东西,所以我已经做了很多扩展。这是其中之一。注意,我在上面的示例中使用了FindElements,因为如果没有找到任何内容,我不希望抛出异常。这应该适合你。
注意:您需要将它放在静态类中才能正常工作。在逻辑中扩展这样的现有类时要小心,因为当他们试图确定方法的定义时,可能会混淆其他类。
这是我的完整扩展文件,通过Github的要点。我几乎包装了所有Selenium函数。我做了很多Javascript,因为JQuery在查找元素方面100%可靠,而Selenium的find函数在IFrames等内容中有些麻烦。此外,JQuery具有非常强大且超可读的方式,可以使用任意数量的定位器查询DOM中的元素,无论它们是ID,类,文本包含,伪选择器等;所有在同一个查询字符串中! (Selenium css选择器中缺少伪选择器支持可能是一个限制)这就是我使用它的原因。它比xpath更易读,更容易编写,并且在正确编写时100%可靠。如果您在测试页面上没有JQuery,那么每次加载新页面时都可以简单地注入JQuery的脚本。
所以我所做的是使用JQuery查找并生成一个显式的XPath到我想要的页面上的确切元素,然后我将精确的XPath传递给Selenium的“查找”逻辑。握住Selenium的手,找到元素没有问题。
https://gist.github.com/tsibiski/04410e9646ee9ced9f3794266d6c5a82
的 注意: 强> 您可以将此与上面的单击逻辑结合使用以扩展点击次数,并始终等到您尝试单击的对象准备好进行单击。通过我的扩展,您可以完全等待您能想到的任何条件,在明确等待中的特定场景,以及隐含的一般等待。
请注意,在我的扩展方法中,我将Element.Click()扩展为Element.ReliableClick()。这不仅处理难以找到的元素,而且在点击之前等待。此外,您可以在此抽象扩展功能中执行许多操作,例如自定义报告。
如果您想快速修复,可以添加呼叫 WebDriverWait.until() 在每个页面对象的构造函数中,如下所示: webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(CSS_SELECTOR))) 哪里 CSS_SELECTOR 将是一个定位器 独特 到你需要等待的页面。
WebDriverWait.until()
webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(CSS_SELECTOR)))
CSS_SELECTOR
例如,如果 CSS_SELECTOR 是一个id,它会是 "#some-unique-id" 如果它是一些独特的类,那将是 ".some-unique-class" 或者是一个独特的标签 "some-unique-tag"
"#some-unique-id"
".some-unique-class"
"some-unique-tag"
这将基本上等待页面在实例化时加载 LoginPage lp = new LoginPage(driver) ,或者您需要实例化的任何页面。
LoginPage lp = new LoginPage(driver)
在你的 BaseClass 你需要添加一个类 public static WebDriverWait webDriverWait 对象并像这样实例化它: webDriverWait = new WebDriverWait(driver, MAX_WAIT_SECONDS); 哪里 MAX_WAIT_SECONDS 是抛出异常之前的最大等待秒数。
BaseClass
public static WebDriverWait webDriverWait
webDriverWait = new WebDriverWait(driver, MAX_WAIT_SECONDS);
MAX_WAIT_SECONDS
下面是我等待元素(或by)可点击的重载方法。元素版本硬编码等待10秒,另一个你传递秒等待作为第二个参数。你明白了。显然,这将用于代替页面对象元素。
/** * Wait until a web element is clickable by WebElement * @author Bill Hileman * @param ele - WebElement */ public void waitUntilClickable(WebElement ele) { (new WebDriverWait(driver, 10)).until(ExpectedConditions.elementToBeClickable(ele)); } /** * Wait until a web element is clickable by locator * @author Bill Hileman * @param by - By */ public void waitUntilClickable(By by, int seconds) { (new WebDriverWait(driver, seconds)).until(ExpectedConditions.elementToBeClickable(by)); }