Шаблон Page Object
5-та версія WebdriverIO була розроблена з підтримкою Page Object Pattern. Впровадження принципу «елементи як першокласні об'єкти» дозволило створювати великі набори тестів, використовуючи цей патерн.
Для створення об'єктів сторінок не потрібні додаткові пакети. Виявляється, що чисті, сучасні класи надають всі необхідні функції, які нам потрібні:
- успадкування між об’єктами сторінки
- повільне завантаження елементів
- інкапсуляція методів та дій
Мета використання об'єктів сторінок - відокремити будь-яку інформацію про сторінку від самих тестів. В ідеалі, ви повинні зберігати всі селектори або специфічні інструкції, які є унікальними для певної сторінки, в об'єкті сторінки, щоб ви могли запустити свій тест після того, як повністю переробили сторінку.
Створення об'єкта сторінки
Для початку, нам потрібен об'єкт головної сторінки, який ми назвемо Page.js
. Він буде містити загальні селектори або методи, від яких успадковуватимуться всі об'єкти сторінки.
// Page.js
export default class Page {
constructor() {
this.title = 'My Page'
}
async open (path) {
await browser.url(path)
}
}
Ми завжди експортуємо(export
) екземпляр об'єкта сторінки та ніколи не створюємо його в тесті. Оскільки ми пишемо end-to-end тести, ми завжди розглядаємо сторінк у як конструкцію без стану — так само як кожен HTTP-запит є конструкцією без стану.
Звичайно, браузер може зберігати інформацію про сесію і, відповідно, відображати різні сторінки на основі різних сесій, але це не повинно відображатися в об'єкті сторінки. Такі зміни стану повинні відбуватися у ваших реальних тестах.
Почнімо тестувати першу сторінку. Для демонстрації, як піддослідного кролика, ми використаємо вебсайт The Internet від компанії Elemental Selenium. Спробуємо створити приклад об'єкта сторінки для сторінки входу в систему.
Отримаймо(Get
) ваші селектори
Перший крок - написати всі важливі селектори, які потрібні в нашому об'єкті login.page
, як getter-функції:
// login.page.js
import Page from './page'
class LoginPage extends Page {
get username () { return $('#username') }
get password () { return $('#password') }
get submitBtn () { return $('form button[type="submit"]') }
get flash () { return $('#flash') }
get headerLinks () { return $$('#header a') }
async open () {
await super.open('login')
}
async submit () {
await this.submitBtn.click()
}
}
export default new LoginPage()
Визначення селекторів у getter-функціях може виглядати трохи дивно, але це дійсно корисно. Ці функції обробляються, коли ви отримуєте доступ до властивості, а не коли ви генеруєте об'єкт. Таким чином, ви завжди запитуєте елемент перед тим, як виконати над ним якусь дію.