§8 full browser E2E (todo §8); the real Playwright UI against the live stack — the browser-UI flows the earlier full-stack suites deferred here. New e2e/full-flow.spec.ts + compose.e2e-full.yml covering password login, mocked SSO, menu filtering by role, users/groups/roles CRUD, a permission-gated plugin page, and logout (6/6 green on a clean stack, then torn down). Same-origin gateway (e2e/proxy.mjs, stdlib reverse proxy) fronts web + Kratos on one host so the browser's cookies round-trip (the themed form posts straight to Kratos); ory/kratos/e2e-proxy.yml points Kratos at it + --dev so cookies aren't Secure over http. SSO backed by a stdlib mock OIDC provider (e2e/mock-oidc.mjs, RS256 id_token, nonce-bound codes). Found + fixed a real bug the E2E surfaced: the SSO submit button shares the form with the required email/password fields, so HTML5 validation blocked it — added formnovalidate to the SSO buttons (auth-card.ejs), tests-first. Stability-reviewer APPROVE, no Critical/High (every dev/insecure knob is e2e-overlay-scoped, base/prod compose unaffected). typecheck + 305 units green. Also marks the §8 E2E-harness item (full stack up + seeded admin/Keto roles + tear-down).
This commit is contained in:
@@ -429,9 +429,10 @@ test("renders a fetched flow as the themed auth page: fields post straight to Kr
|
||||
assert.match(html, /name="password"[^>]*type="password"/);
|
||||
assert.match(html, /<button type="submit"[^>]*name="method" value="password">Sign in<\/button>/);
|
||||
assert.match(html, /<a href="\/registration">Create one<\/a>/); // alt link to register
|
||||
// Configured OIDC provider → an SSO submit button in the same form (posts provider=google).
|
||||
// Configured OIDC provider → an SSO submit button in the same form (posts provider=google);
|
||||
// `formnovalidate` so it bypasses the required email/password fields (SSO needs neither).
|
||||
assert.match(html, /<div class="sso"/);
|
||||
assert.match(html, /<button type="submit" class="sso-btn" name="provider" value="google">.*Sign in with Google<\/span><\/button>/s);
|
||||
assert.match(html, /<button type="submit" class="sso-btn" name="provider" value="google" formnovalidate>.*Sign in with Google<\/span><\/button>/s);
|
||||
// The flow-level error renders as an alert.
|
||||
assert.match(html, /class="alert alert-neg"/);
|
||||
assert.match(html, /The provided credentials are invalid\./);
|
||||
|
||||
@@ -26,8 +26,9 @@ test("auth-card renders head, SSO providers (text logo + icon link), body slot a
|
||||
assert.match(html, /<div class="sso" aria-label="Single sign-on options"><ul class="sso-list">/);
|
||||
assert.match(html, /<li><button type="button" class="sso-btn"><span class="sso-logo" aria-hidden="true">G<\/span><span class="sso-label">Continue with Google<\/span><\/button><\/li>/);
|
||||
assert.match(html, /<li><a class="sso-btn" href="\/sso\/saml"><span class="sso-logo" aria-hidden="true"><svg class="ico ico-sm"><use href="#i-shield"\s*\/?><\/svg><\/span><span class="sso-label">Continue with SAML SSO<\/span><\/a><\/li>/);
|
||||
// A provider with name/value submits to the form (Kratos OIDC) — type="submit", not a decorative button.
|
||||
assert.match(html, /<li><button type="submit" class="sso-btn" name="provider" value="microsoft"><span class="sso-logo" aria-hidden="true">M<\/span><span class="sso-label">Sign in with Microsoft<\/span><\/button><\/li>/);
|
||||
// A provider with name/value submits to the form (Kratos OIDC) — type="submit", not a decorative
|
||||
// button; `formnovalidate` so it bypasses the required email/password fields (SSO needs neither).
|
||||
assert.match(html, /<li><button type="submit" class="sso-btn" name="provider" value="microsoft" formnovalidate><span class="sso-logo" aria-hidden="true">M<\/span><span class="sso-label">Sign in with Microsoft<\/span><\/button><\/li>/);
|
||||
assert.match(html, /<\/ul><div class="auth-divider">or<\/div><\/div>/);
|
||||
|
||||
// Body slot lands inside .auth-form; alt footer renders text + link.
|
||||
|
||||
Reference in New Issue
Block a user