138 lines
4.2 KiB
TypeScript
138 lines
4.2 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
/*
|
|
* Test Template for Playwright E2E Tests
|
|
*
|
|
* Copy this file and replace:
|
|
* - {{capability}} with the capability name (e.g., 'authentication')
|
|
* - {{scenario_description}} with the spec scenario description
|
|
*
|
|
* Mark pending tests with test.fixme() during Red Phase
|
|
* Remove test.fixme() and implement during Green Phase
|
|
*/
|
|
|
|
test.describe('{{capability}} Flow', () => {
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
// Setup: Navigate to base URL, login, etc.
|
|
await page.goto('/');
|
|
});
|
|
|
|
/*
|
|
* Scenario: {{scenario_description}}
|
|
*
|
|
* Spec Reference: specs/{{capability}}/spec.md
|
|
* Scenario: {{scenario_number}}
|
|
*/
|
|
test('{{scenario_description}}', async ({ page }) => {
|
|
// Arrange (GIVEN)
|
|
// Set up initial state
|
|
await page.goto('/{{route}}');
|
|
|
|
// Act (WHEN)
|
|
// Perform user actions
|
|
await page.fill('[name="email"]', 'test@example.com');
|
|
await page.fill('[name="password"]', 'password');
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Assert (THEN)
|
|
// Verify expected outcome
|
|
await expect(page).toHaveURL('/dashboard');
|
|
await expect(page.locator('[data-testid="success-message"]')).toBeVisible();
|
|
await expect(page.locator('[data-testid="user-name"]')).toContainText('Test User');
|
|
});
|
|
|
|
/*
|
|
* Example: Error scenario
|
|
*/
|
|
test('displays error when {{error_condition}}', async ({ page }) => {
|
|
// Arrange
|
|
await page.goto('/{{route}}');
|
|
|
|
// Act
|
|
await page.fill('[name="email"]', 'invalid@example.com');
|
|
await page.fill('[name="password"]', 'wrongpassword');
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Assert
|
|
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
|
|
await expect(page.locator('[data-testid="error-message"]')).toContainText('Invalid credentials');
|
|
await expect(page).toHaveURL('/{{route}}');
|
|
});
|
|
|
|
/*
|
|
* Example: Form validation
|
|
*/
|
|
test('validates required fields', async ({ page }) => {
|
|
// Arrange
|
|
await page.goto('/{{route}}');
|
|
|
|
// Act
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Assert
|
|
await expect(page.locator('[data-testid="error-email"]')).toContainText('Email is required');
|
|
await expect(page.locator('[data-testid="error-password"]')).toContainText('Password is required');
|
|
});
|
|
|
|
/*
|
|
* Example: CRUD operation
|
|
*/
|
|
test('completes full {{resource}} CRUD flow', async ({ page }) => {
|
|
// Create
|
|
await page.goto('/{{resource}}/new');
|
|
await page.fill('[name="name"]', 'Test {{resource}}');
|
|
await page.click('button[type="submit"]');
|
|
await expect(page.locator('[data-testid="success-message"]')).toBeVisible();
|
|
|
|
// Read
|
|
await page.goto('/{{resource}}');
|
|
await expect(page.locator('text=Test {{resource}}')).toBeVisible();
|
|
|
|
// Update
|
|
await page.click('[data-testid="edit-{{resource}}"]');
|
|
await page.fill('[name="name"]', 'Updated {{resource}}');
|
|
await page.click('button[type="submit"]');
|
|
await expect(page.locator('[data-testid="success-message"]')).toBeVisible();
|
|
|
|
// Delete
|
|
await page.click('[data-testid="delete-{{resource}}"]');
|
|
await page.click('[data-testid="confirm-delete"]');
|
|
await expect(page.locator('text=Updated {{resource}}')).not.toBeVisible();
|
|
});
|
|
|
|
/*
|
|
* Example: RBAC test
|
|
*/
|
|
test('restricts access based on role', async ({ page }) => {
|
|
// Login as developer (limited permissions)
|
|
await loginAs(page, 'developer');
|
|
|
|
// Try to access admin page
|
|
await page.goto('/admin/{{resource}}');
|
|
|
|
// Should be redirected or show access denied
|
|
await expect(page.locator('[data-testid="access-denied"]')).toBeVisible();
|
|
});
|
|
|
|
});
|
|
|
|
/*
|
|
* Helper functions
|
|
*/
|
|
async function loginAs(page, role: string) {
|
|
await page.goto('/login');
|
|
await page.fill('[name="email"]', `${role}@example.com`);
|
|
await page.fill('[name="password"]', 'password');
|
|
await page.click('button[type="submit"]');
|
|
await expect(page).toHaveURL('/dashboard');
|
|
}
|
|
|
|
async function create{{model}}(page, data: object) {
|
|
await page.goto('/{{resource}}/new');
|
|
for (const [key, value] of Object.entries(data)) {
|
|
await page.fill(`[name="${key}"]`, value);
|
|
}
|
|
await page.click('button[type="submit"]');
|
|
}
|