( params: SelectorRuntimeParams, )
| 195 | } |
| 196 | |
| 197 | export async function dispatchWaitViaRuntime( |
| 198 | params: SelectorRuntimeParams, |
| 199 | ): Promise<DaemonResponse> { |
| 200 | const { req, sessionName, sessionStore } = params; |
| 201 | const parsed = parseWaitPositionals(req.positionals ?? []); |
| 202 | if (!parsed) return errorResponse('INVALID_ARGS', 'wait requires a duration or text'); |
| 203 | const { session, device } = await resolveSessionDevice(sessionStore, sessionName, req.flags); |
| 204 | if (parsed.kind !== 'sleep') { |
| 205 | const unsupported = requireCommandSupported('wait', device); |
| 206 | if (unsupported) return unsupported; |
| 207 | } |
| 208 | if (parsed.kind === 'selector') { |
| 209 | const directResponse = await dispatchDirectIosSelectorWait({ |
| 210 | ...params, |
| 211 | session, |
| 212 | device, |
| 213 | selectorExpression: parsed.selectorExpression, |
| 214 | timeoutMs: parsed.timeoutMs, |
| 215 | }); |
| 216 | if (directResponse) return directResponse; |
| 217 | } |
| 218 | const execute = async () => { |
| 219 | const runtime = createSelectorRuntimeForDevice({ |
| 220 | ...params, |
| 221 | session, |
| 222 | device, |
| 223 | }); |
| 224 | const response = await toDaemonResponse(async () => { |
| 225 | const result = await runtime.selectors.wait({ |
| 226 | session: sessionName, |
| 227 | requestId: req.meta?.requestId, |
| 228 | target: toWaitTarget(parsed, session), |
| 229 | }); |
| 230 | recordIfSession(sessionStore, sessionName, req, result); |
| 231 | return toDaemonWaitData(result); |
| 232 | }); |
| 233 | const enrichedResponse = await maybeWaitTimeoutSurfaceResponse( |
| 234 | { req, logPath: params.logPath, session, device }, |
| 235 | response, |
| 236 | ); |
| 237 | // Keep generic wait-surface details first so Android blocker detection can own the top-level message. |
| 238 | return await maybeAndroidForegroundBlockerResponse(params, enrichedResponse, 'wait'); |
| 239 | }; |
| 240 | if (parsed.kind === 'sleep') return await execute(); |
| 241 | return await withSessionlessRunnerCleanup(session, device, execute); |
| 242 | } |
| 243 | |
| 244 | async function dispatchDirectIosSelectorGet( |
| 245 | params: SelectorRuntimeParams, |
no test coverage detected