Initial commit - production deployment
This commit is contained in:
429
frontend/tests/README.md
Normal file
429
frontend/tests/README.md
Normal file
@@ -0,0 +1,429 @@
|
||||
# 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
|
||||
<div data-testid="product-card">...</div>
|
||||
|
||||
// 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! 🎭
|
||||
Reference in New Issue
Block a user