Playwright E2E Testing Application - Planning Document¶
1. Executive Summary & Feature Overview¶
1.1 Feature Description¶
- Feature Name: Playwright E2E Testing Application for Checkout Process
- Feature Type: New Feature / Testing Infrastructure
- Priority Level: High
1.2 Problem Statement¶
- Current State: The checkout process currently has minimal automated testing coverage. The recent PIQUE-573 bug (race condition in ticket purchases) demonstrates the need for comprehensive end-to-end testing to catch integration issues before production.
- Pain Points:
- Manual testing is time-consuming and error-prone
- Race conditions and edge cases in checkout flow aren't caught early
- No systematic regression testing for the critical checkout path
- Integration between frontend (Next.js), API (Django), and payment system (Stripe) lacks automated validation
- User Impact: Customers and event producers affected by checkout bugs, oversold tickets, failed payments, and poor user experience
- Business Value:
- Prevent revenue loss from checkout failures
- Reduce customer support burden
- Increase confidence in deployments
- Enable faster feature development with safety net
1.3 Expected Outcomes¶
- Success Metrics:
- 90%+ coverage of checkout user journeys
- Test execution time < 5 minutes for full suite
- Zero false positives in CI/CD pipeline
- Catch race conditions and concurrency issues
- User Experience Goals:
- Seamless checkout experience validated across browsers
- Mobile responsiveness verified
- Accessibility compliance tested
- Technical Goals:
- Isolated test environment with fixture data
- Parallel test execution
- Visual regression testing for checkout UI
- Integration with CI/CD pipeline
2. Stakeholder Analysis & Requirements¶
2.1 Affected Users & Systems¶
- Primary Users: Development team, QA engineers
- Secondary Users: DevOps team, Product managers
- System Components:
- Frontend (apps/frontend) - Next.js 15 customer website
- API (apps/api) - Django REST Framework backend
- PostgreSQL database
- Redis cache
- Stripe payment integration
- Integration Points:
- Stripe Checkout Sessions
- Email delivery system (AWS SES)
- PDF ticket generation (Celery tasks)
2.2 Functional Requirements¶
Must-Have Features: - Complete checkout flow testing (ticket selection → payment → confirmation) - Race condition testing for concurrent ticket purchases - Promo code validation testing - Form validation testing (email, phone, name fields) - reCAPTCHA handling in tests - Stripe payment mock/test mode integration - Database state verification after purchase - Email delivery verification - Cross-browser testing (Chromium, Firefox, WebKit)
Should-Have Features: - Visual regression testing for checkout UI - Accessibility testing (WCAG compliance) - Performance testing (page load times, API response times) - Mobile viewport testing - Test data factories for different scenarios
Could-Have Features: - Integration with Jira for automated bug reporting - Video recording of failed tests - Test result analytics dashboard - Load testing capabilities
Won't-Have Features: - Unit test replacement (keep existing unit tests) - Full application E2E beyond checkout - Performance benchmarking tools
2.3 Non-Functional Requirements¶
Performance: - Test suite execution < 5 minutes - Test startup time < 30 seconds - Parallel execution with 4+ workers
Security: - Use Stripe test mode exclusively - No production credentials in test code - Isolated test database - Secure test data cleanup
Accessibility: - WCAG 2.1 AA compliance verification - Screen reader compatibility testing - Keyboard navigation testing
Browser/Platform Support: - Chromium (Desktop) - Firefox (Desktop) - WebKit/Safari (Desktop) - Mobile Chrome (Pixel 5) - Mobile Safari (iPhone 13)
Reliability: - Automatic retry on flaky tests (max 2 retries) - Test isolation (no cross-test dependencies) - Deterministic test data - Cleanup after each test
3. Current State Analysis¶
3.1 Codebase Research Methodology¶
Tools Used: Serena symbolic search, file pattern matching, code review
3.2 Existing Architecture & Patterns¶
Tech Stack: - Frontend: Next.js 15.3.1, React 19, TypeScript 5, Tailwind CSS 4 - Backend: Django 5.1, DRF 3.15, PostgreSQL 15, Redis, Celery 5.4 - Payments: Stripe SDK with Checkout Sessions - Testing: Jest (producer app), Vitest (checkin app), Django TestCase (backend)
Architecture Pattern: - Microservices with separate frontend/backend - Service-oriented architecture in Django - RESTful API design - Event-driven async processing (Celery)
Checkout Flow:
1. User selects tickets on show page (apps/frontend/src/components/Forms/tickets.tsx)
2. Form submission calls checkout() function (apps/frontend/src/lib/api.ts:203-263)
3. API creates Stripe Checkout Session (apps/api/tickets/views/order_views.py)
4. User redirected to Stripe for payment
5. Webhook confirms payment and creates order
6. User redirected to success page with ticket details
7. Celery task sends email with PDF ticket
3.3 Relevant Existing Code¶
Similar Features:
- Producer portal has Jest tests with Zod validation (apps/producer/src/features/shows/components/__tests__/show-form-validation.test.ts)
- Django admin has Django TestCase tests
Reusable Components:
- Form components with validation
- API client utilities
- Test fixtures in */fixtures/*.json
Integration Points:
- Checkout API: /api/v1/checkout/ (GET request with query params)
- Order creation: Django view with Redis locking
- Stripe integration: Checkout Sessions API
- Email system: Celery tasks with AWS SES
3.4 Current Dependencies¶
Core Dependencies: - Node.js 18+ for Playwright - Docker & Docker Compose for services - PostgreSQL 15 - Redis latest - Python 3.12 for backend
Development Dependencies: - TypeScript 5 - None currently for E2E testing (will add Playwright)
Infrastructure Dependencies:
- Docker network piquetickets
- Database service piquetickets-db.local
- API service piquetickets-api.local
- Redis service piquetickets-redis.local
3.5 Potential Conflicts & Constraints¶
Technical Debt: - No existing E2E test infrastructure - Frontend apps run outside Docker currently (manual npm run dev) - Need test database isolation strategy
Legacy Code: - Checkout form uses client-side state management only - No test IDs on critical elements (will need to add)
Resource Constraints: - Tests must not interfere with development database - CI/CD pipeline resource limits - Stripe test mode rate limits
Compliance Requirements: - PCI DSS compliance (use Stripe Elements, no card data storage) - GDPR compliance (test data cleanup)
4. Research & Best Practices¶
4.1 Industry Standards Research¶
Research Sources: Playwright documentation, Context7 library docs
Industry Best Practices: - Page Object Model (POM) for maintainable tests - Data-testid attributes for reliable selectors - Test isolation with beforeEach/afterEach hooks - Parallel execution for speed - Visual regression with screenshots - Accessibility testing with built-in tools
Framework-Specific Patterns:
- Playwright Test fixtures for setup/teardown
- Auto-waiting for elements (no manual sleeps)
- Network mocking with page.route()
- Trace viewer for debugging
- Codegen for rapid test creation
Security Guidelines: - Use environment variables for sensitive data - Never commit credentials - Use Stripe test mode tokens - Cleanup test data after execution
Performance Benchmarks: - Playwright is 30% faster than Selenium - Parallel execution reduces suite time by 70% - Auto-waiting eliminates flaky timeouts
4.2 Framework/Library Research¶
Official Documentation: - Playwright Test API: https://playwright.dev/docs/api/class-test - TypeScript configuration: https://playwright.dev/docs/test-typescript - CI/CD integration: https://playwright.dev/docs/ci
Community Resources: - Best practices for Page Object Models - Stripe test integration patterns - Database fixtures management
Known Issues: - reCAPTCHA requires special handling in tests - Stripe redirects need careful navigation tracking - Email verification requires mock SMTP or API polling
4.3 Case Studies & Examples¶
Similar Implementations: - E-commerce checkout testing patterns - Payment gateway integration testing - Multi-step form testing - Race condition testing strategies
5. Solution Design¶
5.1 Proposed Architecture¶
High-Level Design:
apps/tests/ # New Playwright test app
├── playwright.config.ts # Main configuration
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
├── .env.test # Test environment variables
├── tests/
│ ├── checkout/ # Checkout test suite
│ │ ├── happy-path.spec.ts # Standard purchase flow
│ │ ├── race-condition.spec.ts # Concurrent purchases (PIQUE-573)
│ │ ├── promo-codes.spec.ts # Promo code validation
│ │ ├── form-validation.spec.ts # Input validation
│ │ ├── payment-failures.spec.ts # Error handling
│ │ └── accessibility.spec.ts # A11y compliance
│ ├── fixtures/ # Test data
│ │ ├── shows.ts # Show fixture data
│ │ ├── tickets.ts # Ticket fixture data
│ │ └── users.ts # User fixture data
│ └── support/ # Utilities
│ ├── pages/ # Page Object Models
│ │ ├── show-page.ts # Show details page
│ │ ├── checkout-form.ts # Ticket purchase form
│ │ └── success-page.ts # Order confirmation
│ ├── api/ # API helpers
│ │ ├── setup-db.ts # Database seeding
│ │ ├── stripe-helpers.ts # Stripe test utilities
│ │ └── cleanup.ts # Test data cleanup
│ └── utils/
│ ├── recaptcha-bypass.ts # reCAPTCHA handling
│ └── wait-for-email.ts # Email verification
├── reports/ # Test results
├── screenshots/ # Visual regression baselines
└── traces/ # Playwright traces
Data Model Changes: - No database schema changes required - Use existing test fixtures with enhancements - Add test-specific show/ticket data
API Design:
- No new API endpoints needed
- Use existing /checkout/ endpoint with test mode
UI/UX Design:
- Add data-testid attributes to critical checkout elements
- Maintain existing UI, only enhance for testability
Integration Strategy:
Test Suite → Docker Compose (API + DB + Redis) → Frontend Dev Server → Stripe Test Mode
↓
Playwright Browser → Navigate to show page → Fill form → Submit → Verify order
↓
API Database Check → Order created, tickets reduced
↓
Email Verification (optional) → PDF generated
5.2 Technology Decisions¶
New Dependencies:
Alternative Solutions: - Cypress - Rejected: Slower, no native multi-browser support - Puppeteer - Rejected: Lower-level API, more boilerplate - Selenium - Rejected: Slower, more flaky
Proof of Concepts Needed: - reCAPTCHA bypass strategy (test key vs. mocking) - Stripe test mode integration - Race condition testing approach - Database isolation strategy
5.3 Security Considerations¶
Threat Model: - Test data leakage to production - Exposed Stripe test keys - Race condition vulnerabilities
Authentication/Authorization: - No authentication needed for checkout flow - Producer portal tests (future) will need auth
Data Protection: - Use fake but realistic test data - Never use real email addresses - Stripe test cards only (4242 4242 4242 4242)
Security Testing: - SQL injection attempts on form inputs - XSS prevention validation - CSRF token verification - Rate limiting validation
6. Implementation Plan¶
6.1 Development Phases¶
Phase 1: Foundation (Days 1-2)
- [ ] Create apps/tests directory structure
- [ ] Initialize npm package with Playwright dependencies
- [ ] Configure playwright.config.ts with test database settings
- [ ] Set up TypeScript configuration
- [ ] Create .env.test with test environment variables
- [ ] Configure Docker Compose integration
- [ ] Create database seed script for test data
- [ ] Deliverable: Working Playwright setup that can launch browser and connect to test environment
Phase 2: Core Test Infrastructure (Days 3-5) - [ ] Implement Page Object Models (ShowPage, CheckoutForm, SuccessPage) - [ ] Create test fixtures for shows, tickets, and orders - [ ] Implement API helpers for database setup/teardown - [ ] Create reCAPTCHA bypass utility - [ ] Implement Stripe test mode helpers - [ ] Set up test data cleanup automation - [ ] Deliverable: Reusable test infrastructure with helper utilities
Phase 3: Checkout Test Suite (Days 6-10) - [ ] Write happy path test (standard ticket purchase) - [ ] Write race condition test (PIQUE-573 regression) - [ ] Write promo code validation tests - [ ] Write form validation tests (email typos, required fields) - [ ] Write payment failure handling tests - [ ] Write accessibility compliance tests - [ ] Add visual regression tests for checkout UI - [ ] Deliverable: Complete checkout test suite with 90%+ coverage
Phase 4: CI/CD Integration (Days 11-12) - [ ] Create GitHub Actions workflow for test execution - [ ] Configure test result reporting - [ ] Set up screenshot/trace artifact uploading - [ ] Add test status badges to README - [ ] Configure parallel execution in CI - [ ] Implement test result notifications (Slack) - [ ] Deliverable: Automated testing in CI/CD pipeline
Phase 5: Documentation & Handoff (Day 13) - [ ] Write comprehensive README for test app - [ ] Document Page Object Models - [ ] Create test writing guide for team - [ ] Record demo video of test execution - [ ] Add troubleshooting guide - [ ] Deliverable: Fully documented testing application ready for team use
6.2 Detailed Task Breakdown¶
| Task | Files Affected | Dependencies | Estimate |
|---|---|---|---|
| Create app structure | apps/tests/ (new directory) |
None | 2h |
| Install Playwright | apps/tests/package.json |
npm init | 1h |
| Configure Playwright | apps/tests/playwright.config.ts |
Playwright installed | 3h |
| Add test IDs to checkout form | apps/frontend/src/components/Forms/tickets.tsx |
None | 2h |
| Create Show page POM | apps/tests/tests/support/pages/show-page.ts |
Config done | 4h |
| Create CheckoutForm POM | apps/tests/tests/support/pages/checkout-form.ts |
Config done | 4h |
| Create test fixtures | apps/tests/tests/fixtures/*.ts |
None | 3h |
| Database seed script | apps/tests/tests/support/api/setup-db.ts |
API running | 4h |
| reCAPTCHA bypass | apps/tests/tests/support/utils/recaptcha-bypass.ts |
None | 2h |
| Stripe test helpers | apps/tests/tests/support/api/stripe-helpers.ts |
Stripe SDK | 3h |
| Happy path test | apps/tests/tests/checkout/happy-path.spec.ts |
All POMs | 4h |
| Race condition test | apps/tests/tests/checkout/race-condition.spec.ts |
All POMs | 6h |
| Promo code tests | apps/tests/tests/checkout/promo-codes.spec.ts |
All POMs | 3h |
| Form validation tests | apps/tests/tests/checkout/form-validation.spec.ts |
All POMs | 4h |
| Payment failure tests | apps/tests/tests/checkout/payment-failures.spec.ts |
Stripe helpers | 4h |
| Accessibility tests | apps/tests/tests/checkout/accessibility.spec.ts |
axe-core | 3h |
| CI/CD workflow | .github/workflows/e2e-tests.yml |
All tests | 4h |
| Documentation | apps/tests/README.md |
All complete | 4h |
Total Estimated Time: ~60 hours (13 days with 1 person, or 6-7 days with 2 people)
6.3 File Change Summary¶
New Files:
- apps/tests/package.json - Dependencies and scripts
- apps/tests/playwright.config.ts - Playwright configuration
- apps/tests/tsconfig.json - TypeScript configuration
- apps/tests/.env.test - Test environment variables
- apps/tests/.gitignore - Ignore test artifacts
- apps/tests/tests/checkout/*.spec.ts - 6 test files
- apps/tests/tests/fixtures/*.ts - 3 fixture files
- apps/tests/tests/support/pages/*.ts - 3 Page Object Models
- apps/tests/tests/support/api/*.ts - 3 API helper files
- apps/tests/tests/support/utils/*.ts - 2 utility files
- apps/tests/README.md - Documentation
- .github/workflows/e2e-tests.yml - CI/CD workflow
Modified Files:
- apps/frontend/src/components/Forms/tickets.tsx - Add data-testid attributes
- apps/frontend/src/app/shows/[slug]/page.tsx - Add data-testid attributes
- apps/frontend/src/app/success/[slug]/page.tsx - Add data-testid attributes
- README.md - Add E2E testing section
- docker-compose.yml - Add test database service (optional)
Deleted Files: - None
7. Testing Strategy¶
7.1 Test Coverage Plan¶
Unit Tests: (Keep existing) - Form validation logic - API helper functions - Utility functions
Integration Tests: - Full checkout flow (ticket selection → payment → confirmation) - Concurrent purchases (race condition testing) - Promo code application and validation - Form validation with various inputs - Payment failure handling - Email delivery verification - PDF ticket generation
End-to-End Tests: - Complete user journey from homepage to ticket confirmation - Multi-ticket purchases - Mobile responsive checkout - Accessibility compliance
Performance Tests: - Page load times (< 3 seconds for show page) - API response times (< 500ms for checkout endpoint) - Form submission speed - Concurrent user handling
Security Tests: - SQL injection attempts - XSS prevention - CSRF token validation - Rate limiting
7.2 Test Environment Requirements¶
Development:
- Local Docker Compose stack
- Test database (piquetickets_test)
- Stripe test mode keys
- reCAPTCHA test key
Staging: - Separate test database - Isolated Redis instance - Mock email service - Stripe test mode
Production: - Not applicable (tests don't run in production)
7.3 Acceptance Criteria¶
Definition of Done: - [ ] All functional requirements implemented - [ ] All tests pass (unit, integration, e2e) - [ ] Code review completed - [ ] Documentation updated (README, test guide) - [ ] Performance benchmarks met (< 5 min suite execution) - [ ] Security review completed (no credentials in code) - [ ] Accessibility requirements met (WCAG 2.1 AA) - [ ] CI/CD integration working - [ ] Team training completed
Specific Test Scenarios to Pass:
- Happy Path Test:
- User can select 2 tickets
- Fill out form with valid data
- Complete Stripe payment (test mode)
- Receive order confirmation
- Database shows order created and tickets reduced
-
Email sent with PDF attachment
-
Race Condition Test (PIQUE-573):
- Two concurrent users try to buy last 2 tickets
- Only one succeeds, other gets error message
- No overselling occurs
-
Database integrity maintained
-
Promo Code Test:
- Valid promo code reduces price correctly
- Invalid promo code shows error
-
Expired promo code rejected
-
Form Validation Test:
- Empty required fields show errors
- Invalid email shows typo suggestion
- Phone number formatting works
-
reCAPTCHA required
-
Payment Failure Test:
- Stripe decline card shows error
- User can retry payment
-
Failed attempts don't create orders
-
Accessibility Test:
- All form fields have labels
- Keyboard navigation works
- Screen reader announcements correct
- Color contrast meets WCAG AA
8. Risk Assessment & Mitigation¶
8.1 Technical Risks¶
| Risk | Probability | Impact | Mitigation Strategy |
|---|---|---|---|
| Flaky tests due to network timing | High | Medium | Use Playwright auto-waiting, add explicit timeouts, retry mechanism |
| Race condition tests are non-deterministic | Medium | High | Use Redis locking verification, multiple test runs, database state checks |
| reCAPTCHA blocks automated tests | High | High | Use reCAPTCHA test key, bypass in test environment, or mock implementation |
| Stripe test mode rate limiting | Low | Medium | Implement request throttling, use mock responses for bulk tests |
| Test database pollution | Medium | High | Implement strict cleanup hooks, use transaction rollback, isolated test DB |
| Docker startup time delays tests | Medium | Low | Use webServer config to wait for services, implement health checks |
| Frontend dev server not stable | Low | Medium | Add retry logic for server startup, health check endpoint |
| Email verification unreliable | Medium | Medium | Use database polling for email queue instead of SMTP, mock email service |
8.2 Resource Risks¶
Schedule Risks: - Dependency on frontend team for adding test IDs - Mitigation: Work with selectors initially, add test IDs incrementally - Learning curve for Playwright - Mitigation: Pair programming, Playwright documentation study - CI/CD pipeline configuration complexity - Mitigation: Use GitHub Actions templates, seek DevOps support
Skill Gaps: - Team unfamiliar with Playwright - Mitigation: Training session, documentation, demo video - Page Object Model pattern new to team - Mitigation: Code examples, pair programming - Async testing patterns - Mitigation: TypeScript/async training materials
External Dependencies: - Stripe test mode availability - Mitigation: Fallback to mocked responses if Stripe unavailable - Docker Desktop licensing changes - Mitigation: Alternative container runtimes documented
8.3 Rollback Strategy¶
Feature Flags: - Not applicable (testing infrastructure doesn't affect production)
Database Migrations: - No migrations needed - Test database can be dropped and recreated
Deployment Strategy: - Tests run in CI/CD before deployment - Failed tests block merge to main - Can disable test suite in CI if blocking releases (emergency only)
9. Deployment & Operations¶
9.1 Deployment Plan¶
Environment Progression: - Dev → CI → (No production deployment for tests)
Database Changes:
- Create piquetickets_test database (optional, can use temp DB)
- No schema changes needed
Configuration Updates:
# apps/tests/.env.test
PLAYWRIGHT_BASE_URL=http://localhost:3000
API_URL=http://localhost:8080
DATABASE_URL=postgresql://user:password@localhost:5432/piquetickets_test
REDIS_URL=redis://localhost:6379/1
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAA... # Test key
Monitoring Setup: - GitHub Actions test results - Playwright HTML reporter - Test execution time tracking - Failure notifications to Slack
9.2 Monitoring & Observability¶
Key Metrics: - Test suite execution time (target: < 5 minutes) - Test pass/fail rate - Flaky test frequency - Code coverage percentage - Test execution frequency (per commit, per PR)
Alerting: - Slack notification on test failures in CI - Email to team lead on repeated failures - GitHub PR comment with test results
Logging: - Playwright trace files for failed tests - Screenshot artifacts for visual debugging - Console logs captured during test execution - Network request logs
Health Checks: - Docker services health (API, DB, Redis) - Frontend dev server responsiveness - Stripe test mode connectivity
9.3 Support & Maintenance¶
Documentation:
- apps/tests/README.md - Setup and running tests
- apps/tests/docs/WRITING_TESTS.md - Test writing guide
- apps/tests/docs/PAGE_OBJECTS.md - POM documentation
- apps/tests/docs/TROUBLESHOOTING.md - Common issues and solutions
Training: - Team walkthrough session (1 hour) - Video tutorial for writing new tests - Office hours for questions
Ongoing Maintenance: - Review flaky tests weekly - Update test data fixtures monthly - Playwright version updates quarterly - Add tests for new checkout features
10. Success Measurement¶
10.1 Success Metrics¶
Technical Metrics: - Test suite execution time: < 5 minutes ✓ - Test coverage: 90%+ of checkout flows ✓ - Test flakiness rate: < 5% ✓ - CI/CD pipeline success rate: > 95% ✓ - Zero false positives: All failures are real bugs ✓
User Metrics: - Developer satisfaction: Survey after 1 month - Test adoption rate: % of new checkout features with tests - Bug catch rate: # of bugs caught by E2E tests vs. production
Business Metrics: - Reduced production checkout bugs (track over 3 months) - Faster feature velocity (measure deployment frequency) - Reduced customer support tickets related to checkout - Increased confidence in deployments
10.2 Review Schedule¶
- Week 1 Review: Initial setup complete, first test running
- Week 2 Review: All checkout tests implemented, passing in CI
- Month 1 Review: Team adoption, test stability, initial metrics
- Month 3 Review: Full success evaluation, ROI analysis
11. Appendices¶
Appendix A: Research References¶
- Playwright Official Documentation: https://playwright.dev/
- Playwright Best Practices: https://playwright.dev/docs/best-practices
- Page Object Model Pattern: https://playwright.dev/docs/pom
- Stripe Test Mode: https://stripe.com/docs/testing
- WCAG 2.1 Guidelines: https://www.w3.org/WAI/WCAG21/quickref/
- Docker Compose Best Practices: https://docs.docker.com/compose/
- GitHub Actions Playwright: https://playwright.dev/docs/ci-intro
Appendix B: Technical Diagrams¶
Checkout Flow Architecture:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Playwright │─────▶│ Next.js │─────▶│ Django API │
│ Test Suite │ │ Frontend │ │ Backend │
└─────────────┘ └──────────────┘ └─────────────┘
│ │
▼ ▼
┌──────────────┐ ┌─────────────┐
│ Stripe │ │ PostgreSQL │
│ Checkout │ │ Database │
└──────────────┘ └─────────────┘
Test Execution Flow:
1. Test starts → Start Docker services (API, DB, Redis)
2. Seed test data → Create show, tickets, promo codes
3. Launch browser → Navigate to show page
4. Fill checkout form → Select tickets, enter details
5. Submit → API creates Stripe session
6. Stripe redirect → Test mode payment
7. Return to app → Verify success page
8. Database check → Verify order created
9. Cleanup → Delete test data, stop browser
10. Report results → HTML report, screenshots
Appendix C: Code Examples¶
Example Test (Happy Path):
import { test, expect } from '@playwright/test';
import { ShowPage } from '../support/pages/show-page';
import { CheckoutForm } from '../support/pages/checkout-form';
import { SuccessPage } from '../support/pages/success-page';
import { setupTestShow } from '../fixtures/shows';
test.describe('Checkout - Happy Path', () => {
test('user can purchase tickets successfully', async ({ page }) => {
// Setup
const testShow = await setupTestShow();
// Navigate to show page
const showPage = new ShowPage(page);
await showPage.goto(testShow.slug);
// Select tickets
const checkoutForm = new CheckoutForm(page);
await checkoutForm.selectTickets('General Admission', 2);
// Fill form
await checkoutForm.fillPurchaserInfo({
firstName: 'Test',
lastName: 'User',
email: 'test@example.com',
phone: '555-1234'
});
// Submit (bypasses reCAPTCHA in test)
await checkoutForm.submit();
// Verify Stripe redirect and complete payment
await checkoutForm.completeStripePayment();
// Verify success page
const successPage = new SuccessPage(page);
await expect(successPage.confirmationMessage).toBeVisible();
await expect(successPage.orderTotal).toHaveText('$50.00');
// Verify database state
const order = await page.request.get(`/api/v1/orders/?email=test@example.com`);
expect(order.ok()).toBeTruthy();
});
});
Example Page Object Model:
// apps/tests/tests/support/pages/checkout-form.ts
export class CheckoutForm {
constructor(private page: Page) {}
async selectTickets(ticketName: string, quantity: number) {
const ticket = this.page.locator(`[data-testid="ticket-${ticketName}"]`);
const incrementBtn = ticket.locator('[data-testid="increment-btn"]');
for (let i = 0; i < quantity; i++) {
await incrementBtn.click();
}
}
async fillPurchaserInfo(info: PurchaserInfo) {
await this.page.locator('[data-testid="first-name"]').fill(info.firstName);
await this.page.locator('[data-testid="last-name"]').fill(info.lastName);
await this.page.locator('[data-testid="email"]').fill(info.email);
await this.page.locator('[data-testid="phone"]').fill(info.phone);
}
async submit() {
// In test environment, bypass reCAPTCHA
await this.page.evaluate(() => {
(window as any).grecaptcha = {
ready: (cb: any) => cb(),
execute: () => Promise.resolve('test-token')
};
});
await this.page.locator('[data-testid="checkout-submit-btn"]').click();
}
async completeStripePayment() {
// Wait for Stripe redirect
await this.page.waitForURL(/checkout\.stripe\.com/);
// Fill Stripe test card
await this.page.frameLocator('iframe').locator('[name="cardnumber"]')
.fill('4242424242424242');
await this.page.frameLocator('iframe').locator('[name="exp-date"]')
.fill('1234');
await this.page.frameLocator('iframe').locator('[name="cvc"]')
.fill('123');
await this.page.frameLocator('iframe').locator('[name="postal"]')
.fill('12345');
// Submit payment
await this.page.locator('button[type="submit"]').click();
// Wait for redirect back to app
await this.page.waitForURL(/localhost:3000\/success/);
}
}
Appendix D: Configuration Files¶
playwright.config.ts:
import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.test' });
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 2 : 4,
reporter: [
['html', { outputFolder: 'reports/html' }],
['json', { outputFile: 'reports/results.json' }],
['junit', { outputFile: 'reports/junit.xml' }],
['list']
],
timeout: 60000, // 60 seconds per test
expect: {
timeout: 10000
},
use: {
baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
actionTimeout: 15000,
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
{
name: 'mobile-chrome',
use: { ...devices['Pixel 5'] },
},
{
name: 'mobile-safari',
use: { ...devices['iPhone 13'] },
},
],
webServer: {
command: 'cd ../frontend && npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120000,
},
});
package.json:
{
"name": "@piquetickets/e2e-tests",
"version": "1.0.0",
"description": "End-to-end tests for PiqueTickets checkout flow",
"scripts": {
"test": "playwright test",
"test:headed": "playwright test --headed",
"test:debug": "playwright test --debug",
"test:ui": "playwright test --ui",
"test:chromium": "playwright test --project=chromium",
"test:firefox": "playwright test --project=firefox",
"test:webkit": "playwright test --project=webkit",
"test:mobile": "playwright test --project=mobile-chrome --project=mobile-safari",
"report": "playwright show-report reports/html",
"codegen": "playwright codegen http://localhost:3000"
},
"devDependencies": {
"@playwright/test": "^1.45.0",
"@axe-core/playwright": "^4.9.0",
"@types/node": "^20.0.0",
"dotenv": "^16.4.5",
"typescript": "^5.0.0"
}
}
tsconfig.json:
{
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./tests",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"types": ["node", "@playwright/test"]
},
"include": ["tests/**/*"],
"exclude": ["node_modules", "dist", "reports", "screenshots", "traces"]
}
.env.test (template):
# Playwright Configuration
PLAYWRIGHT_BASE_URL=http://localhost:3000
API_URL=http://localhost:8080
# Database Configuration
DATABASE_URL=postgresql://user:password@localhost:5432/piquetickets_test
REDIS_URL=redis://localhost:6379/1
# Stripe Test Mode Keys
STRIPE_PUBLISHABLE_KEY=pk_test_51...
STRIPE_SECRET_KEY=sk_test_51...
# reCAPTCHA Test Key (Google's official test key)
RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
# Email Configuration (optional)
SMTP_HOST=localhost
SMTP_PORT=1025
.gitignore:
# Playwright
node_modules/
reports/
screenshots/
traces/
test-results/
playwright-report/
playwright/.cache/
# Environment
.env.test
# TypeScript
dist/
*.tsbuildinfo
# OS
.DS_Store
Thumbs.db
Document Information: - Created: 2025-10-28 - Last Updated: 2025-10-28 - Version: 1.0 - Author(s): Claude (via PiqueTickets development team) - Status: Draft - Ready for Review
Quick Reference¶
Running Tests¶
# Navigate to test directory
cd apps/tests
# Install dependencies
npm install
# Run all tests
npm test
# Run tests in headed mode (see browser)
npm run test:headed
# Run tests in debug mode
npm run test:debug
# Run tests in UI mode (interactive)
npm run test:ui
# Run specific browser
npm run test:chromium
npm run test:firefox
npm run test:webkit
# Run mobile tests
npm run test:mobile
# View test report
npm run report
# Generate test code (codegen)
npm run codegen
Key Files to Modify¶
- Add test IDs to frontend components:
apps/frontend/src/components/Forms/tickets.tsxapps/frontend/src/app/shows/[slug]/page.tsx-
apps/frontend/src/app/success/[slug]/page.tsx -
Review existing checkout implementation:
apps/frontend/src/lib/api.ts:203-263(checkout function)-
apps/api/tickets/views/order_views.py(order creation) -
Reference existing test patterns:
apps/producer/src/features/shows/components/__tests__/show-form-validation.test.ts
Resources¶
- Playwright Docs: https://playwright.dev/
- Test Writing Guide:
apps/tests/docs/WRITING_TESTS.md(to be created) - Troubleshooting:
apps/tests/docs/TROUBLESHOOTING.md(to be created) - PIQUE-573 (Race Condition Bug): https://piquetickets.atlassian.net/browse/PIQUE-573