# Playwright E2E Testing Guide for Bakery-IA This directory contains end-to-end (E2E) tests for the Bakery-IA SaaS application using [Playwright](https://playwright.dev). ## ๐Ÿ“ Project Structure ``` tests/ โ”œโ”€โ”€ auth/ # Authentication tests (login, register, logout) โ”œโ”€โ”€ onboarding/ # Onboarding wizard tests โ”œโ”€โ”€ dashboard/ # Dashboard and main page tests โ”œโ”€โ”€ operations/ # Business operations tests โ”œโ”€โ”€ analytics/ # Analytics page tests (to be added) โ”œโ”€โ”€ settings/ # Settings page tests (to be added) โ”œโ”€โ”€ fixtures/ # Test data files (CSV, images, etc.) โ”œโ”€โ”€ helpers/ # Utility functions and helpers โ”‚ โ”œโ”€โ”€ auth.ts # Authentication helpers โ”‚ โ””โ”€โ”€ utils.ts # General utilities โ”œโ”€โ”€ .auth/ # Stored authentication states (gitignored) โ”œโ”€โ”€ .gitignore # Files to ignore in git โ””โ”€โ”€ auth.setup.ts # Global authentication setup ``` ## ๐Ÿš€ Getting Started ### Prerequisites - Node.js 20+ - npm installed - Playwright browsers installed ### Installation Playwright is already installed in this project. If you need to reinstall browsers: ```bash npx playwright install ``` ## ๐ŸŽฏ Running Tests ### Testing Against Local Dev Server (Default) These commands test against the Vite dev server running on `localhost:5173`: #### Run all tests (headless) ```bash npm run test:e2e ``` #### Run tests with UI (interactive mode) ```bash npm run test:e2e:ui ``` #### Run tests in headed mode (see browser) ```bash npm run test:e2e:headed ``` #### Run tests in debug mode (step through tests) ```bash npm run test:e2e:debug ``` ### Testing Against Local Kubernetes/Tilt Environment These commands test against your Tilt-managed Kubernetes cluster on `localhost`: #### Prerequisites - Tilt must be running: `tilt up` - Frontend service must be accessible at `http://localhost` (via ingress) - All services should be healthy (check with `tilt status` or the Tilt UI) #### Run all tests against K8s (headless) ```bash npm run test:e2e:k8s ``` #### Run tests with UI (interactive mode) ```bash npm run test:e2e:k8s:ui ``` #### Run tests in headed mode (see browser) ```bash npm run test:e2e:k8s:headed ``` #### Run tests in debug mode ```bash npm run test:e2e:k8s:debug ``` #### Record tests against K8s environment ```bash npm run test:e2e:k8s:codegen ``` #### Custom base URL If your K8s ingress uses a different URL (e.g., `bakery-ia.local`): ```bash PLAYWRIGHT_BASE_URL=http://bakery-ia.local npm run test:e2e:k8s ``` ### General Test Commands #### Run specific test file ```bash npx playwright test tests/auth/login.spec.ts # Or against K8s: npx playwright test --config=playwright.k8s.config.ts tests/auth/login.spec.ts ``` #### Run tests matching a pattern ```bash npx playwright test --grep "login" # Or against K8s: npx playwright test --config=playwright.k8s.config.ts --grep "login" ``` #### View test report ```bash npm run test:e2e:report ``` ## ๐ŸŽฌ Recording Tests (Codegen) Playwright has a built-in test generator that records your actions: ```bash npm run test:e2e:codegen ``` This opens a browser where you can interact with your app. Playwright will generate test code for your actions. ## ๐Ÿ” Authentication Tests use a global authentication setup to avoid logging in before every test. ### How it works: 1. `auth.setup.ts` runs once before all tests 2. Logs in with test credentials 3. Saves authentication state to `tests/.auth/user.json` 4. Other tests reuse this state ### Test Credentials Set these environment variables (or use defaults): ```bash export TEST_USER_EMAIL="test@bakery.com" export TEST_USER_PASSWORD="test-password-123" ``` ### Creating authenticated tests ```typescript import { test, expect } from '@playwright/test'; test.describe('My Test Suite', () => { // Use saved auth state test.use({ storageState: 'tests/.auth/user.json' }); test('my test', async ({ page }) => { // Already logged in! await page.goto('/app/dashboard'); }); }); ``` ## ๐Ÿ“ Writing Tests ### Basic Test Structure ```typescript import { test, expect } from '@playwright/test'; test.describe('Feature Name', () => { test.beforeEach(async ({ page }) => { // Setup before each test await page.goto('/your-page'); }); test('should do something', async ({ page }) => { // Your test code await page.getByRole('button', { name: 'Click me' }).click(); await expect(page).toHaveURL('/expected-url'); }); }); ``` ### Using Helpers ```typescript import { login, logout, TEST_USER } from '../helpers/auth'; import { waitForLoadingToFinish, expectToastMessage } from '../helpers/utils'; test('my test with helpers', async ({ page }) => { await login(page, TEST_USER); await waitForLoadingToFinish(page); await expectToastMessage(page, 'Success!'); }); ``` ### Best Practices 1. **Use semantic selectors** ```typescript // โœ… Good page.getByRole('button', { name: 'Submit' }) page.getByLabel('Email') // โŒ Avoid page.locator('.btn-primary') page.locator('#email-input') ``` 2. **Wait for elements properly** ```typescript // โœ… Good - Auto-waits await page.getByText('Hello').click(); // โŒ Avoid - Manual waits await page.waitForTimeout(3000); ``` 3. **Use data-testid for complex elements** ```typescript // In your component
...
// In your test await page.getByTestId('product-card').click(); ``` 4. **Reuse authentication** ```typescript // โœ… Good - Reuse saved state test.use({ storageState: 'tests/.auth/user.json' }); // โŒ Avoid - Login in every test test.beforeEach(async ({ page }) => { await login(page); }); ``` ## ๐Ÿ” Debugging Tests ### 1. Use Playwright Inspector ```bash npm run test:e2e:debug ``` ### 2. Use console.log ```typescript test('debug test', async ({ page }) => { console.log('Current URL:', page.url()); }); ``` ### 3. Take screenshots ```typescript await page.screenshot({ path: 'screenshot.png' }); ``` ### 4. View trace When tests fail, check the trace viewer: ```bash npx playwright show-trace test-results/trace.zip ``` ## ๐ŸŽจ Test Reports After running tests, view the HTML report: ```bash npm run test:e2e:report ``` This shows: - โœ… Passed tests - โŒ Failed tests - ๐Ÿ“ธ Screenshots on failure - ๐ŸŽฅ Videos on failure - ๐Ÿ“Š Traces for debugging ## ๐ŸŒ Multi-Browser Testing Tests run on multiple browsers automatically: - Chromium (Chrome/Edge) - Firefox - WebKit (Safari) - Mobile Chrome - Mobile Safari Configure in `playwright.config.ts`. ## ๐Ÿ“ฑ Mobile Testing Tests automatically run on mobile viewports. To test specific viewport: ```typescript test('mobile test', async ({ page }) => { await page.setViewportSize({ width: 375, height: 667 }); // Your test }); ``` ## ๐Ÿ”„ CI/CD Integration Tests run automatically on GitHub Actions: - โœ… On every push to `main` or `develop` - โœ… On every pull request - โœ… Uploads test reports as artifacts - โœ… Comments on PRs with results ### GitHub Secrets Required Set these in your repository settings: - `TEST_USER_EMAIL`: Test user email - `TEST_USER_PASSWORD`: Test user password ## ๐Ÿงช Test Coverage Current test coverage: - โœ… Authentication (login, register, logout) - โœ… Onboarding wizard - โœ… Dashboard smoke tests - โœ… Purchase order management - โœ… Product/Recipe creation - ๐Ÿ”œ Analytics pages - ๐Ÿ”œ Settings pages - ๐Ÿ”œ Team management - ๐Ÿ”œ Payment flows ## ๐Ÿšจ Common Issues ### Tests fail with "timeout exceeded" - Check if dev server is running (for regular tests) - For K8s tests: Verify Tilt is running and services are healthy - Increase timeout in `playwright.config.ts` or `playwright.k8s.config.ts` - Check network speed ### Authentication fails - Verify test credentials are correct - Check if test user exists in database - For K8s tests: Ensure the database is seeded with test data - Clear `.auth/user.json` and re-run ### "Element not found" - Check if selectors match your UI - Add `await page.pause()` to inspect - Use Playwright Inspector ### Tests work locally but fail in CI - Check environment variables - Ensure database is seeded with test data - Check for timing issues (add explicit waits) ### K8s-Specific Issues #### Cannot connect to http://localhost ```bash # Check if ingress is running kubectl get ingress -n bakery-ia # Verify services are up tilt status # Check if you can access the frontend manually curl http://localhost ``` #### Ingress returns 404 or 503 - Verify all Tilt resources are healthy in the Tilt UI - Check frontend pod logs: `kubectl logs -n bakery-ia -l app=frontend` - Restart Tilt: `tilt down && tilt up` #### Tests are slower in K8s than dev server - This is expected due to ingress routing overhead - The K8s config has increased `navigationTimeout` to 30 seconds - Consider running fewer browsers in parallel for K8s tests #### Authentication state doesn't work - Test credentials must match what's seeded in K8s database - Check orchestrator logs for auth issues: `kubectl logs -n bakery-ia -l app=orchestrator` - Delete `.auth/user.json` and re-run setup #### Using custom ingress host (e.g., bakery-ia.local) ```bash # Add to /etc/hosts echo "127.0.0.1 bakery-ia.local" | sudo tee -a /etc/hosts # Run tests with custom URL PLAYWRIGHT_BASE_URL=http://bakery-ia.local npm run test:e2e:k8s ``` ## ๐Ÿ“š Resources - [Playwright Documentation](https://playwright.dev) - [Best Practices](https://playwright.dev/docs/best-practices) - [API Reference](https://playwright.dev/docs/api/class-playwright) - [Selectors Guide](https://playwright.dev/docs/selectors) ## ๐Ÿค Contributing When adding new features: 1. Write E2E tests for critical user flows 2. Use existing helpers and utilities 3. Follow the established test structure 4. Add test data to `fixtures/` if needed 5. Update this README if adding new patterns ## ๐Ÿ’ก Tips - Use `test.only()` to run a single test during development - Use `test.skip()` to temporarily disable a test - Group related tests with `test.describe()` - Use `test.beforeEach()` for common setup - Keep tests independent and isolated - Name tests descriptively: "should [action] when [condition]" --- Happy Testing! ๐ŸŽญ