test(e2e): fix dev-system test suite — storageState + strict-mode + signout
Fixes 8 failures from the first test run: 1. Rate limiter exhaustion (5/8 failures) Admin was logged in 9× across the suite, hitting the 5/15min auth limit. Fix: global-setup.ts logs in once per role and saves storage state; all non-login tests use storageState so they skip the form. Total admin logins per suite run: 3 (global setup + 2 explicit tests). 2. Strict-mode violations (2/8 failures) toBeVisible() matched 3 email cells / 2 permission-error nodes. Fix: .first() on both locators. 3. Auth.js v5 signout confirmation page (1/8 failures) GET /auth/signout renders a confirm form rather than immediately redirecting. Fix: signOut() helper clicks the submit button. Note: running the suite right after a previous run may fail if the in-memory rate limit hasn't reset (15-min window). Restart the dev server, or add E2E_TEST_MODE=true to apps/web/.env.local to bypass. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Playwright global setup for dev-system tests.
|
||||
*
|
||||
* Logs in once per user role and saves browser storage state to disk.
|
||||
* Tests that don't need to exercise the login flow itself can use these
|
||||
* cached states via `test.use({ storageState: '...' })` to avoid
|
||||
* hitting the auth rate limiter (5 attempts / 15 min / email).
|
||||
*/
|
||||
import { chromium, type FullConfig } from "@playwright/test";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
const USERS = {
|
||||
admin: { email: "admin@planarchy.dev", password: "admin123" },
|
||||
manager: { email: "manager@planarchy.dev", password: "manager123" },
|
||||
viewer: { email: "viewer@planarchy.dev", password: "viewer123" },
|
||||
} as const;
|
||||
|
||||
async function globalSetup(config: FullConfig) {
|
||||
const baseURL = config.projects[0]?.use?.baseURL ?? "http://localhost:3100";
|
||||
const authDir = path.join(__dirname, ".auth");
|
||||
fs.mkdirSync(authDir, { recursive: true });
|
||||
|
||||
const browser = await chromium.launch();
|
||||
|
||||
for (const [role, creds] of Object.entries(USERS)) {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
await page.goto(`${baseURL}/auth/signin`);
|
||||
await page.fill('input[type="email"]', creds.email);
|
||||
await page.fill('input[type="password"]', creds.password);
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Wait for successful redirect
|
||||
await page.waitForURL(/\/(dashboard|resources)/, { timeout: 15000 });
|
||||
|
||||
await context.storageState({ path: path.join(authDir, `${role}.json`) });
|
||||
await context.close();
|
||||
console.log(`[global-setup] Saved auth state for ${role}`);
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
export default globalSetup;
|
||||
Reference in New Issue
Block a user