Renamed, reformatted and expanded project readmes in anticipation of project handover.

This commit is contained in:
LosEvons
2025-12-01 00:44:14 +00:00
parent 7e90658e12
commit be312ba140
11 changed files with 955 additions and 203 deletions
+152 -20
View File
@@ -1,14 +1,35 @@
# End-to-End Testing with Playwright
## Setup
_Last Updated: November 30, 2025_
This directory contains E2E tests using [Playwright](https://playwright.dev/) to test the application in real browsers.
## Prerequisites
- **Node.js**: v20+ (included in dev container)
- **Environment**: Run commands inside the dev container at `/host/gradesa`
- **Database**: Tests run against the test database (configured via `.env.test`)
## Initial Setup
Playwright is already configured in this project. If setting up from scratch:
```
npm install --save-dev @playwright/test
npx playwright install
```
## Quick E2E checklist
- Ensure the app is running (dev server at `http://localhost:3000`).
- Ensure the test database is migrated/available (`npm run db:migrate` with `.env.test` set if needed).
- Install Playwright browsers: `npx playwright install`.
- Run tests: `npm run test:e2e` (or `npx playwright test <file>`).
## Commands
Run these commands from `/host/gradesa` inside the container:
```bash
npm run test:e2e # Run all tests
npm run test:e2e:ui # Run with UI mode
@@ -16,18 +37,75 @@ npm run test:e2e:debug # Run in debug mode
npx playwright test [file] # Run specific test file
```
## Test Structure
## CI/CD Integration
Playwright tests run automatically in the GitHub Actions pipeline:
- Triggered on pull requests to `master`
- Tests run in headless mode
- Screenshots and videos captured on failure
- Test results available in GitHub Actions artifacts
## Writing New Tests
### File Naming
Follow the existing pattern: `feature-name.spec.js`
### Test Structure
```javascript
import { test, expect } from "@playwright/test";
test.describe("Feature Name", () => {
test.beforeEach(async ({ page }) => {
// Setup: navigate to page, login if needed
await page.goto("/your-route");
});
test("should do something specific", async ({ page }) => {
// Arrange: Set up test data
// Act: Perform user actions
// Assert: Verify results
await expect(page.locator("selector")).toBeVisible();
});
});
```
### Naming Conventions
- Use descriptive test names: `should display error message when form is invalid`
- Group related tests in `test.describe` blocks
- Use `test.beforeEach` for common setup
### Finding Elements
Prefer semantic selectors (in order of preference):
1. `getByRole()` - Most robust, uses accessibility roles
2. `getByLabel()` - For form fields
3. `getByText()` - For unique text content
4. `getByTestId()` - Last resort, requires adding `data-testid`
## Test Files Structure
Current test files in this directory:
- `homepage.spec.js` - Home page tests
- `navigation.spec.js` - Navigation tests
- `auth.spec.js` - Authentication tests
- `components.spec.js` - Component interaction tests
- `forms.spec.js` - Form tests
- `grammar.spec.js` - Grammar feature tests
- `page-analyzer.spec.js` - Page analysis utilities
- `advanced.spec.js` - Advanced interaction examples
- `utils/helpers.js` - Helper functions
## Key Findings
## Developer Notes
The following sections contain observations and findings from E2E test development. These are helpful for understanding the application structure and writing effective tests.
### Key Findings
1. **Navigation** - `page.goto()` is more reliable than clicking links
2. **Selectors** - `getByRole()` is more reliable than `locator()` with CSS selectors
@@ -39,30 +117,84 @@ npx playwright test [file] # Run specific test file
- Resources: Chapter navigation and content
- No hamburger menu or mobile-specific UI elements
### Screenshots
Playwright automatically captures screenshots on test failures. These are saved in:
- `test-results/` directory (gitignored)
- Available as artifacts in CI/CD runs
To manually capture screenshots during development:
```javascript
await page.screenshot({ path: "debug-screenshot.png" });
```
## Best Practices
1. Use `page-analyzer.spec.js` to understand page structure
2. Review screenshots in `screenshots/` to understand the UI
3. Use role-based selectors: `getByRole('link', { name: 'Kapitel 1' })`
4. For navigation, use direct `page.goto()` rather than clicking links
5. Add appropriate assertions to verify page content
1. **Understand page structure first**: Use `page-analyzer.spec.js` to explore pages
2. **Review screenshots**: Check `test-results/` and `screenshots/` to understand the UI
3. **Use semantic selectors**: Prefer `getByRole('link', { name: 'Kapitel 1' })`
4. **Direct navigation**: Use `page.goto()` for navigation rather than clicking links when appropriate
5. **Wait for stability**: Use `waitForLoadState('networkidle')` after navigation
6. **Isolate tests**: Each test should be independent and not rely on others
7. **Clean up**: Reset state after tests (e.g., delete created data)
## Common Issues
## Common Issues & Debugging
- **Element not found**: Use more robust selectors
- **Strict mode violations**: Use more specific selectors when multiple elements match
- **Navigation timeouts**: Use direct navigation
- **Timing issues**: Use `waitForLoadState('networkidle')`
### Element Not Found
## Next Steps
- **Solution**: Use more robust selectors (role-based)
- **Debug**: Use `await page.pause()` to inspect the page
- **Debug**: Print available elements: `console.log(await page.content())`
1. Form submission tests after analyzing form behavior
2. Content interaction tests
3. User journey tests
### Strict Mode Violations
- **Error**: "locator resolved to multiple elements"
- **Solution**: Make selector more specific or use `.first()`, `.last()`, `.nth()`
### Navigation Timeouts
- **Solution**: Use direct navigation with `page.goto()`
- **Solution**: Increase timeout: `await page.goto(url, { timeout: 60000 })`
### Timing Issues
- **Solution**: Use Playwright's auto-waiting (preferred)
- **Solution**: Explicit waits: `await page.waitForSelector('selector')`
- **Avoid**: `page.waitForTimeout()` - this is an anti-pattern
### Debugging Tips
```javascript
// Pause test execution
await page.pause();
// Take screenshot at specific point
await page.screenshot({ path: "debug.png" });
// Print page HTML
console.log(await page.content());
// Check what's visible
const visible = await page.locator("selector").isVisible();
console.log("Element visible:", visible);
```
## Further Development
Planned improvements:
1. Form submission tests with various input scenarios
2. Content interaction tests (exercise completion flows)
3. User journey tests (end-to-end user scenarios)
4. Visual regression tests
5. Accessibility tests using Playwright's accessibility testing
## Resources
- [Playwright Documentation](https://playwright.dev/docs/intro)
- [API Reference](https://playwright.dev/docs/api/class-playwright)
- [Best Practices](https://playwright.dev/docs/best-practices)
- [Playwright Documentation](https://playwright.dev/docs/intro) - Getting started guide
- [Playwright API Reference](https://playwright.dev/docs/api/class-playwright) - Complete API docs
- [Playwright Best Practices](https://playwright.dev/docs/best-practices) - Official best practices
- [Playwright Test Generator](https://playwright.dev/docs/codegen) - Generate tests by recording actions
- [Debugging Tests](https://playwright.dev/docs/debug) - Debugging guide