Skip to content

Test the dashboard bundle, with no toolchain to maintain - #12

Merged
garethx merged 1 commit into
fix/queue-status-countsfrom
tests/dashboard-bundle
Aug 12, 2026
Merged

Test the dashboard bundle, with no toolchain to maintain#12
garethx merged 1 commit into
fix/queue-status-countsfrom
tests/dashboard-bundle

Conversation

@garethx

@garethx garethx commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Closes #9. Takes the issue's preferred option — no package.json, no lockfile, no second ecosystem.

The bundle takes React, its hooks, its components and its fetch from the injected window.__HERMES_PLUGIN_SDK__, so faking that SDK and running the file under node:vm exercises the shipped bytes with no install step. createElement returns plain objects instead of rendering: every question worth asking is which endpoint a button posts to and whether it is disabled, and neither needs a DOM. Node's built-in runner runs it, so CI gains a job and nothing else.

node --test "tests/dashboard/*.test.mjs"

Mutation-checked, which is the point

15 tests. Each guard was verified by breaking the bundle and confirming the suite fails:

Mutation Tests failing
c.paused ? "/pause" : "/resume" — toggle inverted 4
c.paused ? "Pause" : "Resume" — label inverted only 4
disabled: busydisabled: false 1
SDK guard removed 1
/retry/replay 1
registered as "hookdek" 14

The first two are the ones the issue was written for: a button labelled Pause that resumes, invisible on screen.

Two of my tests were wrong first time

Both passed against their own mutation, and both were the test's fault:

  • The SDK-guard test could not express what it claimed. The harness always built a complete SDK and merged the caller's over it, so "no SDK" was unrepresentable — it was asserting that a valid host loads. Added mountRaw(), which passes a window through verbatim.
  • The busy-on-failure test would have passed against anything. It asserted no button was left disabled, and a failed action swaps the whole page for the error card — which has no disabled buttons at all.

One correction to the issue

The third bullet expects setBusy(false) in act()'s catch to be what stops the panel wedging after a failed retry. It isn't. A failure sets error, which short-circuits the render to the error card, and that card's Retry has no disabled binding — so the way back is open whatever busy holds. Removing that line changes nothing observable, which is why the mutation survives every test I could write honestly. The test now asserts the recovery that actually exists: the error card appears, its Retry is enabled, and clicking it restores the page.

Not a reason to delete the line — it is correct and cheap — but it is belt-and-braces, not the guard.


Stacked on #11 (base fix/queue-status-counts, itself on #10). Retarget to main as the stack merges. Only tests/, .github/ and docs/ — nothing ships, so no release needed.

Closes #9.

`dist/index.js` ships in the wheel and had no tests of any kind. It was also
invisible in the 86% figure, which is Python only — so the number read better
than the coverage was.

Takes the issue's preferred option. The bundle gets React, its hooks, its
components and its fetch from the injected SDK, so faking that SDK and running
the file under `node:vm` exercises the shipped bytes with no package.json, no
lockfile and no second ecosystem. `createElement` returns plain objects rather
than rendering: every question here is about the tree and the requests, and
none of them need a DOM. Node's own test runner runs it, so CI adds a job and
nothing else.

15 tests, each one mutation-checked. Inverting the pause/resume expression,
inverting only its label, dropping `disabled: busy`, removing the SDK guard,
changing the retry endpoint and typo'ing the registered name all now fail.

Two of them failed to catch their mutation on the first pass, and both were
the test's fault rather than the code's:

* the SDK-guard test could not express "this host has no SDK", because the
  harness always built a complete one and merged the caller's over it. It was
  asserting that a valid host loads.
* the busy-on-failure test asserted no button was left disabled, and passed
  because a failed action swaps the whole page for the error card — which has
  no disabled buttons at all. It would have passed against anything.

The second is worth recording: the issue expected `setBusy(false)` in `act()`'s
catch to be what stops the panel wedging. It is not. The error card replaces
the page and its Retry has no `disabled` binding, so the way back is open
whatever `busy` holds. The test now asserts the recovery that actually exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@garethx
garethx merged commit dc1b13f into fix/queue-status-counts Aug 12, 2026
8 checks passed
garethx added a commit that referenced this pull request Aug 12, 2026
…#14)

* Report real counts from hookdeck_queue_status

Found by watching the agent answer with it. Asked what needed attention in a
project with four open issues, it said "1 page of open issues detected" and
then guessed at what that might mean.

The tool listed events and issues with `limit=1` and returned the length of
each page, so `failed_events_page_count` and `open_issues_page_count` could
only ever be 0 or 1. The names were honest and the numbers were useless: the
agent's primary status tool could not report how much of anything there was.

Issues have a dedicated count endpoint, so open issues are now counted exactly.
Events do not, so failures are counted over a page of 100 with
`failed_events_is_at_least` saying when that page was full — a floor the model
can report as a floor, rather than a ceiling it will report as a total.

Same question now answers "Open issues: 4".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Test the dashboard bundle, with no toolchain to maintain

Closes #9.

`dist/index.js` ships in the wheel and had no tests of any kind. It was also
invisible in the 86% figure, which is Python only — so the number read better
than the coverage was.

Takes the issue's preferred option. The bundle gets React, its hooks, its
components and its fetch from the injected SDK, so faking that SDK and running
the file under `node:vm` exercises the shipped bytes with no package.json, no
lockfile and no second ecosystem. `createElement` returns plain objects rather
than rendering: every question here is about the tree and the requests, and
none of them need a DOM. Node's own test runner runs it, so CI adds a job and
nothing else.

15 tests, each one mutation-checked. Inverting the pause/resume expression,
inverting only its label, dropping `disabled: busy`, removing the SDK guard,
changing the retry endpoint and typo'ing the registered name all now fail.

Two of them failed to catch their mutation on the first pass, and both were
the test's fault rather than the code's:

* the SDK-guard test could not express "this host has no SDK", because the
  harness always built a complete one and merged the caller's over it. It was
  asserting that a valid host loads.
* the busy-on-failure test asserted no button was left disabled, and passed
  because a failed action swaps the whole page for the error card — which has
  no disabled buttons at all. It would have passed against anything.

The second is worth recording: the issue expected `setBusy(false)` in `act()`'s
catch to be what stops the panel wedging. It is not. The error card replaces
the page and its Retry has no `disabled` binding, so the way back is open
whatever `busy` holds. The test now asserts the recovery that actually exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@garethx
garethx deleted the tests/dashboard-bundle branch August 12, 2026 12:46
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