【问题标题】:Using PageObjects, Page Factory and WebDriverWait in Selenium WebDriver using Java使用 Java 在 Selenium WebDriver 中使用 PageObjects、Page Factory 和 WebDriverWait
【发布时间】:2013-04-24 02:02:23
【问题描述】:

我一直在使用 Selenium WebDriver 为我参与过的一些项目实施功能测试。我正在尝试将页面对象设计模式与页面工厂一起使用来分解我的定位器。我还创建了一个静态 WaitTool 对象(单例),它使用可选的超时参数实现了几种等待技术。

我当前的问题是我想在 PageFactory 尝试初始化 WebElements 之前使用我的等待方法。我想等待的原因是因为 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>T signIn(String username, String password, Class<T> 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())));
    }
}

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

【问题讨论】:

    标签: java selenium-webdriver pageobjects


    【解决方案1】:

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

    这有一些好处:

    • 初始化 PageFactory 时,代理已配置,但此时未找到 WebElement(因此您不会收到 NoSuchElementException)
    • 每次您使用 WebElement 时,它都会再次找到它,因此您不应出现 StaleElementException

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

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

    总之,你需要做的就是移动

    PageFactory.initElements(driver, this);
    

    进入您的构造函数,一切都会正常工作。

    【讨论】:

    • 我猜这意味着我无法在登录函数中返回PageFactory.initElements(driver, expectedPage)
    • PageFactory.initElements(driver, this.class); 似乎不起作用。但是,提供 thisthis.getClass() 可以,但我不确定这是否符合我的要求。
    • 抱歉,我的回答有误。我实际上就是这个意思(更新答案以显示正确的代码 sn-p)
    • 如果我对你的理解正确,你只是担心当你实例化类时它会开始抛出 NoSuchElementExcpetion 错误,因为页面可能没有加载 PageFactory 引用的所有 WebElement。如果那是你的担心,那就不会发生。当您执行 'PageFactory.initElements(driver, this);'届时它将配置所有代理,但在您实际使用其中一个 WebElement 之前,它不会尝试在页面上查找元素。
    • @Ardesco:在我阅读了这篇文章和你的 cmets 之后,我有一个问题。这种情况下的代理是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2015-07-12
    • 2018-01-07
    • 2021-12-19
    • 2013-07-09
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多