Playwright BDD: Combining Cucumber with Page Objects
Playwright BDD: Combining Cucumber with Page Objects
The Problem with Functional BDD Implementations link
I've seen many BDD implementations that start well but become unmaintainable over time. The most common issue? Using functional programming patterns with utility functions instead of proper Page Objects.
Here's what typically happens:
- Test utilities become a scattered mess of functions
- Duplicated logic across different step definitions
- No clear ownership of UI interactions
- Difficult to refactor when the UI changes
- Hard for new team members to understand
The Solution: BDD + POM link
The answer is simple: combine the readability of BDD/Gherkin with the maintainability of the Page Object Model.
Feature Files (Gherkin) link
Write scenarios in business language:
Page Objects (Maintainable UI Logic) link
Encapsulate UI interactions in page classes:
Step Definitions (The Glue) link
Connect Gherkin to Page Objects:
Key Architecture Decisions link
Domain-Driven Page Objects link
Don't use a generic pages/ folder. Organize by feature domains:
This matches your application structure and makes it easy to find what you need.
Combined Factory + Navigation link
Instead of separate navigation and factory classes, use a combined approach:
Cleaner API, less boilerplate.
No Assertions in Page Objects link
Keep page objects pure:
Docker for Consistency link
Two modes of testing:
Local Mode (PR Testing) link
- Starts your app inside the container
- Tests against
localhost:3000 - Perfect for validating changes before merge
Remote Mode (Environment Testing) link
- Tests against deployed environments
- No local app needed
- For dev/staging/production validation
CI/CD Integration link
Three GitHub Actions workflows:
- PR Workflow - Every pull request
- Dev Workflow - After deployments
- Smoke Workflow - Every 6 hours against all environments
All running in Docker for consistency.
Benefits of This Approach link
For Product/BA link
- Write scenarios in plain English
- No technical knowledge required
- Features become living documentation
For QA/SDET link
- Maintainable page objects
- Clear separation of concerns
- Easy to refactor when UI changes
- Reusable step definitions
For Developers link
- Scenarios serve as specifications
- Can run tests locally
- Quick feedback loop
- Clear acceptance criteria
The Boilerplate link
I've created a complete boilerplate with:
- Playwright BDD (playwright-bdd package)
- Domain-driven page objects
- Combined factory pattern
- Docker support
- GitHub Actions workflows
- Comprehensive documentation
Get it here: GitHub - playwright-bdd-boilerplate
Getting Started link
That's it. Five minutes from clone to running tests.
When to Use BDD vs Plain POM link
Use BDD when:
- Collaborating with non-technical stakeholders
- Need living documentation
- Want tests readable by Product/BA
- Multiple people write scenarios
Use plain POM when:
- Pure technical testing
- Don't need Gherkin scenarios
- Faster test execution
- Only QA/developers write tests
Lessons Learned link
1. Don't Use Functional Utilities link
I've refactored too many codebases with messy utility functions. Page Objects are worth the upfront structure.
2. Keep Step Definitions Thin link
All logic belongs in page objects. Step definitions should just call page object methods and assert.
3. Tag Everything link
Use tags (@smoke, @regression) to run different test suites. Not every test needs to run on every commit.
4. Docker is Non-Negotiable link
The "works on my machine" problem is real. Docker ensures consistency.
Resources link
Wrapping Up link
BDD doesn't have to mean unmaintainable test code. By combining Gherkin with proper Page Objects, you get the best of both worlds: readable tests that stakeholders understand, and maintainable code that scales with your application.
More posts coming on Playwright patterns, Docker testing strategies, and CI/CD optimization. Follow me for updates.
Feel free to update this blog post on GitHub, thanks in advance!