当前位置: 首页 > 面试题库 >

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

穆英飙
2023-03-14
问题内容

我一直在使用Selenium WebDriver为我曾经处理过的某些项目实施功能测试。我正在尝试将Page Object设计模式与Page
Factory一起使用来排除我的定位器。我还创建了一个静态WaitTool对象(单例),该对象通过可选的超时参数实现了几种等待技术。

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

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


问题答案:

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

这具有一些优点:

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

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

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

因此总而言之,您需要做的就是移动

PageFactory.initElements(driver, this);

到您的构造函数中,它将一切正常。



 类似资料:
  • 我正在尝试播放以下网站的视频(使用JUnit)-Day01。http://www.itelearn.com/live-training/security-testing-live-training我试图实现的是,在播放视频后,我将拍摄一张屏幕截图,以证明视频播放正确。点击Day01视频后,它会在一个新窗口中打开——当我查看代码时,我意识到他们使用了iFrame。我可以关闭此视频窗口,但无法播放/暂

  • 问题内容: 我如何在seleniumwebdriver 3.0 beta版本中使用geckodriver。当我实例化Firefox时: 我得到错误: 线程“主”中的异常java.lang.IllegalStateException:驱动程序可执行文件的路径必须由webdriver.gecko.driver系统属性设置;否则,必须执行以下操作:有关更多信息,请参见 https://github.co

  • 如果使用隐式和显式等待器,将发生以下错误:

  • 这是我到目前为止所拥有的: 一个基于Webdriver的Java类,它可以登录到应用程序并进入主页: 现在我们看到有两页:1。登录页面,其中我必须输入用户名和密码,以及主页,一旦身份验证成功,我将被带到这里。 现在我想使用Pagefactory将其实现为PageObjects: 对于登录页面,我不确定如何实现它,以及调用这些页面的测试。

  • 我在Selenium 1(又名Selenium RC)中编写了以下代码,用于使用java滚动页面: Selenium 2(WebDriver)中的等效代码是什么?

  • 我知道我们可以通过[FindsBy]属性覆盖属性并使用PageFactory初始化所有元素来清理页面对象。我们这样定义这些属性: 我们可以通过调用来初始化所有此类属性: 我想到的第一个问题是搜索过程将如何运行?重试多少次,是否应用了超时?我假设只有一次尝试,没有超时。 是否可以将PageFactory方法与自定义搜索过程相结合,例如在设置ExpectedCondition的情况下进行3次搜索尝试等