| 75 | } |
| 76 | |
| 77 | fn batch_line_to_json_step(line: &str) -> anyhow::Result<Value> { |
| 78 | let tokens = tokenize_step(line)?; |
| 79 | let Some(command) = tokens.first().map(String::as_str) else { |
| 80 | return Err(crate::error::AppError::bad_request("Empty batch step.").into()); |
| 81 | }; |
| 82 | let args = parse_step_options(&tokens[1..]); |
| 83 | let value = match command { |
| 84 | "sleep" => serde_json::json!({ |
| 85 | "action": "sleep", |
| 86 | "ms": parse_batch_sleep_duration_ms(&args, tokens.get(1).map(String::as_str))?, |
| 87 | }), |
| 88 | "tap" => { |
| 89 | let mut step = serde_json::json!({ |
| 90 | "action": "tap", |
| 91 | "x": args.value("x").and_then(|value| value.parse::<f64>().ok()), |
| 92 | "y": args.value("y").and_then(|value| value.parse::<f64>().ok()), |
| 93 | "normalized": args.flag("normalized"), |
| 94 | "selector": batch_selector_json(&args), |
| 95 | "durationMs": args.value("duration-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(60), |
| 96 | "waitTimeoutMs": args.value("wait-timeout-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(0), |
| 97 | "pollMs": args.value("poll-interval-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(100), |
| 98 | }); |
| 99 | if let Some(expect) = batch_expectation_json(&args) { |
| 100 | if let Some(object) = step.as_object_mut() { |
| 101 | object.insert("expect".to_owned(), expect); |
| 102 | } |
| 103 | } |
| 104 | step |
| 105 | } |
| 106 | "back" => serde_json::json!({ |
| 107 | "action": "back", |
| 108 | "timeoutMs": args.value("timeout-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(5_000), |
| 109 | "pollMs": args.value("poll-interval-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(100), |
| 110 | "fallbackSwipe": !args.flag("no-fallback-swipe"), |
| 111 | }), |
| 112 | "wait-for" | "waitFor" => serde_json::json!({ |
| 113 | "action": "waitFor", |
| 114 | "selector": batch_selector_json(&args), |
| 115 | "source": args.value("source"), |
| 116 | "maxDepth": args.value("max-depth").and_then(|value| value.parse::<usize>().ok()), |
| 117 | "includeHidden": args.flag("include-hidden"), |
| 118 | "timeoutMs": args.value("timeout-ms").or_else(|| args.value("wait-timeout-ms")).and_then(|value| value.parse::<u64>().ok()).unwrap_or(5_000), |
| 119 | "pollMs": args.value("poll-interval-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(100), |
| 120 | }), |
| 121 | "assert" => serde_json::json!({ |
| 122 | "action": "assert", |
| 123 | "selector": batch_selector_json(&args), |
| 124 | "source": args.value("source"), |
| 125 | "maxDepth": args.value("max-depth").and_then(|value| value.parse::<usize>().ok()), |
| 126 | "includeHidden": args.flag("include-hidden"), |
| 127 | "timeoutMs": args.value("timeout-ms").or_else(|| args.value("wait-timeout-ms")).and_then(|value| value.parse::<u64>().ok()).unwrap_or(5_000), |
| 128 | "pollMs": args.value("poll-interval-ms").and_then(|value| value.parse::<u64>().ok()).unwrap_or(100), |
| 129 | }), |
| 130 | "assert-not" | "assertNot" | "wait-for-not" | "waitForNot" => serde_json::json!({ |
| 131 | "action": "assertNot", |
| 132 | "selector": batch_selector_json(&args), |
| 133 | "source": args.value("source"), |
| 134 | "maxDepth": args.value("max-depth").and_then(|value| value.parse::<usize>().ok()), |