Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

[Resolved] Не могу разобраться с ошибкой NullPointerException. После написания кода с помощью паттерна PageObject


(Рома Маринский) #1

Проблема состоит в том что, не понимаю что нужно проинициализировать
Головной класс:

public class AbstractPage {
    WebDriver driver;

    AbstractPage(){
        driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    }

    protected void openMainPage(String mainPageUrl) {
        driver.get(mainPageUrl);
    }
    protected void clickButton (String linkText) {
        driver.findElement(By.linkText(linkText)).click();
    }
    protected void clickCssButton (String cssId) {
        driver.findElement(By.cssSelector(cssId)).click();
    }
    protected void selectRadioButton(String RButton){ driver.findElement((By.id(RButton))); }
    protected void fillField (String fillField, String valueField) { driver.findElement((By.id(fillField))).sendKeys(valueField); }
}

Исполняющие классы:

public class LoginPage extends AbstractPage {

    public void authorizationUser () throws Exception {
        fillField("email", "asd@asd.asd");
        fillField("password", "111111");
        clickCssButton("input.btn.btn-primary");
    } }

public class NewCampaignPage extends AbstractPage {
    private Integer valueOfScenario = 1;   

    public void createNewCampaign() throws Exception {    
            while (valueOfScenario < 5) {
                switch (valueOfScenario) {
                    case 1:
                        //actions
                    case 2:
                        //actions
                        break;
                    case 3:
                         //actions
                    case 4:
                         //actions
                        break;
                }}}}

Класс контроллер:

public class CreateCampaigns extends AbstractPage{

    protected NewCampaignPage create;
    protected LoginPage auth;

    @Test
    public void startCreation() throws Exception {
        openMainPage("http://site.com.ua/");
        clickButton("login");
        auth.authorizationUser(); > **java.lang.NullPointerException at myPageObject.CreateCampaigns.startCreation**
        create.createNewCampaign(); >  **java.lang.NullPointerException at myPageObject.CreateCampaigns.startCreation**
    }}

Что и где нужно проинициализировать? :frowning:


(Sergey Korol) #2

Очевидно же, что вы пытаетесь обратиться к методу класса через неинициализированный объект auth / create, игнорируя Java Basics -> MyClass ob = new MyClass();

Второй момент: не знаю, что вы там начитались, но ваша абстрактная пейджа получилась уж совсем не абстрактной. Пример:

protected void clickButton (String linkText) {
        driver.findElement(By.linkText(linkText)).click();
    }

Исходя из вашей логики, все кнопки по дефолту должны быть найдены по linkText. А что если в любой другой кнопке ее (линки) не будет?

Почему именно clickButton? Абстрактному клику должно быть глубоко без разницы, по чему кликать. Кнопка, чекбокс, радио-баттон и т.д.

С таким подходом ваш AbstractPage со временем превратится в абсолютно неподдерживаемого монстра. Это даже больше походит не на ООП, а на функциональное программирование, где в 1 файле у вас будет миллион методов на одно и то же действие.


(Антон) #3

И тут на помощь приходят helper-ы :smile:


(Рома Маринский) #4

Извиняюсь за такую грубую оплошность свою.
Я сделал ссылки на объекты, но проблема не исчезла.

По поводу второго момента, мне для тестов сайта больше никаких действий не потребуется. Только клики на радио баттоны, клики на кнопки 2-ух типов ну и прочие.

Сделал я вот что:

 public class CreateCampaigns extends AbstractPage{
        NewCampaignPage create = new NewCampaignPage(); // ссылка на соответствующий класс
    
//вынес из абстракткпэйдж создание профиля (пусть здесь пока будет, потому что при обращении в абстрактпэйдж, создавались новые профили, т.е окна новые открывались)
        public CreateCampaigns() {
            driver = new FirefoxDriver();
            driver.get("http://site.ua/");
            driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        }
    
//удалил класс "Логинпэйдж" за ненадобностью
        @Test
        public void startCreation() throws Exception {
            clickButton("login");
            fillField("email", "asd@asd.asd");
            fillField("password", "111111");
            clickCssButton("input.btn.btn-primary"); 
            create.createNewCampaign(); // при вызове этого метода вылазит ошибка 
        }
    }

Вылазит ошибка к этим строкам:

    public class AbstractPage {
protected void selectRadioButton(String RButton){ driver.findElement((By.id(RButton))); } 
...
}

И в самом методе

public class NewCampaignPage extends AbstractPage {
   selectRadioButton("daily-lim"); // к этой строке
}

Это мой первый код на java, после web. Пусть меня это и не оправдывает, но я очень хочу научиться писать чистый и стандартизированный код. Помогите пожалуйста разобраться :frowning:


(Рома Маринский) #5

А если все действия вынести в класс “CreateCampaigns” то действия выполняются нормально


(Sergey Korol) #6

Начните с осознания базовых концепций, ответив себе на вопрос, какое назначение у AbstractPage, а также PageObjects (как частный случай). От того, что вы будете бездумно перемещать методы туда-сюда из класса в класс, пока не заработает, - ваш код не станет лучше.

Специально для концептуальных вопросов создан раздел - база знаний. И уверяю, тема PageObject’ов уже не раз обсасывалась вдоль и поперек. :wink:


(Рома Маринский) #7

В AbstractPage определены методы для их использования в других классах, чтобы сделать код более читабельным, без дублирования кода, и лёгким для понимания любому человеку.

Спасибо, почитаю)


(Incredible Eldrich) #8

Рекомендую к просмотру http://www.youtube.com/watch?v=RlppaRSqvhs и вторая часть http://www.youtube.com/watch?v=MwVSvUIqOE0


(Рома Маринский) #9

Спасибо, я тогда ещё разобрался в чём моя ошибка, всё заработало. Нужно было просто сделать методы и инициализацию вебдрайвера статическими.
Извиняюсь за свою неосведомлённость)


(Рома Маринский) #10

Спасибо, но я уже их посмотрел, тогда и разобрался со всем