
Modern web applications demand fast feedback, reliable automation, and clear collaboration between technical and non-technical stakeholders. I have seen teams adopt powerful testing tools yet still struggle with readability, maintainability, and alignment between business requirements and automated tests. This gap often appears when test cases are written in purely technical code that product managers, QA analysts, and business teams cannot easily interpret.
This is where combining Cypress with Cucumber becomes practical. Cypress delivers fast, reliable end-to-end testing for modern web applications, while Cucumber introduces behavior-driven development through human-readable scenarios. Together, they enable teams to write automated tests that reflect real user behavior and business rules in a structured and understandable format.
In this article, I will cover how Cypress and Cucumber work together, how to set them up, how to write parameterized scenarios, generate reports, and follow best practices for building scalable Cypress Cucumber test suites.
Cypress is a modern JavaScript-based end-to-end testing framework designed specifically for web applications. Unlike traditional automation tools that operate outside the browser, Cypress runs directly inside the browser. This architectural decision provides native access to the DOM, network layer, and application events, which results in faster and more stable test execution.
Cypress simplifies several common automation challenges. It eliminates the need for separate drivers, handles automatic waiting, and provides built-in retry logic. Instead of manually adding waits or sleep statements, Cypress intelligently waits for elements to appear and assertions to pass. This reduces flaky tests and improves reliability across environments.
Another strong advantage is its developer-friendly experience. Cypress offers:
From a technical standpoint, Cypress uses a command queue and executes commands asynchronously under the hood while presenting a synchronous-looking syntax. This design reduces callback complexity and makes test code more readable.
Cypress is commonly used for:
Because it is tightly coupled with the browser environment, Cypress is particularly effective for modern JavaScript-heavy applications where dynamic content, network calls, and real-time UI updates are common.
Cucumber is a Behavior-Driven Development framework that enables writing automated tests in a human-readable format. Instead of defining test cases purely in programming code, Cucumber uses structured natural language to describe application behavior from a user’s perspective.
At the core of Cucumber is Gherkin, a domain-specific language that follows a simple syntax built around keywords such as:
For example, a login scenario written in Gherkin might look like this:
Feature: User Login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters valid credentials
Then the user should be redirected to the dashboard
This structure makes test scenarios understandable to developers, testers, product managers, and business stakeholders. The goal is to ensure that requirements, documentation, and automated tests follow the same language and behavioral expectations.
In test automation, Cucumber works by mapping each Gherkin step to a step definition written in code. These step definitions contain the actual automation logic that interacts with the application. The feature file describes behavior, while the step definitions execute the behavior.
Cucumber introduces structure and clarity into automated testing by focusing on behavior instead of implementation details. This shift changes how teams design, review, and maintain test cases.
Below are the key benefits of using Cucumber in a test automation strategy.
Combining Cypress with Cucumber is particularly effective when teams want both technical reliability and business-readable test scenarios. This integration supports several practical testing scenarios across development lifecycles.
Below are common use cases where Cypress Cucumber testing provides strong value.
The Cypress Cucumber preprocessor acts as a bridge between Cypress and Cucumber. By default, Cypress executes test files written in JavaScript or TypeScript. The preprocessor extends this capability so that Cypress can understand and execute .feature files written in Gherkin syntax.
At a high level, the preprocessor performs three key functions.
Technically, the preprocessor integrates into Cypress through its plugin system. When Cypress loads test files, the preprocessor intercepts .feature files and compiles them into JavaScript before execution. This allows teams to retain behavior-driven syntax without modifying Cypress’s core execution model.
A typical project structure using the preprocessor looks like this:
The step definitions contain actual Cypress commands such as cy.visit(), cy.get(), or cy.intercept(). While feature files describe behavior, step definitions implement browser interactions.
The preprocessor ensures that:
Gherkin is the language used by Cucumber to define application behavior in a structured and readable format. It follows a strict syntax that ensures consistency across teams and projects.
A Gherkin file uses specific keywords to define features and scenarios.
Core Structure of a Gherkin File
A basic feature file contains the following elements:
Example:
Feature: User Login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters valid username and password
Then the user should see the dashboard
This structure ensures that every test follows a behavior-driven flow. The scenario describes what the system should do from a user perspective rather than how it is implemented.
For more advanced test design, Gherkin supports additional constructs.
Example of a Scenario Outline:
Feature: Login Validation
Scenario Outline: Login with different credentials
Given the user is on the login page
When the user enters "<username>" and "<password>"
Then the login result should be "<result>"
Examples:
| username | password | result |
| user1 | pass123 | success |
| user2 | wrong | failure |
In this structure, the same scenario runs multiple times with different input values. The preprocessor replaces placeholders with actual data from the Examples table.
Integrating Cypress and Cucumber allows behavior-driven .feature files to execute within the Cypress test runner. This setup combines readable Gherkin scenarios with Cypress’s fast browser automation engine. The integration is enabled using a Cucumber preprocessor plugin that translates feature files into executable test code.
Setting up Cypress Cucumber involves installing the required dependencies, configuring the preprocessor, and organizing the project structure correctly.
Step 1: Install Cypress
If Cypress is not already installed:
npm install cypress --save-dev
Step 2: Install the Cucumber Preprocessor
Install the modern Cucumber preprocessor package:
npm install @badeball/cypress-cucumber-preprocessor --save-dev
Additional required bundler dependency:
npm install @bahmutov/cypress-esbuild-preprocessor --save-dev
Step 3: Configure cypress.config.js
Register the preprocessor in the Cypress configuration file:
const { defineConfig } = require("cypress");
const createBundler = require("@bahmutov/cypress-esbuild-preprocessor");
const addCucumberPreprocessorPlugin = require("@badeball/cypress-cucumber-preprocessor").addCucumberPreprocessorPlugin;
const createEsbuildPlugin = require("@badeball/cypress-cucumber-preprocessor/esbuild").createEsbuildPlugin;
module.exports = defineConfig({
e2e: {
specPattern: "**/*.feature",
async setupNodeEvents(on, config) {
await addCucumberPreprocessorPlugin(on, config);
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
);
return config;
},
},
});
Step 4: Create Folder Structure
Recommended structure:
Once configured, Cypress will recognize .feature files as valid test specifications.
After setup is complete, running Cucumber tests follows the same execution model as standard Cypress tests.
Run in Interactive Mode:
npx cypress open
Select the desired .feature file from the Cypress Test Runner.
Run in Headless Mode:
npx cypress run
Cypress will automatically parse feature files, map step definitions, and execute scenarios inside the browser environment.
Because the preprocessor converts Gherkin scenarios into executable test cases, no additional execution steps are required beyond standard Cypress commands.
While running tests locally works during development, production-ready validation requires cross-browser and cross-device coverage. This is where cloud platforms like BrowserStack help execute Cypress Cucumber tests on real browsers and devices at scale.
It enables parallel execution across multiple browser and OS combinations, which significantly reduces regression cycle time. Teams also gain access to real-time logs, screenshots, and video recordings that simplify debugging and improve release confidence.
Parameterized steps allow dynamic data to be passed from Gherkin feature files into step definitions. This approach improves reusability and reduces duplication in test scenarios. Instead of writing separate scenarios for each data variation, placeholders can be defined and replaced at runtime.
Parameters are defined inside quotes in feature files.
Feature file example:
Scenario: Login with valid credentials
Given the user is on the login page
When the user enters "standard_user" and "secret123"
Then the user should see the dashboard
In the step definition file, placeholders are captured as arguments:
import { When } from "@badeball/cypress-cucumber-preprocessor";
When("the user enters {string} and {string}", (username, password) => {
cy.get("#username").type(username);
cy.get("#password").type(password);
cy.get("#loginBtn").click();
});
Here, {string} captures values from the feature file and passes them as arguments to the function.
For testing multiple combinations, Scenario Outline with an Examples table is more efficient.
Feature file example:
Scenario Outline: Login with different credentials
Given the user is on the login page
When the user enters "<username>" and "<password>"
Then the login result should be "<result>"
Examples:
| username | password | result |
| standard_user | secret123 | success |
| locked_user | wrongpass | failure |
In the step definition:
Then("the login result should be {string}", (result) => {
if (result === "success") {
cy.url().should("include", "/dashboard");
} else {
cy.contains("Invalid credentials").should("be.visible");
}
});
Each row in the Examples table runs as a separate test instance.
Generating structured reports in a Cypress Cucumber setup helps track execution results, analyze failures, and share outcomes with stakeholders. Since Cucumber supports JSON reporting natively, most reporting workflows involve generating a JSON file first and then transforming it into an HTML report.
When using the @badeball/cypress-cucumber-preprocessor, reporting can be enabled in the Cypress configuration.
Add the following inside cypress.config.js:
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
env: {
cucumberJson: {
generate: true,
outputFolder: "cypress/reports",
filePrefix: "",
},
},
},
});
This configuration generates a JSON report after test execution.
A commonly used reporter is:
npm install multiple-cucumber-html-reporter --save-dev
This package converts generated JSON files into a structured HTML dashboard.
Add a script in package.json:
{
"scripts": {
"generate-report": "node generate-report.js"
}
}
Create generate-report.js:
const report = require("multiple-cucumber-html-reporter");
report.generate({
jsonDir: "cypress/reports",
reportPath: "cypress/reports/html",
metadata: {
browser: {
name: "chrome",
version: "latest",
},
device: "Local test machine",
platform: {
name: "macOS",
},
},
});
After running tests:
npx cypress run
npm run generate-report
An HTML report will be available inside the specified output folder.
What the Report Includes:
These reports are especially useful in CI pipelines, where artifacts can be stored and shared for release validation.
In large teams, local reports are often insufficient. Cloud testing platforms like BrowserStack provide centralized dashboards, execution logs, screenshots, and CI integration to monitor Cypress Cucumber runs across environments.
A Cypress Cucumber setup can scale effectively when feature files remain behavior-focused and step definitions stay maintainable. Without structure, large test suites can become repetitive, tightly coupled to UI changes, and difficult to debug. The following practices help maintain clarity, reusability, and long-term stability.
Cypress Cucumber testing combines the execution speed of Cypress with the structured readability of Cucumber. This integration enables teams to write behavior-driven scenarios that directly reflect business requirements while maintaining strong automation reliability.
When implemented with proper structure and discipline, Cypress Cucumber testing provides long-term value across agile development cycles, ensuring that application behavior is continuously validated in a maintainable and transparent way.
Get visual proof, steps to reproduce and technical logs with one click
Try Bird on your next bug - you’ll love it
“Game changer”
Julie, Head of QA
Try Bird later, from your desktop