7.2 KiB
TestWorkspaceApp
ワークスペース・アプリをヘッドレスブラウザで実起動し、操作・期待値検証・ファイルの変化確認を行う E2E テストツール。workspace-app ピースの verify ステップが自動的に呼び出す。
入力パラメータ
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
space |
string | ✓ | テスト対象スペースの ID |
app |
string | ✓ | apps/ 配下のアプリフォルダ名(パスではなく名前のみ) |
entry |
string | — | エントリー HTML のパス(スペースファイルルートからの相対)。省略時は apps/{app}/index.html |
seed_files |
array | — | テスト前にワークスペースへ書き込むファイル群(下記参照) |
steps |
array | — | ブラウザアクション列(BrowseWebAction と同じ形式、下記参照) |
expect |
array | — | 検証する期待値リスト(下記参照) |
timeout_ms |
number | — | ブラウザ操作全体のタイムアウト(ミリ秒、デフォルト 30000) |
seed_files
テスト開始前にワークスペースへ書き込むファイルを指定する。アプリが読み取る入力データを事前配置するために使う。
"seed_files": [
{ "path": "output/notes.md", "content": "# Hello\nworld" }
]
pathはワークスペースルートからの相対パス(resolveAndGuardでパストラバーサルを防ぐ)contentは UTF-8 文字列- 書き込んだファイルは
file_changesに記録される(bytes はシード時の書き込みサイズ)
steps(BrowseWebAction 形式)
ハーネスページ上で実行するブラウザ操作を配列で渡す。型は BrowseWebAction と共通。
| type | 追加フィールド | 説明 |
|---|---|---|
goto |
url |
指定 URL へ移動(ハーネス URL は自動で最初に追加されるため通常不要) |
click |
selector または ref |
要素をクリック |
fill |
selector または ref, value |
フォーム入力 |
screenshot |
value(ファイル名) |
スクリーンショットを撮影 |
getText |
— | ページのテキストを取得(期待値チェックに使われる) |
dumpHtml |
— | ページの HTML を取得 |
wait |
ms |
指定ミリ秒待機 |
ハーネスは起動時に自動的に goto → wait(2000ms) → getText を実行してからユーザー指定ステップを追加する。goto を先頭に追加する必要はない。
expect(期待値リスト)
| kind | フィールド | 説明 |
|---|---|---|
text |
target(CSS セレクタ), contains |
ページテキスト全体が contains を含む。target は情報的なセレクタ(精度向上には getText アクションを先に実行) |
file |
target(ワークスペース相対パス), contains |
指定ファイルが存在し、その内容が contains を含む |
重要: kind は "text" または "file" のみ有効。他の値は常に失敗として記録される(サイレントパスなし)。contains が空文字列の場合も評価は行われる(空文字列はどの文字列にも含まれるため通過)。
"expect": [
{ "kind": "text", "target": "[data-testid=\"status\"]", "contains": "保存OK" },
{ "kind": "file", "target": "output/notes.md", "contains": "edited-by-e2e" }
]
戻り値
{
"ok": true,
"failures": [],
"screenshots": ["app-test-myapp-final.png"],
"console_errors": [],
"bridge_calls": [],
"file_changes": [
{ "path": "output/notes.md", "bytes": 14 }
]
}
| フィールド | 説明 |
|---|---|
ok |
failures が空なら true |
failures |
失敗した期待値の説明(配列) |
screenshots |
撮影したスクリーンショットのファイル名一覧 |
console_errors |
ブラウザコンソールのエラーメッセージ |
bridge_calls |
V1 では常に [](ヘッドレス環境ではブリッジ呼び出しの観測不可) |
file_changes |
seed_files で書き込んだファイルの一覧と byte 数 |
テンプレートの e2e.example.json を使う
docs/examples/workspace-apps/{note-editor,data-viewer,form-input,dashboard}/e2e.example.json にひな型が入っている。TestWorkspaceApp に渡す JSON の例として使えるので、新しいアプリを作る際はここをコピーして改変する。
note-editor の例
{
"app": "note-editor",
"seed_files": [
{ "path": "output/note.md", "content": "seeded-content" }
],
"steps": [
{ "type": "click", "selector": "[data-testid=\"load\"]" },
{ "type": "getText", "selector": "[data-testid=\"status\"]" },
{ "type": "fill", "selector": "[data-testid=\"body\"]", "value": "edited-by-e2e" },
{ "type": "click", "selector": "[data-testid=\"save\"]" },
{ "type": "getText", "selector": "[data-testid=\"status\"]" }
],
"expect": [
{ "kind": "text", "target": "[data-testid=\"status\"]", "contains": "保存OK" },
{ "kind": "file", "target": "output/note.md", "contains": "edited-by-e2e" }
]
}
注意事項(ゴッチャ)
(a) seed_files の書き込みは本物の output/ に入る
seed_files で書き込んだファイルはワークスペースの実際のパスに書かれる。テスト用の一時領域ではなく、output/note.md を指定すれば本物の output/note.md が変更される。テスト後のクリーンアップはユーザー(またはエージェント)が行う必要がある。
(b) 書き込み確認ダイアログはハーネス側で自動承認される
ブラウザ内の writeFile / deleteFile ブリッジ呼び出しは、/app-harness ルートではダイアログが自動承認される。本番の /ui/app/... 上では確認ダイアログが表示されるので挙動が異なる。
(c) UI のビルドが必要
/app-harness ルートは Vite でビルドされた UI から配信される。npm run build:ui を実行していないと 404 になり、テストが失敗する。開発中は cd ui && npm run dev を起動してから dev モードで試すこともできる。
(d) bridge_calls は V1 では常に空
ヘッドレスブラウザ環境ではブリッジ呼び出し(readFile / writeFile など)の観測が技術的に困難なため、bridge_calls フィールドは常に [] を返す。ブリッジの動作確認は expect の kind: "file" でファイルの変化を確認することで代替する。
ワークフロー例
# 1. アプリを作成
Write({ path: "apps/note-editor/index.html", content: "..." })
# 2. E2E テストで動作確認
TestWorkspaceApp({
space: ctx.spaceId,
app: "note-editor",
seed_files: [{ path: "output/test-note.md", content: "# Test" }],
steps: [
{ type: "wait", ms: 1500 },
{ type: "getText" },
{ type: "screenshot", value: "after-load.png" }
],
expect: [
{ kind: "text", target: "body", contains: "Test" }
]
})
テストが通れば ok: true が返り、failures は空になる。