Про практикум

На цьому інтенсивно познайомимося з Playwright – сучасним інструментом для автоматизації тестування веб-додатків. Ми розберемо основи його роботи, переваги перед іншими фреймворками та навчимося писати стабільні та ефективні тести.

Практикум розрахований на тестувальників-початківців і розробників, які хочуть освоїти Playwright для повсякденної роботи.

Що таке Playwright?

Playwright - це сучасний інструмент для автоматизації тестування, створений з акцентом на стабільність та мультибраузерну підтримку. Основні переваги:

  • Робота з Chromium, Firefox та WebKit «з коробки».
  • Підтримка емуляції мобільних пристроїв та роботи з кількома браузерами одночасно.
  • Потужний API для стабільних випробувань.

Що таке TypeScript?

TypeScript — це надмножина JavaScript, яка додає статичну типізацію та інші корисні функції до JavaScript, що робить код більш передбачуваним, безпечним і зручним для масштабування. Playwright — це потужний інструмент для автоматизації тестів веб-додатків, і він має відмінну підтримку для TypeScript.

Коли використовуємо Playwright з TypeScript,  отримуємо кілька переваг:

Статична типізація: TypeScript дозволяє визначати типи змінних і функцій, що знижує ймовірність помилок при компіляції. Це допомагає запобігти помилкам, таким як неправильне використання методів чи властивостей об’єктів.

Наприклад, у вас є об’єкт сторінки loginPage, і TypeScript підкаже, що методи цього об’єкта мають правильні типи:

const title = await loginPage.getTitle(); // TypeScript знає, що getTitle() повертає string

Інтелектуальні підказки та автодоповнення:
При використанні TypeScript у середовищах розробки (IDE), таких як Visual Studio Code, ви отримуєте зручні автодоповнення для методів Playwright, а також підказки для параметрів та типів, що спрощує написання коду та робить його більш надійним.

Краще рефакторинг і підтримка коду:
Оскільки TypeScript є статично типізованим, він дозволяє легше проводити рефакторинг коду, автоматично виявляючи можливі проблеми при зміні коду або структури додатка.

Перевірка типів під час компіляції: В TypeScript компілятор перевіряє відповідність типів на етапі компіляції, що допомагає виявити помилки на ранніх етапах і уникнути багів під час виконання тестів.

Плюси Playwright

  • Підтримка кількох браузерів:
    Chromium, Firefox, WebKit - ідеально підходить для кроссбраузерного тестування.

  • Швидкість та стабільність:
    Працює безпосередньо з браузерами, без потреби у додаткових драйверах.

  • Асинхронна архітектура:
    Швидке виконання тестів завдяки паралельній роботі контекстів.

  • Зручні інструменти налагодження:
    Playwright Inspector та Trace Viewer дозволяють аналізувати та усувати помилки в тестах.

  • Гнучкість роботи з API:
    Можливість перехоплення запитів та створення мок даних для різних сценаріїв.

  • Підтримка мобільних емуляцій:
    Ефективне тестування веб-додатків для смартфонів та планшетів.

  • Ізоляція контекстів:
    Кожен тест виконується в окремій сесії браузера, що знижує ризики впливу тесту на інший.

  • Хороша документація:
    Докладні приклади та регулярні оновлення роблять інструмент доступним для вивчення.

Мінуси Playwright

  • Відносна новизна:
    Спільнота менша порівняно з Selenium або Cypress, що може ускладнити пошук рішень.

  • Поріг входу:
    Асинхронна природа (робота з async/await) може бути складною для початківців.

  • Розмір залежностей:
    Проекти з Playwright важчі через інтегровані браузери.

Встановлення та настроювання оточення для Playwright

  1. Встановіть Node.js
    Завантажте Node.js з официального сайта та виконайте інсталяцію.

  2. Встановіть Visual Studio Code
    Завантажте та встановіть Visual Studio Code - зручний редактор для написання тестів.

  3. Перевірте версію Node.js
    Після встановлення відкрийте термінал у Visual Studio Code та виконайте команду:

    node -v

    Це дозволить переконатися, що Node.js встановлено коректно.

  4. Створіть нову папку для проекту
    Наприклад:

    saucedemo-test
  5. Встановіть Playwright
    Всередині створеної папки виконайте команду:

    npm init playwright@latest

    Під час встановлення виберіть:

    • Тип проекту: TypeScript.
    • Необхідні браузери: Chromium, Firefox, WebKit.
    • Додаткові інструменти: GitHub Actions або інші CI/CD сервіси (за потребою).
  6. Результат встановлення
    Після виконання команди буде автоматично:

    • Створено структуру проекту з прикладами тестів.
    • Згенеровано файл playwright.config.ts.
    • Завантажено необхідні браузери для тестування.

Тепер ви готові писати та запускати тести з використанням Playwright!🎉

Перед створенням структури проєкту необхідно визначити, що саме потрібно тестувати. Для цього слід поставити завдання.

Ось основні завдання:

  • Авторизація.
  • Негативні перевірки авторизації.
  • Додавання товару до кошика.

Для самостійної роботи:

  • Ще більше негативних перевірок авторизації.
  • Оформлення замовлення

Для успішної автоматизації тестування ми розділяємо проєкт на логічні частини, щоб зробити код більш організованим, читабельним і зручним для підтримки. Це також допомагає застосовувати найкращі практики, такі як Page Object Model (POM), і забезпечує зручність командної роботи.

https://www.saucedemo.com

saucedemo-tests/
├── tests/ # Тестові файли
│ ├── login.spec.ts # Тест авторизації
│ ├── inventory.spec.ts # Тест інвентарю
│ ├── product.spec.ts # Тест товару
│ ├── cart.spec.ts # Тест корзини
│ └── checkout.spec.ts # Тест оформлення замовлення
├── pages/ # Page Object Model
│ ├── login.page.ts # Логін
│ ├── inventory.page.ts # Список товарів
│ ├── product.page.ts # Сторінка товару
│ ├── cart.page.ts # Корзина
│ └── checkout.page.ts # Оформлення замовлення
└── playwright.config.ts # Конфігурація Playwright


Каталог tests/ – Тестові файли

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

  • login.spec.ts — тестує процес авторизації користувача, перевіряючи правильність вводу логіну та пароля, а також коректність відображення повідомлень про помилки при неправильному введенні даних.
  • inventory.spec.ts — тестує відображення інвентаря, тобто список доступних товарів на сторінці, їх правильність, доступність, зображення та інші характеристики.
  • product.spec.ts — тестує функціональність, пов’язану з товарами, наприклад, відкриття сторінки товару, перегляд деталей, вибір кількості, додавання товару в корзину.
  • cart.spec.ts — тестує корзину покупок, перевіряючи додавання товарів, їх коректне відображення, можливість змінювати кількість або видаляти товари з кошика.
  • checkout.spec.ts — тестує процес оформлення замовлення, перевіряючи правильність введених даних, перевірку платіжних методів, оформлення замовлення та відправку підтвердження.

2. Каталог pages/ – Page Object Model (POM)

Цей каталог містить файли, що реалізують Page Object Model (POM), підхід до автоматизації тестування, де кожна сторінка або компонент веб-застосунку має свій відповідний об’єкт для взаємодії з елементами сторінки.

  • login.page.ts — клас, що містить методи для взаємодії з елементами сторінки авторизації, наприклад, введення логіну та пароля, натискання кнопки входу.
  • inventory.page.ts — клас для роботи зі сторінкою інвентаря, де зберігаються методи для взаємодії з товарами, фільтрами та іншими елементами на сторінці списку товарів.
  • product.page.ts — клас для взаємодії зі сторінкою конкретного товару, де можна отримати дані товару, додавати його в кошик та виконувати інші операції.
  • cart.page.ts — клас для взаємодії з кошиком, включаючи методи для перевірки товарів у кошику, зміни їх кількості, видалення товарів та інше.
  • checkout.page.ts — клас для роботи з процесом оформлення замовлення, включаючи введення даних доставки, вибір платіжного методу, завершення оформлення покупки.

3. Файл playwright.config.ts – Конфігурація Playwright

Цей файл містить конфігурацію для Playwright, інструменту для автоматизації тестування веб-застосунків. Тут можуть бути вказані параметри, як-от:

  • Налаштування браузера — вибір браузерів (наприклад, Chromium, Firefox, WebKit) для запуску тестів.
  • Мережеві налаштування — конфігурація для симуляції різних умов мережі, наприклад, повільного інтернет-з’єднання.
  • Інші параметри тестування — час очікування між діями, настройка тестового середовища, запуск паралельних тестів тощо.

Цей файл є основним для налаштування середовища для виконання тестів у Playwright.


Переваги такої структури

  1. Розділення логіки:

    • Тести зосереджені лише на сценаріях.
    • Уся логіка роботи з елементами зберігається в pages/.
  2. Зручність підтримки:

    • Якщо зміниться інтерфейс сторінки, достатньо оновити відповідний файл у pages/.
  3. Читабельність:

    • Тести читаються як кроки користувача, що спрощує їх розуміння навіть для новачків.
  4. Масштабованість:

    • Додавати нові тести або сторінки легко завдяки чіткій структурі.

Пояснення

  • Чому ми виділяємо сторінки в окремі файли?
    Уявіть, що на сайті змінилася кнопка «Login» на «Sign In». Замість того, щоб оновлювати всі тести, достатньо змінити лише один метод у login.page.ts.

  • Чому різні файли для тестів?
    Тести поділені за функціональністю, щоб у разі помилки легко зрозуміти, де проблема: авторизація, кошик чи замовлення.

  • Навіщо потрібен playwright.config.ts?
    Цей файл задає базові налаштування, щоб уникнути їх дублювання в кожному тесті. Наприклад, для тестування сайту у кількох браузерах це вказується лише один раз у конфігурації.

playwright.config.ts — це основний файл конфігурації для Playwright. Він дозволяє централізовано задавати налаштування для запуску тестів, такі як браузери, базовий URL, час очікування та багато іншого. Цей файл допомагає скоротити дублювання коду та спрощує управління тестами.

export default defineConfig({
testDir: ‘./tests’,
retries: 1,
use: {
headless: true,
viewport: { width: 1280, height: 720 },
actionTimeout: 5000,
baseURL: ‘https://www.saucedemo.com’,
screenshot: ‘only-on-failure’,
video: ‘retain-on-failure’,
},
projects: [
{
name: ‘desktop’,
use: { …devices[‘Desktop Chrome’] },
},
{
name: ‘mobile’,
use: { …devices[‘Pixel 5’] },
},
],
});

Основні розділи playwright.config.ts

  1. Імпорти

На початку файлу підключається необхідна бібліотека Playwright:

import { defineConfig } from '@playwright/test';

defineConfig спрощує створення конфігурації з автодоповненням.

Основні параметри конфігурації:

  • testDir: './tests' — вказує каталог, в якому будуть розміщуватися тести. У цьому випадку це папка ./tests, де зберігаються всі ваші тести.

  • retries: 1 — налаштовує кількість повторів для кожного тесту в разі невдачі. У цьому випадку, якщо тест не пройде, він буде повторений один раз (всього два спроби).

  • use — налаштування, що стосуються середовища виконання тестів.

    • headless: true — тестування буде виконуватися в безголовому режимі, тобто без відкриття вікна браузера.
    • viewport: { width: 1280, height: 720 } — вказує розмір екрану, на якому тестуватиметься додаток (в даному випадку це 1280×720 пікселів).
    • actionTimeout: 5000 — максимальний час очікування для кожної дії (наприклад, кліки, введення тексту тощо). Якщо дія не завершиться протягом 5 секунд, тест буде визнаний невдалим.
    • baseURL: 'https://www.saucedemo.com' — базова URL-адреса, яка буде використовуватись для тестів. Це дозволяє зручніше писати тести, оскільки URL може не повторюватися в кожному тесті.
    • screenshot: 'only-on-failure' — робити знімок екрану тільки в разі невдачі тесту.
    • video: 'retain-on-failure' — записувати відео тільки в разі невдачі тесту, що допомагає аналізувати, що пішло не так.

Налаштування для різних пристроїв (проектів):

projects: [
{
name: ‘desktop’,
use: { …devices[‘Desktop Chrome’] },
},
{
name: ‘mobile’,
use: { …devices[‘Pixel 5’] },
},
],

Цей блок налаштовує проекти для тестування на різних пристроях:

  • Проект desktop — тестуватиме сайт на десктопній версії браузера Chrome. Для цього використовується конфігурація, передбачена для Desktop Chrome в об’єкті devices.

  • Проект mobile — тестуватиме сайт на мобільному телефоні Pixel 5. Для цього використовується конфігурація, передбачена для Pixel 5 в об’єкті devices.

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

login.page.ts

import { Page } from ‘@playwright/test’;

export class LoginPage {
private page: Page;
private usernameInput = ‘#user-name’;
private passwordInput = ‘#password’;
private loginButton = ‘#login-button’;
private errorMessage = ‘.error-message-container’;

constructor(page: Page) {
this.page = page;
}

async goto() {
await this.page.goto(‘/’);
}

async login(username: string, password: string) {
await this.page.fill(this.usernameInput, username);
await this.page.fill(this.passwordInput, password);
await this.page.click(this.loginButton);
}

async getErrorMessage() {
return await this.page.innerText(this.errorMessage);
}
}

Опис класу LoginPage

Клас LoginPage інкапсулює елементи і взаємодії на сторінці логіну для подальшого використання у тестах. Він надає методи для навігації на сторінку, введення даних користувача, натискання кнопки логіну та отримання повідомлень про помилки.

Імпорти:

import { Page } from ‘@playwright/test’;

Імпортується Page з Playwright для роботи зі сторінкою, на якій будуть виконуватись дії.

Оголошення класу:

export class LoginPage {
private page: Page;
private usernameInput = ‘#user-name’;
private passwordInput = ‘#password’;
private loginButton = ‘#login-button’;
private errorMessage = ‘.error-message-container’;

  • page — об’єкт сторінки, через який здійснюються всі взаємодії.
  • usernameInput, passwordInput, loginButton, errorMessage — селектори елементів на сторінці (поле для введення імені користувача, поле для пароля, кнопка для входу та контейнер для повідомлення про помилку).

Конструктор:

constructor(page: Page) {
this.page = page;
}

Конструктор приймає об’єкт page і ініціалізує його для подальшого використання у методах класу.

Методи класу:

  1. Метод goto:

async goto() {
await this.page.goto(‘/’);
}

Цей метод використовує Playwright для переходу на домашню сторінку (за умовчанням / — корінь сайту).

Метод login:

async login(username: string, password: string) {
await this.page.fill(this.usernameInput, username);
await this.page.fill(this.passwordInput, password);
await this.page.click(this.loginButton);
}

Метод заповнює поля для імені користувача і пароля, а потім натискає кнопку логіну для авторизації.

Метод getErrorMessage:

async getErrorMessage() {
return await this.page.innerText(this.errorMessage);
}

Цей метод повертає текст повідомлення про помилку, якщо авторизація не вдалася.

Пояснення основних дій:

  • this.page.fill(selector, value) — метод Playwright, який заповнює текстове поле на сторінці значенням.
  • this.page.click(selector) — метод, який натискає на елемент сторінки, наприклад, кнопку.
  • this.page.innerText(selector) — отримує текст, що міститься в елементі, що відповідає заданому селектору.

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

inventory.page.ts

import { Page } from ‘@playwright/test’;

 

export class InventoryPage {
  private page: Page;
  private productTitles = ‘.inventory_item_name’;
  private productPrice = ‘.inventory_item_price’;
  private addToCartButton = ‘.btn_inventory’;
  private backpackTitle = ‘Sauce Labs Backpack’;  // Название товара

 

  constructor(page: Page) {
    this.page = page;
  }

 

  async getProductTitles() {
    return await this.page.$$eval(this.productTitles, titles => titles.map(title => title.textContent?.trim()));
  }

 

  async getProductPrices() {
    return await this.page.$$eval(this.productPrice, prices => prices.map(price => price.textContent?.trim()));
  }

 

  async addBackpackToCart() {
    const backpackIndex = await this.page.$$eval(this.productTitles, (titles, backpackTitle) =>
      titles.findIndex(title => title.textContent?.trim() === backpackTitle), this.backpackTitle);

 

    if (backpackIndex !== -1) {
      const addToCartButtons = await this.page.$$(this.addToCartButton);
      await addToCartButtons[backpackIndex].click();
    } else {
      throw new Error(‘Sauce Labs Backpack not found on the page’);
    }
  }
}

Опис класу InventoryPage

Клас InventoryPage інкапсулює елементи і взаємодії на сторінці інвентарю. Він надає методи для отримання назв та цін товарів, а також для додавання певного товару (наприклад, «Sauce Labs Backpack») у кошик.

Оголошення класу:

export class InventoryPage {
private page: Page;
private productTitles = ‘.inventory_item_name’;
private productPrice = ‘.inventory_item_price’;
private addToCartButton = ‘.btn_inventory’;
private backpackTitle = ‘Sauce Labs Backpack’; 

  • page — об’єкт сторінки для взаємодії з веб-сторінкою.
  • productTitles — CSS-селектор для елементів, що містять назви товарів на сторінці.
  • productPrice — CSS-селектор для елементів, що містять ціни товарів.
  • addToCartButton — CSS-селектор для кнопок додавання товарів у кошик.
  • backpackTitle — конкретна назва товару, який ми хочемо додати в кошик (в даному випадку, «Sauce Labs Backpack»).

Методи класу:

Метод getProductTitles:

async getProductTitles() {
return await this.page.$$eval(this.productTitles, titles => titles.map(title => title.textContent?.trim()));
}

Метод використовує метод $$eval для отримання всіх елементів, що відповідають селектору productTitles (тобто назв товарів), і повертає їх текстове значення у вигляді масиву.

Метод getProductPrices:

async getProductPrices() {
return await this.page.$$eval(this.productPrice, prices => prices.map(price => price.textContent?.trim()));
}

Аналогічно до попереднього методу, цей метод отримує ціни товарів з елементів, що відповідають селектору productPrice, і повертає їх як масив.

Метод addBackpackToCart:

async addBackpackToCart() {
const backpackIndex = await this.page.$$eval(this.productTitles, (titles, backpackTitle) =>
titles.findIndex(title => title.textContent?.trim() === backpackTitle), this.backpackTitle);

if (backpackIndex !== -1) {
const addToCartButtons = await this.page.$$(this.addToCartButton);
await addToCartButtons[backpackIndex].click(); 
} else {
throw new Error(‘Sauce Labs Backpack not found on the page’);
}
}

  • Цей метод шукає товар «Sauce Labs Backpack» на сторінці, використовуючи $$eval для пошуку індексу цього товару серед усіх назв товарів.
  • Якщо товар знайдений (тобто індекс не дорівнює -1), метод натискає кнопку «Add to cart» для цього товару, використовуючи знайдений індекс товару в масиві кнопок додавання.
  • Якщо товар не знайдений, викидається помилка з повідомленням про відсутність товару на сторінці.

Пояснення основних методів Playwright:

  • $$eval(selector, callback) — цей метод дозволяє отримати всі елементи, що відповідають селектору, і застосувати до них функцію зворотного виклику (callback), яка повертає значення.
  • this.page.$$(selector) — знаходить всі елементи, що відповідають даному селектору, і повертає їх як масив елементів.
  • element.click() — викликає клік на елементі.

cart.page.ts

import { Page } from ‘@playwright/test’;

export class CartPage {
  private page: Page;
  private cartItemsSelector = ‘.cart_item’;

  constructor(page: Page) {
    this.page = page;
  }

  async getCartItems() {
    return await this.page.$$eval(this.cartItemsSelector, items => items.map(item => item.textContent?.trim()));
  }

  async goto() {
    await this.page.goto(‘/cart.html’);
  }
}

Опис класу CartPage

Клас CartPage відповідає за взаємодію з елементами на сторінці кошика, такими як отримання списку товарів у кошику та навігація на сторінку кошика.

Оголошення класу:

export class CartPage {
private page: Page;
private cartItemsSelector = ‘.cart_item’;

  • page — об’єкт сторінки, на якій будуть виконуватися дії.
  • cartItemsSelector — CSS-селектор для елементів, що містять товари в кошику (в даному випадку клас .cart_item).

Методи класу:

Метод getCartItems:

async getCartItems() {
return await this.page.$$eval(this.cartItemsSelector, items => items.map(item => item.textContent?.trim()));
}

  • Цей метод використовує метод $$eval, щоб отримати всі елементи, які відповідають селектору cartItemsSelector (тобто всі товари в кошику).
  • Він застосовує функцію до кожного елементу, яка отримує текстовий вміст елемента та видаляє зайві пробіли, повертаючи масив назв товарів у кошику.

Метод goto:

async goto() {
await this.page.goto(‘/cart.html’);
}

Метод використовує this.page.goto() для переходу на сторінку кошика (/cart.html), щоб автоматизовано відкривати цю сторінку в тестах.

Пояснення основних методів Playwright:

  • $$eval(selector, callback) — цей метод шукає всі елементи на сторінці, що відповідають заданому селектору, і викликає на них функцію зворотного виклику, яка повертає необхідні дані (в даному випадку, текстові значення).
  • this.page.goto(url) — перехід на іншу сторінку сайту, в даному випадку на сторінку кошика.

checkout.page.ts

Клас CheckoutPage відповідає за взаємодію з елементами на сторінці оформлення замовлення, такими як заповнення форми з особистими даними та завершення процесу оформлення замовлення.

Оголошення класу:

export class CheckoutPage {
private page: Page;
private firstNameInput = ‘#first-name’;
private lastNameInput = ‘#last-name’;
private postalCodeInput = ‘#postal-code’;
private continueButton = ‘#continue’;
private finishButton = ‘#finish’;

  • page — об’єкт сторінки, з якою здійснюються взаємодії.
  • firstNameInput — CSS-селектор для поля введення імені.
  • lastNameInput — CSS-селектор для поля введення прізвища.
  • postalCodeInput — CSS-селектор для поля введення поштового індексу.
  • continueButton — CSS-селектор для кнопки продовження після введення особистих даних.
  • finishButton — CSS-селектор для кнопки завершення оформлення замовлення.
 

Цей код описує сторінку оформлення замовлення для автоматизованого тестування за допомогою Playwright у файлі checkout.page.ts. Ось його розшифровка та коментарі:

Опис класу CheckoutPage

Клас CheckoutPage відповідає за взаємодію з елементами на сторінці оформлення замовлення, такими як заповнення форми з особистими даними та завершення процесу оформлення замовлення.

 

Оголошення класу:

export class CheckoutPage { private page: Page; private firstNameInput = '#first-name'; private lastNameInput = '#last-name'; private postalCodeInput = '#postal-code'; private continueButton = '#continue'; private finishButton = '#finish';
  • page — об’єкт сторінки, з якою здійснюються взаємодії.
  • firstNameInput — CSS-селектор для поля введення імені.
  • lastNameInput — CSS-селектор для поля введення прізвища.
  • postalCodeInput — CSS-селектор для поля введення поштового індексу.
  • continueButton — CSS-селектор для кнопки продовження після введення особистих даних.
  • finishButton — CSS-селектор для кнопки завершення оформлення замовлення.

Методи класу:

Метод goto:

async goto() {
await this.page.goto(‘/checkout-step-one.html’);
}

Цей метод використовує this.page.goto() для переходу на сторінку оформлення замовлення (/checkout-step-one.html). Це необхідно для навігації до цієї сторінки під час тестів.

Метод fillCheckoutForm:

async fillCheckoutForm(firstName: string, lastName: string, postalCode: string) {
await this.page.fill(this.firstNameInput, firstName);
await this.page.fill(this.lastNameInput, lastName);
await this.page.fill(this.postalCodeInput, postalCode);
await this.page.click(this.continueButton);
}

  • Цей метод заповнює форму оформлення замовлення. Він використовує метод this.page.fill() для введення значень в поля «ім’я», «прізвище» та «поштовий індекс».
  • Після заповнення форми, метод натискає кнопку «Continue» (this.page.click(this.continueButton)), щоб продовжити процес оформлення замовлення.

Метод completeCheckout:

async completeCheckout() {
  await this.page.click(this.finishButton);
}

Цей метод натискає кнопку «Finish» (this.page.click(this.finishButton)), щоб завершити процес оформлення замовлення після заповнення форми.

Пояснення основних методів Playwright:

  • this.page.goto(url) — перехід на вказану URL-адресу, в даному випадку на сторінку оформлення замовлення.
  • this.page.fill(selector, value) — заповнює поле введення (вказане селектором) значенням.
  • this.page.click(selector) — натискає на елемент (кнопку), що відповідає вказаному селектору.

product.page.ts

import { Page } from ‘@playwright/test’;

export class ProductPage {
  private page: Page;
  private addToCartButton = ‘.btn_inventory’;
  private cartBadge = ‘.shopping_cart_badge’;

  constructor(page: Page) {
    this.page = page;
  }

  async addToCart() {
    await this.page.click(this.addToCartButton);
  }

  async getCartBadge() {
    return await this.page.textContent(this.cartBadge);
  }
}
Клас ProductPage відповідає за взаємодію з елементами на сторінці продукту, зокрема, для додавання товару в кошик та перевірки кількості товарів у кошику.
 
Оголошення класу:
export class ProductPage {
private page: Page;
private addToCartButton = ‘.btn_inventory’;
private cartBadge = ‘.shopping_cart_badge’;
  • page — об’єкт сторінки, з якою здійснюються взаємодії.
  • addToCartButton — CSS-селектор для кнопки «Додати в кошик».
  • cartBadge — CSS-селектор для значка кошика, який показує кількість товарів в кошику.

Методи класу:

Метод addToCart:

async addToCart() {
await this.page.click(this.addToCartButton);
}

Цей метод натискає на кнопку «Додати в кошик» (addToCartButton) на сторінці продукту, що дозволяє додати товар до кошика.

Метод getCartBadge:

async getCartBadge() {
return await this.page.textContent(this.cartBadge);
}

Цей метод отримує текстовий вміст елемента, що відповідає значку кошика (cartBadge). Зазвичай цей елемент містить кількість товарів у кошику. Метод повертає текст, який може бути використаний для перевірки, скільки товарів знаходиться в кошику після додавання нового товару.

Пояснення основних методів Playwright:

  • this.page.click(selector) — натискає на елемент, що відповідає вказаному CSS-селектору. У даному випадку — це кнопка додавання товару в кошик.
  • this.page.textContent(selector) — отримує текстовий вміст елемента, що відповідає вказаному селектору. У цьому випадку це кількість товарів у кошику.
login.spec.ts
 
import { test, expect } from ‘@playwright/test’;
import { LoginPage } from ‘../pages/login.page’;
import { InventoryPage } from ‘../pages/inventory.page’;

test.describe(‘Login Tests’, () => {
  let loginPage: LoginPage;
  let inventoryPage: InventoryPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    inventoryPage = new InventoryPage(page);
  });

  test(‘Valid login’, async () => {
    await loginPage.goto();
    await loginPage.login(‘standard_user’, ‘secret_sauce’);
    const titles = await inventoryPage.getProductTitles();
    expect(titles.length).toBeGreaterThan(0);
  });

  test(‘Invalid login’, async () => {
    await loginPage.goto();
    await loginPage.login(‘invalid_user’, ‘invalid_pass’);
    const errorMessage = await loginPage.getErrorMessage();
    expect(errorMessage).toContain(‘Epic sadface: Username and password do not match’);
  });
});
Цей код є тестовим сценарієм для перевірки процесу входу на сайт за допомогою Playwright. Він тестує два випадки: успішний вхід та неуспішний (з невірними даними)
import { test, expect } from ‘@playwright/test’;
import { LoginPage } from ‘../pages/login.page’;
import { InventoryPage } from ‘../pages/inventory.page’;
  • test, expect — імпортуються з бібліотеки Playwright для створення тестів та асерцій.
  • LoginPage та InventoryPage — імпортуються класи, що представляють відповідно сторінку входу та сторінку інвентарю. Вони використовуються для взаємодії з елементами цих сторінок.

Опис групи тестів:

test.describe(‘Login Tests’, () => {
let loginPage: LoginPage;
let inventoryPage: InventoryPage;

  • test.describe — групує тести за певною темою, у цьому випадку тестування входу на сайт.
  • loginPage та inventoryPage — змінні для зберігання екземплярів класів сторінок.

beforeEach хук:

test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
inventoryPage = new InventoryPage(page);
});

beforeEach — виконується перед кожним тестом. Створюється новий екземпляр класів LoginPage і InventoryPage для кожного тесту, забезпечуючи, що тест починається з чистої сторінки.

Тест 1: Успішний вхід

test(‘Valid login’, async () => {
await loginPage.goto();
await loginPage.login(‘standard_user’, ‘secret_sauce’);
const titles = await inventoryPage.getProductTitles();
expect(titles.length).toBeGreaterThan(0);
});

  • loginPage.goto() — переходимо на сторінку логіна.
  • loginPage.login('standard_user', 'secret_sauce') — виконується вхід з правильними даними (користувач: standard_user, пароль: secret_sauce).
  • inventoryPage.getProductTitles() — отримуємо список назв продуктів на сторінці інвентарю після успішного входу.
  • expect(titles.length).toBeGreaterThan(0) — перевіряємо, що кількість продуктів на сторінці інвентарю більша за 0, що свідчить про успішний вхід.

Тест 2: Невірний вхід

test(‘Invalid login’, async () => {
await loginPage.goto();
await loginPage.login(‘invalid_user’, ‘invalid_pass’);
const errorMessage = await loginPage.getErrorMessage();
expect(errorMessage).toContain(‘Epic sadface: Username and password do not match’);
});

 

  • loginPage.goto() — переходимо на сторінку логіна.
  • loginPage.login('invalid_user', 'invalid_pass') — намагаємося увійти з невірними даними (користувач: invalid_user, пароль: invalid_pass).
  • loginPage.getErrorMessage() — отримуємо повідомлення про помилку на сторінці.
  • expect(errorMessage).toContain('Epic sadface: Username and password do not match') — перевіряємо, що повідомлення про помилку містить вказану фразу, що підтверджує невірні дані для входу.

Цей код містить два тести:

  1. Тест на успішний вхід — перевіряє, що після правильного входу відображаються продукти на сторінці інвентарю.
  2. Тест на невірний вхід — перевіряє, що після введення неправильних даних з’являється відповідне повідомлення про помилку.

inventory.spec.ts

import { test, expect } from ‘@playwright/test’;
import { InventoryPage } from ‘../pages/inventory.page’;
import { LoginPage } from ‘../pages/login.page’;
import { CartPage } from ‘../pages/cart.page’;

test.describe(‘Inventory Tests’, () => {
  let loginPage: LoginPage;
  let inventoryPage: InventoryPage;
  let cartPage: CartPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.login(‘standard_user’, ‘secret_sauce’);
    inventoryPage = new InventoryPage(page);
    cartPage = new CartPage(page);
  });

  test(‘Add Sauce Labs Backpack to cart’, async () => {
    await inventoryPage.addBackpackToCart();
    await cartPage.goto();  
   
    const cartItems = await cartPage.getCartItems();
    const backpackInCart = cartItems.some(item => item.includes(‘Sauce Labs Backpack’));
    expect(backpackInCart).toBe(true);
  });
});
Цей код тестує сценарій додавання товару до кошика в онлайн-магазині.
 
Опис групи тестів:
test.describe(‘Inventory Tests’, () => {
let loginPage: LoginPage;
let inventoryPage: InventoryPage;
let cartPage: CartPage;
  • test.describe — групує тести за певною темою, в даному випадку це тести, що стосуються інвентарю.
  • loginPage, inventoryPage, cartPage — змінні, що містять екземпляри відповідних класів для взаємодії з цими сторінками.

beforeEach хук:

test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login(‘standard_user’, ‘secret_sauce’);
inventoryPage = new InventoryPage(page);
cartPage = new CartPage(page);
});

 

  • beforeEach — виконується перед кожним тестом.
  • Створюються екземпляри класів LoginPage, InventoryPage і CartPage.
  • За допомогою loginPage.goto() та loginPage.login() відбувається вхід на сайт з використанням правильних даних користувача.
  • Після цього створюються екземпляри для сторінок інвентарю та кошика.

Тест: Додавання рюкзака «Sauce Labs Backpack» до кошика

test(‘Add Sauce Labs Backpack to cart’, async () => {
await inventoryPage.addBackpackToCart();
await cartPage.goto();

const cartItems = await cartPage.getCartItems();
const backpackInCart = cartItems.some(item => item.includes(‘Sauce Labs Backpack’));
expect(backpackInCart).toBe(true);
});

  • inventoryPage.addBackpackToCart() — додаємо товар «Sauce Labs Backpack» до кошика, викликаючи метод з InventoryPage. Цей метод знаходить товар на сторінці і натискає кнопку «Add to Cart».
  • cartPage.goto() — переходимо на сторінку кошика, щоб перевірити, чи додався товар.
  • cartPage.getCartItems() — отримуємо всі елементи в кошику.
  • const backpackInCart = cartItems.some(item => item.includes('Sauce Labs Backpack')) — перевіряємо, чи є товар «Sauce Labs Backpack» серед елементів у кошику. Для цього перевіряємо, чи є в будь-якому з елементів кошика назва товару.
  • expect(backpackInCart).toBe(true) — асертуємо, що товар «Sauce Labs Backpack» знаходиться в кошику. Якщо це не так, тест не пройде.

Цей тест перевіряє функціональність додавання товару до кошика і правильність відображення доданого товару на сторінці кошика.

Якщо товар додано успішно, тест завершується успішно. Якщо товар не з’являється в кошику, тест завершується з помилкою.

Використання beforeEach гарантує, що перед кожним тестом користувач входить в систему, і тестуємо дію на чистій сторінці інвентарю.

cart.spec.ts

import { test, expect } from ‘@playwright/test’;
import { CartPage } from ‘../pages/cart.page’;
import { LoginPage } from ‘../pages/login.page’;
import { InventoryPage } from ‘../pages/inventory.page’;

test.describe(‘Cart Tests’, () => {
  let loginPage: LoginPage;
  let inventoryPage: InventoryPage;
  let cartPage: CartPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.login(‘standard_user’, ‘secret_sauce’);
    inventoryPage = new InventoryPage(page);
    cartPage = new CartPage(page);
    await inventoryPage.addBackpackToCart();  // Add to cart
  });

  test(‘Check items in cart’, async () => {
    await cartPage.goto();
    const cartItems = await cartPage.getCartItems();
    expect(cartItems.length).toBeGreaterThan(0);
  });
});
import { test, expect } from ‘@playwright/test’;
import { CartPage } from ‘../pages/cart.page’;
import { LoginPage } from ‘../pages/login.page’;
import { InventoryPage } from ‘../pages/inventory.page’;

test.describe(‘Cart Tests’, () => {
  let loginPage: LoginPage;
  let inventoryPage: InventoryPage;
  let cartPage: CartPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.login(‘standard_user’, ‘secret_sauce’);
    inventoryPage = new InventoryPage(page);
    cartPage = new CartPage(page);
    await inventoryPage.addBackpackToCart();  // Add to cart
  });

  test(‘Check items in cart’, async () => {
    await cartPage.goto();
    const cartItems = await cartPage.getCartItems();
    expect(cartItems.length).toBeGreaterThan(0);
  });
});
Цей код тестує функціональність кошика на онлайн-магазині.
beforeEach хук:
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login(‘standard_user’, ‘secret_sauce’);
inventoryPage = new InventoryPage(page);
cartPage = new CartPage(page);
await inventoryPage.addBackpackToCart(); // Add to cart
});
  • beforeEach — виконується перед кожним тестом.
  • Створюються екземпляри класів для сторінок: LoginPage, InventoryPage та CartPage.
  • Виконується вхід на сайт через loginPage.goto() та loginPage.login() з правильними даними користувача.
  • Після цього товар «Sauce Labs Backpack» додається до кошика через inventoryPage.addBackpackToCart().

Тест: Перевірка наявності елементів у кошику

test(‘Check items in cart’, async () => {
await cartPage.goto();
const cartItems = await cartPage.getCartItems();
expect(cartItems.length).toBeGreaterThan(0);
});

  • cartPage.goto() — переходимо на сторінку кошика, щоб перевірити, чи є додані товари.
  • cartPage.getCartItems() — отримуємо всі елементи в кошику за допомогою методу getCartItems() з CartPage.
  • expect(cartItems.length).toBeGreaterThan(0) — асертуємо, що в кошику є хоча б один товар. Якщо кошик порожній, тест не пройде.

Як запустити тести?

Для запуску тестів за допомогою Playwright, використовуйте команду:

npx playwright test

Ця команда автоматично запустить всі тести з папки tests, згідно з налаштуваннями в конфігураційному файлі playwright.config.ts.

 

Запуск конкретного тесту:

Якщо ви хочете запустити конкретний тест, вкажіть шлях до цього тесту:

npx playwright test tests/login.spec.ts

Наприклад, щоб запускати тести в режимі headed (з інтерфейсом браузера), використовуйте:

npx playwright test —headed

Щоб включити більше логів під час запуску тестів:

npx playwright test —verbose

Після завершення тестування, ви зможете побачити результат виконання тестів прямо в консолі. Якщо тести не пройшли, Playwright виведе детальні помилки, щоб допомогти вам виправити проблеми.

 

 

Завантажити готовий проект із GitLab?

Для звірки свого коду ви можете завантажити вже готовий проект з репозиторію

Хочете пройти повноцінний 2 місячний курс Playwright на TypeScript?

На курсі ви

Вивчіть Playwright в деталях

від базових операцій до сучасних технік автоматизації.

Опануйте TypeScript

щоб створювати більш надійні та масштабовані тести.

Створіть тестові сценарії для реальних проектів

наближених до бойових завдань.

Пориньте в сучасні підходи автоматизації

інтеграція з CI/CD, робота з API

16 грудня в 20:00

старт

Початок через

0 Днів
0 Годин
0 Хвилин
0 Секунд

Бажаєте дізнатися більше про курс?