Add Playwright fixtures with 5 test user types for e2e tests
Creates test infrastructure to enable previously skipped e2e tests: - Onboarding user (no period data) for setup flow tests - Established user (period 14 days ago) for normal usage tests - Calendar user (with calendarToken) for ICS feed tests - Garmin user (valid tokens) for connected state tests - Garmin expired user (expired tokens) for expiry warning tests Also fixes ICS feed route to strip .ics suffix from Next.js dynamic route param, adds calendarToken to /api/user response, and sets viewRule on users collection for unauthenticated ICS access. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
86
e2e/fixtures.ts
Normal file
86
e2e/fixtures.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
// ABOUTME: Playwright test fixtures for different user states.
|
||||
// ABOUTME: Provides pre-authenticated pages for onboarding, established, calendar, and garmin users.
|
||||
import { test as base, type Page } from "@playwright/test";
|
||||
import { TEST_USERS, type TestUserPreset } from "./pocketbase-harness";
|
||||
|
||||
/**
|
||||
* Logs in a user via the email/password form.
|
||||
* Throws if the email form is not visible (OIDC-only mode).
|
||||
*/
|
||||
async function loginUser(
|
||||
page: Page,
|
||||
email: string,
|
||||
password: string,
|
||||
): Promise<void> {
|
||||
await page.goto("/login");
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
const emailInput = page.getByLabel(/email/i);
|
||||
const hasEmailForm = await emailInput.isVisible().catch(() => false);
|
||||
|
||||
if (!hasEmailForm) {
|
||||
throw new Error(
|
||||
"Email/password form not visible - app may be in OIDC-only mode",
|
||||
);
|
||||
}
|
||||
|
||||
await emailInput.fill(email);
|
||||
await page.getByLabel(/password/i).fill(password);
|
||||
await page.getByRole("button", { name: /sign in/i }).click();
|
||||
|
||||
// Wait for successful redirect to dashboard
|
||||
await page.waitForURL("/", { timeout: 15000 });
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fixture for a specific user preset.
|
||||
*/
|
||||
function createUserFixture(preset: TestUserPreset) {
|
||||
return async (
|
||||
{ page }: { page: Page },
|
||||
use: (page: Page) => Promise<void>,
|
||||
) => {
|
||||
const user = TEST_USERS[preset];
|
||||
await loginUser(page, user.email, user.password);
|
||||
await use(page);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended test fixtures providing pre-authenticated pages for each user type.
|
||||
*
|
||||
* Usage:
|
||||
* import { test, expect } from './fixtures';
|
||||
*
|
||||
* test('onboarding user sees set date button', async ({ onboardingPage }) => {
|
||||
* await onboardingPage.goto('/');
|
||||
* // User has no period data, will see onboarding UI
|
||||
* });
|
||||
*
|
||||
* test('established user sees dashboard', async ({ establishedPage }) => {
|
||||
* await establishedPage.goto('/');
|
||||
* // User has period data from 14 days ago
|
||||
* });
|
||||
*/
|
||||
type TestFixtures = {
|
||||
/** User with no period data - sees onboarding UI */
|
||||
onboardingPage: Page;
|
||||
/** User with period data (14 days ago) - sees normal dashboard */
|
||||
establishedPage: Page;
|
||||
/** User with period data and calendar token - can copy/regenerate URL */
|
||||
calendarPage: Page;
|
||||
/** User with valid Garmin tokens (90 days until expiry) */
|
||||
garminPage: Page;
|
||||
/** User with expired Garmin tokens */
|
||||
garminExpiredPage: Page;
|
||||
};
|
||||
|
||||
export const test = base.extend<TestFixtures>({
|
||||
onboardingPage: createUserFixture("onboarding"),
|
||||
establishedPage: createUserFixture("established"),
|
||||
calendarPage: createUserFixture("calendar"),
|
||||
garminPage: createUserFixture("garmin"),
|
||||
garminExpiredPage: createUserFixture("garminExpired"),
|
||||
});
|
||||
|
||||
export { expect } from "@playwright/test";
|
||||
Reference in New Issue
Block a user