feature/gherkin-e2e-tests #26
@@ -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