Переиспользуемые компоненты

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

Одним из популярных подходов для создания переиспользуемых компонентов является паттерн PageObject. Это структура, при которой каждый компонент страницы (например, форма, модальное окно, таблица) представляется как объект с методами для взаимодействия с элементами этой страницы. Это позволяет легко обновлять тесты, так как логика взаимодействия с элементами страницы централизована в одном месте.

Пример реализации 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

В процессе написания тестов важно интегрировать переиспользуемые компоненты с библиотеками для тестирования. В случае с Puppeteer часто используются библиотеки, такие как Jest, Mocha или Chai. Эти библиотеки позволяют организовать тесты в виде наборов сценариев, где каждый тест может вызывать переиспользуемые компоненты для проверки функциональности приложения.

Пример использования с Jest

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, помогает избежать дублирования кода, улучшает читаемость и облегчает модификацию тестов в будущем. Эффективная структура проекта и интеграция с библиотеками для тестирования дают возможность масштабировать тестовую базу и легко поддерживать её в актуальном состоянии.