A demonstration application showcasing Behavior-Driven Development (BDD) and Test-Driven Development (TDD) practices using React, TypeScript, Vite, and CucumberJS.
This project implements a searchable PayID address book for an online banking system, demonstrating how to:
- Set up CucumberJS with React and TypeScript
- Write executable specifications using Gherkin scenarios
- Implement BDD workflows with proper test automation
- Generate comprehensive test reports
- Frontend: React 19 + TypeScript + Vite
- BDD Framework: CucumberJS 12.1.0
- Testing: Vitest (unit tests) + Playwright (E2E) + CucumberJS (BDD)
- Reporting: Cucumber HTML Reporter
- Development: ESLint + TypeScript strict mode
- Node.js 20.19.0+ or 22.12.0+
- npm 10+
# Clone and install dependencies
npm install
# Run development server
npm run dev
# Run Cucumber BDD tests
npm run test:cucumber
# Generate test reports
npm run test:cucumber:report
The application includes a demo mode with pre-seeded PayID data for development and demonstration purposes.
# Start development server with demo data
npm run dev:demo
# Start regular development server (empty data)
npm run dev
-
Pre-seeded Data: 12 realistic PayID payees including:
- Email PayIDs:
alexandra.smith@example.com
,david.chen@gmail.com
- Mobile PayIDs:
0412 784 539
,0423 567 890
(formatted) - ABN PayIDs:
80123456789
,90234567890
- Mix of payees with and without nicknames
- Email PayIDs:
-
Visual Indicator: Demo mode displays a banner indicating sample data is being used
-
Realistic Loading: 800ms delay simulation for demonstration purposes
-
Console Logging: Shows "π Demo mode enabled" message for developers
Name | PayID | Type | Nickname |
---|---|---|---|
Alexandra Smith | a.smith@example.com | Lexi | |
Andy Bolton | 0412 784 539 | mobile | AndyB |
Fresh Foods Pty Ltd | 80123456789 | abn | - |
Grace Liu | grace@business.com.au | Gracie |
- Development: Test PayID list functionality without backend setup
- Demos: Show realistic data for stakeholder presentations
- QA Testing: Consistent dataset for manual testing scenarios
- Documentation: Screenshot generation with meaningful data
This section documents the complete setup process for integrating CucumberJS with a React + TypeScript + Vite project.
npm install --save-dev @cucumber/cucumber @cucumber/html-formatter @types/node ts-node
tests/
βββ cucumber/
β βββ features/
β β βββ search-payees.feature
β β βββ duplicate-payees.feature
β βββ step-definitions/
β β βββ search-payees.steps.cjs
β β βββ duplicate-payees.steps.cjs
β βββ package.json # Override ES modules
β βββ tsconfig.json # TypeScript config for tests
βββ cucumber.config.cjs # Main Cucumber configuration
βββ reports/ # Generated HTML reports
module.exports = {
default: {
paths: ['tests/cucumber/features/**/*.feature'],
require: ['tests/cucumber/step-definitions/**/*.cjs'],
format: [
'progress',
'html:reports/cucumber-report.html'
],
publish: false,
failFast: false,
parallel: 1
}
};
{
"type": "commonjs"
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node"
},
"include": ["**/*"]
}
// tests/cucumber/step-definitions/search-payees.steps.cjs
const { Given, When, Then } = require('@cucumber/cucumber');
Given('Priya has the following payees in her address book:', function (dataTable) {
// TODO: Implement step to set up payees data
});
When('Priya searches for {string}', function (searchTerm) {
// TODO: Implement step to perform search action
});
Then('she should see the following results:', function (dataTable) {
// TODO: Implement step to verify search results
});
{
"scripts": {
"dev": "vite",
"dev:demo": "vite --mode demo",
"test:cucumber": "npx cucumber-js --config cucumber.config.cjs",
"test:cucumber:dry": "npx cucumber-js --config cucumber.config.cjs --dry-run",
"test:cucumber:watch": "npx cucumber-js --config cucumber.config.cjs --watch",
"test:cucumber:report": "npx cucumber-js --config cucumber.config.cjs && echo 'π Report generated at reports/cucumber-report.html'"
}
}
Problem: Projects with "type": "module"
in package.json conflict with CucumberJS CommonJS requirements.
Solution:
- Use
.cjs
extension for step definitions - Create
tests/cucumber/package.json
with{"type": "commonjs"}
- Use
module.exports
syntax in configuration files
Problem: Cucumber reports "0 scenarios" or undefined steps.
Solutions:
- Ensure step definition files use
.cjs
extension - Verify the
require
path incucumber.config.cjs
matches your file structure - Check that step definition files are properly exporting functions
- Use
npm run test:cucumber:dry
to debug without execution
Problem: TypeScript compilation errors with step definitions.
Solution:
- Use JavaScript
.cjs
files for step definitions instead of TypeScript - Create separate
tsconfig.json
in test directory with CommonJS module setting - Install
@types/node
for Node.js type definitions
Problem: Cucumber can't find feature files or step definitions.
Solution:
- Use relative paths from project root in
cucumber.config.cjs
- Ensure glob patterns match your actual file structure
- Test with
--dry-run
flag to verify file discovery
Problem: HTML reports not generating or empty.
Solution:
- Install
@cucumber/html-formatter
dependency - Create
reports/
directory before running tests - Use proper format syntax:
'html:reports/cucumber-report.html'
- Given: Set up the initial state
- When: Perform the action being tested
- Then: Assert the expected outcome
- Background: Common setup for all scenarios
- Scenario Outline: Data-driven testing with examples
- Use parameterized steps with
{string}
,{int}
,{word}
- Create reusable steps that work across multiple scenarios
- Keep step definitions implementation-agnostic
- Use data tables for complex test data setup
- Write scenarios from user perspective, not UI implementation
- Focus on business value and behavior, not technical details
- Use consistent language and terminology
- Include both positive and negative test cases
The application demonstrates BDD implementation for:
- Search Functionality: Name, nickname, email, mobile, ABN matching
- Data Normalization: Mobile number format handling
- Partial Matching: Case-insensitive substring searches
- Suggestions: Dropdown with 3+ character threshold
- Result Limiting: Maximum 10 suggestions displayed
- Error Handling: No results messaging
- Duplicate Prevention: PayID uniqueness validation
# Run all tests with console output
npm run test:cucumber
# Generate detailed HTML report
npm run test:cucumber:report
# View report
open reports/cucumber-report.html
- Write Feature: Define behavior in Gherkin scenarios
- Generate Steps: Run with
--dry-run
to get missing step definitions - Implement Steps: Add step definition functions with TODO comments
- Build Feature: Implement actual application code using TDD
- Verify: Run tests and generate reports
- Refactor: Improve code while maintaining green tests
- Implement Playwright integration for UI automation
- Add Page Object Model for step definitions
- Set up CI/CD pipeline with test reporting
- Add visual regression testing
- Implement API mocking strategies
This project serves as a complete reference for implementing BDD with CucumberJS in React applications. The setup handles the common pitfalls and provides a solid foundation for behavior-driven development.