Написание собственных плагинов

Cypress поддерживает создание собственных плагинов, которые расширяют функциональность тестовой среды. Плагины работают на уровне Node.js и позволяют взаимодействовать с файловой системой, внешними сервисами, базами данных, выполнять задачи, недоступные в браузере. Основная точка входа для плагинов — файл cypress/plugins/index.js. В нём определяется функция с параметрами on и config, где on используется для подписки на события Cypress, а config позволяет менять конфигурацию тестовой среды.

Пример базовой структуры плагина:

module.exports = (on, config) => {
  on('before:browser:launch', (browser = {}, launchOptions) => {
    console.log(`Запуск браузера: ${browser.name}`);
    return launchOptions;
  });
};

Здесь before:browser:launch — событие, которое срабатывает перед запуском браузера. Подобным образом можно обрабатывать множество событий: загрузку тестового окружения, выполнение задач из тестов, обработку ошибок и другие.


Создание кастомных команд через плагины

Хотя Cypress позволяет определять команды в cypress/support/commands.js, иногда требуется реализовать команды, которые используют Node.js API или внешние сервисы. Для этого используют task — механизм передачи задач из тестов в плагин:

// cypress/plugins/index.js
module.exports = (on, config) => {
  on('task', {
    readFileMaybe(path) {
      const fs = require('fs');
      return fs.existsSync(path) ? fs.readFileSync(path, 'utf8') : null;
    }
  });
};

// В тесте
cy.task('readFileMaybe', 'path/to/file.txt').then(content => {
  expect(content).to.not.be.null;
});

Ключевой момент: всё, что выполняется через task, работает в Node.js, а не в браузере, что открывает доступ к файловой системе и сторонним библиотекам.


Расширение событий Cypress

Cypress предоставляет большое количество событий, на которые можно подписываться через объект on:

  • before:browser:launch — перед запуском браузера.
  • after:screenshot — после создания скриншота.
  • after:spec — после выполнения файла тестов.
  • task — выполнение пользовательских задач из тестов.

Каждое событие получает объект с параметрами, которые можно модифицировать. Например, для изменения настроек браузера перед запуском:

on('before:browser:launch', (browser, launchOptions) => {
  if (browser.family === 'chromium') {
    launchOptions.args.push('--disable-dev-shm-usage');
  }
  return launchOptions;
});

Использование событий позволяет тонко настраивать тестовую среду под конкретные требования проекта.


Создание собственного плагина как npm-пакета

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

my-cypress-plugin/
├─ index.js
├─ package.json
├─ README.md

Пример реализации плагина:

function registerPlugin(on, config) {
  on('task', {
    logMessage(message) {
      console.log(`[PLUGIN LOG]: ${message}`);
      return null;
    }
  });
}

module.exports = registerPlugin;

Подключение в проекте Cypress:

// cypress/plugins/index.js
const myPlugin = require('my-cypress-plugin');
module.exports = (on, config) => {
  myPlugin(on, config);
};

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


Работа с асинхронными задачами в плагинах

Cypress поддерживает промисы и асинхронные функции в task. Это особенно полезно для работы с API или базами данных:

on('task', {
  async fetchData(url) {
    const fetch = require('node-fetch');
    const response = await fetch(url);
    return response.json();
  }
});

// В тесте
cy.task('fetchData', 'https://jsonplaceholder.typicode.com/todos/1')
  .then(data => {
    expect(data).to.have.property('id', 1);
  });

Важно: Cypress ждёт разрешения промиса перед продолжением теста, что обеспечивает синхронное поведение тестов, несмотря на асинхронные операции на уровне Node.js.


Интеграция с внешними библиотеками

Плагины позволяют подключать любые Node.js библиотеки. Например, можно использовать xlsx для работы с Excel-файлами:

const xlsx = require('xlsx');

on('task', {
  readExcel(filePath) {
    const workbook = xlsx.readFile(filePath);
    const sheetName = workbook.SheetNames[0];
    return xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);
  }
});

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


Советы по организации плагинов

  1. Минимизировать код в index.js — основной файл плагинов должен только регистрировать события, а логика выносится в отдельные модули.
  2. Использовать промисы для асинхронных операций — упрощает обработку ошибок и делает тесты предсказуемыми.
  3. Избегать побочных эффектов в браузере — плагины работают в Node.js, поэтому не стоит пытаться напрямую изменять DOM.
  4. Документировать задачи и события — для крупных проектов важно, чтобы все task и события были описаны, иначе тестировщики будут тратить время на поиск функциональности.

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