Skip to content

E2E: the playground publish silently omits its scoped assets, disabling Run forever #650

Description

@pal-tamas

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

  1. 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.
  2. 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.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions