control-ui について
ブラウザー自動化でローカルの Web、IDE、Electron の UI を検証するスキルです。既存のテスト環境を優先して使い、スクリーンショット、スナップショット、ログ、診断データを取得します。
主な機能
- 01ブラウザー操作のテスト
- 02スクリーンショットとスナップショット取得
- 03コンソール・ネットワークログ
- 04CPU・メモリ診断
- 05アクセシビリティと描画の確認
活用シーン
- 01フォーカスやキー操作の不具合再現
- 02視覚的な変更の検証
- 03ローカル Electron の動作確認
- 04変更前後の証拠の取得
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cursor/ plugins --skill control-uiインストール後、Claude Code で/control-uiを入力して読み込まれたか確認します。
詳細
コントロール UI
ローカルのブラウザー自動化を使って、証拠を残しながら UI の動作を検証します。まず、リポジトリに Playwright、ブラウザー、Electron のハーネスがあれば再利用し、なければアプリの開発サーバーまたは Chromium のデバッグポートを使って、一時的なローカルハーネスを構築します。
用途
- 実際のブラウザーでのフォーカス、キーボード入力、スクロール、サイズ変更、描画に依存する UI のバグを再現します。
- スクリーンショットやスナップショットで、視覚やアクセシビリティに関する変更を検証します。
- リリース前に、ローカルの Web、IDE、Electron の動作を確認します。
- コンソールログ、ネットワークログ、CPU プロファイル、トレース、ヒープスナップショットを取得します。
verify-this用に変更前後の証拠を作成します。
セットアップ手順
- リポジトリに記載されている開発コマンドを使って、アプリをローカルで起動します。
- 既存のローカルハーネスを探します。Playwright テスト、Cypress 仕様、Storybook、ブラウザースクリプト、Electron 起動スクリプト、スナップショットツールなどが対象です。
- Web アプリの場合は、既存のブラウザーツールを使ってローカル URL に接続します。
- Electron または Chromium の場合は、対応していればリモートデバッグポートを有効にします。
- タブの順番だけに頼らず、安定したアプリのマーカーを使って適切なページを選びます。
- 座標よりも、アクセシビリティロール、ラベル、安定した
data-*セレクターを優先します。
一般的な Web ハーネス
可能な場合は、リポジトリにインストール済みのブラウザーツールを使います。すでにリポジトリに Playwright がある場合、最小限の単発プローブは次のようになります。
import { chromium } from "playwright";
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto("http://127.0.0.1:<port>");
await page.getByRole("button", { name: /submit/i }).click();
await page.screenshot({ path: "/tmp/ui-harness-after.png", fullPage: true });
await browser.close();
ユーザーから依頼された場合を除き、このプローブだけのために Playwright をプロジェクトの依存関係に追加しないでください。既存の開発用依存関係か、環境で利用できる外部ブラウザーツールを優先してください。
一般的な CDP ハーネス
--remote-debugging-port=<port> を指定して起動した Electron または Chromium アプリの場合、CDP 経由で接続します。
import { chromium } from "playwright";
const browser = await chromium.connectOverCDP("http://127.0.0.1:<debug-port>");
const pages = browser.contexts().flatMap((context) => context.pages());
let page;
for (const candidate of pages) {
if (await candidate.locator("<app-root-selector>").count()) {
page = candidate;
break;
}
}
if (!page) {
console.log(await Promise.all(pages.map(async (p) => ({
title: await p.title(),
url: p.url(),
}))));
throw new Error("No matching app page found");
}
await page.screenshot({ path: "/tmp/ui-harness-cdp.png", fullPage: true });
await browser.close();
<app-root-selector> は、ルートアプリノード、ランドマーク、製品固有の data-* 属性など、現在のリポジトリにある安定したマーカーに置き換えてください。
操作のループ
- 操作する前に、ページのスナップショットまたはスクリーンショットを取得します。
- 最新のページ構造から対象を選びます。
- クリック、入力、キー押下、ドラッグ、スクロール、移動、サイズ変更のうち、構造に影響する操作を正確に 1 つだけ実行します。
- 新しいスナップショットまたはスクリーンショットを取得します。
- 期待した状態の変化を確認します。
- ユーザーから証拠を求められた場合は、変更前後の比較に使う成果物を保存します。
CDP の機能
上位レベルのブラウザー API では不十分な場合に限り、生の CDP を使います。
- パフォーマンス:CPU プロファイル、トレース、ペイントの点滅表示、FPS メーター、レイアウトシフトの調査。
- メモリ:リーク調査用のヒープスナップショットと強制 GC。
- ネットワーク:リクエストのブロック、スロットリング、キャッシュの無効化、リクエスト/レスポンスログ。
- レンダリング:ビューポートの変更、配色のエミュレーション、視差効果の低減、アクセシビリティのチェック。
- デバッグ:コンソールのストリーミング、例外の捕捉、DOM スナップショット。
ページの選択
複数のアプリウィンドウやタブがデバッグポートを共有している場合:
- テスト対象の画面を示す、アプリのルートセレクターなどの肯定的なマーカーを優先します。
- 必要に応じて、誤った画面を避けるために否定的なマーカーを使います。
- 一致するページがない場合は、推測せずに利用可能なページのタイトルと URL を一覧表示します。
注意事項
- ページ遷移や構造の変更後は、古い要素参照に頼らないでください。
- 直前に新しいスクリーンショットを取得していない限り、座標クリックは避けてください。
- テストデータはローカルに保ち、破棄できるようにしてください。
- ユーザーから明示的な同意を得ていない限り、プライバシーに配慮が必要なワークスペースのスクリーンショットやヒープスナップショットを保存しないでください。
- 他のリポジトリのセレクター、ポート、スクリプトパスをハードコードしないでください。現在のリポジトリにあるローカルアプリのマーカーを調べてください。
- 完了したら、開発サーバー、デバッグセッション、一時プロファイルをクリーンアップしてください。