towerops/e2e/tests/auth.setup.ts
Graham McIntire 17bf1f83e8
feat: add Playwright e2e test suite
- Set up Playwright in dedicated e2e directory
- Multi-environment support (local, staging)
- TOTP authentication handling with otplib
- Test coverage for organizations, devices, alerts, status indicators
- Helper utilities for common test operations
- Comprehensive README with setup and usage instructions
- Setup script for quick initialization
2026-03-06 15:02:56 -06:00

64 lines
2 KiB
TypeScript

import { test as setup, expect } from '@playwright/test';
import { authenticator } from 'otplib';
const authFile = 'tests/.auth/user.json';
/**
* Authentication setup
*
* This runs before all other tests to authenticate once and save the session state.
* Other tests will reuse this authentication state instead of logging in each time.
*
* Setup:
* 1. Create a test user in your database
* 2. Enable TOTP for that user
* 3. Set TEST_USER_EMAIL, TEST_USER_PASSWORD, and TEST_USER_TOTP_SECRET in .env
*/
setup('authenticate', async ({ page }) => {
const email = process.env.TEST_USER_EMAIL || 'test@example.com';
const password = process.env.TEST_USER_PASSWORD || 'password';
const totpSecret = process.env.TEST_USER_TOTP_SECRET;
if (!totpSecret) {
throw new Error(
'TEST_USER_TOTP_SECRET is not set. ' +
'Create a test user with TOTP enabled and set the secret in .env'
);
}
console.log(`Authenticating as ${email}...`);
// Navigate to login page
await page.goto('/users/log_in');
// Fill in email and password
await page.getByLabel('Email').fill(email);
await page.getByLabel('Password').fill(password);
// Submit login form
await page.getByRole('button', { name: 'Sign in' }).click();
// Wait for TOTP page
await page.waitForURL('**/users/log_in/totp');
// Generate TOTP code
const token = authenticator.generate(totpSecret);
console.log(`Generated TOTP token: ${token}`);
// Fill in TOTP code
await page.getByLabel(/authentication code|totp|code/i).fill(token);
// Submit TOTP form
await page.getByRole('button', { name: /verify|submit|continue/i }).click();
// Wait for redirect to dashboard/home
await page.waitForURL('**/orgs');
// Verify we're logged in by checking for user menu or organization elements
await expect(page.getByRole('link', { name: /organizations|dashboard/i })).toBeVisible();
console.log('Authentication successful!');
// Save authenticated state
await page.context().storageState({ path: authFile });
});