Skip to content

Add hosted Playwright data-flow mode#102

Merged
BASIC-BIT merged 3 commits into
mainfrom
feat/hosted-e2e-mode
May 30, 2026
Merged

Add hosted Playwright data-flow mode#102
BASIC-BIT merged 3 commits into
mainfrom
feat/hosted-e2e-mode

Conversation

@BASIC-BIT
Copy link
Copy Markdown
Owner

@BASIC-BIT BASIC-BIT commented May 30, 2026

Summary

  • Adds hosted Playwright @flow mode via PLAYWRIGHT_BASE_URL, skipped local web servers, and pnpm test:e2e:hosted.
  • Adds run-scoped E2E profile cleanup by VRDEX_E2E_RUN_ID while keeping helpers token-gated and production-blocked by default.
  • Adds deployed health checks for post-merge/manual/scheduled runs: mutation-backed dev/staging hosted flow plus production-safe read-only smoke.
  • Hardens local Convex Playwright startup against stale local backend state and real .env.local deployment leakage.
  • Switches the SES Terraform backend to S3 native lockfiles and documents the old DynamoDB lock table cleanup boundary.

Refs #100.

Deployed Health Settings

  • Dev/staging mutation health: repo variable VRDEX_HOSTED_E2E_BASE_URL and repo secret VRDEX_HOSTED_E2E_BROWSER_TOKEN.
  • Production smoke health: repo variable VRDEX_PRODUCTION_SMOKE_BASE_URL, or a successful production deployment_status URL.
  • Manual dispatch supports all, staging-mutation, and production-smoke.
  • The deployed health workflow uploads artifacts and fails on test failure, but does not auto-create GitHub issues.

Validation

  • pnpm verify:backend:local
  • pnpm typecheck:backend
  • pnpm test:backend
  • pnpm --filter web lint
  • pnpm --filter web typecheck
  • pnpm --filter web exec playwright test --grep "@flow" --project=desktop-chromium --list
  • VRDEX_ENABLE_E2E_HELPERS=true VRDEX_E2E_BROWSER_TOKEN=local-playwright-token VRDEX_E2E_CONVEX_SECRET=local-convex-e2e-secret pnpm --filter web exec playwright test --grep "@flow" --project=desktop-chromium
  • pnpm test:e2e
  • PLAYWRIGHT_BASE_URL=https://example.com PLAYWRIGHT_SKIP_WEBSERVERS=true pnpm test:e2e:hosted:smoke -- --list
  • pnpm dlx js-yaml .github/workflows/deployed-health.yml
  • terraform fmt -check
  • terraform init
  • terraform validate
  • terraform plan -var "domain_name=vrdex.net" -var "from_email=no-reply@vrdex.net" -detailed-exitcode

@vercel
Copy link
Copy Markdown

vercel Bot commented May 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vr-dex-web Ready Ready Preview, Comment May 30, 2026 9:13am

Request Review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

Playwright Data-Flow Preview

Outcome: success
Run: https://github.com/BASIC-BIT/VRDex/actions/runs/26680110026
Artifact: playwright-data-flow

Captured flow:

  • test-gated profile submission form
  • gated helper rejection without the Playwright token
  • Convex profile creation
  • submission success state
  • public profile page readback
  • discovery search readback

Artifacts include screenshots, traces, and recorded video for the flow run.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

Playwright Image Diff

Outcome: success
Run: https://github.com/BASIC-BIT/VRDex/actions/runs/26680110026
Artifact: playwright-image-diff

Changed screenshot baselines: none in this PR.

This check compares public route screenshots against committed baselines. Inline images show only added or modified baseline PNGs.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

Playwright Public Screenshot Preview

Outcome: success
Run: https://github.com/BASIC-BIT/VRDex/actions/runs/26680110026
Artifact: playwright-public-preview

Screenshots: all public route checks passed on desktop and mobile.

Full screenshot set is available in the artifact. Pixel diff baselines are handled by the separate Playwright Image Diff check.

@BASIC-BIT BASIC-BIT marked this pull request as ready for review May 30, 2026 09:01
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR adds a hosted Playwright data-flow mode that runs E2E tests against a deployed target (dev/staging or production) by pointing PLAYWRIGHT_BASE_URL at a live URL and skipping local web servers. It also adds a new deployed-health.yml workflow for post-merge and scheduled health checks, introduces run-scoped E2E cleanup via VRDEX_E2E_RUN_ID, and migrates the Terraform SES backend from DynamoDB locking to S3 native lockfiles.

  • Hosted E2E mode: New test:e2e:hosted / test:e2e:hosted:smoke scripts, PLAYWRIGHT_BASE_URL-driven server bypass in playwright.config.mjs, vrdex_e2e_run_id cookie propagation to the submission form, and a matching cleanupProfilesByRunId Convex mutation backed by a new by_sourceSubmitterTokenIdentifier index.
  • Deployed health workflow: Two independent jobs — mutation-backed staging flow and read-only production smoke — triggered by deployment_status, push to main, daily schedule, and manual dispatch; gated on repo secrets/variables with graceful skip when unconfigured.
  • Local Convex hardening: run-convex-local.mjs now passes --local-force-upgrade in non-TTY/CI contexts, and both local scripts unconditionally clear cloud credentials to prevent .env.local leakage.

Confidence Score: 4/5

The PR is safe to merge. All new code paths are gated behind environment variables that are absent in most contexts, the production-block defense-in-depth layer is correctly ordered, and the Convex cleanup logic is consistent with how profiles are stored.

The core logic — run-scoped cleanup, hosted mode configuration, and the deployed-health workflow — is well-structured and the token/production guards are correct. The cookie extraction pattern in the submission form is fragile and could silently truncate the runId if the value ever contains =, which would cause cleanup to miss profiles for that run. The smoke script's test selection being identical to the standard E2E suite is a latent risk if future mutation tests are added without the @flow tag.

apps/web/src/app/submit/profile-submission-form.tsx (cookie extraction); apps/web/package.json (smoke script filter)

Important Files Changed

Filename Overview
apps/web/src/app/submit/profile-submission-form.tsx Reads vrdex_e2e_run_id cookie to seed the E2E form's runId; uses a fragile split("=")[1] extraction that would truncate any cookie value containing "=".
convex/e2e.ts Adds cleanupProfilesByRunId mutation using the new by_sourceSubmitterTokenIdentifier index; extraction logic is consistent with how submitProfile stores tokenIdentifier and subject.
apps/web/src/app/api/e2e/profile-submissions/route.ts Adds productionBlocked guard and run-ID-based cleanup path; token and production gating logic is correct.
.github/workflows/deployed-health.yml New workflow for post-merge and scheduled deployed health checks; gate pattern correctly skips jobs when env vars are absent.
.github/workflows/baseline-checks.yml Adds optional playwright-hosted-data-flow job gated on repo secret/variable; fork guard prevents token exposure; comment dedup pattern is correct.
apps/web/playwright.config.mjs PLAYWRIGHT_BASE_URL now drives skipWebServers and overrides the local baseURL; CONVEX_URL env vars are only set for local runs.
scripts/run-convex-local.mjs Hardens local backend startup: adds --local-force-upgrade in CI/non-TTY, snaps and restores .env.local, and clears cloud credentials unconditionally.
convex/schema.ts Adds by_sourceSubmitterTokenIdentifier index on profiles table, needed by cleanupProfilesByRunId.
infra/terraform/ses/versions.tf Bumps required_version to >=1.10.0 (needed for use_lockfile) and replaces DynamoDB lock table with S3 native lockfile.

Sequence Diagram

sequenceDiagram
    participant CI as GitHub Actions
    participant PW as Playwright Runner
    participant Browser as Browser (Page)
    participant Form as E2eSubmissionForm
    participant API as /api/e2e/profile-submissions
    participant Convex as Convex Backend

    CI->>PW: set PLAYWRIGHT_BASE_URL, VRDEX_E2E_BROWSER_TOKEN, VRDEX_E2E_RUN_ID
    PW->>Browser: addCookies(vrdex_e2e_token, vrdex_e2e_run_id)
    Browser->>Form: read vrdex_e2e_run_id cookie → runId
    Form->>API: "POST /api/e2e/profile-submissions {runId, displayName, …}"
    API->>API: requireE2eRequest() — token + productionBlocked check
    API->>Convex: "mutation e2e.submitProfile {runId, …}"
    Convex-->>API: "{slug, profileId, profilePath}"
    API-->>Form: "200 {slug}"
    Form-->>Browser: navigate to /p/slug
    Browser-->>PW: assert profile + discovery visible

    alt cleanup — slug captured
        PW->>API: "DELETE {slug, runId}"
        API->>Convex: "mutation e2e.cleanupProfileBySlug {slug}"
    else cleanup — slug not captured
        PW->>API: "DELETE {runId}"
        API->>Convex: "mutation e2e.cleanupProfilesByRunId {runId}"
        Convex->>Convex: index by_sourceSubmitterTokenIdentifier → deleteE2eProfile × n
    end
Loading

Comments Outside Diff (1)

  1. apps/web/package.json, line 503 (link)

    P2 test:e2e:hosted:smoke has the same grep filter as test:e2e

    test:e2e:hosted:smoke uses --grep-invert "@visual|@flow|@snapshot", which is identical to test:e2e. Any future test that mutates data but is not tagged @flow (e.g. a setup test tagged @setup) would silently become part of the production smoke run. Adding a positive @smoke tag and filtering with --grep @smoke would make the production-safe scope explicit and less fragile as the test suite grows.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/web/package.json
    Line: 503
    
    Comment:
    **`test:e2e:hosted:smoke` has the same grep filter as `test:e2e`**
    
    `test:e2e:hosted:smoke` uses `--grep-invert "@visual|@flow|@snapshot"`, which is identical to `test:e2e`. Any future test that mutates data but is not tagged `@flow` (e.g. a setup test tagged `@setup`) would silently become part of the production smoke run. Adding a positive `@smoke` tag and filtering with `--grep @smoke` would make the production-safe scope explicit and less fragile as the test suite grows.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/web/src/app/submit/profile-submission-form.tsx:300-304
The `split("=")[1]` pattern returns only the segment between the first and second `=`. If the cookie value ever contains a literal `=` (e.g. a percent-decoded base64 fragment), the runId would be silently truncated and the run-scoped cleanup would miss profiles created under that run. Using `slice` from the known prefix length is unambiguous and avoids the dependency on `=` being absent from the value.

```suggestion
    const cookieName = "vrdex_e2e_run_id=";
    const cookieRunId = document.cookie
      .split(";")
      .map((cookie) => cookie.trim())
      .find((cookie) => cookie.startsWith(cookieName))
      ?.slice(cookieName.length);
```

### Issue 2 of 2
apps/web/package.json:503
**`test:e2e:hosted:smoke` has the same grep filter as `test:e2e`**

`test:e2e:hosted:smoke` uses `--grep-invert "@visual|@flow|@snapshot"`, which is identical to `test:e2e`. Any future test that mutates data but is not tagged `@flow` (e.g. a setup test tagged `@setup`) would silently become part of the production smoke run. Adding a positive `@smoke` tag and filtering with `--grep @smoke` would make the production-safe scope explicit and less fragile as the test suite grows.

Reviews (1): Last reviewed commit: "Add deployed Playwright health checks" | Re-trigger Greptile

Comment thread apps/web/src/app/submit/profile-submission-form.tsx Outdated
@BASIC-BIT BASIC-BIT merged commit ca30880 into main May 30, 2026
17 checks passed
@BASIC-BIT BASIC-BIT deleted the feat/hosted-e2e-mode branch May 30, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant