test: version-pinned end-to-end suite for generated apps#124
test: version-pinned end-to-end suite for generated apps#124dawsontoth wants to merge 4 commits into
Conversation
Scaffolds each template with the real create-harper CLI, exercises it against a real Harper instance, and lets the Harper version under test be pinned — including unpublished builds from a git commit — so we can catch API-surface changes and instability before a Harper release breaks a generated app. - template.tests/e2e/: bootHarper (shared isolated-instance module), overlay (a schema + custom resource + a frontend component that consumes the API), Playwright specs (auto-REST CRUD, custom resource, frontend, browser), and run.js (generate -> overlay -> install -> resolve Harper -> build -> test). - Harper resolution, no global install: HARPER_BIN, or --harper-ref <sha|branch|tag> (clone + build harperfast/harper from source), or --harper <npm-spec> (default latest; next/beta/tarball too). - runtimeSmoke.js refactored onto the shared bootHarper module. - .github/workflows/e2e.yaml: nightly latest+next canary that files an issue on failure, plus workflow_dispatch (harper-version / harper-ref / template). - Fixtures live under template.tests/ (outside template-*/ and the npm files allowlist), so they can never reach a scaffolded app. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive end-to-end testing suite using Playwright, which scaffolds a real application, overlays fixtures, boots an isolated Harper instance, and runs browser and API specs. It also refactors the existing runtime smoke test to share the new Harper booting logic. The review feedback highlights several critical improvements: registering signal handlers (SIGINT/SIGTERM) in both the Harper boot utility and the runner script to ensure proper cleanup of detached processes and temporary directories on interruption; ensuring heavy temporary directories (harperPrefix and harperSrc) are always cleaned up even when --keep is specified; and noting that git fetch will fail with short SHAs, requiring documentation or handling for full 40-character SHAs.
workflow_dispatch can't be triggered until this workflow lands on the default branch, so add a temporary pull_request trigger (scoped to a single cheap cell: react-ts @ latest) to exercise the workflow on GitHub runners before merge. Revert before merging — PRs stay on the fast runtimeSmoke check by design. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Validated on real runners via PR #124 (react-ts @ latest, 4/4 green). The E2E workflow stays nightly + workflow_dispatch only; PRs keep using the fast runtimeSmoke check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address PR review feedback: - bootHarper now installs SIGINT/SIGTERM handlers that kill the detached Harper (and run an onStop hook) so an interrupted run can't orphan a Harper process holding its ports; stop() deregisters them so it stays idempotent across boots. - runtimeSmoke delegates its injected-resource cleanup to onStop instead of maintaining duplicate signal handlers. - run.js cleans its temp dirs on SIGINT/SIGTERM, and --keep now retains only the generated app under test — the heavy Harper install/build dirs are always removed. - --harper-ref requires a full 40-char sha (git can't fetch a short sha directly); documented, with a preflight guard that rejects a short sha with a clear message. Branches/tags still work as refs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What & why
A way to test create-harper's generated apps against real Harper, with the Harper version under test as a knob — so we catch changed API surfaces, instability, and defaults create-harper should follow before a Harper release breaks a scaffolded app.
It's the deeper tier above the existing per-PR
runtimeSmoke.js; both now share one isolated-Harper boot module.How a run works
node template.tests/e2e/run.js --template <name> [--harper <spec> | --harper-ref <ref>]Picking the Harper version (precedence)
HARPER_BIN=….jspath is launched vianode)--harper-ref <sha|branch|tag>harperfast/harper(public; override via--harper-repo),npm install+npm run build, runsdist/bin/harper.js--harper <spec>(defaultlatest)latest,next,5.2.0-beta.1, a tarball …Scenarios
Every template runs the API specs (framework-agnostic Harper surface); SPA templates also run the frontend + browser specs.
crudresourceresources/class loads and answers GET with JSONfrontend/browserCI
runtimeSmoke.jscheck (integration.yaml) against latest Harper.e2e.yaml: scheduledlatestandnextacross a representative template subset (vanilla-ts,react-ts,vue-ts,react-ts-ssr), files a dedupede2e-canaryissue on failure.workflow_dispatchinputs:harper-version,harper-ref,template.No cruft in users' apps
Fixtures live under
template.tests/— outsidetemplate-*/(so scaffolding can't copy them) and outside the npmfilesallowlist (so they're not published). Verified:npm pack --dry-runships zero e2e/fixture files.Validated locally (real Harper)
react-ts@ 5.1.22 — 4/4 (incl. browser rendering live API data)vanilla-ts@ 5.1.22 — 4/4 (plain-DOM overlay, no build step)react-ts@next(5.2.0-beta.1) — 4/4react-ts@--harper-ref(5.2.0-beta.1 built from source) — 4/4react-ts-ssr@ 5.1.22 — API specs pass, frontend/browser correctly skipped → greenFindings this already surfaced
/graphql→ 404). "GraphQL" = schema DSL + auto REST/WS; dropped that scenario rather than assert a nonexistent surface./returns 404 underharper run(SSR templates setstatic.index:false;/is served by the entry-server). Treated as an unverified SSR concern, not a create-harper regression — the frontend/browser specs are gated off for SSR (E2E_SSR), which run the API specs only. Confirming intended SSR serving is a good first use of the harness.maindoesn't pass its owntsctypecheck right now (TS2345inresources/DatabaseTransaction.ts). Harper ships anyway —build-tools/build.shrunsnpm run build || truesince tsc still emitsdist/— sorun.jsmirrors that: tolerate the build's exit code, require the entrypoint was emitted.Notes / decisions to weigh
@playwright/testas a devDependency (+npx playwright install chromiumin CI, cached).--harper-refsource build is the heavy path (full install + tsc emit, ~1–2 min); it's on-demand only, not in the nightly schedule.test:(patch bump per.releaserc.json'stype: *rule), since this is internal tooling, not a user-facing feature.🤖 Generated with Claude Code