-
Notifications
You must be signed in to change notification settings - Fork 0
dom webview test infrastructure
Date: 2026-09-14 Tracking: Issue #210, sub-issues #211, #212, #213, #214, and #215
This repository has no infrastructure for testing DOM-manipulating code, so regressions in the webview layer (for example the dragleave bug found by automated review on PR #209) cannot be covered by unit tests:
-
tsconfig.test.jsonexcludessrc/webview/**/*and has noDOMlib. - The only webview-adjacent test (
assistantMessageFormatting.test.ts) covers a pure string-processing module with no DOM usage. -
slashMenu.test.tstestssrc/slashCommandIds.ts(an extension-host constant array), not theSlashMenuDOM class. -
hashMenu.test.tsdoes not exist.
This plan adds unit tests for the three DOM-manipulating webview classes that take their DOM dependencies through the constructor: src/webview/chatRenderer.ts (including the streaming rendering added by PR #237), src/webview/hashMenu.ts, and src/webview/slashMenu.ts.
src/webview/main.ts is out of scope. It runs acquireVsCodeApi(), the document.getElementById lookups, and every addEventListener registration as module-load-time side effects, so testing it needs a production refactor (an initWebview(deps) factory), which is a separate design decision. Wiring the dormant @vscode/test-electron Extension Host harness (src/test/runTests.ts / src/test/suite/index.ts) for end-to-end coverage is also out of scope.
-
happy-dom, notjsdom.jsdomdepends onwhatwg-encoding, whichsrc/test/suite/dependencyVersions.test.tsblocks (blockedPackages).happy-dom^20.14.5does not depend on it, installs 9 packages, needs noallowScriptsentry, and adds nonpm auditfindings. -
Security floor for
happy-dom.dependencyVersions.test.tsasserts that the declared and installedhappy-domversions are 20.0.0 or later, because GHSA-37j7-fg3j-429f (VM context escape leading to remote code execution) affects earlier releases. A floor is used instead of an exact pin so Dependabot updates do not break the test. -
Node.js 22.12 or later.
happy-domis published as an ES module only. The tests are compiled to CommonJS and load it withrequire(), which relies on Node'srequire(esm)support, available without a flag from Node.js 22.12.package.jsondeclaresengines.nodeas>=22.12.0, and the README states the same requirement. -
Single
tsconfig.test.json.libis["ES2020", "DOM"]andsrc/webview/**/*is no longer excluded. TheDOMlib is additive and does not change how the extension-host tests type-check. -
Fixture HTML comes from production. The shared utility calls
ChatViewProvider.getHtmlForWebview()with a stubvscode.Webviewand loads the real panel markup into happy-dom, so the fixture cannot drift from what ships. The provider module is loaded withvscoderesolved to a minimal stub, and the module cache entries added by that load are removed afterwards, sochatViewProvider.test.tsstill loads the provider with its own stubs. -
Locked-down happy-dom window. JavaScript evaluation stays disabled (the happy-dom 20 default), and JavaScript file loading, CSS file loading, iframe page loading, and navigation are disabled. The panel's
<script>tags are therefore parsed but never fetched or run. -
No DOM API stubs. happy-dom implements every DOM API the three classes call, including
Element.prototype.scrollIntoView,requestAnimationFrame,KeyboardEvent, andHTMLElement.click().
-
Phase 1 — Dependencies and build config (#211): Add
happy-dom^20.14.5to devDependencies, raiseengines.nodeto>=22.12.0, updatetsconfig.test.json, add thehappy-domfloor test, and update the README Node.js requirement. -
Phase 2 — Shared DOM test utilities (#212): New
src/test/suite/domTestUtils.ts.renderPanelHtml()returns the production panel HTML.installDom()creates the locked-down happy-dom window, writes the panel HTML into it, installs thewindow,document,requestAnimationFrame, andcancelAnimationFrameglobals, and returns adispose()that restores the previous globals and closes the window. Helpers create cancelableKeyboardEvents and a recordingpostMessagestub. -
Phase 3 —
chatRenderer.tstests (#213): Newsrc/test/suite/chatRenderer.test.ts. Covers user and assistant message rendering (kind,contextLabels, rich-text versus plain-text), the Copy/Append/Replace assistant actions, pinned-state sync (setPinnedItemsand cards built after pinning), the streaming lifecycle (beginAssistantStream→updateAssistantStreamreplacing rather than appending the cumulative text →finalizeAssistantMessagereusing the streaming bubble, plus the fallback that creates a bubble when no stream exists), result-card Open/Copy/PinpostMessagecalls, loading indicators, error banners, andclear()rebuilding#welcome. -
Phase 4 —
hashMenu.tstests (#214): Newsrc/test/suite/hashMenu.test.ts. Covers case-insensitive filtering with the 50-item cap, re-filtering onsetFileswhile open, selection-context edge cases (quoted paths, paths with spaces, tokens mid-text, trailing whitespace,#not preceded by whitespace), ArrowUp/ArrowDown/Enter/Tab/Escape handling witharia-activedescendant, and token-range replacement on keyboard and click selection. -
Phase 5 —
SlashMenuDOM tests (#215): A newsuite('SlashMenu (DOM)', ...)block in the existingsrc/test/suite/slashMenu.test.ts. Covers the constructor's immediate render of all slash commands, prefix filtering, combinable-command handling (/mail /teams), rejection of non-combinable previous tokens, and keyboard and click selection.
npm install
npx tsc -p ./tsconfig.test.json --noEmit
npm test
npm run lint
npm run security:checknpm install
npx tsc -p ./tsconfig.test.json --noEmit
npm test
npm run lint
npm run security:check- All new tests pass, and the existing suites, including the
whatwg-encodingblocklist assertion independencyVersions.test.ts, keep passing. - Adding
happy-domintroduces no newnpm auditfindings.
-
src/webview/main.tsis not refactored or unit-tested as part of this work. - The
@vscode/test-electronExtension Host harness is not wired up as part of this work. - No production code changes are needed to run the tests.