Repository navigation
End-to-end harness and the core loop journey (Playwright over aimock) - #1521
Merged
Merged
Conversation
bun run test:e2e runs Playwright against a fresh, isolated local stack (scripts/start.sh, personal edition, its own compose project, image tags and 46xxx ports) with every model call answered by aimock in strict replay. bun run test:e2e:record re-captures fixtures from the real provider; the key goes to aimock only. The first journey is the core loop: first-run setup, an OpenAI key added in the Vault, a question to the Personal Assistant, the answer rendered whole from one run, and the conversation named. aimock matches exactly (requestTransform), because by substring the Bot's own fixture answered the conversation-naming call. The naming call's answer excerpt is cut before matching, since whether it is there depends on timing. start.sh gains OPENBOT_LOG_DIR and OPENBOT_PERSON_BROWSER=off so a second stack from one checkout neither overwrites .logs nor opens Chrome.
davidmckayv
requested review from
MikeRyanDev,
dustywusty,
guidovizoso,
mxmzb,
samjulien and
tylerslaton
as code owners
November 12, 2026 20:33
This was referenced Nov 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
bun run test:e2e: Playwright against the real OpenBot, in a real browser, on a real local stack, with every model call answered by aimock in strict replay. Slice 1 of the end-to-end suite: the harness and the core loop. Runs on a developer's machine; CI does not run it (by design).The stack
Each run brings up its own fresh stack with
scripts/start.sh(it never reuses one): personal edition (one person, no sign-in, the Personal Assistant), compose projectopenbot-e2e, its own image tags (so--buildnever replacesopenbot-agent-computer:latestunder another stack), ports 46xxx, a new database every run. A stack already running on the machine (OpenBot Desktop on 3001/3010/5432, a dev stack, another worktree) is not touched.E2E_KEEP_STACK=1leaves it up afterwards.scripts/start.shgains two opt-in settings for that:OPENBOT_LOG_DIR(logs beside the screenshots, not over.logs/) andOPENBOT_PERSON_BROWSER=off(no Chrome window on the developer's desktop, as OpenBot Desktop runs).Model traffic
All of it is OpenBot's own and goes to aimock:
OPENAI_BASE_URLandANTHROPIC_BASE_URLpoint at it, with dummy keys, before the server starts. On the core loop that is the Personal Assistant's run (POST /v1/responses), the skill chooser and the conversation's name (POST /v1/chat/completions), and the model list (GET /v1/models). models.dev capability data is switched off so the model stays the package's.Not mocked because they are not model calls: Intelligence (licence, thread storage, the events the run is checked against). Automatic Learning, which would send conversations to Intelligence's own models, is not set up for the run.
Strict replay
strict, never proxy-only. A request no fixture answers fails the test that made it, naming it; after a rungrep -c -E "NO FIXTURE MATCH|STRICT:" e2e/.artifacts/logs/aimock.logmust print 0.requestTransform. By substring, the Bot's fixture for the person's question also answered OpenBot's conversation-naming call (which quotes the question), so the conversation was "named" with the Bot's reply and no naming fixture was ever recorded. That was a silent false pass; exact matching removes it.sk-aimock-dummy that aimock swaps on the way out. A recording containing the key is deleted and fails the test.The core loop journey
Fresh stack, then as a person: Welcome, OpenBot for Business, name; Settings, Setup says the AI model needs a key and links to the Vault, where an OpenAI key is added (a dummy); a question to the Personal Assistant; the answer on screen is exactly what the run streamed, once; one run (one
RUN_STARTEDin the conversation's events, onerun-modelline in the server log, one model call); the conversation gets a generated name that is neither the question nor the answer. Every step saves a full-page screenshot toe2e/.artifacts/screenshots/core-loop/.Run on a Mac
NO FIXTURE MATCH/STRICTlines, 3 of 3 model requests matched.STRICT: No fixture matched for POST /v1/responseslines, the journey failed on the run not finishing and on the strict-replay check listing each missed request. Fixture restored, green again.Best practice followed
expect.poll, no fixed sleeps, isolated contexts (best practices); aimock as awebServerwith a URL readiness check (web server); stack bring-up and teardown as a setup project withteardown, the documented alternative toglobalSetup(global setup and teardown).userMessagematching underrequestTransform(fixtures).e2e/README.mdcovers running, recording, fixture scope and adding a journey.