- 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
64 lines
2 KiB
TypeScript
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 });
|
|
});
|