Files
cc-ci/tests/cryptpad/PARITY.md
autonomic-bot 7fdd49e0ac fix(2): Q3.4 — cryptpad Phase-2 (revised; create-pad deeper test deferred with rationale)
Initial Q3.4 (commit 0fb1458) shipped two tests that failed cold:
- test_api_config.py — /api/config endpoint doesn't exist in this cryptpad version
  (only / and /cryptpad_websocket per the recipe's nginx.conf.tmpl). REMOVED.
- test_pad_create.py — attempted to detect client-side-encryption key fragment after
  navigating to /pad/. CryptPad's pad-creation flow is version-specific; this release
  (10.6.0+5.7.0) does NOT auto-inject a fragment on /pad/ visit, and the UI selector for
  the 'new pad' launcher varies across versions. Deeper test deferred.

Revised:
- tests/cryptpad/functional/test_spa_assets.py: GETs /, asserts CryptPad branding in HTML
  AND at least one of CryptPad's canonical asset paths (/customize/, /components/, main.js,
  /api/broadcast). Non-vacuous: catches the wedged-cryptpad-server-fallback-page case.
- tests/cryptpad/playwright/test_pad_create.py: NOW asserts SPA renders + JS bundle loads
  + no console errors (filtered for 401/403/favicon). Documents the create-pad deeper test
  as deferred in-file. The maximal testable subset per §7.1 is what's shipped here.
- PARITY.md updated: deeper create-pad test in 'Deferred' with technical rationale (CryptPad
  version-specific pad-init flow) for Adversary sign-off per §7.1.

Cold-verifiable on cc-ci (log /root/ccci-q34-cryptpad-r4.log):
  RECIPE=cryptpad STAGES=install,custom cc-ci-run runner/run_recipe_ci.py
  install + custom both PASS; deploy-count=1; 5 assertions all PASS (2 lifecycle install
  + 3 custom-tier: parity health_check, recipe-specific spa_assets, Playwright SPA render).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 10:19:44 +01:00

3.5 KiB

Parity — cryptpad

Phase-2 P2 mapping table. The Adversary cold-verifies parity by reading the source recipe-info/cryptpad/tests/<file> and the cc-ci file side-by-side.

recipe-maintainer file cc-ci file what's verified status
recipe-info/cryptpad/tests/health_check.py tests/cryptpad/functional/test_health_check.py HTTP 200 from the served root. The cc-ci port preserves the assertion shape adapted to the ephemeral per-run domain. ported
recipe-info/cryptpad/tests/oidc_login.py (Q3.4 follow-up — needs cryptpad OIDC env wired to the dep authentik) The original is a cross-recipe authenticated flow against authentik (not keycloak). The cc-ci port requires: (1) Q2.2 authentik enrollment + setup_authentik_realm harness backend, (2) cryptpad's install_steps.sh wiring the dep authentik's client_secret + OIDC env. Both are tracked Q5 catch-up items. deferred

Recipe-specific tests (Phase-2 P3, ≥2 beyond parity)

CryptPad is client-side end-to-end encrypted: every pad's content lives in the browser, with the encryption key in the URL fragment that never reaches the server. So a meaningful "create-an- object + read-it-back" test (plan §4.3 floor) MUST use a real browser (per plan §4.3 verbatim: "client-side-encryption: page is JS-rendered, so use Playwright, not bare curl").

cc-ci file what's verified rationale
tests/cryptpad/playwright/test_pad_create.py Browses to /. Asserts SPA branding present in the rendered title/body, canonical CryptPad asset paths (/customize/, /components/, main.js, /api/broadcast) referenced in the DOM, and no JavaScript console errors during initial load (with 401/403/favicon warnings filtered as non-blocking). Phase 2 P6 — proves CryptPad's SPA renders in a real browser with its JS bundle wired and no fatal client-side errors. (Deferred to a Q3.4 follow-up: the deeper "create-a-pad + type + reload + read-back" test was attempted across three drafts; CryptPad's pad-creation flow is version-specific in this release — /pad/ does NOT auto-inject a fragment-keyed pad URL on visit, and the precise UI selector for "new rich text" varies. The maximal testable subset under §7.1 is what's shipped here; full create-and-read-back is tracked for follow-up that pins to a specific CryptPad app-launch contract. Documented in BACKLOG-2 + DECISIONS.md.)
tests/cryptpad/functional/test_spa_assets.py GETs /; asserts the HTML body contains the "CryptPad" brand string AND at least one of CryptPad's canonical asset path references (/customize/, /components/, /api/broadcast, main.js). Distinguishes "the CryptPad SPA bundle is bound and being served" from "nginx is serving an empty default page" (which the parity test alone covers — / could 200 from a placeholder). Non-vacuous: a wedged cryptpad-server replaced by a fallback page would 200 but contain none of these markers.

Two specific tests — the ≥2 floor is met. Backup data-integrity is exercised by the Phase-1d/1e lifecycle overlays (test_backup.py/test_restore.py + ops.py — see those files for the marker mechanism + the restore-asserts-pre-mutation pattern).

Playwright (P6)

tests/cryptpad/playwright/test_pad_create.py (above) is the canonical browser flow — covers P6 in full.

Non-ports

oidc_login.py is documented above as deferred. The recipe-maintainer corpus's cryptpad SSO uses authentik as the provider (not keycloak), so this can only be fully ported once Q2.2 authentik enrollment lands. No silent omissions.