{
  "$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
  "title": "MetaMask Mobile action E2E validation",
  "description": "Exercises every Mobile manifest-declared action against mm-4 and leaves trace output for false-positive checks.",
  "workflow": {
    "entry": "prepare-files",
    "nodes": {
      "prepare-files": {
        "action": "command",
        "cmd": "mkdir -p temp/recipe-runner.action-validation && printf 'E2E_ACTION_VALIDATION mobile\\n' > temp/recipe-runner.action-validation/probe.txt && printf '{\"platform\":\"mobile\",\"ok\":true}\n' > temp/recipe-runner.action-validation/probe.json && printf 'mobile log E2E_ACTION_VALIDATION\\n' >> temp/recipe-runner.action-validation/validation.log && echo E2E_ACTION_VALIDATION mobile",
        "next": "assert-command-exit",
        "intent": "Prepare runner.action-validation probe files"
      },
      "assert-command-exit": {
        "action": "assert_exit_code",
        "source": "prepare-files",
        "expected": 0,
        "next": "assert-command-output",
        "intent": "Verify the probe command exited successfully"
      },
      "assert-command-output": {
        "action": "assert_output",
        "source": "prepare-files",
        "stream": "stdout",
        "contains": "E2E_ACTION_VALIDATION mobile",
        "next": "assert-file",
        "intent": "Verify the probe command produced expected output"
      },
      "assert-file": {
        "action": "assert_file",
        "path": "temp/recipe-runner.action-validation/probe.txt",
        "contains": "E2E_ACTION_VALIDATION mobile",
        "next": "assert-json",
        "intent": "Verify file assertions work"
      },
      "assert-json": {
        "action": "assert_json",
        "path": "temp/recipe-runner.action-validation/probe.json",
        "assert": {
          "path": "$.platform",
          "operator": "eq",
          "value": "mobile"
        },
        "next": "watch-logs",
        "intent": "Verify JSON assertions work"
      },
      "watch-logs": {
        "action": "watch_logs",
        "path": "temp/recipe-runner.action-validation/validation.log",
        "contains": "E2E_ACTION_VALIDATION",
        "next": "index-artifacts",
        "intent": "Verify log watching works"
      },
      "index-artifacts": {
        "action": "index_artifacts",
        "artifacts": [
          {
            "path": "temp/recipe-runner.action-validation/probe.txt",
            "type": "log",
            "category": "debug",
            "label": "Mobile action validation probe"
          }
        ],
        "next": "wait",
        "intent": "Register the probe file as an artifact"
      },
      "wait": {
        "action": "wait",
        "duration_ms": 1,
        "next": "status",
        "intent": "Verify the base wait action works"
      },
      "status": {
        "action": "app.status",
        "next": "app-hud",
        "intent": "Read project runner compatibility status"
      },
      "cdp-probe": {
        "action": "cdp.target",
        "next": "fixture",
        "required": true,
        "intent": "Verify the automation channel is reachable"
      },
      "fixture": {
        "action": "metamask.wallet.fixture_status",
        "next": "wallet-setup",
        "intent": "Verify wallet fixture availability"
      },
      "wallet-setup": {
        "action": "metamask.wallet.setup",
        "next": "wallet-unlock",
        "intent": "Verify wallet setup is ready"
      },
      "wallet-unlock": {
        "action": "metamask.wallet.ensure_unlocked",
        "next": "wallet-read-state",
        "intent": "Ensure the wallet is unlocked"
      },
      "wallet-read-state": {
        "action": "metamask.wallet.read_state",
        "next": "wallet-list-accounts",
        "intent": "Read wallet state for proof"
      },
      "wallet-list-accounts": {
        "action": "metamask.wallet.list_accounts",
        "next": "select-account",
        "intent": "List wallet accounts for proof"
      },
      "select-account": {
        "action": "metamask.wallet.select_account",
        "address": "0x8dc623e964475d4d669da601fd15ea9125469003",
        "next": "app-navigate-wallet",
        "intent": "Select the validation account"
      },
      "app-navigate-wallet": {
        "action": "ui.navigate",
        "next": "ui-wait-wallet",
        "intent": "Show the wallet home surface",
        "route": "WalletView"
      },
      "ui-wait-wallet": {
        "action": "ui.wait_for",
        "test_id": "wallet-screen",
        "expected": "present",
        "next": "ui-press",
        "intent": "Confirm the wallet surface is ready"
      },
      "ui-press": {
        "action": "ui.press",
        "test_id": "wallet-account-copy-button",
        "next": "ui-scroll",
        "intent": "Activate the visible control"
      },
      "ui-scroll": {
        "action": "ui.scroll",
        "test_id": "wallet-screen",
        "offset": 1000,
        "next": "ui-scroll-into-view",
        "intent": "Expose the next visible content"
      },
      "ui-screenshot-wallet": {
        "action": "ui.screenshot",
        "path": "screenshots/mobile-wallet-runner.action-validation.png",
        "next": "wallet-navigate-perps",
        "intent": "Record the visible wallet state as evidence"
      },
      "wallet-navigate-perps": {
        "action": "ui.navigate",
        "next": "perps-navigate-home",
        "intent": "Show the Perps home surface",
        "route": "PerpsMarketListView"
      },
      "perps-navigate-home": {
        "action": "ui.navigate",
        "next": "perps-navigate-market",
        "intent": "Show the Perps home surface",
        "route": "PerpsMarketListView"
      },
      "perps-navigate-market": {
        "action": "ui.navigate",
        "next": "start-state",
        "intent": "Show the ETH Perps market details",
        "route": "PerpsMarketDetails",
        "params": {
          "market": {
            "symbol": "ETH"
          }
        }
      },
      "ensure-clean": {
        "action": "metamask.perps.ensure_positions",
        "market": "ETH",
        "next": "ensure-orders-clean",
        "state": "none",
        "intent": "Ensure no positions are open",
        "mode": "matching"
      },
      "assert-no-position": {
        "action": "metamask.perps.assert_positions",
        "market": "ETH",
        "next": "read-orders-empty",
        "state": "none",
        "intent": "Confirm selected ETH position state is clean",
        "mode": "matching"
      },
      "read-orders-empty": {
        "action": "metamask.perps.read_orders",
        "market": "ETH",
        "next": "assert-no-orders",
        "intent": "Read order state after cleanup"
      },
      "place-order": {
        "action": "metamask.perps.place_order",
        "market": "ETH",
        "side": "long",
        "amount": "11",
        "leverage": 3,
        "next": "read-positions",
        "intent": "Place a small ETH 3x long validation order"
      },
      "read-positions": {
        "action": "metamask.perps.read_positions",
        "market": "ETH",
        "next": "assert-position",
        "intent": "Read ETH position after order placement"
      },
      "assert-position": {
        "action": "metamask.perps.assert_positions",
        "market": "ETH",
        "next": "read-orders-open",
        "state": "open",
        "intent": "Confirm the ETH validation position opened"
      },
      "read-orders-open": {
        "action": "metamask.perps.read_orders",
        "market": "ETH",
        "next": "close-orders",
        "intent": "Read ETH orders before cleanup"
      },
      "assert-closed": {
        "action": "metamask.perps.assert_positions",
        "market": "ETH",
        "next": "teardown-state",
        "state": "none",
        "intent": "Confirm global position cleanup completed",
        "mode": "matching"
      },
      "done": {
        "action": "end",
        "status": "pass"
      },
      "ensure-orders-clean": {
        "action": "metamask.perps.ensure_orders",
        "market": "ETH",
        "state": "none",
        "next": "assert-no-position",
        "intent": "Ensure no orders are open",
        "mode": "matching"
      },
      "assert-no-orders": {
        "action": "metamask.perps.assert_orders",
        "market": "ETH",
        "state": "none",
        "next": "place-order",
        "intent": "Confirm selected ETH order state is clean",
        "mode": "matching"
      },
      "close-orders": {
        "action": "metamask.perps.close_orders",
        "market": "ETH",
        "next": "close-positions",
        "intent": "Close ETH orders created by validation"
      },
      "close-positions": {
        "action": "metamask.perps.close_positions",
        "market": "ETH",
        "next": "assert-closed",
        "intent": "Close the ETH validation position"
      },
      "start-state": {
        "action": "metamask.perps.start_state",
        "profile": "clean_market_testnet",
        "market": "ETH",
        "positions": {
          "state": "none",
          "mode": "matching"
        },
        "orders": {
          "state": "none",
          "mode": "matching"
        },
        "page": "market",
        "next": "ensure-clean",
        "intent": "Prepare selected-market clean testnet Perps validation state",
        "mode": "matching"
      },
      "teardown-state": {
        "action": "metamask.perps.teardown_state",
        "market": "ETH",
        "positions": {
          "state": "none",
          "mode": "matching"
        },
        "orders": {
          "state": "none",
          "mode": "matching"
        },
        "page": "home",
        "next": "done",
        "intent": "Return Perps to a selected-market clean home state",
        "mode": "matching"
      },
      "app-hud": {
        "action": "app.hud",
        "text": "mobile action parity validation",
        "status": "running",
        "next": "cdp-probe",
        "intent": "Start visible recipe progress HUD"
      },
      "ui-scroll-into-view": {
        "action": "ui.scroll",
        "test_id": "wallet-screen",
        "scroll_into_view": true,
        "offset": 40,
        "next": "app-navigate-network-selector",
        "intent": "Expose the wallet content needed for proof"
      },
      "app-navigate-network-selector": {
        "action": "ui.press",
        "test_id": "import-token-button",
        "next": "wait-token-search-input",
        "intent": "Open token search input"
      },
      "ui-set-input-network": {
        "action": "ui.set_input",
        "test_id": "input-search-asset",
        "value": "ETH",
        "next": "return-wallet-after-input",
        "intent": "Filter the visible token list"
      },
      "return-wallet-after-input": {
        "action": "ui.navigate",
        "next": "ui-screenshot-wallet",
        "intent": "Return to wallet after input validation",
        "route": "WalletView"
      },
      "wait-token-search-input": {
        "action": "ui.wait_for",
        "test_id": "input-search-asset",
        "expected": "present",
        "next": "ui-set-input-network",
        "intent": "Confirm token search is ready"
      }
    }
  }
}
