Skip to content

test: fix Windows flakes in cli standalone, Storybook and snapshot tests - #56181

Merged
neriousy merged 1 commit into
devfrom
windows-test-flakes
Oct 16, 2026
Merged

neriousy merged 1 commit into
devfrom
windows-test-flakes

Conversation

@neriousy

@neriousy neriousy commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Issue for this PR

No issue. Found by reviewing every Windows unit and e2e failure on dev pushes and PRs since #55866 merged.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Fixes or diagnoses the Windows flakes that recur across unrelated PRs and are not covered by an open PR. #55559 (service registration EPERM), #55988 (gui-extensions worker rpc) and #55881 (mobile timeline e2e) cover the others.

Storybook server crash (e2e (windows, app-components)). Two of the three recent Windows component failures (on focus-rings and fix-worker-rpc-flake) were Storybook dying mid-run, after which 97 and 109 tests failed with ERR_CONNECTION_REFUSED:

[WebServer] error: write after end
[WebServer]  code: "ERR_STREAM_WRITE_AFTER_END"
[WebServer] Bun v1.4.2 (Windows x64)
[WebServer] error: script "storybook" exited with code 1

This is oven-sh/bun#40350: Bun's node:http throws an uncaught "write after end" when a browser abandons pipelined requests, which kills the server. It is fixed in Bun 1.4.3 (oven-sh/bun#43557), but the repo pins 1.4.2. The Playwright web server ran Storybook with bun --bun; it now runs on Node, which Storybook targets (CI already installs Node 24.15 for these jobs). The app e2e suite is unaffected: its static server uses Bun.serve, not node:http.

Storybook on Node first hung at startup (100% CPU after the banner). Storybook checks main.ts for CommonJS with stripCommentsAndStrings, which removes string literals before comments using /(['"])(?:\.|(?!\1)[\s\S])*?\1/g. The apostrophe in a main.tscomment ("Storybook's optimizer plugin", added in #55866) opened a string that never closes, and the regex then backtracks exponentially over the backslashes later in the file: about 0.5s on Bun's JavaScriptCore, effectively forever on V8. The comment is reworded, with a note to keep apostrophes out ofmain.tscomments. The function is unchanged on Storybook'snext` branch (it came in with storybookjs/storybook#33572).

standalone server exits when its owner is killed (cli). Failed on a dev push with EBUSY from fs.rm on its temp directory, after every assertion had passed: Windows briefly keeps the exited server's files locked. The test now uses core's tmpdir fixture, which retries removal on EBUSY. Bun's fs.rm does not implement maxRetries (it is parsed only in a test-only validator), so the maxRetries: 20 in packages/cli/test/acp/subprocess.ts most likely does nothing.

Snapshot > captures concurrently from independent processes (core). Failed on Windows on #55866's dev push and on pack-libraries: a capture() returned undefined. capture() reports failures only through Effect.logWarning, and the test harness's TestConsole swallows that output, so the cause never reached the log. The test now collects warnings and prints them as the assertion message, so the next failure shows its cause. I could not reproduce it: a temporary commit ran the test 40 times on Windows CI (run) and all 40 passed, against 2 failures in roughly 30 Windows core runs since #55866. A fix should follow the first logged cause rather than a guess.

How did you verify your code works?

  • bun test test/standalone.test.ts in packages/cli: passes.

  • bun run script/test.ts test/snapshot.test.ts --rerun-each 10 in packages/core: 110/110. I also checked that the logger receives the failed to capture snapshot warning with its full cause chain by forcing a capture failure in a scratch test.

  • Storybook on Node (process tree shows node .../storybook dev), CI=true, locally on macOS:

    • bun --cwd packages/session-ui test:components: 141 passed.
    • bun --cwd packages/app test:components: 117 passed, 3 failed, 1 flaky. The same 3 tests (browser-pane-restore.spec.ts:123 and the two mobile variant drawer dismiss tests) also fail on this machine with the old bun --bun command, so they are local to my setup; they pass in CI.
  • bun typecheck in packages/core and packages/cli: clean.

  • Windows CI on this branch: unit (windows) passed, including the 40 repeats above; e2e (windows, app-components) 121/121 and e2e (windows, session-ui-components) 141/141 with Storybook on Node, nothing flaky.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@neriousy
neriousy force-pushed the windows-test-flakes branch from 511b775 to 004278d Compare October 16, 2026 16:13
@neriousy
neriousy marked this pull request as ready for review October 16, 2026 16:13
@neriousy
neriousy merged commit 0a03b4b into dev Oct 16, 2026
22 checks passed
@neriousy
neriousy deleted the windows-test-flakes branch October 16, 2026 16:24

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I found no blocking concerns.

To check the Storybook fix, I ran Storybook's string-stripping regex under Node 24 on both versions of main.ts. The old file was still running when I killed it after 20s; the reworded one took 0 ms. With this PR, bun run storybook starts under Node and serves the page. The core snapshot test passes and type checks are clean in cli and core. The standalone test fails the same way on base and on this branch in my Linux sandbox, so I couldn't confirm the Windows EBUSY fix here.

The public API is unchanged; only tests and Storybook config are touched.

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