筆者は Optics Framework の開発に関わっています。測定の詳細と録画は optics-framework.org の記事(英語) にあります。
Claude Code などの AI エージェントに E2E テストを作らせると、毎回の実行でモデルを呼ぶ構成になりがちです。Optics Framework の MCP サーバーを使うと、エージェントは一度だけブラウザーを操作して CSV のテストスイートを書き、以降の実行は optics execute だけで済みます。
この記事は、その設定手順と、作業中に気をつける点だけをまとめたメモです。検証環境は Optics Framework 1.11.0、Python 3.12、macOS、Claude Code です。
1. インストールと MCP の登録
pip install "optics-framework[mcp]"
optics setup --install playwright
claude mcp add optics -- optics mcp
Cursor、VS Code、Claude Desktop の設定例は 公式ドキュメント にあります。
2. プロンプトに入れるもの
プロンプトには次の 4 つを入れると、エージェントが迷いません。
- 開く URL(例:
https://www.saucedemo.com)と、Playwright でheadless falseにすること - 操作の手順(ログイン、カートに追加、購入など)
- 最後に確認する文字列(例:
"Thank you for your order!") - スイートを書くフォルダー(例:
./checkout)と、optics dry_runを実行すること
実際に使ったプロンプトはこちらです。
Use the optics tools to open https://www.saucedemo.com in Playwright with headless false.
Sign in as standard_user / secret_sauce, add the Sauce Labs Backpack to the cart,
open the cart, check out as Ava Birch with postcode 560001, finish the order,
and check that "Thank you for your order!" appears.
Then write it as an Optics suite in ./checkout, run optics dry_run on it,
and tell me how to run it.
3. loc を elements.csv の先頭に置く
エージェントは optics://session/{id}/elements リソース(または get_interactive_elements ツール)で画面の要素一覧を読みます。Web では各要素に loc が付くことがあり、これは Optics がブラウザー内で「この要素だけに一致する」と確認した CSS セレクターです。
{"i": 3, "label": "Login", "cls": "input", "bounds": [494, 302, 786, 351], "act": ["tap"], "rid": "login-button", "loc": "[data-test=\"login-button\"]"}
elements.csv では、1 列目に loc、2 列目に画面のラベルを書いておくと、再実行が安定します。
Element_Name,Element_ID,Element_ID_2
login_button,"[data-test=""login-button""]",Login
checkout_button,"[data-test=""checkout""]",Checkout
order_complete_header,text=Thank you for your order!,"[data-test=""complete-header""]"
今回のセッション(71 秒、ツール呼び出し 21 回)では、エージェントは 11 回のクリックと入力すべてで loc を使いました。
4. 再実行
optics execute checkout
API キーのない環境で 10 回実行し、10 回とも成功しました(中央値 3.3 秒)。Optics のプロセスからのネットワーク接続を記録したところ、モデル API への接続は 0 回でした。LLM クライアントが作られるのは ai_self_heal を true にしたときだけです。
5. フォールバックのログを見逃さない
1 列目のロケーターが壊れても、2 列目のラベルで実行は成功します。ただし、1 列目をタイムアウトまで待つので遅くなります。試しに Login ボタンの 1 列目を存在しないセレクターに変えると、このステップは約 0.1 秒から 10.2 秒になりました。
Locating element: [data-test="login-btn-v2"] of type: CSS...
Locating element: Login of type: Text...
Pressing element 'Login'
このログが出たら、1 列目を直すタイミングです。
注意点
-
optics dry_runはファイルの検査だけで、アプリは開きません。CI に入れる前にoptics executeを 1 回実行してください。 -
locは Web のみです。Android と iOS では要素一覧の ID とラベルを使います。 -
optics mcp --transport httpには認証がありません。127.0.0.1 で使ってください。 - 座標でタップするツールは既定で無効です(
OPTICS_MCP_ALLOW_COORDINATE_TAPSで有効化)。