Java и Selenium: статические методы в объектах страницы - PullRequest
3 голосов
/ 08 мая 2019

У меня проблемы с NullPointerExceptions, когда я пытаюсь использовать статические методы в объекте страницы. Если я делаю это нестатическими методами, он работает нормально.

Нестатическая версия:

public class ComplaintPage {

    private ExtendedWebDriver driver;

    @FindBy(css = "[data-selector=date-received-complaint]")
    public WebElement dateComplaintReceoved;

    public ComplaintPage() {
        driver = Browser.extendedDriver();
        PageFactory.initElements(driver, this);
    }

    public void setComplaintDate() {
        dateComplaintReceoved.sendKeys(LocalDate.now().toString());
    }
}

Calling code:

ComplaintPage complaintPage = new ComplaintPage;
complaintPage.setComplaintDate();

Это отлично работает. Поле даты установлено.

Статическая версия

public class ComplaintPage {

    private static ExtendedWebDriver driver;

    @FindBy(css = "[data-selector=date-received-complaint]")
    public static WebElement dateComplaintReceoved;

    public ComplaintPage() {
        driver = Browser.extendedDriver();
        PageFactory.initElements(driver, this);
    }

    public void static setComplaintDate() {
*       dateComplaintReceoved.sendKeys(LocalDate.now().toString());
    }
}

Calling code:

ComplaintPage.setComplaintDate();

Это не работает и приводит к исключению java.lang.NullPointerException в строке, помеченной "*" (строка, обращающаяся к WebElement).

Мне нравится использовать статические методы, подобные этим, в тесте, поскольку я не вижу в этом проблемы, и это делает код еще проще для чтения. И я делал это раньше, в C # / VS, но по какой-то причине я здесь упускаю что-то важное.

1 Ответ

5 голосов
/ 08 мая 2019

NullPointerException выбрасывается из-за того, как PageFactory работает.Видите ли, когда вы создаете экземпляр класса ComplaintPage, вы вызываете его конструктор:

public ComplaintPage() {
        driver = Browser.extendedDriver();
        PageFactory.initElements(driver, this);
    }

Конструктор вызывает initElements метод класса PageFactory.Этот метод инициализирует все поля WebElement и List<WebElement> с помощью Java Reflection API.Это в основном меняет значения по умолчанию null на реализации интерфейса.Он также обеспечивает своего рода Ленивое создание экземпляра WebElement, что означает - WebElement s найдены (искали?) Только при необходимости - когда вы вызываете операции над ними.

Когда вы создали статические методы и статические WebElements -вы не вызывали конструктор класса, что привело к НЕ вызову метода initElements.

Все элементы, отмеченные @FindBy, не были инициализированы.Вот почему не рекомендуется использовать PageFactory со статическими методами.

Вместо использования PageFactory вы можете просто найти элемент с классическим driver.findElement внутри статического метода.

    public void static setComplaintDate(WebDriver driver) {
        driver.findElement(By.cssSelector("[data-selector=date-received-complaint]")).sendKeys(LocalDate.now().toString());
    }
...