使用Java在Selenium WebDriver中使用PageObjects,Page Factory和WebDriverWait

我一直在使用Selenium WebDriver为我曾经使用过的一些项目实现function测试。 我正在尝试使用Page Factory设计模式与Page Factory来分解我的定位器。 我还创建了一个静态WaitTool对象(singleton),它使用可选的超时参数实现了几种等待技术。

我目前的问题是我想在PageFactory尝试初始化WebElements之前使用我的wait方法。 我想等待的原因是因为PageFactory可能会尝试在页面元素可用之前初始化页面元素。

这是一个示例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 signIn(String username, String password, Class expectedPage) { usernameField.type(username); passwordField.type(password); signInButton.click(); return PageFactory.initElements(driver, expectedPage); } } 

这是一个示例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()))); } } 

我倾向于尽可能地将我的逻辑放在页面对象中(包括等待),因为它使测试用例更具可读性。

PageFactroy中的WebElements实际上是WebElements的代理。 这意味着每次访问WebElement时,它都会执行搜索以在页面上查找元素。

这有一些优点:

  • 初始化PageFactory时,会配置代理,但此时找不到WebElements(因此您不会获得NoSuchElementException)
  • 每次使用WebElement时,它都会再次找到它,因此您不应该使用StaleElementException

您正在使用@CacheLookup注释,它会失去第二个好处,因为它会找到该元素一次,然后保持对它的引用,您现在更有可能看到StaleElementExceptions。

话虽如此,你仍然保留了主要的好处,即Selenium不会进入页面并实际找到元素,直到你第一次使用它。

总而言之,您需要做的就是搬家

 PageFactory.initElements(driver, this); 

进入你的构造函数,它将一切正常。