Puppeteer предоставляет мощный инструментарий для автоматизации браузера, который активно используется для тестирования веб-приложений. Важным аспектом при разработке тестов является создание переиспользуемых компонентов, что позволяет избежать дублирования кода, повысить читаемость и поддерживаемость тестов. Разработка таких компонентов в Puppeteer может быть реализована через различные подходы, включая функции, классы и абстракции.
Самый простой способ создания переиспользуемых компонентов — это использование функций. Это позволяет группировать повторяющиеся действия в тестах, таких как клик по элементам, ввод текста в поля или проверка состояния элементов на странице.
const clickElement = async (page, selector) => {
await page.waitForSelector(selector);
await page.click(selector);
};
Функция clickElement принимает два аргумента: объект
page и строку с CSS-селектором. Она ожидает появления
элемента на странице, а затем выполняет клик. Этот компонент можно
переиспользовать в различных тестах, просто передавая нужный селектор.
const typeText = async (page, selector, text) => {
await page.waitForSelector(selector);
await page.type(selector, text);
};
Эта функция ожидает появления элемента с данным селектором и вводит текст в поле. Она универсальна и может быть использована в тестах для различных форм и текстовых полей.
Когда тесты становятся более сложными, возможно потребуется использование классов. Это особенно полезно, когда нужно организовать несколько взаимодействий с элементами или управлять состоянием внутри тестов. Классы позволяют инкапсулировать логику, связанную с взаимодействием с отдельными компонентами страницы.
class LoginForm {
constructor(page) {
this.page = page;
this.usernameSelector = &
this.passwordSelector = '#password';
this.submitButtonSelector = '#submit';
}
async enterUsername(username) {
await this.page.waitForSelector(this.usernameSelector);
await this.page.type(this.usernameSelector, username);
}
async enterPassword(password) {
await this.page.waitForSelector(this.passwordSelector);
await this.page.type(this.passwordSelector, password);
}
async submit() {
await this.page.waitForSelector(this.submitButtonSelector);
await this.page.click(this.submitButtonSelector);
}
}
В этом примере создается класс LoginForm, который
инкапсулирует взаимодействие с формой входа. Вместо того чтобы каждый
раз писать код для поиска и взаимодействия с полями формы, можно просто
создать объект этого класса и вызывать его методы.
const loginForm = new LoginForm(page);
await loginForm.enterUsername('testuser');
await loginForm.enterPassword('password123');
await loginForm.submit();
Такой подход улучшает читаемость кода и упрощает его поддержку, особенно в случае сложных страниц с множеством полей и кнопок.
Одним из популярных подходов для создания переиспользуемых компонентов является паттерн PageObject. Это структура, при которой каждый компонент страницы (например, форма, модальное окно, таблица) представляется как объект с методами для взаимодействия с элементами этой страницы. Это позволяет легко обновлять тесты, так как логика взаимодействия с элементами страницы централизована в одном месте.
class HomePage {
constructor(page) {
this.page = page;
this.searchBoxSelector = '#search';
this.searchButtonSelector = '#search-btn';
}
async search(query) {
await this.page.waitForSelector(this.searchBoxSelector);
await this.page.type(this.searchBoxSelector, query);
await this.page.click(this.searchButtonSelector);
}
}
Класс HomePage инкапсулирует логику поиска на главной
странице сайта. Все взаимодействия с элементами страницы централизованы,
и тесты могут использовать этот класс без необходимости повторно писать
логику для поиска и клика.
В процессе написания тестов важно интегрировать переиспользуемые компоненты с библиотеками для тестирования. В случае с Puppeteer часто используются библиотеки, такие как Jest, Mocha или Chai. Эти библиотеки позволяют организовать тесты в виде наборов сценариев, где каждый тест может вызывать переиспользуемые компоненты для проверки функциональности приложения.
const { chromium } = require('puppeteer');
const { LoginForm } = require('./LoginForm'); // Путь к классу с переиспользуемыми компонентами
describe('Login Test', () => {
let page;
let browser;
beforeAll(async () => {
browser = await chromium.launch();
page = await browser.newPage();
});
afterAll(async () => {
await browser.close();
});
test('should log in successfully', async () => {
const loginForm = new LoginForm(page);
await loginForm.enterUsername('testuser');
await loginForm.enterPassword('password123');
await loginForm.submit();
const userProfile = await page.$('#profile');
expect(userProfile).toBeTruthy();
});
});
Здесь используется Jest для запуска теста, который проверяет
функциональность формы входа. Все взаимодействие с формой
инкапсулировано в классе LoginForm, и это значительно
упрощает код теста, повышая его поддержку и читаемость.
Для лучшей организации и масштабируемости тестов необходимо правильно структурировать проект. Важно разделять компоненты страницы (PageObjects), тесты и вспомогательные функции. Это поможет легко поддерживать тесты, а также добавлять новые компоненты и тестовые сценарии по мере роста проекта.
Пример структуры проекта:
/tests
/login.test.js
/home.test.js
/utils
/utils.js
/pageObjects
/LoginForm.js
/HomePage.js
Каждый файл с тестом содержит только тестовые сценарии, а все
взаимодействия с компонентами страниц вынесены в отдельные файлы в папке
pageObjects. Вспомогательные функции можно хранить в папке
utils, если они часто используются в нескольких тестах.
Создание переиспользуемых компонентов в Puppeteer позволяет значительно повысить эффективность разработки и поддержки тестов. Использование функций, классов и паттернов проектирования, таких как PageObject, помогает избежать дублирования кода, улучшает читаемость и облегчает модификацию тестов в будущем. Эффективная структура проекта и интеграция с библиотеками для тестирования дают возможность масштабировать тестовую базу и легко поддерживать её в актуальном состоянии.