首页 > 解决方案 > 页面对象模型中的 Javascript 执行器

问题描述

对于我的自动化脚本,使用页面对象模型用 Selenium 用 Ja​​va 编写,有时我想使用 Javascript 执行器,因为默认的 WebDriver 点击有时会导致找不到元素的异常。

在初始化 Web 元素的框架页面中,代码如下所示:

public class MainPage {

    WebDriver driver;
    JavascriptExecutor executor = (JavascriptExecutor) driver;


    @FindBy(xpath = "//*[@id='main_button']/div/span")
    WebElement mainButton;

    @FindBy(xpath = "//*[@id='login_button']/div/span")
    WebElement loginButton;

    // constructor, where the elements are initialized
    public MainPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    //method, for clicking mainButton with WebDriver
    public void clickMainButton() {
        WebDriverWait wait = new WebDriverWait(driver, 40);
        wait.until(ExpectedConditions.elementToBeClickable(mainButton)).click();
    }

    //method, for clicking mainButton with JS Executor
    public void clickLoginButton() {
        WebDriverWait wait = new WebDriverWait(driver, 40);
        executor.executeScript("arguments[0].click();", loginButton);
    }

此时,在执行与页面交互的脚本时,当调用clickMainButton(); 方法,它被正确执行。但是当调用 clickLoginButton(); 方法,程序会抛出空指针异常:

java.lang.NullPointerException
at pages.MainPage.clickLoginButton(MainPage.java:55)

如果我在 clickLoginButton(); 中创建 Javascript Executor 的实例;方法,它可以正常工作。我的问题是如何使用页面对象模型正确实现 Javascript 执行器,而不必在每个方法中创建它的新实例?

标签: javascriptjavaseleniumautomation

解决方案


找到了解决问题的方法:

在类和构造函数中初始化 Javascript Executor 的正确方法是:

public class MainPage {

WebDriver driver;
private WebDriverWait wait10;
private WebDriverWait wait40;
JavascriptExecutor executor;


@FindBy(xpath = "//*[@id='main_button']/div/span")
WebElement mainButton;

@FindBy(xpath = "//*[@id='login_button']/div/span")
WebElement loginButton;

// constructor, where the elements are initialized
public MainPage(WebDriver driver) {
    this.driver = driver;
    this.executor = (JavascriptExecutor) this.driver;
    this.wait10 = new WebDriverWait(driver, 10);
    this.wait40 = new WebDriverWait(driver, 40);
    PageFactory.initElements(driver, this);
}

//method, for clicking mainButton with WebDriver
public void clickMainButton() {
    wait40.until(ExpectedConditions.elementToBeClickable(mainButton)).click();
}

//method, for clicking mainButton with JS Executor
public void clickLoginButton() {
    executor.executeScript("arguments[0].click();", loginButton);
}

这也可以应用于 WebDriverWait,具有不同的显式等待时间(可以在构造函数中看到)。


推荐阅读