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:reportThe 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:
[email protected],[email protected] - 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 | [email protected] | Lexi | |
| Andy Bolton | 0412 784 539 | mobile | AndyB |
| Fresh Foods Pty Ltd | 80123456789 | abn | - |
| Grace Liu | [email protected] | 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-nodetests/
βββ 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
.cjsextension for step definitions - Create
tests/cucumber/package.jsonwith{"type": "commonjs"} - Use
module.exportssyntax in configuration files
Problem: Cucumber reports "0 scenarios" or undefined steps.
Solutions:
- Ensure step definition files use
.cjsextension - Verify the
requirepath incucumber.config.cjsmatches your file structure - Check that step definition files are properly exporting functions
- Use
npm run test:cucumber:dryto debug without execution
Problem: TypeScript compilation errors with step definitions.
Solution:
- Use JavaScript
.cjsfiles for step definitions instead of TypeScript - Create separate
tsconfig.jsonin test directory with CommonJS module setting - Install
@types/nodefor 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-runflag to verify file discovery
Problem: HTML reports not generating or empty.
Solution:
- Install
@cucumber/html-formatterdependency - 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-runto 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.