playwright-interactive-sandbox について
playwright-interactive-sandbox は、Playwright でウェブアプリの変更を機能面と視覚面からエンドツーエンドで QA するスキルです。ユーザー向けコントロール、ビューポート適合、探索的テスト、スクリーンショットによる証跡を明確に確認する開発作業向けです。
主な機能
- 01共有 QA チェックリストの作成
- 02対象を絞った Playwright スクリプト
- 03デスクトップとモバイルのフロー検証
- 04機能 QA と視覚 QA の個別実施
- 05ビューポート適合と画面状態の確認
- 06スクリーンショットによる証跡保存
活用シーン
- 01ウェブアプリ変更後のフロー検証
- 02操作コントロールと状態変化の確認
- 03レスポンシブ表示とタッチ操作の確認
- 04スクリーンショットを使った視覚 QA の記録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ customware-ai/ skills --skill playwright-interactive-sandboxインストール後、Claude Code で/playwright-interactive-sandboxを入力して読み込まれたか確認します。
詳細
コアワークフロー
- テストの前に、簡潔な QA インベントリを作成します。
- ユーザーが求めた要件、実際に実装したユーザーに見える機能や動作、最終回答で述べる予定の内容の3つを情報源として、インベントリを作成します。
- これら3つの情報源のいずれかに含まれる内容はすべて、サインオフ前に少なくとも1つの QA チェックに対応付けます。
- サインオフする予定の、ユーザーに見える内容を列挙します。
- ユーザー向けの意味のあるコントロール、モード切り替え、実装したインタラクティブな動作をすべて列挙します。
- 各コントロールや実装した動作によって生じる状態変更や表示変更を列挙します。
- これを、機能 QA とビジュアル QA の両方で共有するカバレッジ一覧として使用します。
- 各内容またはコントロールと状態の組み合わせについて、実施する機能チェック、ビジュアルチェックを行う具体的な状態、取得する予定の証拠を記録します。
- 視覚的に重要で主観的な要件は、暗黙のままにせず、観察可能な QA チェックに置き換えます。
- 脆弱な動作を発見できる可能性のある、探索的なシナリオまたは通常とは異なる経路のシナリオを少なくとも2つ追加します。
- 必要な開発サーバーを、永続的な TTY セッションで起動するか、起動中であることを確認します。
- 変更したフロー専用の Playwright 検証スクリプトを作成します。
- まずデスクトップ用スクリプトを実行し、変更がモバイルレイアウトやタッチ操作に影響する場合は、モバイル用スクリプトも追加します。
- コードを変更するたびに、新しい Node.js プロセスから検証スクリプトを再実行します。
- 通常のユーザー入力を使って機能 QA を実施します。
- 別途、ビジュアル QA を実施します。
- ビューポートへの収まりを確認し、主張を裏付けるために必要なスクリーンショットを取得します。
- 成功した実行のスクリーンショット成果物を保存します。
デスクトップ検証スクリプト
デバッグ対象のアプリを TARGET_URL に設定します。ポート 4444 を使用し、localhost よりも 127.0.0.1 を優先してください。
このサンドボックスでは、Playwright ブラウザーは /ms-playwright にプリインストールされており、PLAYWRIGHT_BROWSERS_PATH がすでにその場所に設定されている場合があります。デフォルトのキャッシュパス ~/.cache/ms-playwright を使えるとは限りません。
この Debian サンドボックスでは、Playwright をヘッドレスモードで使用してください。環境に X サーバーが明示的に用意されていない限り、ヘッドありモードを試すことに時間をかけないでください。
この Debian サンドボックスでは、Playwright をヘッドレスモードで使用してください。環境に X サーバーが明示的に用意されていない限り、ヘッドありモードを試すことに時間をかけないでください。
この Debian サンドボックスでは、Playwright をヘッドレスモードで使用してください。環境に X サーバーが明示的に用意されていない限り、ヘッドありモードを試すことに時間をかけないでください。
import { chromium } from 'playwright';
const TARGET_URL = 'http://127.0.0.1:4444';
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1600, height: 900 }
});
const page = await context.newPage();
try {
await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });
console.log('Loaded:', await page.title());
// Add the task-specific interactions and assertions here.
await page.screenshot({ path: 'playwright-desktop.png', type: 'png' });
} finally {
await context.close().catch(() => {});
await browser.close().catch(() => {});
}
変更したメインフローには、このパターンを使用します。検証が必要な動作に合わせて、スクリプトの対象を絞ってください。
Playwright のブラウザーパスとインストール済みのブラウザーパッケージを確認する場合は、次を実行できます。
echo "$PLAYWRIGHT_BROWSERS_PATH"
ls -al /ms-playwright
実行チェックの例:
node /tmp/playwright-verify-desktop.mjs
モバイル検証スクリプト
タスクがレスポンシブレイアウトやタッチ操作に影響する場合は、モバイル用のスクリプトを別途使用します。
import { chromium } from 'playwright';
const TARGET_URL = 'http://127.0.0.1:4444';
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 390, height: 844 },
isMobile: true,
hasTouch: true
});
const page = await context.newPage();
try {
await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });
console.log('Loaded mobile:', await page.title());
// Add the task-specific interactions and assertions here.
await page.screenshot({ path: 'playwright-mobile.png', type: 'png' });
} finally {
await context.close().catch(() => {});
await browser.close().catch(() => {});
}
イテレーションモデル
- 現在の検証実行ごとに、単独の Node.js スクリプトを1つ使用します。
- コード変更後は、実行間で状態を保持しようとせず、新しいプロセスから検証スクリプトを再実行します。
- 各スクリプトの対象は絞り、変更したフロー、その主要なアサーション、スクリーンショット成果物に限定します。
- デスクトップとモバイルの両方が重要な場合は、1つの大きなステートフルなスクリプトにまとめず、別々のスクリプトまたは別々の実行を使用します。
チェックリスト
セッションループ
- 現在の検証実行用に、Node.js の Playwright 検証スクリプトを作成して実行します。
- 現在のワークスペースから対象の Web アプリを起動します。
- コードを変更します。
- 変更に適した方法で再読み込みまたは再起動します。
- 探索によって追加のコントロール、状態、表示上の主張が見つかった場合は、共有 QA インベントリを更新します。
- 機能 QA を再実行します。
- ビジュアル QA を再実行します。
- 評価対象の状態が現在の状態であることを確認してから、最終成果物を取得します。
再読み込みの判断
- レンダラーのみの変更:既存のページを再読み込みします。
- 現在のスクリプトが変更後の動作にも適合するか不明な場合:推測せず、新しいスクリプトを実行します。
機能 QA
- サインオフには実際のユーザー操作を使用します。キーボード、マウス、クリック、タッチ、または同等の Playwright 入力 API を使用してください。
- 重要なエンドツーエンドのフローを少なくとも 1 つ検証します。
- 内部状態だけでなく、そのフローの目に見える結果を確認します。
- リアルタイム性が高いアプリやアニメーションを多用するアプリでは、実際の操作タイミングでの動作を検証します。
- その場しのぎのスポットチェックではなく、共有 QA 項目リストに沿って確認します。
- サインオフ前に、メインの正常系だけでなく、目に見えるすべての明らかな操作要素を少なくとも 1 回確認します。
- 項目リストにある、元に戻せる操作要素や状態を持つ切り替え機能については、初期状態、変更後の状態、初期状態への復帰という一連のサイクルをテストします。
- スクリプトによるチェックに合格したら、想定された操作手順だけをたどるのではなく、通常の入力で 30~90 秒間、短い探索的テストを行います。
- 探索的テストで新しい状態、操作要素、または主張が見つかった場合は、共有 QA 項目リストに追加し、サインオフ前に確認します。
page.evaluate(...)は状態の調査や設定に使用できますが、サインオフのための入力とはみなされません。
ビジュアル QA
- ビジュアル QA は機能 QA とは別に行います。
- テスト前に定義し、QA 中に更新した同じ共有 QA 項目リストを使用します。暗黙の別リストをもとに、ビジュアル確認を始めないでください。
- ユーザーに見える主張を改めて列挙し、それぞれを明示的に検証します。機能テストに合格したからといって、視覚的な主張も証明されたとみなしてはいけません。
- ユーザーに見える主張は、それが認識されるべき具体的な状態で確認するまで、サインオフできません。
- スクロールする前に、最初のビューポートを確認します。
- 最初の表示が、インターフェイスの主要な主張を視覚的に裏付けていることを確認します。重要な要素がそこで明確に認識できない場合は、バグとして扱います。
- メインの操作領域だけでなく、確認が必要なすべての表示領域を確認します。
- 操作を伴うタスクでは、少なくとも 1 つの意味のある操作後の状態を含め、共有 QA 項目リストにすでに列挙されている状態とモードを確認します。
- 動きやトランジションが体験の一部である場合は、落ち着いた状態の開始点と終了点に加え、トランジション中の状態も少なくとも 1 つ確認します。
- ラベル、オーバーレイ、注釈、ガイド、ハイライトが変化するコンテンツに追従する想定である場合は、関連する状態変更の後に、その関係を検証します。
- 動的な表示や操作に依存する表示については、安定性、重なり順、読みやすさを判断できるだけの時間をかけて確認します。サインオフを 1 枚のスクリーンショットだけに頼ってはいけません。
- 読み込みや操作の後に表示が高密度になる可能性があるインターフェイスでは、空の状態、読み込み中の状態、折りたたまれた状態だけでなく、QA 中に到達できる最も現実的で高密度な状態も確認します。
- 製品でサポートする最小のビューポートサイズまたはウィンドウサイズが定められている場合は、そのサイズで別途ビジュアル QA を行います。定められていない場合は、現実的な範囲で小さめのサイズを選び、明示的に確認します。
- 要素が技術的には存在していても、コントラストの弱さ、他要素による隠れ、クリッピング、不安定さによって明確に認識できない場合は、存在と実装を区別し、ビジュアル上の不具合として扱います。
- 評価対象の状態で必要な表示領域がクリッピングされている、切れている、隠れている、またはビューポートの外に押し出されている場合は、ページ全体のスクロール指標に問題がなくても、バグとして扱います。
- クリッピング、オーバーフロー、歪み、レイアウトのバランスの悪さ、スペーシングの不統一、配置のずれ、読みにくいテキスト、コントラストの弱さ、重なり順の崩れ、不自然な動きを確認します。
- 正しさだけでなく、美的な質も評価します。UI は意図が感じられ、一貫性があり、タスクにふさわしく見た目もよいものであるべきです。
- サインオフにはビューポートのスクリーンショットを優先します。ページ全体のキャプチャは二次的なデバッグ資料としてのみ使用し、詳しく確認する必要がある領域は、対象を絞って撮影します。
- 動きによってスクリーンショットが判断しにくい場合は、UI が落ち着くまで少し待ってから、実際に評価する画像を撮影します。
- サインオフ前に、「このインターフェイスの目に見える部分で、まだ詳しく確認していないものは何か」と明示的に問いかけます。
- サインオフ前に、「ユーザーが注意深く見たとき、結果を最も台無しにする可能性の高い視覚的な不具合は何か」と明示的に問いかけます。
サインオフ
- 通常のユーザー入力で機能上のフローを確認しました。
- 共有 QA インベントリに照らして、カバレッジを明示してください。どの要件、実装済み機能、コントロール、状態、主張を検証したかを記録し、意図的に対象外とした項目も明記してください。
- ビジュアル QA では、関連するインターフェース全体を確認しました。
- ユーザーに見える各主張について、その主張が該当する状態とビューポートまたはウィンドウサイズで、対応するビジュアルチェックとレビュー済みのスクリーンショット成果物を用意しました。
- 想定される初期表示と、必要な場合はサポート対象の最小ビューポートサイズについて、ビューポートへの収まりを確認しました。
- UI は機能するだけでなく、視覚的にまとまりがあり、タスクに対して見た目が不十分ではありません。
- 機能の正しさ、ビューポートへの収まり、ビジュアル品質はそれぞれ独立して合格する必要があります。いずれかの合格が、ほかの合格を意味するわけではありません。
- インタラクティブな製品については、短い探索的確認を実施し、その確認内容を回答に記載しました。
- スクリーンショットのレビューと数値チェックに食い違いがあった場合は、サインオフ前に原因を調査しました。スクリーンショットで見えるクリッピングは、メトリクスで覆せるものではなく、解消すべき不具合です。
- 確認したうえで見つからなかった主な不具合の種類について、簡潔に否定確認を記載してください。
- エビデンスに必要な最終版の成功スクリーンショット成果物を保持し、失敗した実行や中間実行で作成された古い画像や置き換え済みの画像成果物は削除してください。
スクリーンショットのキャプチャ
エビデンスとデバッグには、通常の Playwright スクリーンショットを使用してください。
デスクトップのスクリーンショット:
await page.screenshot({ path: 'playwright-desktop.png', type: 'png' });
モバイルのスクリーンショット:
await mobilePage.screenshot({ path: 'playwright-mobile.png', type: 'png' });
特定の領域に焦点を当てたクリップ済みスクリーンショット:
const clip = await page.locator('[data-testid="target"]').boundingBox();
if (clip) {
await page.screenshot({ path: 'playwright-target.png', type: 'png', clip });
}
サインオフには、デフォルトでビューポートのスクリーンショットを使用してください。必要に応じて、フルページのスクリーンショットは補助的なデバッグ成果物としてのみ使用してください。
ビューポートへの収まりの確認(必須)
メインウィジェットが見えているというだけで、スクリーンショットに問題がないと判断しないでください。サインオフ前に、スクリーンショットのレビューと数値チェックの両方を用いて、想定される初期表示が製品要件を満たしていることを明示的に確認してください。
- サインオフ前に、想定される初期表示を定義してください。スクロール可能なページでは、これはファーストビューの表示内容です。アプリのようなシェル、ゲーム、エディター、ダッシュボード、ツールでは、これは操作に必要なコントロールとステータスを含む、インタラクティブな画面全体です。
- 収まりを確認するための主なエビデンスとして、スクリーンショットを使用してください。数値チェックはスクリーンショットを補助するものであり、目に見えるクリッピングを覆すものではありません。
- 想定される初期表示で、必須の表示領域がクリップされている、切れている、隠れている、またはビューポートの外に押し出されている場合、ページレベルのスクロールメトリクスが問題ないように見えても、サインオフは不合格です。
- スクロールする設計の製品では、初期表示で中核となる体験が伝わり、主要な行動喚起または必要な開始コンテキストが確認できる場合、スクロールは許容されます。
- 固定シェルのインターフェースでは、主要なインタラクティブ画面の一部や必須コントロールに到達するためにスクロールが必要となる場合、スクロールを回避策として使用してはいけません。
- ドキュメントのスクロールメトリクスだけに頼らないでください。固定高さのシェル、内部ペイン、非表示のオーバーフローを持つコンテナーでは、ページレベルのスクロールチェックに問題がなくても、必須 UI がクリップされることがあります。
- ドキュメントの境界だけでなく、領域の境界を確認してください。起動時の状態で、必須の表示領域がそれぞれビューポート内に収まっていることを検証してください。
- ビューポートへの収まりのチェックに合格したことが証明するのは、意図しないクリッピングやスクロールなしで、想定される初期表示が見えていることだけです。UI の見た目の正しさや、美観の良さを証明するものではありません。
Web またはレンダラーのチェック:
console.log(
await page.evaluate(() => ({
innerWidth: window.innerWidth,
innerHeight: window.innerHeight,
clientWidth: document.documentElement.clientWidth,
clientHeight: document.documentElement.clientHeight,
scrollWidth: document.documentElement.scrollWidth,
scrollHeight: document.documentElement.scrollHeight,
canScrollX: document.documentElement.scrollWidth > document.documentElement.clientWidth,
canScrollY: document.documentElement.scrollHeight > document.documentElement.clientHeight
}))
);
数値チェックに加えて、クリッピングが現実的に起こりうる UI では、必須の表示領域に対する getBoundingClientRect() チェックを追加してください。固定シェルでは、ドキュメントレベルのメトリクスだけでは不十分です。
開発サーバー
ローカルでウェブをデバッグする場合は、アプリを永続的な TTY セッションで実行し続けてください。短時間で終了するシェルから、一度きりのバックグラウンドコマンドを実行する方法には頼らないでください。
まずビルドし、その後、ビルド済みアプリをポート 4444 のみで起動します。
pnpm run build
PORT=4444 pnpm run start
page.goto(...) の前に、ポート 4444 がリッスンしており、アプリが応答することを確認してください。
- インタラクティブな検証が完了したら、ポート
4444で起動したサーバープロセスを停止し、タスクの残りの間、サンドボックスをクリーンな状態に保ってください。 - この Debian サンドボックスでは
fuserを使用できません。ss -ltnp | rg ":4444"を使ってリッスン中の PID を見つけ、kill <pid>を実行した後、もう一度ss -ltnp | rg ":4444"を実行して、ポート4444がリッスンされていないことを確認してください。 - クリーンアップ後、古い、または差し替えられたインタラクティブ画像の成果物を削除し、最終的に成功した証拠だけを残してください。
- インタラクティブな検証が完了したら、ポート
4444で起動したサーバープロセスを停止し、タスクの残りの間、サンドボックスをクリーンな状態に保ってください。 - この Debian サンドボックスでは
fuserを使用できません。ss -ltnp | rg ":4444"を使ってリッスン中の PID を見つけ、kill <pid>を実行した後、もう一度ss -ltnp | rg ":4444"を実行して、ポート4444がリッスンされていないことを確認してください。 - インタラクティブな検証が完了したら、ポート
4444で起動したサーバープロセスを停止し、タスクの残りの間、サンドボックスをクリーンな状態に保ってください。
よくある失敗
Cannot find module 'playwright':現在のワークスペースにplaywrightパッケージがインストールされていることを確認し、Node.js スクリプトを実行する前にインポートを検証してください。- Playwright パッケージはインストールされているのに、ブラウザーの実行ファイルが見つからないようです。まず
echo $PLAYWRIGHT_BROWSERS_PATHとls -al /ms-playwrightを確認してください。このサンドボックスでは、ブラウザーは~/.cache/ms-playwrightではなく/ms-playwrightにある想定です。そのディレクトリが存在しないか、使用できない場合に限り、npx playwright install chromiumを実行してください。 page.goto: net::ERR_CONNECTION_REFUSED:開発サーバーが永続的な TTY セッションで引き続き実行されていることを確認し、ポートを再確認して、http://127.0.0.1:<port>を優先してください。- Node.js プロセスが予期せず終了またはリセットされました。クリーンなプロセスから検証スクリプトを再実行してください。