只要我使用PageObject模式,我就想知道应该在哪里等待动态页面上的元素。假设我们有测试方法和pageObject类。我应该做类似的事情吗(在测试方法中):
也许还有其他好的做法来等待该要素?也许我们应该等待PageObject.class中的isElementDisplayed方法中的元素?
您应该等待页面对象类中的元素,而不是测试类中的元素,因为您的元素应该在页面对象类中定义,测试类应该不了解任何元素,选择器或类似元素。测试(恕我直言)应该只包含描述测试流程的方法调用链,与网站和基础DOM的所有交互都应在Page
Object类中进行。
因此,等待某个元素出现的过于冗长的方法可能类似于:
private final By yourElement = By.id("id");
@Override
public void isLoaded() throws Error {
new FluentWait<WebDriver>(driver)
.withTimeout(60, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class)
.until(new Function<WebDriver, Boolean>() {
@NotNull
@Override
public Boolean apply(WebDriver webDriver) {
WebElement element = driver.findElement(yourElement);
return element != null && element.isDisplayed();
}
});
}
用简单的话来说,该函数将轮询DOM
60秒(每1秒)以查看元素是否存在于DOM中并且可见(意味着高度和witdh大于1px)。如果该元素存在(并显示),则该函数将返回找到的元素并停止轮询(尽管isLoaded()
在这种情况下方法不会返回该元素)。
如果找不到元素NoSuchElementException
,可以忽略findElement
方法可能抛出的错误,并且StaleElementException
,它指示对元素的引用现在已“陈旧”-该元素不再出现在页面的DOM上。这通常意味着,某些内容(最常见的是JS)已修改DOM,并且引用不再有效,因此WebDriver
需要再次查找它。
当然,较短的代码也可以解决问题,例如:
new WebDriverWait(driver, 60)
.until(ExpectedConditions.visibilityOf(someWebElement));
该文档实际上对此非常好。
编辑:评论的答案:
好,懂了。但是,如果在单击某个按钮等之后存在元素,该怎么办?
假设您有一个方案,其中有一个按钮,单击该按钮后,将出现一个文本框,您想与之交互。
public class PageObject extends LoadableComponent<PageObject>{
public PageObject() throws Exception {
driver = getWebDriver();
PageFactory.initElements(driver, this);
isLoaded();
}
private WebDriver driver = null;
@FindBy(id = "yourButton")
private WebElement button;
@FindBy(id = "textBoxThatAppears")
private WebElement txtBox;
@Override
public void isLoaded() throws Error {
// Initial loading, called when creating the page object to make sure that the page is loaded to a state where it is ready to interact with us, in our case it means that button is present in DOM and visible.
waitForVisibility(button);
}
private void waitForVisibility(WebElement element) throws Error{
new WebDriverWait(driver, 60)
.until(ExpectedConditions.visibilityOf(element));
}
public void clickButton(){
button.click();
}
public void interactWithTextbox(String text){
// Wait for txtBox to be visible, then send text
waitForVisibility(txtBox);
txtBox.sendKeys(text);
// EDIT 27.04.14:
// Actually you should not do the assertion here or anywhere in
// the pageObject, because when reusing the method in some other test, you might
// not want to assert, you might wonder that why wouldn't you assert some
// specific condition every time, but I would throw that question right back
// to you and ask: What is the point of checking the exact same thing over and
// over again. There are 2 things, firstly the assertion takes resources (and
// that can become important when test suite grows, secondly your tests can
// simply start failing at the same point when one little condition is not as
// it should be. Also, having the asserts in the test, makes the test more
// readable and understandable for others.
// end edit 27.04.14
// Next line is no longer recommended by this answer.
// assert that something happened that you expected.
}
}
现在您的测试课:
public void TestClass {
@Test
public void testClickButtonAndInteractWithTextbox(){
// Initiate the page object
Pageobject po = new PageObject();
po.clickButtonAndWaitForTextbox();
po.interactWithTextbox("blabla");
// edit 27.04.14
assertSomethingGoodHappened();
}
}
问题内容: 我正在寻找类似于在单击元素之前检查元素是否已显示的内容。我认为可以通过完成此操作,因此我使用了以下方法: 然后点击 不幸的是,有时它等待元素,有时不等待。我寻找了一段时间,找到了这个解决方案: 它等待一切正常,但是在超时之前必须等待10次5、50秒。有点多。因此,我将隐式等待时间设置为1秒,直到现在一切都还不错。因为现在有些事情在超时前等待10秒,而另一些事情在1秒之后超时。 如何覆盖
等待元素出现在网页上的最佳方式是什么?我已经读到,我们可以使用隐式等待和功能,如网络驱动程序wait,流利的等待等,最后但不是最不重要的线程.sleep()...我使用最多,但想停止使用。 我的场景: 用户登录到网站…网站检查凭据,并以叠加的形式向用户提供报价(一种弹出窗口,但不是单独的窗口)。我需要验证叠加图上的文字。用户登录和显示覆盖之间存在时间间隔。最好的方法是什么,以便硒只等待元素不可见的
它一直在等待,但在超时之前,它必须等待10乘以5,50秒。有点多。所以我将隐含的等待设置为1秒,直到现在看起来一切都很好。因为现在有些事情在超时前等待10秒,但有些事情在1秒后超时。 如何在代码中覆盖等待元素的存在/可见性?任何暗示都是可以察觉的。
问题内容: 是否有办法让a 等待许多元素之一出现并根据哪个元素出现而采取相应的行动? 目前,我在try循环中执行了一个操作,如果发生超时异常,我将运行备用代码,等待其他元素出现。这看起来很笨拙。有没有更好的办法?这是我的(笨拙的)代码: 它需要等待整整10秒钟,然后才能查看系统上是否已存在该文件的消息。 该函数仅执行许多调用,如下所示: 有人有任何建议以更有效的方式完成此任务吗? 问题答案: 创建
我有一个动态加载的页面,其中包含一个按钮。我正在尝试等待selenium使用C#绑定点击按钮。我有以下代码: 不过这不管用。click事件永远不会被触发。selenium脚本不会抛出异常警告ID为“addInspectionButton”的元素不存在。它只是不能点击它。如果我加一根线。Sleep(3000)在wait语句和我获得按钮元素句柄的那一行之间。 我没有使用预期条件.元素在这里正确点击吗?
问题内容: 等待和一起出现很方便。 问题是, 如果 找到元素的唯一可能方法 是 什么,因为它没有id,没有名称,没有唯一的类? 的构造函数仅接受作为参数,而不接受。 我已经设定了时间,所以使用它似乎不是一个好主意,因为我不想为这个元素等待那么长时间。 这是场景: 有一个网页,其中包含许多标签。每个标签都有格式要求。 当不满足格式要求时,动态标签将出现在该标签之后。 由于标签太多,因此我创建了一个通