Files
bakery-ia/frontend/tests
2025-11-15 21:21:06 +01:00
..
2025-11-15 21:21:06 +01:00
2025-11-15 21:21:06 +01:00
2025-11-15 21:21:06 +01:00
2025-11-15 21:21:06 +01:00
2025-11-15 21:21:06 +01:00
2025-11-14 07:46:29 +01:00
2025-11-15 21:21:06 +01:00
2025-11-15 21:21:06 +01:00

Playwright E2E Testing Guide for Bakery-IA

This directory contains end-to-end (E2E) tests for the Bakery-IA SaaS application using Playwright.

📁 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:

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)

npm run test:e2e

Run tests with UI (interactive mode)

npm run test:e2e:ui

Run tests in headed mode (see browser)

npm run test:e2e:headed

Run tests in debug mode (step through tests)

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)

npm run test:e2e:k8s

Run tests with UI (interactive mode)

npm run test:e2e:k8s:ui

Run tests in headed mode (see browser)

npm run test:e2e:k8s:headed

Run tests in debug mode

npm run test:e2e:k8s:debug

Record tests against K8s environment

npm run test:e2e:k8s:codegen

Custom base URL

If your K8s ingress uses a different URL (e.g., bakery-ia.local):

PLAYWRIGHT_BASE_URL=http://bakery-ia.local npm run test:e2e:k8s

General Test Commands

Run specific test file

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

npx playwright test --grep "login"
# Or against K8s:
npx playwright test --config=playwright.k8s.config.ts --grep "login"

View test report

npm run test:e2e:report

🎬 Recording Tests (Codegen)

Playwright has a built-in test generator that records your actions:

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):

export TEST_USER_EMAIL="test@bakery.com"
export TEST_USER_PASSWORD="test-password-123"

Creating authenticated tests

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

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

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

    // ✅ Good
    page.getByRole('button', { name: 'Submit' })
    page.getByLabel('Email')
    
    // ❌ Avoid
    page.locator('.btn-primary')
    page.locator('#email-input')
    
  2. Wait for elements properly

    // ✅ Good - Auto-waits
    await page.getByText('Hello').click();
    
    // ❌ Avoid - Manual waits
    await page.waitForTimeout(3000);
    
  3. Use data-testid for complex elements

    // In your component
    <div data-testid="product-card">...</div>
    
    // In your test
    await page.getByTestId('product-card').click();
    
  4. Reuse authentication

    // ✅ 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

npm run test:e2e:debug

2. Use console.log

test('debug test', async ({ page }) => {
  console.log('Current URL:', page.url());
});

3. Take screenshots

await page.screenshot({ path: 'screenshot.png' });

4. View trace

When tests fail, check the trace viewer:

npx playwright show-trace test-results/trace.zip

🎨 Test Reports

After running tests, view the HTML report:

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:

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

# 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)

# 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

🤝 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! 🎭