You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The smoke test added in #2495 instantiates RemoteClawApp and asserts every required host-interface field is !== undefined on the class instance. This catches "production class missing initializers" (the original #2493 regression) but does NOT catch "production renders but layout is broken" — the regression class demonstrated by #2517 (sidebar wrappers missing → overflow: hidden clips content).
JSDOM doesn't apply most CSS, so layout assertions in JSDOM are mostly meaningless. But computed-style assertions ARE possible if we use a real browser harness (Playwright in headless mode) or the Vitest browser mode (already a dev dependency at @vitest/browser-playwright per ui/package.json).
Goal
Extend the existing class-instance smoke test to also assert key computed-style properties on the rendered DOM. Catch "rendered but visually clipped/hidden/wrong-sized" symptoms without requiring full visual regression baselines.
Concrete assertions to add
For the RemoteClawApp smoke test (running in browser-mode Vitest with real CSS applied):
describe("RemoteClawApp instance — computed-style smoke",()=>{beforeEach(async()=>{document.body.innerHTML='<remoteclaw-app></remoteclaw-app>';awaitnewPromise(r=>requestAnimationFrame(r));awaitnewPromise(r=>requestAnimationFrame(r));});it("sidebar has non-zero height (not clipped)",()=>{constsidebar=document.querySelector(".sidebar");expect(sidebar).not.toBeNull();constrect=sidebar!.getBoundingClientRect();expect(rect.height).toBeGreaterThan(300);// empirical threshold; tune to viewportexpect(rect.width).toBeGreaterThan(0);});it("topbar-status renders with non-zero width",()=>{conststatus=document.querySelector(".topbar-status");expect(status).not.toBeNull();expect(status!.getBoundingClientRect().width).toBeGreaterThan(0);});it("nav-section group headers are all visible (not clipped)",()=>{constgroups=document.querySelectorAll(".nav-section");expect(groups.length).toBeGreaterThanOrEqual(4);for(constgroupofgroups){constrect=group.getBoundingClientRect();// Each group is at least partially visibleexpect(rect.height).toBeGreaterThan(0);}});it("chat panel renders with non-zero area when on chat tab",async()=>{constapp=document.querySelector("remoteclaw-app")asany;app.tab="chat";awaitnewPromise(r=>requestAnimationFrame(r));constchat=document.querySelector("section.chat");expect(chat).not.toBeNull();constrect=chat!.getBoundingClientRect();expect(rect.height).toBeGreaterThan(100);expect(rect.width).toBeGreaterThan(100);});});
Test runner choice
The project already has @vitest/browser-playwright and playwright as dev dependencies (ui/package.json), and a vitest.config.ts that supports browser mode. Two integration paths:
Browser-mode Vitest in ui/src/ui/app.computed-style.test.ts — runs in a real browser instance via Playwright; CSS is applied; getBoundingClientRect returns real layout values
Standalone Playwright test in ui/test/e2e/layout.spec.ts — heavier setup; better suited for full visual regression (separate work item P-4)
Recommend option 1 (browser-mode Vitest) — uses existing infra, fast iteration, runs in pnpm test.
Acceptance criteria
New test file at ui/src/ui/app.computed-style.test.ts (or co-located with existing smoke test)
Tests run via existing pnpm test (or a dedicated pnpm test:browser if browser-mode requires separate config)
All 4 example assertions above pass on a healthy build
Re-introducing the #2517 regression (removing .shell-nav wrapper) makes the sidebar-height test FAIL
CI runs the browser-mode tests on PRs (may require GitHub Actions runner adjustment)
Documented in CLAUDE.md § Testing or a new § Visual Smoke Tests subsection
Test runtime overhead < 30s on CI (acceptable for the prevention value)
Why this catches future variants
Unlike the class-existence check (#2503) which only sees "is this class defined?", computed-style assertions see "did the rendered DOM end up with the expected dimensions?". Any structural drift, CSS rename without markup update, missing wrapper, or computed-style regression will surface as a layout assertion failure.
Trade-off: tests need maintenance when intentional layout changes occur (height thresholds need tuning). Acceptable cost for the regression class it prevents.
Estimated effort
2-4 hours: ~30 min set up browser-mode test config, ~1 h write the assertion suite, ~30-60 min verify on local + CI, ~30 min documentation.
References
Catches the regression class of: #2493, #2501, #2517
Problem
The smoke test added in
#2495instantiatesRemoteClawAppand asserts every required host-interface field is!== undefinedon the class instance. This catches "production class missing initializers" (the original#2493regression) but does NOT catch "production renders but layout is broken" — the regression class demonstrated by#2517(sidebar wrappers missing →overflow: hiddenclips content).JSDOM doesn't apply most CSS, so layout assertions in JSDOM are mostly meaningless. But computed-style assertions ARE possible if we use a real browser harness (Playwright in headless mode) or the Vitest
browsermode (already a dev dependency at@vitest/browser-playwrightperui/package.json).Goal
Extend the existing class-instance smoke test to also assert key computed-style properties on the rendered DOM. Catch "rendered but visually clipped/hidden/wrong-sized" symptoms without requiring full visual regression baselines.
Concrete assertions to add
For the
RemoteClawAppsmoke test (running in browser-mode Vitest with real CSS applied):Test runner choice
The project already has
@vitest/browser-playwrightandplaywrightas dev dependencies (ui/package.json), and avitest.config.tsthat supports browser mode. Two integration paths:ui/src/ui/app.computed-style.test.ts— runs in a real browser instance via Playwright; CSS is applied;getBoundingClientRectreturns real layout valuesui/test/e2e/layout.spec.ts— heavier setup; better suited for full visual regression (separate work item P-4)Recommend option 1 (browser-mode Vitest) — uses existing infra, fast iteration, runs in
pnpm test.Acceptance criteria
ui/src/ui/app.computed-style.test.ts(or co-located with existing smoke test)pnpm test(or a dedicatedpnpm test:browserif browser-mode requires separate config)#2517regression (removing.shell-navwrapper) makes the sidebar-height test FAILWhy this catches future variants
Unlike the class-existence check (
#2503) which only sees "is this class defined?", computed-style assertions see "did the rendered DOM end up with the expected dimensions?". Any structural drift, CSS rename without markup update, missing wrapper, or computed-style regression will surface as a layout assertion failure.Trade-off: tests need maintenance when intentional layout changes occur (height thresholds need tuning). Acceptable cost for the regression class it prevents.
Estimated effort
2-4 hours: ~30 min set up browser-mode test config, ~1 h write the assertion suite, ~30-60 min verify on local + CI, ~30 min documentation.
References
#2493,#2501,#2517#2495(class-instance presence smoke test),#2503(class-name lint)remoteclaw/hq#57(post-mortem) — third confirmed instance via#2517fork-syncskill: § "Definition-site sync without paired call-site update" → Mitigation Implement CLIRuntimeBase abstract class #6 (computed-style smoke tests)