docs: add README for Cucumber test framework
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
# Cucumber Gherkin-Style E2E Tests
|
||||
|
||||
This directory contains Gherkin-style acceptance tests using Cucumber and Playwright for testing the EuchreCamp application.
|
||||
|
||||
## Overview
|
||||
|
||||
These tests follow the **Given-When-Then** syntax for behavior-driven development (BDD) and test the application from a user's perspective by interacting with the browser UI only.
|
||||
|
||||
## Key Principles
|
||||
|
||||
1. **Browser-only interactions**: Tests interact with the application via the browser (click, type, navigate)
|
||||
2. **No direct database access**: All data is created/modified through the UI
|
||||
3. **Dev site testing**: Tests run against a running development server
|
||||
4. **Happy path focus**: Tests verify common user workflows
|
||||
5. **Gherkin syntax**: Tests are written in plain English using Given-When-Then
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Run all Cucumber tests
|
||||
```bash
|
||||
bun run test:acceptance:cucumber
|
||||
```
|
||||
|
||||
### Run with pretty formatter (visible output)
|
||||
```bash
|
||||
bun run test:acceptance:cucumber:pretty
|
||||
```
|
||||
|
||||
### Run specific feature file
|
||||
```bash
|
||||
bun cucumber-js e2e/cucumber/features/user-registration.feature
|
||||
```
|
||||
|
||||
### Run specific scenario
|
||||
```bash
|
||||
bun cucumber-js --name "Successful registration with valid data"
|
||||
```
|
||||
|
||||
### Dry run (check for undefined steps)
|
||||
```bash
|
||||
bun cucumber-js --config e2e/cucumber/cucumber.config.ts --dry-run
|
||||
```
|
||||
|
||||
## Test Structure
|
||||
|
||||
```
|
||||
e2e/cucumber/
|
||||
├── features/ # Gherkin feature files
|
||||
│ ├── user-registration.feature
|
||||
│ └── authentication.feature
|
||||
├── step-definitions/ # Step implementations
|
||||
│ ├── common-steps.ts # Navigation, forms, assertions
|
||||
│ └── auth-steps.ts # Login, logout, registration
|
||||
├── support/ # Test infrastructure
|
||||
│ ├── world.ts # Shared test context
|
||||
│ └── hooks.ts # Before/After hooks
|
||||
├── cucumber.config.ts # Cucumber configuration
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Example Test
|
||||
|
||||
### Feature File (user-registration.feature)
|
||||
```gherkin
|
||||
Feature: User Registration
|
||||
As a new user
|
||||
I want to register for an account
|
||||
So that I can participate in Euchre tournaments
|
||||
|
||||
Background:
|
||||
Given I am on the registration page
|
||||
|
||||
Scenario: Successful registration with valid data
|
||||
When I fill in "name" with "Test User"
|
||||
And I fill in "email" with "test@example.com"
|
||||
And I fill in "password" with "TestPassword123!"
|
||||
And I click the "Create Account" button
|
||||
Then I should be redirected to my profile page
|
||||
And my user account should exist
|
||||
```
|
||||
|
||||
### Step Definition (auth-steps.ts)
|
||||
```typescript
|
||||
Given('I am logged in as a player', async function () {
|
||||
const credentials = generateTestCredentials();
|
||||
world.user = credentials;
|
||||
|
||||
await world.page.goto(`${world.baseURL}/auth/register`);
|
||||
await world.page.fill('input[name="name"]', credentials.name);
|
||||
await world.page.fill('input[name="email"]', credentials.email);
|
||||
await world.page.fill('input[name="password"]', credentials.password);
|
||||
await world.page.click('button[type="submit"]');
|
||||
await world.page.waitForURL(/\/players\/\d+\/profile/);
|
||||
});
|
||||
```
|
||||
|
||||
## Tags
|
||||
|
||||
Use tags to organize and filter tests:
|
||||
|
||||
- `@happy-path` - Tests successful user workflows
|
||||
- `@negative-test` - Tests error cases and validation
|
||||
- `@authentication` - Tests related to login/registration
|
||||
- `@wip` - Work in progress (skipped by default)
|
||||
- `@skip` - Temporarily skipped tests
|
||||
|
||||
## Configuration
|
||||
|
||||
The Cucumber configuration is in `cucumber.config.ts`:
|
||||
|
||||
- Feature files: `e2e/cucumber/features/**/*.feature`
|
||||
- Step definitions: `e2e/cucumber/step-definitions/**/*.ts`
|
||||
- TypeScript loader: tsx (for path alias support)
|
||||
- Tags: Skips `@wip` and `@skip` by default
|
||||
- Retries: 2 retries in CI environment
|
||||
|
||||
## World Context
|
||||
|
||||
The `world.ts` file provides a shared context for tests:
|
||||
|
||||
```typescript
|
||||
interface WorldState {
|
||||
page: Page; // Playwright page
|
||||
context: BrowserContext;
|
||||
baseURL: string; // Dev server URL
|
||||
user?: { // Current test user
|
||||
email: string;
|
||||
name: string;
|
||||
password: string;
|
||||
};
|
||||
tournament?: any; // Current test tournament
|
||||
player?: any; // Current test player
|
||||
}
|
||||
```
|
||||
|
||||
## Hooks
|
||||
|
||||
Hooks run before/after tests:
|
||||
|
||||
- `BeforeAll` - Launch browser once before all tests
|
||||
- `AfterAll` - Close browser and cleanup after all tests
|
||||
- `Before` - Create new page context before each scenario
|
||||
- `After` - Close page and cleanup test data after each scenario
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Unique test data**: Use timestamps to ensure unique test users
|
||||
2. **Wait for navigation**: Always wait for page loads and redirects
|
||||
3. **Clear assertions**: Verify expected state after user actions
|
||||
4. **No database access**: Use UI/API for all data creation
|
||||
5. **Tag organization**: Use tags to filter test suites
|
||||
6. **One assertion per step**: Keep steps focused and readable
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Steps showing as undefined
|
||||
Run with `--dry-run` to check step matching:
|
||||
```bash
|
||||
bun cucumber-js --dry-run
|
||||
```
|
||||
|
||||
### Database errors
|
||||
These tests don't interact with the database directly. If you see Prisma errors, check that:
|
||||
- The dev server is running
|
||||
- The database is accessible
|
||||
- Environment variables are set correctly
|
||||
|
||||
### Slow tests
|
||||
Use the `@wip` tag for tests in development and skip them during full runs.
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
In CI, the tests should:
|
||||
1. Start the dev server (if not already running)
|
||||
2. Run Cucumber tests against `http://localhost:3000`
|
||||
3. Use JUnit format for reporting:
|
||||
```bash
|
||||
bun cucumber-js --format junit --out reports/cucumber.xml
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [Cucumber.js Documentation](https://github.com/cucumber/cucumber-js)
|
||||
- [Gherkin Syntax Reference](https://cucumber.io/docs/gherkin/)
|
||||
- [Playwright Documentation](https://playwright.dev)
|
||||
Reference in New Issue
Block a user