Инициализация страниц в классе Application / Java

java
testng
maven
selenium
Теги: #<Tag:0x00007f7b619be180> #<Tag:0x00007f7b619be040> #<Tag:0x00007f7b619bdf00> #<Tag:0x00007f7b619bddc0>

(Soft_World) #1

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

public class Application {
    private WebDriver driver;

public Application(Webdriver driver){
this.driver=driver;  }

public LoginPageElements loginPage(){
return new LoginPageElements(driver); }
}

пример страницы -

public class LoginPageElements{
private Webdriver driver;

public LoginPageElements(WebDriver driver)
{
 this.driver = driver;
}

@FindBy(how=How.ID, using="")
private WebElement loginID;

public void Login_as(String username){
loginID.sendkeys(username) }

}

в тесте страница вызывается как

 app.loginPage().Login_as("username")

(Alexandr D.) #2

Делается дженерик класс для работы со страницами, который в первый раз создаёт объект и записывает его в переменную, а далее при обращении к странице смотрит, есть ли уже созданный объект этой страницы, и если есть - возвращает его


(Soft_World) #3

Такой класс уже существует и подход вполне себе успешно работает.

Вы имеете ввиду, что должен быть if по-типу:

public LoginPageElements loginPage(){
if(loginPage()==null;{
LoginPageElement = new LoginPageElements(driver); }
return.this;
}

(Павел) #4

Интересно, есть ли какие-то методики (может даже паттерны программирования), которые позволяют гарантировать, что у класса будет только один инстанс :thinking:


(Taras) #5

lazy init использовать - посмотри html elements yandex


(Alexandr D.) #6

Нет.
У вас совсем другое.

Пример такого варианта на шарпе может выглядеть так:

public static class Pages
{
    public static T GetPage<T>() where T : BasePage, new()
    {
        T page;
        var pageType = typeof(T);
        if (!_pagesTypesList.Contains(pageType))
        {
            page = new T();
            _pagesTypesList.Add(pageType);
            _initializedPagesList.Add(page);
            return page;
        }

        page = (T) _initializedPagesList.First(_ => _.GetType() == pageType);      
        return page;
    }
}

Ну а использовать просто:

Pages.GetPage<AuthorizationPage>().LoginToApplication();

(Максим Таран) #7

Ну для этого как раз предназначен шаблон Singlton. Он гарантирует, что будет создан именно один экземпляр класса.


(Alexandr D.) #8

Синглтон и параллельные тесты это не очень.
Так что я бы его не юзал.


(Максим Таран) #9

А где там речь про параллельность?
Да и параллельность разная бывает. Singlton же в рамках одной jvm создаётся, а не всех.


(Александр Анисимов) #10

Если у Вас в тесте данная страница открывается один раз и потом нет переходов на другие страницы или перезагрузок страницы: синглтон (или переменная в классе Application c if на существование) - вполне себе решение.
Но если в процессе теста Вы: переходите по разным страницам; перезагружаете страницу; закрываете/открываете браузер и т.д. То необходимо каждый раз пересоздавать PageObject-объект (как уже сделано у Вас в коде). Это связано с тем, что при, выше описанных, действиях ссылки на WebElement в драйвере будут уже другие и Вашь, ранее созданный, PageObject-объект будет генерить Вам кучу ошибок при любой попытке сделать с ним что-либо.