pediatric-ai-scribe-v3/e2e/tests/auth-screen.spec.js
Daniel 3c04d662f6 feat: the password door is gone; One Sign In is the only way in
POST /api/auth/login answers 410 for everyone, administrators included. The
sign-in screen never draws an email or a password: it is the provider's
button, or a sentence saying sign-in is not configured. The admin CLI no
longer resets passwords. The e2e harness mints its sessions inside the
container instead of signing in with a password.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fZGJNyDvERbMgS2Uc2msP
2026-09-15 04:14:04 +02:00

69 lines
3.5 KiB
JavaScript

// ============================================================
// AUTH SCREEN — unauthenticated landing page structure.
// These tests do NOT use the `authedPage` fixture; they visit the
// app with a fresh context (no cookie) and assert the sign-in
// form + register + forgot-password transitions render correctly.
// ============================================================
const { test, expect, E2E_BASE } = require('../fixtures');
test.describe('Unauthenticated auth screen', () => {
// Use the base test that doesn't auto-login.
//
// There is no password sign-in. The screen is the provider's button when a
// provider is configured, and otherwise a sentence saying sign-in is not
// set up; the email and password fields exist in the DOM for the local
// machinery behind the switch and are never shown.
test('the sign-in screen never offers an email or a password', async ({ page }) => {
await page.goto(E2E_BASE + '/');
await expect(page.locator('#auth-screen')).toBeVisible({ timeout: 10000 });
await expect(page.locator('#login-email')).toBeHidden();
await expect(page.locator('#btn-login-continue')).toBeHidden();
await expect(page.locator('#login-password')).toBeHidden();
await expect(page.locator('#btn-local-login')).toBeHidden();
await expect(page.locator('#show-admin-login')).toHaveCount(0);
// One of the two things the screen can be.
await expect(page.locator('#btn-sso:visible, #signin-unavailable:visible')).toHaveCount(1);
// main app body must be hidden while unauthenticated
await expect(page.locator('#main-app')).toBeHidden();
});
test('register form DOM is wired correctly if manually unhidden', async ({ page }) => {
await page.goto(E2E_BASE + '/');
await page.waitForSelector('#auth-screen', { timeout: 10000 });
// Force the link visible so we can exercise the swap path — useful for
// future tests that want to validate the full register flow.
await page.locator('#show-register').evaluate(el => { el.style.display = ''; });
await page.click('#show-register');
await expect(page.locator('#register-form')).toBeVisible();
await expect(page.locator('#reg-name')).toBeVisible();
await expect(page.locator('#reg-email')).toBeVisible();
await expect(page.locator('#reg-password')).toBeVisible();
await page.click('#show-login');
await expect(page.locator('#login-form')).toBeVisible();
await expect(page.locator('#register-form')).toBeHidden();
});
test('clicking "Forgot password?" swaps to forgot form', async ({ page }) => {
await page.goto(E2E_BASE + '/');
await page.waitForSelector('#auth-screen', { timeout: 10000 });
await page.click('#show-forgot');
await expect(page.locator('#forgot-form')).toBeVisible();
await expect(page.locator('#forgot-email')).toBeVisible();
await expect(page.locator('#login-form')).toBeHidden();
// Back link returns to login
await page.click('#show-login-2');
await expect(page.locator('#login-form')).toBeVisible();
await expect(page.locator('#forgot-form')).toBeHidden();
});
test('password minlength enforces 8 chars in register form', async ({ page }) => {
await page.goto(E2E_BASE + '/');
await page.waitForSelector('#auth-screen', { timeout: 10000 });
// Attribute check doesn't require the element to be visible.
const pw = page.locator('#reg-password');
await expect(pw).toHaveAttribute('minlength', '8');
await expect(pw).toHaveAttribute('type', 'password');
});
});