fix(mobile): keep locator polling through unreadable android snapshots

Merged
OK
5d ago
+110-2

What and why

  • agent-device throws a retriable COMMAND_FAILED with details.androidSnapshotHelperFailureReason (empty-helper-output, content-poor-app-window, system-window-only) when an Android snapshot has no usable app content, e.g. while the app is still loading.
  • translateError mapped it to non-retryable ENGINE_FAILURE, so resolveOnce stopped polling and toBeVisible failed immediately instead of waiting out its timeout.
  • locate() now treats an unreadable capture as zero matches and keeps polling. If the capture overruns the time budget, the original error is rethrown.
  • Tradeoff: while the screen is unreadable, not.toBeVisible(), count() and isVisible() see 0 matches. Alternative is a retryable NODE_STALE; open to switching.
  • Seen as flakes in react-navigation Android CI: https://github.com/react-navigation/react-navigation/pull/13299

Verified

Ran it locally: yes - unit tests and pnpm check only, not on a real emulator.

  • 4 new unit tests in packages/mobile/tests/unit/engine.test.ts.

Checklist

  • Changeset added (pnpm changeset) for any change to a published package, or the change is testbed, docs, or CI only.
  • Breaking change: title carries !, the changeset body names what breaks and what replaces it, and the deprecation warning landed a window earlier (stability policy in CONTRIBUTING.md).
  • Docs updated in the same PR: the docs/**/*.mdx page for the behavior, and skills/e2e/ if the skill describes it.
  • Contract change: emitted .d.ts reviewed, tests/types/sdk-types.ts updated; wire change edits the schema and both fixtures.
  • Engine contract change (e2e/engine): changesets for e2e, @e2e-dev/web, and @e2e-dev/mobile.