Java 等待元素-WebDriver-页面对象模式
只要我使用PageObject模式,我就想知道应该在哪里等待动态页面上的元素。假设我们有测试方法和pageObject类。我是否应该(在测试方法中)执行以下操作:Java 等待元素-WebDriver-页面对象模式,java,selenium,webdriver,selenium-webdriver,pageobjects,Java,Selenium,Webdriver,Selenium Webdriver,Pageobjects,只要我使用PageObject模式,我就想知道应该在哪里等待动态页面上的元素。假设我们有测试方法和pageObject类。我是否应该(在测试方法中)执行以下操作: 点击按钮 等待显示元素 验证元素(包含例如方法isElementDisplayed()) 或者可能还有其他好的实践来等待元素?也许我们应该等待PageObject.class中的isElementDisplayed方法中的元素?您应该等待PageObject类中的元素,而不是测试类中的元素,因为您的元素应该在PageObject类中定
或者可能还有其他好的实践来等待元素?也许我们应该等待PageObject.class中的isElementDisplayed方法中的元素?您应该等待PageObject类中的元素,而不是测试类中的元素,因为您的元素应该在PageObject类中定义,测试类应该不知道任何元素、选择器或类似内容。测试IMHO应该只包含描述测试流的方法调用链,与网站和底层DOM的所有交互都应该在页面对象类中进行 因此,等待某个元素出现的过于冗长的方法可能类似于:
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();
}
});
}
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.
}
}
另一个有效的测试页面概念(从selenium 1开始)可以在这里使用。它有延迟加载的元素、自定义组件特性和自动等待(而不是降低性能的隐式等待)、内置的等待方法和元素以及其他对ajax应用程序非常有用的特性 它为开发测试用例提供了以下构建块:
此外,还具有描述性 谢谢你的回答。你的解决方案是我们等待每一个元素。如果我想等待一个元素,例如60秒,而另一个元素是静态的,因此我只能等待15秒,该怎么办?我的问题是:如何定义这个等待测试?测试用例需要等待吗?或者它应该隐藏在PageObject中吗?不,它不是等待每个元素,而是等待您指定的元素,例如,第二段代码等待“someWebElement”(只有一个WebElement类型的项,而不是所有已定义元素的列表,等等)。如果您想在测试中等待,这意味着您必须在测试类中定义此元素,这将超出页面对象的用途,所以我想说,只在页面对象中等待,如果元素是在页面上动态创建的,那么每次都应该等待您想要与之交互的特定元素。好的,明白了。但是,如果在单击某个按钮等之后元素出现了呢?ClickButton和WaitForTextBox()-我的主要问题是关于这个方法的。好的,所以我们必须在单击中等待元素。所以,我们应该在与元素交互之前一直等待它,还是在交互之前检查它的存在?我不这么做-在与元素交互之前检查每个元素的存在,因为我看不出这有什么意义。我只在必要时等待(即动态创建元素、发生数据绑定、某些异步javascript正在执行某些操作等)。我的意思是,你自己知道当这样的事情发生时,你会编写代码来支持它。
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();
}
}