argent-device-interact について
コーディングエージェント向けのデバイス操作スキルです。iOS、Android、Chromium を共通のツール手順で扱い、アプリ起動、UI 検出、ジェスチャー、キーボード入力、待機によるテストや調査を支援します。
主な機能
- 01対応ターゲット共通の操作
- 02アプリ起動と URL の表示
- 03アクセシブルな UI 要素の確認
- 04ジェスチャー、キーボード、ハードウェアボタン
- 05UI 要素または画面の静止待ち
活用シーン
- 01シミュレーターやエミュレーターでアプリのフローを実行
- 02画面操作の前に要素を確認
- 03URL スキームやキーボード操作をテスト
- 04再現可能な UI 操作シーケンスを自動化
MCP 対応
このスキルは、デバイスや Chromium ターゲット向けに、UI 検出や入力操作を含む共通の操作ツール群を説明します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ software-mansion/ argent --skill argent-device-interactインストール後、Claude Code で/argent-device-interactを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/chromium.mdgesture-examples.mdharmonyos.mdsecrets.md詳細
統一されたツールサーフェス
以下のすべての操作ツールは udid パラメーターを受け取り、その形式に応じて iOS と Android を自動的に振り分けます(UUID → iOS シミュレーター、chromium-cdp-<port> → Chromium(CDP)アプリ、それ以外 → Android adb シリアル)。すべてのプラットフォームで同じツール名を使用します。
Chromium(CDP)アプリとは、Chrome DevTools Protocol エンドポイントを公開している Electron アプリ、または Chromium 系ブラウザー(Chrome/Brave/Edge)です。同じ describe/tap/keyboard/screenshot の操作サーフェスで操作できますが、スクロール、タブ、Cookie、ストレージの扱いは異なります。chromium ターゲットを操作する前に、references/chromium.md を読んでください。
1. 開始する前に
シミュレーター関連のタスクをサブエージェントに委任する場合は、MCP の権限があることを確認してください。
list-devices を使ってターゲット ID を取得します。結果には platform(ios、android、chromium)が付いており、起動済み/準備完了のデバイスが先に表示されます。harmony ターゲットの場合は、操作する前に references/harmonyos.md を読んでください。必要なプラットフォームに一致する最初の項目を選びます。準備完了のデバイスがない場合は、udid(iOS)、avdName(Android)、または electronAppPath(Electron アプリを chromium デバイスとして起動)を指定して boot-device を呼び出します。すでに実行中の Chromium ブラウザーは CDP ポートとともに直接表示されるため、boot-device は不要です。セットアップの全手順については、argent-ios-simulator-setup/argent-android-emulator-setup を参照してください。
最初にツールスキーマを読み込んでください。 ジェスチャーツール(gesture-tap、gesture-swipe、gesture-pinch、gesture-rotate、gesture-custom)は、パラメータースキーマが取得されるまで読み込みが保留される場合があります。使用するジェスチャーツールのスキーマは、呼び出す前に必ず ToolSearch で読み込んでください。この手順を省くと、パラメーターが数値ではなく文字列に変換され、検証エラーが発生する場合があります。
2. ベストプラクティス
- タップする前に、必ず argent.md のルールにある tapping_rule を参照してください。
- 操作を実行する前に、順番にディスパッチできるかどうかを検討してください。詳しくは
run-sequenceを参照してください。 - リストの操作やスクロールには、
gesture-customではなくgesture-swipeを使ってください(非線形の動きが必要な場合を除きます)。Chromium では代わりにgesture-scrollを使います。gesture-swipeはタッチ操作専用です。スワイプが複数回必要な場合はrun-sequenceを使ってください。正確に移動するため、終了前に減速させる必要がある場合はmomentum: falseを指定します。 - 入力する前にテキストフィールドをタップし、その後
keyboardを使ってテキストを入力してください。 - 座標は正規化されています。ピクセルではなく、常に 0.0~1.0 の値を使ってください。
- アプリ内を移動する際は、各操作の後に返される要素ツリー(
--- Elements after action (describe) ---)を使ってください。現在の画面について新しいツリーがない場合に限り、describeを呼び出します。アプリを再起動せず、どの画面でも動作します。ツリーで信頼できるターゲットを取得できなかった場合を除き、通常のアプリ内画面ではスクリーンショットのピクセルを基に移動しないでください。アプリ単位の UIKit プロパティが必要な場合にのみnative-describe-screenを使ってください。
3. アプリを開く
ホーム画面のアイコンをタップしてアプリを開かないでください。 launch-app または open-url を使ってください。これらはすぐに実行され、確実です。
launch-app:バンドル ID を指定
{ "udid": "<UDID>", "bundleId": "com.apple.MobileSMS" }
一般的な ID:com.apple.MobileSMS(メッセージ)、com.apple.mobilesafari(Safari)、com.apple.Preferences(設定)、com.apple.Maps、com.apple.mobileslideshow(写真)、com.apple.MobileAddressBook(連絡先)
open-url:URL スキームを指定
{ "udid": "<UDID>", "url": "messages://" }
一般的なスキーム:messages://、settings://、maps://?q=<query>、tel://<number>、mailto:<address>、https://...(Safari)
4. 適切なツールの選択
| 操作 | ツール | 備考 |
|---|---|---|
| 複数の操作 | run-sequence | 1 回の呼び出しで手順をまとめて実行します(途中のスクリーンショットは取得しません) |
| アプリを開く | launch-app | 必ず守ること:ホーム画面のアイコンはタップしないでください |
| アプリを再起動する | restart-app | バンドル ID を指定して終了し、再起動します |
| URL/スキームを開く | open-url | ウェブページ、ディープリンク、URL スキーム |
| 1 回タップする | gesture-tap | ボタン、リンク、チェックボックス |
| スクロール/スワイプ | gesture-swipe | 直線的なスクロールまたはスワイプ |
| スクロール(Chromium) | gesture-scroll | ホイール式。デルタ値はウィンドウに対する割合で、正の deltaY は下方向 |
| ドラッグ(Chromium) | gesture-drag | スライダー、ドラッグ&ドロップ、テキスト選択 |
| 長押し | gesture-custom | コンテキストメニュー、ドラッグの開始 |
| ドラッグ&ドロップ | gesture-custom | 複雑なドラッグ操作 |
| ピンチ/ズーム | gesture-pinch | 自動補間による 2 本指のピンチ |
| 回転 | gesture-rotate | 自動補間による 2 本指の回転 |
| カスタムジェスチャー | gesture-custom | 任意のタッチ操作シーケンス。補間は任意 |
| ハードウェアキー | button | ホーム、戻る、電源、音量、アプリ切り替え、アクションボタン |
| テキストを入力する | keyboard | すべてのプラットフォーム。1 回の呼び出しにつき、テキストまたは名前付きキー 1 つを指定します。両方は指定できません |
| テキストを貼り付ける | paste | ユーザーが貼り付ける場面のみ(OTP コード、長いリンク)。シミュレーター/エミュレーターのみ |
| デバイスを回転する | rotate | 画面の向きを変更します |
| デバイスを折りたたむ | fold | 折りたたみ式シミュレーター/エミュレーター:閉じた状態/半開き/開いた状態、または角度を指定 |
| デバイスを振る | shake | シェイクハンドラー(シミュレーター/エミュレーターのみ)、入力取り消しプロンプト、RN 開発メニュー |
| UI を待つ | await-ui-element | 要素が表示/非表示になる、存在する、またはテキストを含むまで待機します |
| アイドル状態を待つ | await-screen-idle | 空ではない画面ツリーの変化が止まるまで待機します |
5. タップ対象の特定
重要です。操作後に別の画面へ移動した場合や、コンポーネントの座標がわからない場合は、必ず最初に適切な検出を行ってください。
| アプリの種類 | 検出ツール | 返される内容 |
|---|---|---|
| 対象アプリの検出 | describe | 正規化されたフレーム座標を含む、現在のデバイス画面のアクセシビリティ要素ツリー(iOS AX-service、Android uiautomator、または Chromium DOM walker)。あらゆるアプリ、システムダイアログ、ホーム画面で動作し、アプリの再起動や bundleId は不要です |
| React Native | debugger-component-tree | 名前、テキスト、testID、および(タップ位置:x,y)を含む React コンポーネントツリー |
| アプリスコープのネイティブ | native-describe-screen | 正規化座標と生の座標を含む、低レベルのアプリスコープのアクセシビリティ要素。bundleId が必要です |
| 権限/システムモーダルオーバーレイ | describe | describe はシステムダイアログを自動的に検出し、タップ座標付きのダイアログボタンを返します。describe でコントロールが見つからない場合に限り、screenshot にフォールバックしてください |
| 最後の視覚的な代替手段 | screenshot | 検出ツールで現在の UI を確実に調査できない場合にのみ使用してください。通常のアプリ内ナビゲーションの対象をスクリーンショットから推測しないでください |
候補となる座標を取得した後の、位置指定によるネイティブ診断ツール:
native-user-interactable-view-at-point:既知の生の iOS 座標において、タッチを受け取る最も深いネイティブビュー。bundleIdが必要ですnative-view-at-point:既知の生の iOS 座標において、表示されている最も深いネイティブビュー。bundleIdが必要です
describe ツールが失敗した場合
正確なエラーを読み、その内容に合った対処を選んでください。
- エラーに
ax-serviceが利用できない、またはデーモンの起動失敗と記載されている場合: ax-service デーモンを起動できませんでした。シミュレーターが起動していることを確認してください。一時的な代替手段としてscreenshotを使用するか、アプリにネイティブ devtools が注入されている場合は、明示的なbundleIdを指定してnative-describe-screenを使用してください。 describeが空の要素リストを返す場合: 画面が空白、読み込み中、またはアクセシビリティラベルのないコンテンツを表示している可能性があります。screenshotを使って表示内容を確認し、コンテンツの読み込み後に再試行してください。describeは成功するものの、React Native アプリの詳細が不十分な場合: 次にdebugger-component-treeを使用してください。- UIKit のプロパティ(
accessibilityIdentifier、viewClassName)をすべて含むアプリスコープの調査が必要な場合: 明示的なbundleIdを指定してnative-describe-screenを使用してください。これにはネイティブ devtools(dylib)の注入が必要です。 - 候補となる座標がすでにあり、実際にどのビューがタッチを受け取るか確認したい場合:
native-user-interactable-view-at-pointを使用してください。ヒットテストの対象ではなく、視覚的に最も深いビューを確認したい場合はnative-view-at-pointを使用してください。
6. ツールの使用
gesture-tap:指定した位置をシングルタップ
{ "udid": "<UDID>", "x": 0.5, "y": 0.5 }
座標:0.0 = 左端/上端、1.0 = 右端/下端。
React Native アプリで画面下部付近をタップする前に、「Open Debugger to View Warnings」バナーが表示されていないことを確認してください。バナーをタップすると、デバッガーとの接続が切れます。表示されている場合は、X アイコンで閉じてください。
gesture-swipe:直線のジェスチャー
{ "udid": "<UDID>", "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 }
上へのスワイプ(fromY > toY)=コンテンツを下へスクロールします。デフォルトの時間:300ms。オプション:スワイプを遅くするには "durationMs": 500 を指定します。
"momentum" のデフォルトは true(自然な勢いのあるスワイプ)です。勢いをつけずにスワイプするには "momentum": false を渡します。指が減速しながら終点に到達するため、勢いによるスクロールはほとんど、またはまったく発生しません。この場合、durationMs は150以上である必要があり、それより小さい値は拒否されます。
gesture-pinch:2本指のピンチ
{ "udid": "<UDID>", "centerX": 0.5, "centerY": 0.5, "startDistance": 0.2, "endDistance": 0.6 }
すべての値は0.0~1.0に正規化されます(ピクセルではなく画面に対する割合)。ほかのすべてのジェスチャーツールと同じです。startDistance: 0.2 は、指が画面幅の20%離れた位置から始まることを意味します。endDistance: 0.6 は、指が画面幅の60%離れた位置で終わることを意味します。startDistance < endDistance = ピンチアウト(拡大)。startDistance > endDistance = ピンチイン(縮小)。デフォルト:angle: 0(水平)、durationMs: 300。オプション:垂直方向にするには "angle": 90、ピンチを遅くするには "durationMs": 500、ジェスチャー中に重心を新しい中心へ移動させるには "endCenterX"/"endCenterY" を指定します(省略した場合は中心を固定します)。
gesture-rotate:2本指の回転
{
"udid": "<UDID>",
"centerX": 0.5,
"centerY": 0.5,
"radius": 0.15,
"startAngle": 0,
"endAngle": 90
}
すべての位置と半径は0.0~1.0に正規化されます(ピクセルではなく画面に対する割合)。radius: 0.15 は、各指が中心から画面幅の15%離れていることを意味します。endAngle > startAngle = 時計回り。デフォルトの時間:300ms。オプション:回転を遅くするには "durationMs": 500 を指定します。また、"radiusX"/"radiusY"(画面の幅/高さに対する割合。両方を指定してください。指定すると radius を上書きします)を使用し、物理的に円形の軌道にするには radiusX·width = radiusY·height とします。正方形ではない画面で radius を1つだけ指定すると、物理的な楕円を描き、回転にわずかなピンチ動作が伴います。
gesture-custom:カスタムタッチシーケンス
長押し、ドラッグ&ドロップ、その他の複雑なシーケンスについては、references/gesture-examples.md を参照してください。キーフレーム間の滑らかな中間 Move イベントを自動生成するには、"interpolate": 10 を指定します。
button:ハードウェアボタンの押下
{ "udid": "<UDID>", "button": "home" }
値:home、back、power、volumeUp、volumeDown、appSwitch、actionButton
keyboard:テキストの入力または特殊キーの押下
{ "udid": "<UDID>", "text": "search query" }
1回の呼び出しで実行できる操作は1つです。text と key は同時に指定できません。両方を含む呼び出しは拒否され、何も入力されません。入力後に送信するには、run-sequence(§ 8)で keyboard ステップを2つ送信します。まず { "text": "search query" }、次に { "key": "enter" } を指定します。呼び出しを2回に分けても同じ操作を実行できますが、追加のラウンドトリップが発生します。
React Native:入力後の最初のタップは、キーボードを閉じるだけの場合があります。 デフォルトの keyboardShouldPersistTaps="never" が設定されたスクロールビュー内では、React Native はフォーカス中のフィールドの外側へのタップをキーボードの非表示に使用し、そのタップを引き継ぎません("handled" または "always" の場合はタップがボタンに届きます)。そのため、入力直後にボタンをタップしても、もう一度タップする必要がある場合があります。返されたツリーを確認してください。フィールドがリターンキーで送信される場合は、{ "key": "enter" } を使うと余分なタップを避けられます。
特殊キー:enter、escape、backspace、tab、space、arrow-up、arrow-down、arrow-left、arrow-right、f1~f12。オプション:キーストローク間の "delayMs": 100(デフォルトは50ms)。iOS シミュレーターと Chromium に適用されます。Android のスマートフォン/タブレット(adb input text で入力するため、キーごとの間隔は設定されません)、Vega、TV ターゲットでは無視されます。
シークレットの入力。 平文がコンテキスト、トランスクリプト、ログに一切含まれないように認証情報を入力するには、text にシークレットプレースホルダーを使用します(keyboard、paste、run-sequence の keyboard ステップ、e2e の type ステップで使用できます)。
{ "udid": "<UDID>", "text": "{{secret:APP_PASSWORD}}" }
値の読み込み元と、プレースホルダーの使用ルール(入力後にフィールドのスクリーンショットを撮らないことなど)については、references/secrets.md を参照してください。認証情報を入力する前にお読みください。
paste:フォーカスされたフィールドにテキストを貼り付けます
{ "udid": "<UDID>", "text": "482913" }
text をデバイスのクリップボードに保存し、プラットフォームの貼り付けショートカットを実行します。iOS シミュレーターと Android エミュレーターのみで使用できます。TV ターゲット、実機、Chromium、Vega は拒否されます。
paste は keyboard より速い方法ではありません。keyboard はユーザーと同じように文字を入力するため、検索クエリ、ログイン、フォームフィールドなど、あらゆるテキスト入力でデフォルトとして使用してください。paste を使うのは、別のアプリからコピーした2FA/OTPコード、長いリンクやトークンなど、実際のユーザーが貼り付ける場面や、アプリが貼り付けられた入力をどのように処理するかをテストする場合に限ります。また、特定のプラットフォームで keyboard が入力できないテキスト(複数行テキスト、Android での非 ASCII テキスト)も扱えますが、それだけで貼り付けを使う理由にはなりません。ユーザーが貼り付けるかどうかを考えてください。
まずフィールドをタップしてフォーカスします。フォーカスされたフィールドがない状態で貼り付けると、keyboard と同様に何も起こりません。text では、keyboard と同じ {{secret:<NAME>}} プレースホルダーを使用でき、自動スクリーンショットのスキップも同様に適用されます。
rotate:向きを変更します
{ "udid": "<UDID>", "orientation": "LandscapeLeft" }
値:Portrait、LandscapeLeft、LandscapeRight、PortraitUpsideDown
展開した折りたたみ式シミュレーターでは、この値は UI ではなくデバイスの向きを設定します。Portrait にすると UI は横向きになり、LandscapeLeft にすると UI は縦向きになります。
fold:折りたたみ式デバイスを折りたたむ、または展開します
{ "udid": "<UDID>", "posture": "open" }
posture(closed、half-open、open)または angle(0~180)を指定します。両方は指定しないでください。
fold は、折りたたみ式の iOS シミュレーター(iPhone Duo)または Android エミュレーター(Pixel Fold または汎用折りたたみ式 AVD)でのみ使用してください。list-devices では foldable: true と表示されます。それ以外のデバイスでは呼び出しが拒否されます。
閉じると、カバーパネルに UI が表示されます。半開きまたは展開すると、内側のパネルに UI が表示されます。argent の外で折りたたんだ場合も含め、すべてのツールはアクティブなパネル(UI が表示されているパネル)を使用します。fold はデバイスが再び入力を受け付けると戻るため、次のタップが反映されます。これは run-sequence の次のステップでも同様です。
ルール:
- パネルが変わると座標も変わります。タップする前に、
foldの結果に含まれる要素ツリーを確認するか、describeを再実行してください。折りたたむ前のフレームは使用しないでください。 - パネルが変わるとスクリーンショットのサイズも変わります。姿勢ごとにスクリーンショット差分のベースラインを用意してください。
- iOS:展開時、UI は横向きです。スクリーンショットでは UI が90度回転して表示され、
describeのフレームも回転した iPhone と同じ軸を使用します。 - iOS:角度が0でも180でもない状態同士で折りたたむと、現在のパネルが維持されることがあります。結果にアクティブなパネルが表示されます。パネルを切り替えるには、
closedまたはopenにしてください。 - ジェスチャーの途中ではなく、ジェスチャーの合間に折りたたんでください。ジェスチャーは開始したパネル上で続行されます。
- Android:結果には
deviceState(CLOSED、HALF_OPENED、OPENED)が表示されます。閉じることで表示されたロック画面は閉じられます。ロック画面を閉じられない場合、または折りたたんだ後にロック画面が表示されている場合は、warningにその旨が記載されます。次の操作の前にデバイスのロックを解除してください。 - Android:カバーパネルがあるのは Pixel Fold AVD のみです。汎用折りたたみ式 AVD を閉じると、エミュレーターにはディスプレイの左側だけが表示されます。
describeのフレームはタップ座標と一致しません。argent が確実にタップできるのは、全幅の行など、表示領域を覆う要素だけです。カバーパネルをテストするには Pixel Fold AVD を使用してください。 - iOS:argent がアクティブなパネルを見つけられない場合、カバーパネルを使用します。その場合、ツールの結果に
warningが含まれ、スクリーンショット差分の概要にpanel:行が表示されます。スクリーンショットを撮ってデバイスの表示を確認し、warningに記載されたチェックを行ってください。
await-ui-element:UI 要素が状態に達するまで待機する
何かを待つために、ループ内で screenshot/describe をポーリングしないでください。 await-ui-element を使用してください。これは、describe が読み取るものと同じツリーをサーバー側でブロックして待機します。設計上、単独のタイマー待機モードはありません。単純な一時停止には、ご自身のハーネスのスリープを使用してください。
{ "udid": "<UDID>", "condition": "visible", "selector": { "text": "Continue" } }
このツール自体の説明には、条件、セレクターの照合方法、デフォルト値、戻り値の形式が記載されています。記載されていないのは、次の点です。
hiddenのチェックが直ちに成功した場合、誤判定の可能性があります。その場合、noteにはセレクターが一度も何にも一致しなかったと記載されています。これをチェック失敗として扱い、セレクターを修正してください。「要素が消えた」と解釈しないでください。describeが出力する合成ROOTコンテナは一致対象にならないため、AXGroup/htmlのようなroleで画面全体に単純に「一致」することはありません。- 曖昧なセレクターを明確にするには、
roleをStaticTextのようなテキストロールに固定します。これにより、同名のボタンは除外されます。 textのタイムアウト時、noteにはチェックが実際に読み取った要素のテキストが引用されるため、どの一致要素が選ばれたかを確認できます。
await-screen-idle:画面の変化が止まるまで待機する
起動/ナビゲーション後、および画面に早く描画された要素がまだ動いている可能性があるときに、生のタップを行う前に使用します。
{ "udid": "<UDID>", "timeoutMs": 3000, "minStableMs": 250 }
ローカルの iOS、Android、Chromium では、このツールは空でない describe ツリーの変化が止まるまで待機します。settled: true の場合にのみ続行してください。画面固有の await-ui-element と組み合わせてください。画面が静止しただけでは、どの画面かは特定できません。
ライブ診断にのみ使用してください。記録したり、run-sequence に追加したりしないでください。E2E テストでは、ピクセルも比較する await: { idle: true } を使用します。このライブツールは、プレゼンテーションレイヤーのアニメーション中に戻ることがあります。
7. スクリーンショット
次の場合に限り、明示的に screenshot ツールを使用してください。
- 操作を行う前の初期画面の状態を確認する必要がある場合。
- 表示されている UI を編集する前に、変更前の基準となる画面をキャプチャする必要がある場合。
- 自動添付されたスクリーンショットが遷移中または読み込み中の画面を示している場合。
- 追加のコンテキストが必要な場合。
- 待機してネットワーク応答を確認するなど、時間を置いた後の状態を確認したい場合。
- 権限ダイアログ、システムアラート、ネイティブモーダルオーバーレイが表示されており、
describeで信頼できるターゲットを特定できなかった場合。
権限やネイティブモーダルの操作に screenshot を使用する場合:
- モーダルが表示されているという理由だけで、スクリーンショットを使った操作に切り替えないでください。通常のアプリ画面やアプリ内モーダルでは、引き続き
describeを使用してください。 Allow、OK、Don't Allow、Not Now、Continueなど、分かりやすく中央に配置されたアラートボタンを優先してください。- 一度に 1 つのコントロールをタップし、次の操作を行う前に、返された自動スクリーンショットを確認してください。
- モーダルが閉じたら、
describe、native-describe-screen、またはdebugger-component-treeを使った通常の画面情報の取得に戻ってください。
Settings ツールよりもダイアログを優先してください。 アプリ独自の権限プロンプトが表示された場合は、ここで応答するのが実際のユーザーの操作経路です。そうしてください。
settings-permissionsツールを使うのは、アプリを通じて変更できない場合に限ります。たとえば、アプリから要求される前に権限を許可または拒否する場合、ユーザーがすでに拒否した権限を再度有効にする場合(iOS ではプロンプトが再表示されません)、またはプロンプトを再表示させるために権限をリセットする場合です。argent-settings-permissionsスキルを参照してください。
オプションの回転パラメーター:{ "udid": "<UDID>", "rotation": "LandscapeLeft" }:シミュレーターの向きを変更せずに、キャプチャ画像を回転します。
コンテキストのサイズを抑えるため、スクリーンショットはデフォルトで元の解像度の 30% に縮小されます。UI の状況把握や状態の確認には、通常の縮小スクリーンショットを使用してください。scale には 0.01 から 1.0 までの値を指定できますが、読みやすさやタップの補助として一般的に scale: 1.0 を使用しないでください。
比較用の基準 PNG ファイルや現在の PNG ファイルを保存する場合に限り、フル解像度のスクリーンショットを使用してください。その場合、フルサイズ PNG がエージェントのコンテキストに読み込まれないよう、画像ブロックを抑制してください。
{ "udid": "<UDID>", "scale": 1.0, "includeImageInContext": false }
ビジュアルリグレッションチェック、変更前後のスクリーンショット比較、および screenshot-diff のパラメーターに関する詳しい説明は、argent-screenshot-diff スキルを使用してください。このスキルは、デバイス操作の仕組みとスクリーンショットのキャプチャに特化したものとして扱ってください。
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| スクリーンショットがタイムアウトする | stop-simulator-server ツールで simulator-server を再起動します |
| 起動済みの iOS シミュレーターがない | iOS の udid を指定して boot-device を呼び出します |
| 使用可能な Android デバイスがない | avdName を指定して boot-device を呼び出します |
8. run-sequence によるアクションの順次実行
複数の操作ステップを1 回のツール呼び出しにまとめるには、run-sequence を使用してください。すべてのステップが完了した後に、スクリーンショットが 1 枚だけ返されます。
前のステップの結果を確認してから実行する必要があるステップが含まれる場合は、run-sequence を使用しないでください。
使用例
- 「一番下までスクロール」「一番上までスクロール」「X が見つかるまでスクロール」→ 3~5 回のスクロールを順に実行
- フォーム操作、「フィールドをクリアして再入力」→ トリプルタップですべて選択してから、新しい値を入力
- 「フォームを送信」→ すべてのフィールドを順に入力し、送信ボタンをタップ
- 「X に戻る」→ 定義したタップの順序で移動
run-sequence 内で使用できるツール
gesture-tap、gesture-swipe、gesture-scroll、gesture-drag、gesture-custom、gesture-pinch、gesture-rotate、button、keyboard、paste、rotate、shake、fold、tv-remote、await-ui-element
udid は共有されます。各ステップの args に含めないでください。ステップごとに delayMs を任意で指定できます(デフォルトは 100ms)。
画面遷移を待ってから後続のタップを実行するには、await-ui-element ステップを追加してください(例:タップ → 次の画面のボタンを待機 → そのボタンをタップ)。タイムアウト前に条件が満たされない場合、シーケンスはそのステップで停止し、後続のステップは実行されません。そのため、画面の遷移が完了しなかった場合に、タイミングのずれたタップが実行されることはありません。
例
下方向に 3 回スクロールします。
{
"udid": "<UDID>",
"steps": [
{ "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } },
{ "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } },
{ "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }
]
}
フォーカスされているフィールドに入力して送信します。keyboard 呼び出し 1 回ではテキストとキーを両方指定できないため、これらを組み合わせる唯一の方法です。
{
"udid": "<UDID>",
"steps": [
{ "tool": "keyboard", "args": { "text": "hello world" } },
{ "tool": "keyboard", "args": { "key": "enter" } }
]
}
既知のボタンをタップしてから、下方向にスクロールします。
{
"udid": "<UDID>",
"steps": [
{ "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.15 } },
{
"tool": "gesture-swipe",
"args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 },
"delayMs": 300
}
]
}
タップし、次の画面を待ってから操作します。await-ui-element ステップは、その後のタップの実行を制御します。
{
"udid": "<UDID>",
"steps": [
{ "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.9 } },
{
"tool": "await-ui-element",
"args": { "condition": "visible", "selector": { "text": "Continue" } }
},
{ "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.5 } }
]
}
ステップが画面遷移に依存する場合は、固定の delayMs よりこちらを優先してください。実際の読み込み時間に応じて動作し、タイムアウト前に条件が満たされない場合は、シーケンスがそこで停止するため、画面の遷移が完了しなかった場合に次のタップが実行されることはありません。
最初のエラー(または満たされなかった await-ui-element の条件)で停止し、部分的な結果を返します。
9. プラットフォーム固有の注意事項
Android
- Metro への接続:RN アプリを起動する前に、デバイスで
adb reverse tcp:8081 tcp:8081を実行してください。実行しないと、デバイスから Metro に接続できません。ワークフロー全体についてはargent-metro-debuggerを参照してください。デバイスを再起動した場合は、再度実行してください。 - 初回起動時の権限プロンプト:Android では
reinstall-appによって常に-gを指定してインストールされるため、初回起動時に実行時権限が事前に許可されています。指定できるフラグはありません。 - 画面ロック中/セキュアなサーフェス:キャプチャできない場合(keyguard、DRM、Play Integrity)、
describeは明確なエラーを返します。デバイスのロックを解除するか、screenshotを使用してください。 reinstall-appでの APK と .app:Android では.apkの絶対パスを、iOS では.appディレクトリを指定してください。
Chromium
references/chromium.md(タブ、Cookie/ストレージ)を参照してください。
iOS
(iOS 固有の注意事項はまだありません。見つかり次第、追加してください)