使用 Java 在 Selenium WebDriver 中使用 PageObjects、Page Factory 和 WebDriverWait
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16182173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using PageObjects, Page Factory and WebDriverWait in Selenium WebDriver using Java
提问by Jamie Piltz
I've been using Selenium WebDriver to implement functional tests for some projects that I've worked with. I'm trying to use the Page Object design pattern with Page Factory to factor out my locators. I've also created a static WaitTool object (singleton) that implements several waiting techniques with optional timeout parameters.
我一直在使用 Selenium WebDriver 为我合作过的一些项目实施功能测试。我正在尝试将页面对象设计模式与页面工厂一起使用来分解我的定位器。我还创建了一个静态 WaitTool 对象(单例),它实现了几种带有可选超时参数的等待技术。
My current problem is that I would like to use my wait methods before the PageFactory attempts to initialise the WebElements. The reason I would like to wait is because the PageFactory may try to initialise the page elements before they are available on the page.
我当前的问题是我想在 PageFactory 尝试初始化 WebElements 之前使用我的等待方法。我想等待的原因是因为 PageFactory 可能会尝试在页面元素在页面上可用之前对其进行初始化。
Here is a sample PageObject:
这是一个示例页面对象:
public class SignInPage extends PageBase {
@FindBy(id = "username")
@CacheLookup
private WebElement usernameField;
@FindBy(id = "password")
@CacheLookup
private WebElement passwordField;
@FindBy(name = "submit")
@CacheLookup
private WebElement signInButton;
public SignInPage(WebDriver driver) {
super(driver);
WaitTool.waitForPageToLoad(driver, this);
// I'd like initialisation to occur here
}
public MainPage signInWithValidCredentials(String username, String password){
return signIn(username, password, MainPage.class);
}
private <T>T signIn(String username, String password, Class<T> expectedPage) {
usernameField.type(username);
passwordField.type(password);
signInButton.click();
return PageFactory.initElements(driver, expectedPage);
}
}
Here is a sample TestObject:
这是一个示例测试对象:
public class SignInTest extends TestBase {
@Test
public void SignInWithValidCredentialsTest() {
SignInPage signInPage = PageFactory.initElements(driver, SignInPage.class);
MainPage mainPage = signInPage.signInWithValidCredentials("sbrown", "sbrown");
assertThat(mainPage.getTitle(), is(equalTo(driver.getTitle())));
}
}
I tend to put my logic in the Page Object as much as possible (including waits), as it makes the test cases much more readable.
我倾向于将我的逻辑尽可能多地放在页面对象中(包括等待),因为它使测试用例更具可读性。
回答by Ardesco
The WebElements in a PageFactroy are really proxies to WebElements. This means that every time you access a WebElement it will perform a search to find the element on the page.
PageFactroy 中的 WebElements 实际上是 WebElements 的代理。这意味着每次访问 WebElement 时,它都会执行搜索以查找页面上的元素。
This has some advantages:
这有一些优点:
- When the PageFactory is initialised the proxies are configured, but the WebElements are not found at that point (so you won't get a NoSuchElementException)
- Every time you use a WebElement it will go and find it again so you shouldn't se StaleElementException's
- 当 PageFactory 初始化时,代理已配置,但此时未找到 WebElements(因此您不会得到 NoSuchElementException)
- 每次使用 WebElement 时,它都会再次查找它,因此您不应设置 StaleElementException
You are using the @CacheLookup annotation which is losing you the second benefit as it will find the element once and then keep a reference to it, you are now far more likely to see StaleElementExceptions.
您正在使用 @CacheLookup 注释,它失去了第二个好处,因为它会找到元素一次,然后保留对它的引用,现在您更有可能看到 StaleElementExceptions。
That being said you still keep the main benefit which is that Selenium will not go to the page and actually find the element until you first use it.
话虽如此,您仍然保留了主要好处,即在您第一次使用之前,Selenium 不会进入页面并实际找到元素。
So in summary all you need to do is move
所以总而言之,你需要做的就是移动
PageFactory.initElements(driver, this);
Into your constructor and it will all work fine.
进入你的构造函数,它会一切正常。