94 lines
3.0 KiB
TypeScript
94 lines
3.0 KiB
TypeScript
/**
|
|
* Authentication helper for cPad Control Panel tests.
|
|
*
|
|
* Usage in tests that do NOT use the pre-saved storageState:
|
|
* import { loginAsAdmin } from '../helpers/auth';
|
|
* await loginAsAdmin(page);
|
|
*
|
|
* The cpad-setup project (auth.setup.ts) calls loginAsAdmin once and persists
|
|
* the session to tests/.auth/admin.json so all other cpad tests reuse it.
|
|
*/
|
|
|
|
import { type Page, expect } from '@playwright/test';
|
|
import path from 'path';
|
|
|
|
export const ADMIN_EMAIL = 'gregor@klevze.si';
|
|
export const ADMIN_PASSWORD = 'Gre15#10gor!1976$';
|
|
export const CP_PATH = '/cp';
|
|
export const DASHBOARD_PATH = '/cp/dashboard';
|
|
export const AUTH_FILE = path.join('tests', '.auth', 'admin.json');
|
|
|
|
/**
|
|
* Perform a full cPad login and wait for the dashboard to load.
|
|
* Verifies the redirect ends up on a /cp/dashboard URL.
|
|
*/
|
|
export async function loginAsAdmin(page: Page): Promise<void> {
|
|
// Attach console-error listener so callers can detect JS exceptions
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error') {
|
|
console.warn(`[CONSOLE ERROR] ${msg.text()}`);
|
|
}
|
|
});
|
|
|
|
await page.goto(CP_PATH);
|
|
|
|
// Wait for the login form to be ready
|
|
const emailField = page.locator('input[name="email"], input[type="email"]').first();
|
|
const passwordField = page.locator('input[name="password"], input[type="password"]').first();
|
|
const submitButton = page.locator('button[type="submit"], input[type="submit"]').first();
|
|
|
|
await emailField.waitFor({ state: 'visible', timeout: 15_000 });
|
|
await emailField.fill(ADMIN_EMAIL);
|
|
await passwordField.fill(ADMIN_PASSWORD);
|
|
await submitButton.click();
|
|
|
|
// After login, the panel may show a 2FA screen or land on dashboard
|
|
// Wait up to 20 s for a URL that contains /cp (but isn't the login page)
|
|
await page.waitForURL((url) => url.pathname.startsWith(CP_PATH) && !url.pathname.endsWith('/login'), {
|
|
timeout: 20_000,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Verify the current page is the cPad dashboard.
|
|
* Call this *after* loginAsAdmin to assert a successful login.
|
|
*/
|
|
export async function assertDashboard(page: Page): Promise<void> {
|
|
await expect(page).toHaveURL(new RegExp(`${CP_PATH}`));
|
|
}
|
|
|
|
/**
|
|
* Attach console-error and network-failure listeners to the page.
|
|
* Returns arrays that accumulate errors so the calling test can assert them.
|
|
*/
|
|
export function attachErrorListeners(page: Page): {
|
|
consoleErrors: string[];
|
|
networkErrors: string[];
|
|
} {
|
|
const consoleErrors: string[] = [];
|
|
const networkErrors: string[] = [];
|
|
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error') {
|
|
consoleErrors.push(msg.text());
|
|
}
|
|
});
|
|
|
|
page.on('pageerror', (err) => {
|
|
consoleErrors.push(`[pageerror] ${err.message}`);
|
|
});
|
|
|
|
page.on('response', (response) => {
|
|
const status = response.status();
|
|
if (status >= 500) {
|
|
networkErrors.push(`HTTP ${status}: ${response.url()}`);
|
|
}
|
|
});
|
|
|
|
page.on('requestfailed', (request) => {
|
|
networkErrors.push(`[requestfailed] ${request.url()} — ${request.failure()?.errorText}`);
|
|
});
|
|
|
|
return { consoleErrors, networkErrors };
|
|
}
|