Skip to content

test(integration): migrate api-tests foundation to harperLifecycle framework#555

Open
kriszyp wants to merge 2 commits into
mainfrom
claude/silly-torvalds-4f148c
Open

test(integration): migrate api-tests foundation to harperLifecycle framework#555
kriszyp wants to merge 2 commits into
mainfrom
claude/silly-torvalds-4f148c

Conversation

@kriszyp
Copy link
Copy Markdown
Member

@kriszyp kriszyp commented May 15, 2026

Summary

First slice of migrating the legacy test:integration:api-tests suite (which runs sequentially against an externally-started Harper server) onto the @harperfast/integration-testing framework that owns Harper's lifecycle per test file on isolated loopback IPs.

  • Adds createApiClient(harper) — supertest bound to a HarperContext (URLs + admin creds from startHarper), replacing the legacy utils/request.mjs + config/envConfig.mjs globals.
  • Adds restartHttpWorkers(client) — per-instance restart_service http_workers helper.
  • Ports three fully-independent suites:
    • integrationTests/apiTests/system-information.test.mjs (was tests/13_systemInformation.mjs)
    • integrationTests/apiTests/alter-user.test.mjs (was tests/11_alterUserTests.mjs) — now self-contained: creates the northnwd schema + minimum table/column shape that add_role validates against.
    • integrationTests/apiTests/headers.test.mjs (was tests/27_headerTests.mjs) — installs its own headerTests component via add_component/set_component_file and restarts http workers.
  • test:integration:all glob now matches both *.test.ts and *.test.mjs.
  • README relaxes the "must be .test.ts" rule (the framework runner is glob-based, so .test.mjs works equally well).

Legacy testSuite.mjs and tests/*.mjs are intentionally untouched — they continue to run under test:integration:api-tests until enough of the suite is ported to cut over in one go.

Purpose

Two objectives from the migration plan:

  1. Use harperLifecycle (startHarper / teardownHarper) so the test runner controls Harper rather than relying on an externally-started server.
  2. Break the monolithic numbered suite into independent files that can run in parallel.

This PR validates the pattern end-to-end (helper layer + 3 converted suites) before tackling the suites with cross-file state dependencies (Northwind CRUD, role testing, components).

Where to look

  • integrationTests/apiTests/utils/client.mjs — surface area that every future ported suite will use; worth a careful read.
  • integrationTests/apiTests/utils/lifecycle.mjs — the 15s hardcoded setTimeout after restart_service mirrors the legacy helper but will become a bottleneck once many suites use it. Worth replacing with a readiness poll in a follow-up.
  • integrationTests/apiTests/alter-user.test.mjs — the explicit Northwind schema/seed in before() is the pattern we'll use for the suites that genuinely need Northwind data. Future iterations will likely factor this into a prepareNorthwindFixture(ctx) helper.

Testing

All 11 tests across the 3 ported suites pass in parallel:

npm run test:integration -- integrationTests/apiTests/*.test.mjs
# ▶ System Information ✔ (2/2)
# ▶ Alter User ✔ (7/7)
# ▶ HTTP Header / Set-Cookie handling ✔ (2/2)
# ℹ pass 11 fail 0

Lint + format clean. Gemini cross-review surfaced the restartHttpWorkers polling note above; no blockers.


🤖 Generated by Claude (Opus 4.7), see commit Co-Authored-By tag.

…amework

First slice of the migration from sequential api-tests (run against an
existing Harper server) to the @harperfast/integration-testing framework
that spins up isolated Harper instances per test file on separate
loopback IPs.

- Add createApiClient(harper) helper binding supertest to a HarperContext
- Add restartHttpWorkers(client) helper for in-place http_workers restart
- Port three fully-independent suites: system_information, alter_user,
  HTTP header / Set-Cookie handling
- Broaden test:integration:all glob to also pick up *.test.mjs
- Relax README to permit .mjs in addition to .test.ts

Legacy testSuite.mjs and tests/*.mjs are intentionally left in place;
they continue to run under test:integration:api-tests until the full
migration is complete and we can drop them in one cutover.

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

claude Bot commented May 15, 2026

Reviewed; no blockers found.

…p headers suite on Bun

Two CI issues surfaced after the original commit:

1. Windows runners hit ECONNREFUSED in headers.test.mjs because the
   fixed 15s sleep in restartHttpWorkers was not long enough for the
   REST workers to come back online. Replace the sleep with a readiness
   poll against a caller-supplied probe path. The probe must be a route
   the test exercises, so we wait both for workers to be up AND for the
   freshly-installed component to register its routes (a plain workers-up
   probe races with route registration on fast Linux runners). Default
   timeout 60s; typical wall time ~9s on Linux (down from ~25s).

2. Bun runners failed the Set-Cookie assertions because Harper-on-Bun
   currently returns multiple Set-Cookie response headers as a single
   combined string instead of an array. The legacy
   test:integration:api-tests skips Bun entirely, so this code path was
   never exercised under Bun before. Skip the suite on Bun with a
   docstring noting the underlying runtime difference; this can be
   re-enabled once the Bun cookie serialization is aligned.

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

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't how I would've migrated these tests, but I'm not against this methodology either.

Since we are rewriting these test files anyways, why not make them TypeScript? Sticking with mjs only makes sense if we were sorta just copying the files over. But I'm seeing a noticeable difference between the old version and new version of the test.

Furthermore, supertest is okay I guess, but I really find it an unnecessary wrapper around pure assertions. Other integration tests demonstrate how using fetch directly and then asserting parts of the actual response. This is definitely my personal preference. I'm open to the client pattern too if that helps make it more DRY; but I often find it just makes us learn a new http client API. Just use Fetch!

Like I said, I'm not against this work. I think any migration of the old tests is great. This isn't how I would've done it, and that's okay. I don't really have the time to do the work myself right now 😅

@kriszyp
Copy link
Copy Markdown
Member Author

kriszyp commented May 15, 2026

This isn't how I would've migrated these tests,

Anything you would have done differently beyond the comments here?

Since we are rewriting these test files anyways, why not make them TypeScript?

Trying to do multiple multiple things at once has been the rationale beyond some of our biggest mistakes in the past. Feel free to share any other reasons, but I don't see that advancing the specific focus and scope of this effort: to move on to the new framework so we have isolated and parallelized execution of these tests.

@Ethan-Arrowood
Copy link
Copy Markdown
Member

Ethan-Arrowood commented May 15, 2026

Basically just switch to TypeScript and ditch supertest is the main things. Since we are tasking AI with doing it anyways I don't see as much harm in trying. I'm more confident the AI would get that conversion correct than myself.

I think that these API tests have great merit so as long as we are retaining what they are truly testing then I am happy.

From spending time with them in the past, I think some could be better organized. One of the tests converted here mentions that it had to add like tables to the before step that were previously created in another test file. One idea to make this cleaner is to have those tables defined via a fixture (with schema files) so that we don't have to use operations api like that one test does. And thus leverage the available integration testing method for running with a fixture.

Its edits like that that I would include as I convert the tests over.

Trying to do multiple multiple things at once has been the rationale beyond some of our biggest mistakes in the past.

I totally understand this sentiment

@Ethan-Arrowood
Copy link
Copy Markdown
Member

But again, I don't have the capacity to do this work myself so as much as these are my "wants" I'm all for whatever methodology the rest of the team wants to pursue to simply get these tests running more efficiently.

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.

2 participants