-
Notifications
You must be signed in to change notification settings - Fork 0
dom webview test infrastructure_ja
Kazushi Kamegawa edited this page Sep 13, 2026
·
2 revisions
日付: 2026-09-14 追跡: Issue #210、sub-issue #211、#212、#213、#214、#215
このリポジトリには DOM を操作するコードをテストする基盤がありません。そのため、webview 層の不具合(たとえば PR #209 の自動レビューで見つかった dragleave のバグ)をユニットテストで押さえられません。現状は次のとおりです。
-
tsconfig.test.jsonはsrc/webview/**/*を除外しており、libにDOMを含めていない。 - webview 関連の唯一のテスト
assistantMessageFormatting.test.tsは、DOM を使わない文字列処理モジュールだけを対象にしている。 -
slashMenu.test.tsがテストしているのはsrc/slashCommandIds.ts(拡張ホスト側の定数配列)で、DOM を操作するSlashMenuクラスではない。 -
hashMenu.test.tsは存在しない。
この計画では、DOM への依存をコンストラクタで受け取る3つのクラスにユニットテストを追加します。対象は src/webview/chatRenderer.ts(PR #237 で追加されたストリーミング描画を含む)、src/webview/hashMenu.ts、src/webview/slashMenu.ts です。
src/webview/main.ts は対象外です。このモジュールは、acquireVsCodeApi() の呼び出し、document.getElementById による要素の取得、すべての addEventListener の登録を、読み込んだ時点でトップレベルで実行します。テストするには本番コードを initWebview(deps) のようなファクトリ関数に切り出す必要があり、これは別の設計判断です。使われていない @vscode/test-electron の Extension Host ハーネス(src/test/runTests.ts / src/test/suite/index.ts)を配線して E2E で検証することも対象外とします。
-
jsdomではなくhappy-domを使う。jsdomはwhatwg-encodingに依存しており、このパッケージはsrc/test/suite/dependencyVersions.test.tsのブロックリスト(blockedPackages)に入っている。happy-dom^20.14.5はこれに依存せず、インストールされるのは 9 パッケージで、allowScriptsへの追加も不要、npm auditの指摘も増えない。 -
happy-domにセキュリティ上の下限を設ける。 GHSA-37j7-fg3j-429f(VM コンテキストから抜け出してリモートでコードを実行できる脆弱性)が 20.0.0 未満に該当するため、dependencyVersions.test.tsで宣言バージョンとインストール済みバージョンがどちらも 20.0.0 以上であることを検証する。完全一致で固定しないのは、Dependabot の更新でテストが壊れないようにするため。 -
Node.js 22.12 以上を必須にする。
happy-domは ES モジュールとしてのみ配布されている。テストは CommonJS にコンパイルされてrequire()で読み込むため、Node.js 22.12 からフラグなしで使えるrequire(esm)に依存する。package.jsonのengines.nodeを>=22.12.0とし、README にも同じ要件を書く。 -
tsconfig.test.jsonは1つのままにする。libを["ES2020", "DOM"]にし、src/webview/**/*の除外を外す。DOMライブラリは型を追加するだけなので、拡張ホスト側テストの型チェックは変わらない。 -
フィクスチャ HTML は本番コードから生成する。 共通ユーティリティがスタブの
vscode.Webviewを渡してChatViewProvider.getHtmlForWebview()を呼び、本番のパネル HTML を happy-dom に読み込む。これにより、フィクスチャが出荷されるマークアップとずれない。プロバイダのモジュールはvscodeを最小限のスタブに差し替えて読み込み、読み込みで増えたモジュールキャッシュのエントリをその後で削除する。こうすることで、chatViewProvider.test.tsは引き続き自前のスタブでプロバイダを読み込める。 -
happy-dom のウィンドウを制限する。 JavaScript の実行は無効のまま(happy-dom 20 の既定値)にし、JavaScript ファイル・CSS ファイル・iframe ページの読み込みとページ遷移も無効にする。パネルの
<script>タグは解析されるが、取得も実行もされない。 -
DOM API のスタブは作らない。 3つのクラスが呼ぶ DOM API(
Element.prototype.scrollIntoView、requestAnimationFrame、KeyboardEvent、HTMLElement.click()を含む)は、すべて happy-dom が実装している。
-
Phase 1 — 依存関係とビルド設定(#211): devDependencies に
happy-dom^20.14.5を追加し、engines.nodeを>=22.12.0に上げる。tsconfig.test.jsonを更新し、happy-domの下限テストを追加し、README の Node.js 要件を更新する。 -
Phase 2 — 共通 DOM テストユーティリティ(#212): 新規ファイル
src/test/suite/domTestUtils.ts。renderPanelHtml()は本番のパネル HTML を返す。installDom()は制限した happy-dom のウィンドウを作ってパネル HTML を書き込み、window、document、requestAnimationFrame、cancelAnimationFrameをグローバルに設定する。戻り値のdispose()は元のグローバルを戻してウィンドウを閉じる。キャンセル可能なKeyboardEventを作るヘルパーと、postMessageの呼び出しを記録するスタブも用意する。 -
Phase 3 —
chatRenderer.tsのテスト(#213): 新規ファイルsrc/test/suite/chatRenderer.test.ts。次をカバーする。- ユーザーとアシスタントのメッセージ描画(
kind、contextLabels、リッチテキストとプレーンテキストの判定) - アシスタントの Copy/Append/Replace 操作
- ピン状態の同期(
setPinnedItemsと、ピン留め後に作られたカード) - ストリーミングの一連の流れ。
beginAssistantStreamの後、updateAssistantStreamが累積テキストを追記ではなく置き換えること、finalizeAssistantMessageがストリーミング中の吹き出しを再利用すること。ストリームがない場合に新しい吹き出しを作るフォールバックも含む - 結果カードの Open/Copy/Pin による
postMessage - 読み込み中表示、エラーバナー、
clear()による#welcomeの再構築
- ユーザーとアシスタントのメッセージ描画(
-
Phase 4 —
hashMenu.tsのテスト(#214): 新規ファイルsrc/test/suite/hashMenu.test.ts。次をカバーする。- 大文字小文字を区別しない絞り込みと 50 件の上限
- メニュー表示中に
setFilesを呼んだときの再絞り込み - 入力位置の判定の境界ケース(クォート付きパス、スペースを含むパス、文中のトークン、末尾の空白、直前が空白でない
#) - ArrowUp/ArrowDown/Enter/Tab/Escape の処理と
aria-activedescendant - キーボードとクリックで選んだときに、該当トークンの範囲だけが置き換わること
-
Phase 5 —
SlashMenuの DOM テスト(#215): 既存のsrc/test/suite/slashMenu.test.tsにsuite('SlashMenu (DOM)', ...)を追加する。次をカバーする。- コンストラクタがすべてのスラッシュコマンドをすぐに描画すること
- 前方一致による絞り込み
- 組み合わせ可能なコマンドの扱い(
/mail /teams) - 組み合わせできない先行トークンがあるときにメニューを閉じること
- キーボードとクリックによる選択
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- 新しいテストがすべて成功し、既存のスイート(
dependencyVersions.test.tsのwhatwg-encodingブロックリストのテストを含む)も成功し続けること。 -
happy-domの追加でnpm auditの指摘が増えないこと。
-
src/webview/main.tsのリファクタリングとテストは対象外。 -
@vscode/test-electronの Extension Host ハーネスの配線は対象外。 - テストを動かすために本番コードを変更する必要はない。