Generate E2e Tests
Generate E2e Tests
Creates comprehensive end-to-end tests for your application or feature, covering user journeys, integration, and edge cases.
How to use
Provide details about your app or feature in place of {{args}}, such as main flows, platforms, or critical paths to generate E2E tests.
Prompt
Generate End-to-End Tests
Please create comprehensive end-to-end tests for the following application/feature:
{{args}}
Test Framework Considerations
Choose appropriate E2E testing framework:
- Web: Playwright, Cypress, Selenium
- Mobile: Appium, Detox
- API: Supertest, REST Assured
- Desktop: TestComplete, WinAppDriver
E2E Test Structure
1. User Journey Tests
Test complete user workflows from start to finish:
test('User can complete signup and login flow', async ({ page }) => {
// Navigate to signup
await page.goto('/signup');
// Fill signup form
await page.fill('[name="email"]', 'user@example.com');
await page.fill('[name="password"]', 'SecurePass123');
await page.click('button[type="submit"]');
// Verify redirect to dashboard
await expect(page).toHaveURL('/dashboard');
// Verify welcome message
await expect(page.locator('.welcome')).toContainText('Welcome');
});2. Test Categories
Critical User Paths
- User registration and authentication
- Core business workflows
- Payment/checkout processes
- Data submission and retrieval
Cross-Browser/Platform
- Test on major browsers (Chrome, Firefox, Safari, Edge)
- Test on different devices (desktop, tablet, mobile)
- Test on different OS (Windows, macOS, Linux)
Integration Points
- Third-party service integrations
- API interactions
- Database operations
- External system communications
3. Test Patterns
Page Object Model
class LoginPage {
constructor(page) {
this.page = page;
this.emailInput = page.locator('[name="email"]');
this.passwordInput = page.locator('[name="password"]');
this.submitButton = page.locator('button[type="submit"]');
}
async login(email, password) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
test('user can login', async ({ page }) => {
const loginPage = new LoginPage(page);
await page.goto('/login');
await loginPage.login('user@example.com', 'password');
await expect(page).toHaveURL('/dashboard');
});Setup and Teardown
test.beforeEach(async ({ page }) => {
// Clear cookies and local storage
await page.context().clearCookies();
await page.evaluate(() => localStorage.clear());
// Navigate to starting point
await page.goto('/');
});
test.afterEach(async ({ page }, testInfo) => {
// Screenshot on failure
if (testInfo.status !== 'passed') {
await page.screenshot({
path: `test-results/${testInfo.title}-failure.png`
});
}
});4. Test Scenarios to Cover
Authentication & Authorization
- User registration with valid/invalid data
- Login with correct/incorrect credentials
- Logout functionality
- Password reset flow
- Session management
- Access control (authorized vs unauthorized users)
CRUD Operations
- Create new records
- Read/view records
- Update existing records
- Delete records
- List/search records
- Pagination
Forms & Validation
- Submit valid forms
- Submit invalid forms
- Field validation messages
- Required field enforcement
- Format validation (email, phone, etc.)
- File uploads
Navigation
- Menu navigation
- Breadcrumb navigation
- Back/forward browser buttons
- Deep linking
- Redirects
Search & Filters
- Search with various queries
- Apply filters
- Sort results
- Pagination of results
- Empty results handling
Error Handling
- Network errors
- Server errors (500, 503)
- Not found (404)
- Validation errors
- Timeout scenarios
5. Waiting Strategies
// Wait for element
await page.waitForSelector('.data-loaded');
// Wait for navigation
await page.waitForNavigation();
// Wait for API response
await page.waitForResponse(response =>
response.url().includes('/api/data')
);
// Wait for condition
await page.waitForFunction(() =>
document.querySelector('.loading') === null
);
// Custom timeout
await page.waitForSelector('.slow-element', { timeout: 10000 });6. Data Management
Test Data Setup
test.beforeEach(async ({ request }) => {
// Create test user via API
await request.post('/api/users', {
data: {
email: 'test@example.com',
name: 'Test User'
}
});
});Test Data Cleanup
test.afterEach(async ({ request }) => {
// Delete test data
await request.delete('/api/users/test@example.com');
});7. Assertions
// Element visibility
await expect(page.locator('.success-message')).toBeVisible();
// Text content
await expect(page.locator('h1')).toHaveText('Dashboard');
// URL
await expect(page).toHaveURL('/dashboard');
// Element count
await expect(page.locator('.item')).toHaveCount(5);
// Attribute
await expect(page.locator('button')).toHaveAttribute('disabled');
// Screenshot comparison
await expect(page).toHaveScreenshot('homepage.png');8. API Testing in E2E
test('should create user via API and verify in UI', async ({ request, page }) => {
// Create via API
const response = await request.post('/api/users', {
data: { name: 'John Doe', email: 'john@example.com' }
});
expect(response.ok()).toBeTruthy();
const user = await response.json();
// Verify in UI
await page.goto(`/users/${user.id}`);
await expect(page.locator('.user-name')).toHaveText('John Doe');
});9. Mobile/Responsive Testing
test('should work on mobile', async ({ page }) => {
// Set viewport to mobile
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/');
// Open mobile menu
await page.click('.mobile-menu-toggle');
await expect(page.locator('.mobile-menu')).toBeVisible();
});10. Performance Checks
test('page should load within 3 seconds', async ({ page }) => {
const start = Date.now();
await page.goto('/');
await page.waitForLoadState('networkidle');
const loadTime = Date.now() - start;
expect(loadTime).toBeLessThan(3000);
});Best Practices
- Stability: Use reliable selectors (data-testid preferred)
- Independence: Tests should not depend on each other
- Cleanup: Always clean up test data
- Waits: Use explicit waits, avoid arbitrary sleeps
- Retries: Configure retries for flaky tests
- Parallelization: Run tests in parallel when possible
- Screenshots: Capture screenshots on failure
- Videos: Record videos for debugging
- Logs: Capture console logs
- Reports: Generate comprehensive test reports
Output Format
Provide:
- Complete E2E test suite
- Page Object Models (if applicable)
- Setup and teardown code
- Test data factories/fixtures
- Configuration suggestions
- Clear test descriptions
- Comments for complex interactions
Generate a complete, production-ready E2E test suite following these best practices.