Home > Blog > Playwright × BDD: Cucumber.js vs Playwright-bdd
Author: Tomotaka ASAGI
Published: Jan 17, 2026
Introduction
When I started using Playwright with TypeScript, I chose Cucumber.js as my BDD framework.
The reason was simple. I had spent years using Selenium + Cucumber in Java, so I just replaced Selenium with Playwright. It was the same pattern I mentioned in Part 2—sticking with a familiar setup.
But as I worked on projects, I noticed something important.
Cucumber.js and Playwright-bdd use different test runners.
This difference in test runners affects which features are available. As with Parts 1 and 2, understanding this difference is key to making the right choice.
The Cucumber.js + Playwright Architecture
Let's first clarify the architecture when combining Cucumber.js with Playwright.
Cucumber.js (test runner)
↓
Playwright (browser automation)
In this setup, the test runner is Cucumber.js. Playwright is only used as a library for browser automation.
This puts you in the same situation as using "Playwright with Java" from Part 2.
Feature Differences by Test Runner
When using Cucumber.js as your test runner, Playwright Test-specific features are not available. This is not a limitation of Cucumber.js itself, but a structural difference due to using a different test runner.
Feature | Playwright Test | Cucumber.js + Playwright |
toHaveScreenshot() | ✅ | ❌ |
toMatchSnapshot() | ✅ | ❌ |
Fixtures | ✅ | ❌ |
HTML Reporter | ✅ | ❌ (can use Cucumber reporters) |
Trace Viewer integration | ✅ | ❌ |
Sharding | ✅ | ❌ |
UI Mode | ✅ | ❌ |
This information is current as of January 2025. Future updates to Cucumber.js may add support for some of these features.
In my projects, I often wanted to use VRT (toHaveScreenshot()). With the Cucumber.js setup, implementing VRT required separate tools like OpenCV, and managing screenshots needed additional consideration.
Understanding Your Options
Let's organize the available options.
Option 1: Cucumber.js + Playwright (Traditional Setup)
Pros:
- Leverage existing Cucumber assets
- Same setup as Java era, low learning curve
- Access to Cucumber ecosystem (reporting tools, multi-language support, etc.)
- Long track record with abundant resources and community support
- Easy to share knowledge with Cucumber projects in other languages (Java, Ruby, etc.)
Cons:
- Cannot use Playwright Test-specific features
- VRT requires separate implementation
Option 2: Playwright Test (Without BDD)
Pros:
- Full access to Playwright Test features
- VRT, Reporter, Fixtures available out of the box
Cons:
- Cannot use Gherkin syntax
- Cannot write tests as a shared language with business stakeholders
Option 3: Playwright-bdd
Pros:
- Can use Gherkin syntax (maintain BDD concepts)
- Full access to Playwright Test features
- VRT (
toHaveScreenshot()) is available
Cons:
- Migration cost from Cucumber.js
- Need to learn Playwright-bdd specifics
- Shorter track record compared to Cucumber
- Cannot use Cucumber-specific ecosystem (certain reporting tools, etc.)
What is Playwright-bdd?
Playwright-bdd is a library that enables BDD (Gherkin syntax) on top of Playwright Test.
Playwright Test (test runner)
↓
Playwright-bdd (Gherkin support)
↓
Playwright (browser automation)
The key point is that the test runner is Playwright Test. This allows you to write tests in Gherkin while having access to all Playwright Test features.
Basic Usage
Installation
npm init playwright@latest
npm install -D playwright-bdd
Feature File
# features/login.feature
Feature: Login functionality
Scenario: Successful login
Given I open the login page
When I login with valid credentials
Then the dashboard is displayed
Page Objects and Fixtures
In real projects, Page Object Model (POM) is commonly used for maintainability. With Playwright-bdd, you can inject page objects using Fixtures.
// fixtures.ts
import { test as base } from 'playwright-bdd';
import { LoginPage } from './pages/LoginPage';
export const test = base.extend<{ loginPage: LoginPage }>({
loginPage: async ({ page }, use) => {
await use(new LoginPage(page));
},
});
Step Definitions
In step definitions, you use the page objects injected via Fixtures.
Step definitions become simpler, and page operations are consolidated in page objects. When UI changes occur, you only need to modify the page objects.
VRT Works Too
With Playwright-bdd, Playwright Test features work as expected.
Then('the layout is correct', async ({ page }) => {
await expect(page).toHaveScreenshot('dashboard.png');
});
VRT, which requires separate implementation in the Cucumber.js setup, is available as a standard feature with Playwright-bdd.
Cucumber.js vs Playwright-bdd Comparison
Aspect | Cucumber.js + Playwright | Playwright-bdd |
Gherkin syntax | ✅ | ✅ |
Test runner | Cucumber.js | Playwright Test |
VRT (toHaveScreenshot) | Separate implementation | Built-in |
HTML Reporter | Cucumber reporters | Playwright Test built-in |
Fixtures | Via World object | Built-in |
Fixtures + POM | Via World object | Built-in (great fit) |
Trace Viewer | Requires separate setup | Built-in |
Existing Cucumber assets | Easy to reuse | Migration required |
Ecosystem track record | Long | Relatively new |
This comparison is based on information as of January 2025. Both projects are actively developed, and features may be added or changed in the future.
Which Should You Choose?
As with Parts 1 and 2, the answer is: it depends on what you need.
Choose Cucumber.js when:
- You have extensive existing Cucumber assets (feature files, step definitions)
- You want to leverage the Cucumber ecosystem (specific reporting tools, etc.)
- You want to share knowledge with Cucumber projects in other languages
- Your team is familiar with Cucumber
Choose Playwright-bdd when:
- You want to maintain BDD concepts while using Playwright Test features
- You want to leverage VRT (
toHaveScreenshot()) as a built-in feature - It's a new project, or you can accept the migration cost
- You want to adopt a POM structure utilizing Fixtures
Conclusion
Both Cucumber.js and Playwright-bdd are frameworks that enable BDD with Playwright.
The main difference lies in the test runner. Cucumber.js uses Cucumber as its test runner, while Playwright-bdd uses Playwright Test. This difference affects the available features and ecosystem.
- Cucumber.js: Long track record, rich ecosystem, leverage existing assets
- Playwright-bdd: Integration with Playwright Test features (VRT, Fixtures, etc.)
The consistent message throughout this series has been the importance of clarifying "what do you need?" before making a choice.
- Part 1: Selenium vs Playwright
- Part 2: Java vs TypeScript
- Part 3: Cucumber.js vs Playwright-bdd
Every choice involves trade-offs. Understand what your project needs and make the optimal choice.
This article is Part 3 of the Playwright series.
- Part 1: From Selenium to Playwright
- Part 2: TypeScript vs Java - Feature Differences by Language
- Part 3: BDD Framework Comparison - Cucumber.js vs Playwright-bdd (this article)