t.me/atinfo_chat Telegram группа по автоматизации тестирования

PageObject модель з WebDriver


(engine) #1

Привіт. Таке питання. Якщо підганяти модель під стиль PageObject, то чи можна використовувати всередині коду xpath? Чи його потрібно виключати і замінювати визначеним елементом? Наприклад всі елементи сторінки визначені як змінні через PageObject, і з ними непогано працюється. Проте існують ситуації, коли потрібно використовувати xpath і нічим його не замінити. Чи дозволяє це філософія PageObject?

Дякую за відповіді.


(Taras) #2

Це більше питання локаторів, якшо ви їх зберігаєте окремо від фреймворку, або у верньому класі, то варто притримуватись одного стилю в записах локаторів.

Тому кращим фіксом даної проблеми - це зробити обгортку для елементів які будуть доступні через xpath і управляти ними як обєктами, або ж створювати змінні типу WebElement у класах які генерують Ваші тесткейси.

А ще краще скажіть девам нехай id-шки пододають)


(Mykhailo Poliarush) #3

первый вариант, выносить переменные, где будут храниться ваши локаторы, потом эти переменные использовать

второй вариант, вынести все локторы в отдельное место, файл например и потом с этого файла читать локаторы

третий вариант, использовать PageFactory, где уже за вас подумали на счет того, где хранить локаторы, в самом объекте.

    @FindBy(how = How.NAME, using = "q")
    private WebElement searchBox;

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

тогда вы не будете тратить много времени на поддержку ваших тестов


(Taras) #4

поддерживаю на 100 %


(Shaman) #5

недавно переводил проект на page object pattern, какраз задавался подобным вопросом. Сделал следующим образом, обьект страницы реализует интерфейс страницы(Java).

а в свою очередь в интерфейсах определены локаторы в виде констант, после чего используется предложенный выше вариант с PageFactory, определяется элемент который присутствует на данной странице и через аннотацию @FindBy берет данные из интерфейса.(это применимо к статическим локаторам, к динамическим, когда локатор может менятся в зависимости от определенных данных следует использовать несколько другой подход).

после этого в конструкторе страниц я инициализирую все необходимые элементы при помощи PageFactory.initElements;

вот код одного из классов страницы:

public class SomePage  extends BasicPage implements ISomePage{
    
    @FindBy(xpath = SEARCHBUTTON_XPATH)
    private WebElement searchButton;
    
    @FindBy(xpath = TABLEHEADER_XPATH)
    private WebElement searchTableHeader;
    
    @FindBy(name = INSTRUMENTPARTNAMEFIELD_NAME)
    private WebElement instrumentPartNameField;
    
    @FindBy(xpath = ADDNEWINSTRUMENTPARTBUTTON_XPATH)
    private WebElement addNewInstrumentPartField;
    
    @FindBy(xpath = SELECTALLCHECKBOX_XPATH)
    private WebElement selectAllCheckbox;
    
    @FindBy(id = MULTIACTIONSSELECTOR_ID)
    private WebElement multiActionsSelector;
    
    
    public SearchInstrumentpartsPage(WebDriver driver) {
        super(driver);
        PageFactory.initElements(driver, this);
        validatePage();
    }

 

 

 

 


(mac2000) #6

Разделяй и властвуй, как говорится.

PageObject не удобен, возьмем к примеру форму логина - она бывает двух состояний (авторизирован пользователь или нет) и тянеться через большинство страниц сайта.

Мне кажеться так намного удобнее (псевдокод):

 

Controls.AuthForm.Login("login", "password");

Controls.Nav.GoTo(Urls.Profile);

 

 

 

 


(Taras) #7

форму логина вообще можно в @Before вынести, написать один отдельный тест ей и все. Что б не париться


(mac2000) #8

Что то я совсем не понял идеи, что значит "вынести в @Before" и каким боком тут PageObject и\или PageElement


(Taras) #9

так же как и я не понял почему Page Object к форме логина не подходит по вашым словам.))

Проблему логина одна и та же всегда, его нужно делать перед запуском всех тестом, если идет ориентировка на "залогиниться" для управления апликухой.

Или что вы имеете в виду ?


(engine) #10

Вибачте, що так довго не відповідав. Був зайняти з іншим проектом.

Звичайно я розумію, що можна їх задефайнити по аналогії з id. Проте часто буває коли потрібно перевіряти значення елементів таблиці, і там вже самі розумієте шо є купа динамічних xpath і без їх використання ніяк не обійтися.

Наскільки я зрозумів, то Ви пропонуєте дефайнити лише частину xpath, а динамічне значення вписувати вже між змінними, правильно?

Дякую.


(Shaman) #11

предлагаю использовать метод который будет в качестве параметра принимать данные которые нужно искать в ячейках таблицы, и естественно использовать в этом случае составной xpath, например:

 

driver.findElement(By.xpath("//td[@title='"+login+"']")).click();


(Taras) #12

та че вы к этой таблице привезались )+))))

та сделайте класс таблица и обертку напишите к ней, всего то дел)


(engine) #13

Так само робив до того як задати питання, от і не знав на скільки це правильно.

Дякую.


(Vol) #14

Shaman, @FindBy берет данные из интерфейса.(это применимо к статическим локаторам, к динамическим, когда локатор может менятся в зависимости от определенных данных следует использовать несколько другой подход).

С этого момента прошу поподробнее, как можно сделать обвертку элементу, если к количество чекбоксов (элементов) внутри обьекта меняется в зависимости от установленных настроек.

Один и вариантов что я разсматриваю - делать ArrayList<WebElement> (Java), а потом уже работать с тем что словил вебдрайвер внутри List-а.


(dmarapov) #15

Коллеги,

Где можно почитать подробно о PageObject и PageElement. Ничего толкового найти не могу....


(Mykhailo Poliarush) #16

кстати, на следующей неделе я буду делать вебинар на эту тему

http://automated-testing.info/trainings/besplatnyy-vebinar-chto-takoe-pageobject-v-kontekste-selenium-webdriver/announcement