Add frontend testing - Playwright
This commit is contained in:
339
frontend/tests/README.md
Normal file
339
frontend/tests/README.md
Normal file
@@ -0,0 +1,339 @@
|
||||
# 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
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
### Run specific test file
|
||||
```bash
|
||||
npx playwright test tests/auth/login.spec.ts
|
||||
```
|
||||
|
||||
### Run tests matching a pattern
|
||||
```bash
|
||||
npx playwright test --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
|
||||
- Increase timeout in `playwright.config.ts`
|
||||
- Check network speed
|
||||
|
||||
### Authentication fails
|
||||
- Verify test credentials are correct
|
||||
- Check if test user exists in database
|
||||
- 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)
|
||||
|
||||
## 📚 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