Symptom
PlaygroundExampleTests.Compiles_and_runs_user_code_live_in_the_browser fails from a fresh worktree with a 30s timeout clicking .pg-run:
locator resolved to <button disabled ... class="btn btn-primary btn-sm pg-run">Run ▸</button>
- element is not enabled
The page boots and the Run button renders, so the 90s visibility wait passes. The button is simply disabled forever, and the click uses the default 30s timeout rather than the generous headroom the following assertions get.
Root cause
The published wwwroot had no _rask scoped-asset directory at all — zero files — so PlaygroundView.js was never served:
find samples/Rask.Example.Playground/bin/Release/net10.0-browser/publish/wwwroot/_rask -type f | wc -l
0
PlaygroundView.OnRenderedAsync awaits Rask.PlaygroundView.mountEditor, and only sets _editorReady = true afterwards. With the module missing that await never completes, so _editorReady stays false and Disabled: _busy || !_editorReady || IsActiveChapterLocked keeps Run disabled permanently.
Deleting samples/Rask.Example.Playground/{obj,bin} and republishing produces 6 files under _rask, and the test then passes in 7 seconds.
So this is the known static-web-assets/incremental-build glitch, but with a much worse failure mode than usual: the app builds, publishes, boots and renders, and only the editor is quietly missing.
Why it matters
- The E2E gate is not reproducible from a clean checkout. It passes in a warm worktree and fails in a fresh one, which is backwards — the fresh one is the honest test. A contributor's first run of the gate fails on something they didn't touch.
- It fails silently in the direction that looks like a product bug. The symptom is "the playground is broken", not "the build is incomplete", so the natural next step is to go debugging the compiler or Monaco.
- Encountered while running the gate for an unrelated PR (a new
Rask.ObjectStore package that cannot reach the playground — it shares none of its project references).
Suggested fixes
- Make the failure loud.
BakeScopedAssetsTask already logs wrote N file(s); a project that has scoped assets and bakes 0 should fail the build rather than log it. There is already a FailOnEmpty path (BakeScopedAssetsTaskTests.FailOnEmpty_WhenRegistryResolvedButZeroBaked_ReturnsFalseAndLogsError) — it appears not to be engaged here.
- Make the app fail loudly too.
mountEditor is documented as never throwing (it falls back to a textarea), but a missing module isn't a mount failure — the interop await just never returns. A timeout or a guard that surfaces "editor module missing" would turn a permanent disabled button into a diagnosable error.
- Have
scripts/run-e2e-local.sh clean the playground's obj/bin before its publish, since that publish is already the one step that re-restores and takes the native relink.
Related: the repo already carries knowledge that a clean WASM obj/bin plus a serial build works around static-web-assets glitches; this is the same family.
Symptom
PlaygroundExampleTests.Compiles_and_runs_user_code_live_in_the_browserfails from a fresh worktree with a 30s timeout clicking.pg-run:The page boots and the Run button renders, so the 90s visibility wait passes. The button is simply disabled forever, and the click uses the default 30s timeout rather than the generous headroom the following assertions get.
Root cause
The published
wwwroothad no_raskscoped-asset directory at all — zero files — soPlaygroundView.jswas never served:PlaygroundView.OnRenderedAsyncawaitsRask.PlaygroundView.mountEditor, and only sets_editorReady = trueafterwards. With the module missing that await never completes, so_editorReadystaysfalseandDisabled: _busy || !_editorReady || IsActiveChapterLockedkeeps Run disabled permanently.Deleting
samples/Rask.Example.Playground/{obj,bin}and republishing produces 6 files under_rask, and the test then passes in 7 seconds.So this is the known static-web-assets/incremental-build glitch, but with a much worse failure mode than usual: the app builds, publishes, boots and renders, and only the editor is quietly missing.
Why it matters
Rask.ObjectStorepackage that cannot reach the playground — it shares none of its project references).Suggested fixes
BakeScopedAssetsTaskalready logswrote N file(s); a project that has scoped assets and bakes 0 should fail the build rather than log it. There is already aFailOnEmptypath (BakeScopedAssetsTaskTests.FailOnEmpty_WhenRegistryResolvedButZeroBaked_ReturnsFalseAndLogsError) — it appears not to be engaged here.mountEditoris documented as never throwing (it falls back to a textarea), but a missing module isn't a mount failure — the interop await just never returns. A timeout or a guard that surfaces "editor module missing" would turn a permanent disabled button into a diagnosable error.scripts/run-e2e-local.shclean the playground's obj/bin before its publish, since that publish is already the one step that re-restores and takes the native relink.Related: the repo already carries knowledge that a clean WASM obj/bin plus a serial build works around static-web-assets glitches; this is the same family.