{
  "$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
  "title": "Perps release order validation",
  "description": "Exercises Perps minimum amount, percent, leverage, keyboard, and auto-close validation through semantic visible controls without submitting an order.",
  "paramsSchema": {
    "type": "object",
    "additionalProperties": false,
    "required": [
      "market"
    ],
    "properties": {
      "market": {
        "type": "string",
        "description": "Perps market with no existing position so the New Long order form can be validated."
      },
      "below_minimum_amount": {
        "type": "string",
        "default": "1"
      },
      "valid_amount": {
        "type": "string",
        "default": "10"
      },
      "percent": {
        "type": "string",
        "default": "50"
      },
      "minimum_leverage": {
        "type": "string",
        "default": "1"
      },
      "keyboard_leverage": {
        "type": "string",
        "default": "2"
      },
      "maximum_leverage": {
        "type": "string",
        "default": "40"
      },
      "invalid_take_profit": {
        "type": "string",
        "default": "1000"
      },
      "valid_take_profit": {
        "type": "string",
        "default": "70000"
      },
      "invalid_stop_loss": {
        "type": "string",
        "default": "100000"
      }
    }
  },
  "workflow": {
    "entry": "open-perps",
    "nodes": {
      "open-perps": {
        "action": "ui.navigate",
        "page": "perps",
        "intent": "Reset transient Perps navigation state",
        "next": "open-market-list"
      },
      "open-market-list": {
        "action": "ui.navigate",
        "page": "perps-market-list",
        "intent": "Show the live Perps market list",
        "next": "open-market"
      },
      "open-market": {
        "action": "ui.navigate",
        "page": "perps-market",
        "market": "{{params.market}}",
        "intent": "Open the requested Perps market",
        "next": "open-long"
      },
      "open-long": {
        "action": "ui.press",
        "test_id": "perps-long-cta-button",
        "intent": "Open a new long market order",
        "next": "wait-order-entry"
      },
      "wait-order-entry": {
        "action": "ui.wait_for",
        "test_id": "perps-order-entry-page",
        "expected": "visible",
        "timeout_ms": 10000,
        "intent": "Confirm the order form finished opening",
        "next": "enter-below-minimum"
      },
      "enter-below-minimum": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"amount-input-field\"] input",
        "value": "{{params.below_minimum_amount}}",
        "intent": "Enter an amount below the market minimum",
        "next": "assert-below-minimum"
      },
      "assert-below-minimum": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "direction": "long",
        "order_type": "market",
        "amount": "{{params.below_minimum_amount}}",
        "submit_enabled": false,
        "max_items": 150,
        "intent": "Prove the below-minimum amount cannot be submitted",
        "next": "enter-valid-amount"
      },
      "enter-valid-amount": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"amount-input-field\"] input",
        "value": "{{params.valid_amount}}",
        "intent": "Enter the minimum valid USD amount",
        "next": "enter-percent"
      },
      "enter-percent": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"balance-percent-input\"] input",
        "value": "{{params.percent}}",
        "intent": "Enter a midpoint balance percentage",
        "next": "assert-percent"
      },
      "assert-percent": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "direction": "long",
        "order_type": "market",
        "percent": "{{params.percent}}",
        "submit_enabled": true,
        "max_items": 150,
        "intent": "Prove percent input updates a valid order summary",
        "next": "enter-min-leverage"
      },
      "enter-min-leverage": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"leverage-input\"] input",
        "value": "{{params.minimum_leverage}}",
        "intent": "Enter minimum leverage",
        "next": "assert-min-leverage"
      },
      "assert-min-leverage": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "leverage": "{{params.minimum_leverage}}",
        "max_items": 150,
        "intent": "Prove minimum leverage is accepted",
        "next": "raise-with-keyboard"
      },
      "raise-with-keyboard": {
        "action": "ui.key_press",
        "key": "ArrowUp",
        "intent": "Raise leverage with the keyboard",
        "next": "assert-keyboard-leverage"
      },
      "assert-keyboard-leverage": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "leverage": "{{params.keyboard_leverage}}",
        "max_items": 150,
        "intent": "Prove the keyboard changes leverage by one step",
        "next": "enter-max-leverage"
      },
      "enter-max-leverage": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"leverage-input\"] input",
        "value": "{{params.maximum_leverage}}",
        "intent": "Enter the market maximum leverage",
        "next": "assert-max-leverage"
      },
      "assert-max-leverage": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "leverage": "{{params.maximum_leverage}}",
        "max_items": 150,
        "intent": "Prove maximum leverage is accepted",
        "next": "enable-auto-close"
      },
      "enable-auto-close": {
        "action": "ui.press",
        "selector": "label:has([data-testid=\"auto-close-toggle\"])",
        "intent": "Enable take-profit and stop-loss controls",
        "next": "assert-auto-close"
      },
      "assert-auto-close": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "auto_close": true,
        "require_test_ids": [
          "tp-price-input",
          "tp-percent-input",
          "sl-price-input",
          "sl-percent-input"
        ],
        "max_items": 150,
        "intent": "Prove auto-close exposes linked take-profit and stop-loss fields",
        "next": "enter-invalid-take-profit"
      },
      "enter-invalid-take-profit": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"tp-price-input\"] input",
        "value": "{{params.invalid_take_profit}}",
        "intent": "Enter a take-profit below the long entry price",
        "next": "assert-invalid-take-profit"
      },
      "assert-invalid-take-profit": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "auto_close": true,
        "submit_enabled": false,
        "require_test_ids": ["tp-validation-error"],
        "max_items": 150,
        "intent": "Prove an unsafe long take-profit is blocked",
        "next": "enter-valid-take-profit"
      },
      "enter-valid-take-profit": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"tp-price-input\"] input",
        "value": "{{params.valid_take_profit}}",
        "intent": "Enter a take-profit above the long entry price",
        "next": "enter-invalid-stop-loss"
      },
      "enter-invalid-stop-loss": {
        "action": "ui.set_input",
        "selector": "[data-testid=\"sl-price-input\"] input",
        "value": "{{params.invalid_stop_loss}}",
        "intent": "Enter a stop-loss above the long entry price",
        "next": "assert-invalid-stop-loss"
      },
      "assert-invalid-stop-loss": {
        "action": "metamask.perps.read_visible_state",
        "surface": "order-entry",
        "market": "{{params.market}}",
        "auto_close": true,
        "submit_enabled": false,
        "require_test_ids": ["sl-validation-error"],
        "max_items": 150,
        "intent": "Prove an unsafe long stop-loss is blocked",
        "next": "capture"
      },
      "capture": {
        "action": "ui.screenshot",
        "path": "screenshots/perps-order-validation.png",
        "label": "Perps release order validation",
        "intent": "Preserve reviewer-visible proof of the validation controls",
        "next": "done"
      },
      "done": {
        "action": "end",
        "status": "pass"
      }
    }
  }
}
