// The one spec that drives the real login and registration forms. Everything // else signs in over HTTP through the fixture in fixtures.ts. // // `anonTest` gives database seeding with an anonymous browser. import { anonTest as test, expect, E2E_PASSWORD } from './fixtures'; // Registration is rate limited to five requests per hour per IP, and the window // lives in Postgres. tests/e2e/global-setup.ts empties that table before each // run, so this file may spend a few of them; keep it to the two below. const INVITE_CODE = 'test-invite'; test('an anonymous visitor to a protected route lands on the login page', async ({ page }) => { await page.goto('/dashboard'); await expect(page).toHaveURL(/\/login$/); // `CardTitle` renders a
, not a heading, so there is no role to match. await expect(page.getByText('Welcome back')).toBeVisible(); }); test('registration is refused when the invite code is wrong', async ({ page }) => { await page.goto('/register'); await expect(page.getByText('Join OpenFrame to collaborate on video projects')).toBeVisible(); await page.getByLabel('Invite Code').fill('definitely-not-the-invite-code'); await page.getByLabel('Full Name').fill('Wrong Code Person'); await page.getByLabel('Email').fill(`e2e-rejected-${Date.now()}@example.com`); await page.getByLabel('Password', { exact: true }).fill(E2E_PASSWORD); await page.getByLabel('Confirm Password').fill(E2E_PASSWORD); await page.getByRole('button', { name: 'Create Account' }).click(); await expect(page.getByText('Invalid invite code')).toBeVisible(); await expect(page).toHaveURL(/\/register$/); }); test('a new account can be registered with the invite code and then signed in', async ({ page, seed, }) => { const email = `e2e-registered-${Date.now()}@example.com`; await page.goto('/register'); await page.getByLabel('Invite Code').fill(INVITE_CODE); await page.getByLabel('Full Name').fill('Freshly Registered'); await page.getByLabel('Email').fill(email); await page.getByLabel('Password', { exact: true }).fill(E2E_PASSWORD); await page.getByLabel('Confirm Password').fill(E2E_PASSWORD); await page.getByRole('button', { name: 'Create Account' }).click(); // SMTP is unset for the app under test, so isEmailVerificationEnabled() is // false and the account is auto-verified rather than parked on /verify-email. await expect(page).toHaveURL(/\/login\?registered=true$/); await expect(page.getByText('Account created successfully!')).toBeVisible(); await page.getByLabel('Email').fill(email); await page.getByLabel('Password').fill(E2E_PASSWORD); await page.getByRole('button', { name: 'Sign in' }).click(); // /settings, not /onboarding, and that is the real product behaviour rather // than a test artefact: POST /api/auth/register does not set `trialEndsAt`, so // with OPENFRAME_ENABLE_STRIPE on a brand new account has no billing access, // and requireBillingAccessOrRedirect() on /dashboard sends it to billing // before it ever sees the onboarding wizard. await expect(page).toHaveURL(/\/settings$/); await expect(page.getByRole('heading', { name: 'Settings', level: 1 })).toBeVisible(); // The Seed fixture only tracks rows it created itself, so remove this one by // hand rather than leaving it behind for the next run. await seed.deleteUserByEmail(email); }); test('signing in with the wrong password is refused', async ({ page, seed }) => { const user = await seed.user(); await page.goto('/login'); await page.getByLabel('Email').fill(user.email ?? ''); await page.getByLabel('Password').fill('not-the-password'); await page.getByRole('button', { name: 'Sign in' }).click(); await expect(page.getByText('Invalid email or password')).toBeVisible(); await expect(page).toHaveURL(/\/login$/); }); test('signing in through the form reaches the dashboard, and signing out returns to login', async ({ page, seed, }) => { const user = await seed.user(); await page.goto('/login'); await page.getByLabel('Email').fill(user.email ?? ''); await page.getByLabel('Password').fill(E2E_PASSWORD); await page.getByRole('button', { name: 'Sign in' }).click(); await expect(page).toHaveURL(/\/dashboard$/); await expect(page.getByRole('heading', { name: 'Projects', level: 1 })).toBeVisible(); await page.goto('/signout'); await page.getByRole('button', { name: 'Sign out' }).click(); await expect(page).toHaveURL(/\/login$/); // The session really is gone, not just navigated away from. await page.goto('/dashboard'); await expect(page).toHaveURL(/\/login$/); });