passkeys-firefox.spec.ts

3.4 KB · raw

1/**2 * passkeys-firefox.spec.ts — Firefox content-script proxy E2E suite.3 *4 * The MAIN-world monkey-patch only runs under Firefox with a real Gecko5 * credentials API to delegate to. Playwright's bundled chromium runner cannot6 * exercise it. To run this suite, build with `npm run build:firefox` and7 * launch via `web-ext run --target=firefox-desktop --source-dir=dist-firefox`,8 * then drive Firefox with playwright's `firefox` browser type plus the9 * preferences below to load the temporary add-on. Until that harness lands10 * in CI the suite is gated by PEACH_E2E_FIREFOX_PASSKEYS=1, so the default11 * `npx playwright test` run skips it cleanly.12 *13 * The list below is the verification matrix from the v2.12.0 spec. Each14 * item maps to a manual smoke-test step on a real RP (github.com,15 * webauthn.io, google.com account settings).16 */1718import { test } from "@playwright/test";1920const ENABLED = process.env.PEACH_E2E_FIREFOX_PASSKEYS === "1";21const skip = ENABLED ? test : test.skip;2223test.describe("Firefox passkey content-script proxy (MAIN world)", () => {24  // 1. navigator.credentials.create is replaced on document_start.25  skip("navigator.credentials.create is replaced on page load (MAIN world)", async () => {});2627  // 2. navigator.credentials.get is replaced on document_start.28  skip("navigator.credentials.get is replaced on page load (MAIN world)", async () => {});2930  // 3. Registration: approval UI appears, vault gets a passkey entry with31  //    privateKeyJwk and browser:'firefox'.32  skip("registration: approval UI appears, passkey stored in vault", async () => {});3334  // 4. Authentication: approval UI appears, RP receives a valid assertion.35  skip("authentication: approval UI appears, assertion returned", async () => {});3637  // 5. clientDataJSON.origin equals the page origin in both responses.38  skip("clientDataJSON.origin equals the page origin in both responses", async () => {});3940  // 6. clientDataJSON.origin must NEVER contain `moz-extension://`.41  skip("clientDataJSON.origin does not contain moz-extension://", async () => {});4243  // 7. signCount strictly increments across two consecutive get ceremonies.44  skip("signCount increments between two authentication ceremonies", async () => {});4546  // 8. user_cancelled: page receives DOMException with name 'NotAllowedError'.47  skip("user_cancelled: DOMException with NotAllowedError name thrown", async () => {});4849  // 9. Non-publicKey credentials.create requests fall through to the50  //    platform unchanged (PasswordCredential, FederatedCredential).51  skip("non-passkey credentials.create falls through to original", async () => {});5253  // 10. Non-publicKey credentials.get falls through.54  skip("non-passkey credentials.get falls through to original", async () => {});5556  // 11. No passkey for rpId: PASSKEY_HAS_CREDENTIALS returns false → fall57  //     through to the platform authenticator. No Peach UI appears.58  skip("no passkey for rpId: falls through to platform authenticator", async () => {});5960  // 12. Free tier: pro_required fires; page-side dispatches61  //     'peach:passkey-pro-gate' event; ceremony falls through to platform.62  skip("free tier: pro gate fires, falls through to platform", async () => {});6364  // 13. Round-trip: register passkey → authenticate → vault entry's65  //     signCount and lastUsedAt update.66  skip("round-trip: register passkey then authenticate updates vault entry", async () => {});67});