Skip to content

test(integration): wire up Harper v5 integration test harness#67

Merged
heskew merged 3 commits intomainfrom
test/integration-tests-harness
May 5, 2026
Merged

test(integration): wire up Harper v5 integration test harness#67
heskew merged 3 commits intomainfrom
test/integration-tests-harness

Conversation

@heskew
Copy link
Copy Markdown
Member

@heskew heskew commented May 1, 2026

Summary

  • Adds @harperfast/integration-testing-based integration tests that boot a real Harper v5 child process with the OAuth plugin installed via npm pack. Mirrors the HarperFast/nextjs PR #40 pattern.
  • First test asserts ${VAR} substitution in provider config reaches the authorization redirect's client_id (regression guard for Slack false-alarm thread).
  • Adds .github/workflows/integration-tests.yml (Node 22/24 matrix, log artifact upload on failure, SHA-pinned actions).

Notes

  • Fixture deps are installed via npm pack + tarball install (scripts/install-fixtures.js), not file: symlinks. The symlink pattern trips Harper v5's VM sandbox with Can not load module outside of allowed path. Tarball install creates real files under node_modules, mirroring how real users install the plugin.
  • applications.{lockdown,moduleLoader,dependencyLoader} overrides are intentionally not set — the test runs under default v5 sandboxing.
  • Fixture's config.yaml includes rest: true. Harper only falls back to DEFAULT_CONFIG (which sets rest: true) when no config.yaml is present at all; partial configs do not get defaults merged.
  • Linux loopback already routes 127.0.0.0/8, so setup-loopback.sh (macOS-only, targets lo0) is skipped on CI.

Test plan

  • CI green on Node 22 and 24
  • Local: npm install && npm run install:fixtures && npm run test:integration passes
  • CLAUDE.md "Testing" section reflects new layout

🤖 Generated with Claude Code

Adds @harperfast/integration-testing-based integration tests that boot a real
Harper child process with the OAuth plugin installed via npm pack. Mirrors the
HarperFast/nextjs PR #40 pattern. First test asserts ${VAR} substitution in
provider config reaches the authorization redirect's client_id.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@heskew heskew requested a review from a team as a code owner May 1, 2026 04:04
@claude
Copy link
Copy Markdown

claude Bot commented May 1, 2026

Reviewed; no blockers found.

@heskew
Copy link
Copy Markdown
Member Author

heskew commented May 1, 2026

@claude if there are no blockers found, why is ci red?

@claude
Copy link
Copy Markdown

claude Bot commented May 1, 2026

Reviewed; no blockers found.

Pin harper to 5.0.7 (was ^5.0.0 → 5.0.2 in lockfile). Importing real
harper 5.0.7 eagerly opens the system RocksDB (regressed in
dist/resources/databases.js where `RocksDatabase.open(store)` became
`new RocksIndexStore().open()` — opens synchronously). Under unit-test
parallelism the eager open contends for the LOCK and surfaces a
"Cannot read properties of undefined (reading 'localhost')" async
rejection that Node's test runner reports as a flaky failure.

Fix: mirror the existing Bun preload mock for Node — add
test/helpers/harper-mock.mjs (a `module.register` ESM loader) and wire
it into every unit-test script via `--import`. Integration tests do
not load it; they need the real harper module.

Also:
- Drop Node 20 (out of LTS): remove from PR Checks matrix, drop the
  test:node-twenty script, bump engines.node to >=22, bump @types/node
  to ^22.
- bunfig.toml: scope `bun test` to ./test so it doesn't try to run the
  integration tests under the bun runner.
- .prettierignore: exclude .claude/ and integrationTests/fixtures/**/
  node_modules/.
- integrationTests/env-var-substitution.test.ts: prettier-formatted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
kriszyp pushed a commit to HarperFast/harper that referenced this pull request May 5, 2026
…collision

Background: PR #432's `--edit-last` mechanism filters by authenticated
identity (`claude[bot]`) only. After a `@claude` mention, the most
recent `claude[bot]` comment is the mention response — so the next
review run's `--edit-last` clobbers it instead of editing the prior
review. Observed on HarperFast/oauth#67.

Fix — three coordinated changes:

1. **Sentinel marker.** Every review comment body now MUST begin
   with the literal first line `<!-- claude-review:v1 -->`. This is
   what distinguishes review comments from mention responses, which
   never carry the marker.

2. **Workflow lookup step + agent-side targeted edit.** A new
   `Find prior review comment` step runs before the Claude review
   step. It queries the issue-comments REST endpoint, filters for
   `claude[bot]` + marker-prefixed bodies, and exposes the integer
   database ID (or empty) as `steps.prior_review.outputs.id`. The
   agent reads this via the prompt's new `PRIOR_REVIEW_COMMENT_ID`
   field and:
     - if non-empty, edits via `gh api -X PATCH .../issues/comments/<id>`
     - otherwise posts fresh via `gh pr comment <N>`
   Either way, the body starts with the marker.
   Adds `Bash(gh api:*)` to `--allowedTools`. Token only carries
   `pull-requests: write` / `contents: read` / `id-token: write`,
   so the broader API surface is contained to the same single PR.

3. **Log step now filters by marker too.** Same logic that the
   review uses — marker'd comment via raw API, claude[bot] login.
   Also switched the staleness guard from `created_at` to
   `updated_at`, since edit-in-place leaves `created_at` frozen at
   the original post time and we need the most recent activity to
   judge whether the body is fresh-this-run or stale.

Existing un-marker'd review comments on active PRs will be
orphaned (the next review run finds no prior, posts a marker'd
fresh one). Acceptable; old comments stay as historical record.

Mirror to oauth follows in a separate PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 5.0.7-regression framing in the mock's docblock and CLAUDE.md was
wrong (per harper team feedback): RocksDB simply doesn't support
multi-process read-write access to the same database. The 5.0.2 → 5.0.7
change in databases.js only changed how the contention surfaces, not
whether it happens. Reframe accordingly and point at Chris's in-flight
read-only RocksDB mode as the path to dropping this mock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude Bot commented May 5, 2026

Reviewed; no blockers found. CI is green on all checks (Integration Tests Node 22/24, Lint/Build/Test 22/24, Bun) — the red CI from the prior round was resolved by the third commit.

@heskew heskew merged commit c4a5d29 into main May 5, 2026
7 checks passed
@heskew heskew deleted the test/integration-tests-harness branch May 5, 2026 22:17
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