Cucumber.js интеграция

Protractor является мощным инструментом для end-to-end тестирования Angular и не только. В связке с Cucumber.js он позволяет строить тесты в формате BDD (Behavior-Driven Development), что облегчает понимание сценариев тестирования и их поддержку.


Установка и настройка

Для работы потребуется установить следующие пакеты через npm:

npm install --save-dev protractor cucumber protractor-cucumber-framework
  • protractor — основной фреймворк для E2E тестов.
  • cucumber — библиотека для BDD, предоставляющая поддержку Gherkin.
  • protractor-cucumber-framework — интеграция Protractor с Cucumber.js.

После установки необходимо настроить Protractor конфигурацию для работы с Cucumber. Пример protractor.conf.js:

exports.config = {
  framework: 'custom',
  frameworkPath: require.resolve('protractor-cucumber-framework'),
  
  specs: [
    './features/**/*.feature'
  ],

  cucumberOpts: {
    require: ['./step_definitions/**/*.js'],
    tags: [],
    format: ['json:./reports/cucumber_report.json'],
    strict: true
  },

  directConnect: true,

  capabilities: {
    browserName: 'chrome'
  }
};

Ключевые моменты конфигурации:

  • framework: 'custom' и frameworkPath — обязательны для использования Cucumber с Protractor.
  • specs — путь к .feature файлам.
  • cucumberOpts.require — путь к файлам с step definitions.
  • format — задаёт формат отчёта, в данном случае JSON, что удобно для последующей интеграции с отчётами Allure.
  • directConnect — позволяет запускать Chrome напрямую, без Selenium Server.

Структура файлов

Для удобства и поддержки масштабируемости тестов часто используют следующую структуру:

project/
│
├─ features/
│  ├─ login.feature
│  └─ dashboard.feature
│
├─ step_definitions/
│  ├─ loginSteps.js
│  └─ dashboardSteps.js
│
├─ page_objects/
│  ├─ loginPage.js
│  └─ dashboardPage.js
│
├─ protractor.conf.js
└─ package.json
  • features/ — файлы на Gherkin с описанием сценариев.
  • step_definitions/ — реализация шагов, описанных в feature.
  • page_objects/ — модели страниц, используемые в шагах, для поддержки Page Object Model (POM).

Пример Gherkin сценария

Feature: Авторизация на сайте

  Scenario: Успешный вход
    Given пользователь находится на странице входа
    When он вводит корректный логин и пароль
    And нажимает кнопку "Войти"
    Then он видит страницу дашборда

Каждое ключевое слово (Given, When, Then) соответствует функции в step definitions.


Step Definitions

const { Given, When, Then } = require('cucumber');
const LoginPage = require('../page_objects/loginPage');
const DashboardPage = require('../page_objects/dashboardPage');

const loginPage = new LoginPage();
const dashboardPage = new DashboardPage();

Given('пользователь находится на странице входа', async () => {
  await loginPage.open();
});

When('он вводит корректный логин и пароль', async () => {
  await loginPage.enterCredentials('user', 'password');
});

When('нажимает кнопку "Войти"', async () => {
  await loginPage.submit();
});

Then('он видит страницу дашборда', async () => {
  await dashboardPage.waitForVisible();
});
  • Используются async/await для работы с промисами Protractor.
  • Логика шагов отделена от описания страниц с помощью Page Object Model.
  • Каждый шаг максимально атомарен, что повышает читаемость и повторное использование.

Page Object Model в Cucumber.js + Protractor

Пример loginPage.js:

class LoginPage {
  constructor() {
    this.usernameInput = element(by.id('username'));
    this.passwordInput = element(by.id('password'));
    this.loginButton = element(by.css('button[type="submit"]'));
  }

  async open() {
    await browser.get('https://example.com/login');
  }

  async enterCredentials(username, password) {
    await this.usernameInput.sendKeys(username);
    await this.passwordInput.sendKeys(password);
  }

  async submit() {
    await this.loginButton.click();
  }
}

module.exports = LoginPage;

Page Object Model помогает минимизировать дублирование кода, централизует локаторы и методы взаимодействия с элементами страницы.


Теги и фильтрация сценариев

Cucumber.js поддерживает теги для группировки тестов:

@smoke
Scenario: Быстрый тест авторизации
  ...

В конфигурации Protractor можно запускать только определённые сценарии:

cucumberOpts: {
  require: ['./step_definitions/**/*.js'],
  tags: '@smoke',
  format: ['json:./reports/smoke_report.json'],
  strict: true
}

Это удобно для разделения на smoke, regression и другие типы тестов.


Отчётность и интеграция с Allure

Для генерации красивых отчётов можно использовать Allure:

npm install --save-dev allure-commandline

В конфигурации Cucumber.js достаточно добавить формат json и после теста запускать:

allure generate ./reports/cucumber_report.json --clean
allure open

Отчёты будут содержать информацию о каждом сценарии, шаге и скриншотах при падениях тестов.


Работа с Angular и не-Angular приложениями

Protractor умеет ожидать завершения Angular-операций. Если требуется тестировать не-Angular страницы, необходимо отключить синхронизацию:

browser.waitForAngularEnabled(false);

Эта настройка обычно выполняется в шаге Given перед переходом на внешнюю страницу.


Параллельное выполнение тестов

Protractor поддерживает shardTestFiles, что позволяет запускать несколько сценариев одновременно:

capabilities: {
  browserName: 'chrome',
  shardTestFiles: true,
  maxInstances: 3
}
  • shardTestFiles: true — делит файлы на отдельные потоки.
  • maxInstances — количество одновременных браузеров.
  • Повышает скорость тестирования, особенно на большом наборе сценариев.

Использование Hooks

Cucumber.js предоставляет хуки Before, After, BeforeStep, AfterStep для выполнения кода до и после сценариев или шагов:

const { Before, After } = require('cucumber');

Before(async () => {
  await browser.manage().window().maximize();
});

After(async function (scenario) {
  if (scenario.result.status === 'failed') {
    const screenshot = await browser.takeScreenshot();
    this.attach(screenshot, 'image/png');
  }
});
  • Before — подготовка окружения.
  • After — очистка или сохранение артефактов (скриншоты, логи).
  • Поддержка вложенных хуков позволяет гибко настраивать поведение тестов.