Fix Follow Up UI tests timing out on a cold app.tsx import - #18
Merged
Merged
Conversation
… out The first test in app, picker and record-draft to load the app paid for a cold import of @hugeicons/core-free-icons, about 6,000 modules, inside its own 5s timeout. On a busy machine that took 5-11s, so one test per file failed, and which one moved with test order. Importing app.tsx at the top moves the cost to collection, as pill-removal already does with banner.tsx. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
matthewdias
added a commit
that referenced
this pull request
Oct 5, 2026
The registry checked `detail` (the first 8 rows, each needing a label and a value) and `open` (an http(s) or app-path href, nothing else). No surface draws either yet; the floating card would be the first. Released copies freeze what they validate, so a card that turned out to need 12 rows, a row without a value, or a click that runs a command would have had those stripped by every older copy, for good. Both are now reserved names that pass through like any field: copied as JSON, deep-frozen, inside the size cap. The first surface that draws them defines their shape, and it validates them before drawing, an href above all. What v1 still checks is exactly what a real surface has drawn: icon, label, tone, text and fraction. Nothing uses either field today, and nothing has been released, so COMPLICATIONS_IMPLEMENTATION stays at 1. Replaces the three validation tests with two that pin the pass-through, including an href arriving exactly as sent. Making either name validated again turns them red. Also moves the heavy imports in two new UI test files to the top of the file, as #18 did for Follow Up's older ones: the first load of the hugeicons package outlasted a test's timeout on a busy machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes the flaky Follow Up UI tests seen during #16. This PR changes tests only, so there is no version bump.
Cause
The flake was a cold import running inside a test's 5s timeout. It was not test order or state leaking between tests.
app.tsximports@hugeicons/core-free-iconsthroughsrc/handoff.tsxandcomponents/ui/icon*.tsx. That package's ESM entry re-exports about 6,000 per-icon modules. Imported cold under vitest, it took 7.6s and 11.1s in two timed runs. Everything elseapp.tsximports took under 2s together.Three files loaded the app with
loadPluginApp(() => import("../../app.tsx"))inside a test body:app.test.tsx,picker.test.tsxandrecord-draft.test.tsx. The first such test in each file paid the whole cost against vitest's 5s default and failed withTest timed out in 5000ms.pill-removal.test.tsxwas never affected, because it importsbanner.tsx, and with it the icons, at the top of the file.This explains #16. The "three unrelated failures" were one timeout per file, and whether they appear depends on machine load. They were never related to the deliberate break.
Reproduction on
a4da82e, with load average 34 to 73 on 16 coresnpx vitest runfailed 3 of 43 tests, every run. The failing tests took 10.4s, 10.1s and 10.6s.--maxWorkers=1gave the same 3 failures.Fix
The three files now import
app.tsxat the top and callloadPluginApp(pluginApp). The import cost moves to collection, where no per-test timeout applies, which is the same patternpill-removal.test.tsxalready uses.The SDK supports this.
loadPluginAppaccepts a module as well as a loader function, and in SDK 0.6.15definePluginAppand the hooks don't need the test runtime at import time. No timeouts, retries or assertions changed, and no test-only exports were added.Evidence
disabled: (composer) => false && …) and ran the suite 5 times. Each run failed onlyapp.tsx > offers the + menu row whenever the thread has open rows, banner open or not(42 of 43 passed).npm run checkat the repo root passes.Not changed
pill-removaltests share thethr_markthread in the store, and both seed the same rows.src/rpc.tsremembers the RPC client at module level, and everyrecord-drafttest that reads it sets it first.@hugeicons/core-free-icons/<Icon>) would make every load ofapp.tsxandbanner.tsxfast. That changes shipped code and needs a release, so it is left for a separate PR.🤖 Generated with Claude Code