Authentication Tests Guide
Complete guide for running and maintaining authentication E2E tests for the Momentum platform.
Quick Start
Prerequisites
- Test users must exist in AWS Cognito:
- Admin user:
admin@momentum.test - Regular user:
user@momentum.test - See TEST_CREDENTIALS.md for setup instructions
- Admin user:
- Local development server must be running:
npm run dev - Playwright must be installed:
npx playwright install
Running Tests
# Run all authentication tests
npm run test:e2e:auth
# Run admin authentication tests only
npm run test:e2e:auth:admin
# Run user authentication tests only
npm run test:e2e:auth:user
# Run admin panel tests only
npm run test:e2e:auth:panel
# Run all E2E tests
npm run test:e2e
# Run in UI mode (recommended for development)
npm run test:e2e:ui
# Run in headed mode (see browser)
npm run test:e2e:headed
# Run in debug mode
npm run test:e2e:debug
Test Files
1. Admin Authentication (tests/e2e/auth-admin.spec.ts)
Tests admin user authentication flows:
Coverage:
- Sign-in page display
- Successful admin login
- Redirect to admin panel
- Sign out functionality
- Error handling (invalid credentials)
- Form validation
- Loading states
- Session persistence
- Remember me functionality
Key Test Cases:
✅ Display sign-in page correctly
✅ Successfully sign in as admin user
✅ Redirect admin to admin panel after login
✅ Display admin panel cards
✅ Successfully sign out admin user
✅ Show error for invalid email/password
✅ Maintain session after page reload
✅ Prevent unauthorized access
2. User Authentication (tests/e2e/auth-user.spec.ts)
Tests regular user authentication flows:
Coverage:
- Successful user login
- Redirect to user dashboard
- Sign out functionality
- Admin panel access prevention
- Error handling
- Form validation
- Session management
- Navigation flows
Key Test Cases:
✅ Successfully sign in as regular user
✅ Redirect to dashboard (not admin panel)
✅ Successfully sign out
✅ NOT show admin panel link
✅ NOT allow access to admin panel
✅ Show error for invalid credentials
✅ Maintain session after reload
✅ Prevent unauthorized access
3. Admin Panel Access (tests/e2e/admin-panel.spec.ts)
Tests admin panel authorization and functionality:
Coverage:
- Admin panel access control
- UI component rendering
- Navigation between admin sections
- Role-based access control
- Unauthorized access prevention
- Session management
- Branding consistency
Key Test Cases:
✅ Display admin panel for admin user
✅ Show admin badge/indicator
✅ Display all admin panel cards
✅ Display system health
✅ Redirect non-admin users
✅ Navigate to all admin sections
✅ Maintain session across navigation
Test Helpers
Reusable helper functions in tests/e2e/helpers/auth.helper.ts:
Authentication Functions
// Complete sign-in flow
await signIn(page, 'admin'); // or 'user'
// Sign in with custom credentials
await signInWithCredentials(page, 'email@test.com', 'Password123!');
// Sign out
await signOut(page);
// Clear authentication state
await clearAuthState(page);
Navigation Functions
// Navigate to sign-in page
await navigateToSignIn(page);
// Attempt direct admin access
await attemptDirectAdminAccess(page);
Verification Functions
// Verify user is signed in
await verifySignedIn(page, 'User Name');
// Verify user is signed out
await verifySignedOut(page);
// Verify dashboard
await verifyDashboard(page, user);
// Verify error message
await verifyErrorMessage(page, /error text/i);
// Verify admin panel link visibility
await verifyAdminPanelLinkVisible(page);
await verifyAdminPanelLinkNotVisible(page);
Writing New Tests
1. Import Required Utilities
import { test, expect } from '@playwright/test';
import {
signIn,
signOut,
clearAuthState,
} from './helpers/auth.helper';
import { TEST_USERS } from './fixtures/test-users';
2. Set Up Test Suite
test.describe('My Auth Test Suite', () => {
test.beforeEach(async ({ page }) => {
// Clear auth state before each test
await clearAuthState(page);
});
test('should do something', async ({ page }) => {
// Your test code
});
});
3. Use Type-Safe Test Users
// ✅ Type-safe
await signIn(page, 'admin'); // IntelliSense: 'admin' | 'user'
// ❌ Don't hardcode credentials
await page.fill('[name="email"]', 'admin@momentum.test');
4. Use Helper Functions
// ✅ Use helpers
await signIn(page, 'admin');
await verifySignedIn(page, TEST_USERS.admin.name);
// ❌ Don't repeat implementation
await page.goto('/auth/signin');
await page.fill('[name="email"]', 'admin@momentum.test');
await page.fill('[name="password"]', 'AdminTest123!');
await page.click('button[type="submit"]');
5. Add Proper Assertions
// ✅ Explicit assertions
await expect(page).toHaveURL('/admin');
await expect(page.getByRole('heading', { name: /Admin Panel/i })).toBeVisible();
// ❌ No assertions
await page.waitForURL('/admin'); // This doesn't assert, only waits
Best Practices
1. Test Isolation
Each test should be independent and not rely on other tests:
test.beforeEach(async ({ page }) => {
await clearAuthState(page); // Start fresh
});
2. Use Descriptive Test Names
// ✅ Clear and descriptive
test('should successfully sign in as admin user', async ({ page }) => {});
// ❌ Vague
test('test admin login', async ({ page }) => {});
3. Wait for Elements Properly
// ✅ Wait for visibility
await expect(page.getByRole('heading', { name: /Admin Panel/i })).toBeVisible();
// ❌ Don't use arbitrary timeouts
await page.waitForTimeout(5000); // Flaky!
4. Use Semantic Selectors
// ✅ Semantic selectors
await page.getByRole('button', { name: /Sign in/i });
await page.getByLabel(/Email address/i);
// ❌ Fragile selectors
await page.click('.btn-primary'); // Breaks if CSS changes
5. Test Error Cases
test('should show error for invalid password', async ({ page }) => {
await signInWithCredentials(page, 'admin@momentum.test', 'WrongPassword');
await verifyErrorMessage(page, /Incorrect username or password/i);
});
Debugging Failed Tests
1. Run in UI Mode
npm run test:e2e:ui
- Interactive debugging
- Step through tests
- See page visually
- Time-travel through test steps
2. Run in Headed Mode
npm run test:e2e:headed
- See browser window during test
- Watch test execution in real-time
3. Run in Debug Mode
npm run test:e2e:debug
- Pause on breakpoints
- Inspect page state
- Debug with DevTools
4. View Test Report
npm run test:e2e:report
- See detailed test results
- View screenshots and videos
- Analyze failure traces
5. Check Screenshots/Videos
Failed tests automatically capture:
- Screenshots:
test-results/**/test-failed-*.png - Videos:
test-results/**/video.webm - Traces:
test-results/**/trace.zip
6. View Trace
npx playwright show-trace test-results/path-to-trace.zip
Common Issues & Solutions
Issue: “User not found” Errors
Cause: Test users don’t exist in AWS Cognito
Solution:
- Check TEST_CREDENTIALS.md for user setup
- Verify users exist:
source .env.infrastructure aws cognito-idp admin-get-user \ --user-pool-id $COGNITO_USER_POOL_ID \ --username admin@momentum.test \ --region us-east-1 - Create users if missing (see TEST_CREDENTIALS.md)
Issue: Timeouts During Sign-In
Cause: Slow network or server not running
Solution:
- Ensure local dev server is running:
npm run dev - Check network connectivity
- Increase timeout in test if needed:
await page.waitForURL('/admin', { timeout: 10000 });
Issue: “Sign out button not found”
Cause: Page not fully loaded or element selector incorrect
Solution:
- Wait for page load:
await page.waitForLoadState('networkidle'); - Use flexible selectors:
const signOutButton = page.getByRole('button', { name: /sign out/i }) .or(page.getByText(/sign out/i));
Issue: Session Not Persisting
Cause: Cookies not being stored
Solution:
- Ensure
clearAuthState()is only called inbeforeEach, not during test - Check browser context settings in
playwright.config.ts - Verify cookies are being set by inspecting in headed mode
Issue: Flaky Tests
Cause: Race conditions or timing issues
Solution:
- Use proper wait strategies:
await expect(element).toBeVisible(); // Auto-retries - Avoid
waitForTimeout:// ❌ Flaky await page.waitForTimeout(1000); // ✅ Reliable await page.waitForLoadState('networkidle'); - Use stable selectors (roles, labels, not CSS classes)
CI/CD Integration
GitHub Actions
Tests run automatically on:
- Pull Requests: All authentication tests must pass
- Push to Main: Full E2E suite runs
- Scheduled: Nightly regression tests
Configuration
See .github/workflows/test.yml for CI configuration.
CI Environment Variables
Ensure these are set in CI:
COGNITO_USER_POOL_IDCOGNITO_CLIENT_IDBASE_URL(for staging/production tests)
Maintenance Checklist
Weekly
- Run full E2E suite:
npm run test:e2e - Check for flaky tests
- Review test reports
Monthly
- Review test coverage
- Update test documentation
- Clean up test artifacts
On Code Changes
- Run related tests before committing
- Add tests for new auth features
- Update tests if auth flow changes
On Cognito Changes
- Update test user credentials in fixtures
- Verify tests still pass
- Update TEST_CREDENTIALS.md if needed
Performance
Target Metrics
- Individual Test: < 30 seconds
- Full Auth Suite: < 5 minutes
- All E2E Tests: < 15 minutes
Optimization Tips
- Run tests in parallel (default)
- Use
fullyParallel: truein config - Minimize navigation between pages
- Reuse auth state where possible (within same test)
- Use
beforeEachefficiently
Test Coverage Goals
Current Coverage
- ✅ Admin login/logout
- ✅ User login/logout
- ✅ Admin panel access
- ✅ Authorization checks
- ✅ Error handling
- ✅ Session management
Future Coverage
- ⏳ Password reset flow
- ⏳ Sign-up flow
- ⏳ Multi-factor authentication (MFA)
- ⏳ Social auth (Google, Facebook)
- ⏳ Token refresh
- ⏳ Concurrent sessions
Related Documentation
- E2E Tests README - Test structure overview
- TEST_CREDENTIALS.md - Test user setup
- Playwright Config - Test configuration
- Authentication Context - Auth implementation
- CLAUDE.md - Project guidelines
Support
Getting Help
- Check test logs:
npm run test:e2e:report - Review traces:
npx playwright show-trace trace.zip - See Playwright docs: https://playwright.dev
Reporting Issues
- Run test in debug mode
- Capture screenshot/video
- Include error message
- Note environment (local/CI)
- Create GitHub issue
Last Updated: 2025-11-15 Maintained By: Development Team Status: Active