Replaces racy one-shot checks with auto-retrying assertions, asserts the
referrer-block test against the deterministic 403 response (not iframe
content), uses an OS-allocated port for the static test app with
connection-tracked teardown, caches the JWT access token across tests,
sends CSRF on the guest-token call (page.request always carries the
storageState cookie, so JWT-only doesn't actually skip CSRF), and waits
for a real viz element inside chart containers rather than a class that
doesn't exist. Verified with --repeat-each=5 (25/25 passing).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The test app server only ever serves /, /index.html, and /sdk/index.js,
so replace dynamic path joining with a fixed allowlist. This eliminates
the data flow from req.url to readFileSync that CodeQL flagged as a
path-traversal sink — the previous resolve+startsWith containment check
was correct but not recognized as a sanitizer by the analyzer.
Adds five tests covering the embedded dashboard flow against the
world_health example: render, hideTitle UI config, chart rendering,
allowed_domains referrer check, and guest-token data access. Includes:
- A chromium-embedded Playwright project, excluded from the main
project via testIgnore so it can be opted into separately.
- An EmbeddedPage page object and API helpers for embedding/guest
tokens plus dashboard lookup by slug.
- A static test app (embedded-app/index.html) loaded from a minimal
Node static server. Playwright bridges the guest-token fetch from
Node into the browser via page.exposeFunction.
- EMBEDDED timeout/config constants.
Workflow integration and test-environment configuration land in a
follow-up commit.