@e2e-dev/mobile 0.8.0-canary-20260928184528

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +159 -0
  4. package/dist/.build.json +1 -0
  5. package/dist/actions.d.ts +41 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +70 -0
  8. package/dist/actions.js.map +1 -0
  9. package/dist/bindings.d.ts +87 -0
  10. package/dist/bindings.d.ts.map +1 -0
  11. package/dist/bindings.js +112 -0
  12. package/dist/bindings.js.map +1 -0
  13. package/dist/device.d.ts +117 -0
  14. package/dist/device.d.ts.map +1 -0
  15. package/dist/device.js +116 -0
  16. package/dist/device.js.map +1 -0
  17. package/dist/engine.d.ts +17 -0
  18. package/dist/engine.d.ts.map +1 -0
  19. package/dist/engine.js +98 -0
  20. package/dist/engine.js.map +1 -0
  21. package/dist/errors.d.ts +61 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +223 -0
  24. package/dist/errors.js.map +1 -0
  25. package/dist/index.d.ts +21 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +14 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/links.d.ts +41 -0
  30. package/dist/links.d.ts.map +1 -0
  31. package/dist/links.js +79 -0
  32. package/dist/links.js.map +1 -0
  33. package/dist/locate.d.ts +11 -0
  34. package/dist/locate.d.ts.map +1 -0
  35. package/dist/locate.js +119 -0
  36. package/dist/locate.js.map +1 -0
  37. package/dist/nodes.d.ts +107 -0
  38. package/dist/nodes.d.ts.map +1 -0
  39. package/dist/nodes.js +530 -0
  40. package/dist/nodes.js.map +1 -0
  41. package/dist/options.d.ts +134 -0
  42. package/dist/options.d.ts.map +1 -0
  43. package/dist/options.js +7 -0
  44. package/dist/options.js.map +1 -0
  45. package/dist/png.d.ts +4 -0
  46. package/dist/png.d.ts.map +1 -0
  47. package/dist/png.js +25 -0
  48. package/dist/png.js.map +1 -0
  49. package/dist/pool.d.ts +99 -0
  50. package/dist/pool.d.ts.map +1 -0
  51. package/dist/pool.js +235 -0
  52. package/dist/pool.js.map +1 -0
  53. package/dist/provider.d.ts +119 -0
  54. package/dist/provider.d.ts.map +1 -0
  55. package/dist/provider.js +112 -0
  56. package/dist/provider.js.map +1 -0
  57. package/dist/selector.d.ts +17 -0
  58. package/dist/selector.d.ts.map +1 -0
  59. package/dist/selector.js +84 -0
  60. package/dist/selector.js.map +1 -0
  61. package/dist/support.d.ts +63 -0
  62. package/dist/support.d.ts.map +1 -0
  63. package/dist/support.js +87 -0
  64. package/dist/support.js.map +1 -0
  65. package/dist/surface.d.ts +405 -0
  66. package/dist/surface.d.ts.map +1 -0
  67. package/dist/surface.js +1159 -0
  68. package/dist/surface.js.map +1 -0
  69. package/dist/tools.d.ts +24 -0
  70. package/dist/tools.d.ts.map +1 -0
  71. package/dist/tools.js +90 -0
  72. package/dist/tools.js.map +1 -0
  73. package/package.json +83 -0
package/dist/errors.js ADDED
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Translation of agent-device failures onto the engine error contract.
3
+ *
4
+ * | agent-device failure | Code |
5
+ * | ----------------------------------------------------------- | ---------------------------- |
6
+ * | already an EngineError / runner error | passed through untouched |
7
+ * | AbortError | CANCELLED |
8
+ * | no active session / session not found / requires a session | INVALID_STATE |
9
+ * | UNSUPPORTED_OPERATION, NOT_IMPLEMENTED, UNSUPPORTED_PLATFORM | UNSUPPORTED_CAPABILITY |
10
+ * | "not supported on this device" under any code | UNSUPPORTED_CAPABILITY |
11
+ * | a ref the daemon no longer knows (action paths only) | NODE_STALE (retryable) |
12
+ * | the iOS runner busy, wedged, or past its watchdog | ENGINE_FAILURE, naming the |
13
+ * | a snapshot the iOS runner acquired but could not present | runner and the recovery |
14
+ * | anything else, agent-device's own timeouts included | ENGINE_FAILURE with the text |
15
+ *
16
+ * `OPERATION_TIMEOUT` is never produced here. In the contract it means the
17
+ * harness budget expired, which `raceAbort` already reports, and core
18
+ * replaces its message with a bare `operation timed out`. A timeout
19
+ * agent-device itself reports (a simulator boot, the runner connecting, an
20
+ * app launch) is a device-side fault whose text is the diagnosis, so it
21
+ * stays `ENGINE_FAILURE` and keeps its message and hint.
22
+ */
23
+ import { isAgentDeviceError, normalizeAgentDeviceError } from 'agent-device';
24
+ import { EngineError, ConfigurationError, InfrastructureError, TestError, raceAbort } from 'e2e/engine';
25
+ import { cancelled } from './support.js';
26
+ /**
27
+ * True for an error that already carries its classification: an `EngineError`
28
+ * from any module copy, or a runner error. Those cross the boundary untouched;
29
+ * re-wrapping one would turn a `POLICY_DENIED` into an infrastructure failure.
30
+ */
31
+ function isClassified(cause) {
32
+ if (cause instanceof EngineError || cause instanceof TestError)
33
+ return true;
34
+ if (cause instanceof ConfigurationError || cause instanceof InfrastructureError)
35
+ return true;
36
+ return cause instanceof Error && cause.name === 'EngineError';
37
+ }
38
+ /** A failure's message in agent-device's normalized form. */
39
+ export function message(cause) {
40
+ return normalizeAgentDeviceError(cause).message;
41
+ }
42
+ /** The details bag the failure itself declared; the normalizer lifts some keys off it, so it is read raw. */
43
+ function details(cause) {
44
+ return isAgentDeviceError(cause) ? (cause.details ?? {}) : {};
45
+ }
46
+ /**
47
+ * The normalized message followed by the hint the failure itself declared.
48
+ * That hint is the recovery path (press return, tap the app's own Done
49
+ * control) and the model only ever sees the error text, so dropping it leaves
50
+ * the agent retrying the same refused action. The per-code default hint the
51
+ * normalizer would add is CLI advice and stays out.
52
+ */
53
+ function withHint(cause, text) {
54
+ const hint = details(cause).hint;
55
+ if (typeof hint !== 'string' || hint.trim() === '' || CLI_ADVICE.test(hint))
56
+ return text;
57
+ return `${text} Hint: ${hint.trim()}`;
58
+ }
59
+ /** agent-device's generic hint (`Check command arguments and run --help`) is CLI advice, and stays out too. */
60
+ const CLI_ADVICE = /--help|command arguments/i;
61
+ const NO_SESSION_PATTERN = /no active (?:app )?session|requires an active session|session\b.*\bnot found|open an app first|no app (?:is )?open/i;
62
+ const UNSUPPORTED_CODES = new Set(['UNSUPPORTED_OPERATION', 'NOT_IMPLEMENTED', 'UNSUPPORTED_PLATFORM']);
63
+ const UNSUPPORTED_PATTERN = /\b(?:is )?not supported\b|\bunsupported\b/i;
64
+ const STALE_PATTERN = /\bref\b.*\b(?:not found|unknown|stale|no longer|expired|invalid|missing)|\b(?:not found|unknown|stale|no longer|expired|invalid|missing)\b.*\bref\b|refs?generation/i;
65
+ /**
66
+ * What the iOS automation runner reported about itself, by the code
67
+ * agent-device emits for it: `RUNNER_WEDGED` at the top level, `RUNNER_BUSY`
68
+ * and `MAIN_THREAD_TIMEOUT` in `details.runnerErrorCode` under
69
+ * `COMMAND_FAILED`, the shape the daemon folds runner wire codes into. Each
70
+ * value is the headline and the first move; the app is fine in every case.
71
+ */
72
+ const RUNNER_STATE = new Map([
73
+ [
74
+ 'RUNNER_BUSY',
75
+ {
76
+ headline: 'the iOS automation runner is still finishing a command that overran its watchdog',
77
+ firstMove: 'Wait a few seconds and rerun.',
78
+ },
79
+ ],
80
+ [
81
+ 'MAIN_THREAD_TIMEOUT',
82
+ {
83
+ headline: "the iOS automation runner's main thread overran its watchdog on this command",
84
+ firstMove: 'Rerun once it has drained.',
85
+ },
86
+ ],
87
+ [
88
+ 'RUNNER_WEDGED',
89
+ {
90
+ headline: 'the iOS automation runner is wedged: its main thread is stuck in abandoned work',
91
+ firstMove: 'agent-device restarts the runner; rerun.',
92
+ },
93
+ ],
94
+ ]);
95
+ /**
96
+ * A snapshot the iOS runner acquired but could not present. Upstream raises
97
+ * it as `IOS_SNAPSHOT_ENGINE_FAILED` and rethrows it to the client as
98
+ * `COMMAND_FAILED` with the check that failed in `details.reason`: a
99
+ * per-capture presentation check, not a property of the app or the screen.
100
+ * The reasons are agent-device's (`ios-snapshot-runtime`,
101
+ * `runner-presentation`): the viewport checks, a malformed graph, which the
102
+ * presenter rewraps as `invalid-presented-payload` on the presented tree and
103
+ * `invalid-quality-payload` on the quality tree, and the payload checks it
104
+ * raises as `invalid-presented-payload` directly (a parent outside the
105
+ * payload, a disabled or off-viewport node marked actionable).
106
+ */
107
+ const PRESENTATION_CODE = 'IOS_SNAPSHOT_ENGINE_FAILED';
108
+ const PRESENTATION_REASONS = new Set([
109
+ 'invalid-viewport',
110
+ 'missing-viewport',
111
+ 'malformed-graph',
112
+ 'invalid-presented-payload',
113
+ 'invalid-quality-payload',
114
+ ]);
115
+ const PRESENTATION = {
116
+ headline: 'the iOS automation runner could not present the accessibility snapshot',
117
+ firstMove: 'Rerun.',
118
+ };
119
+ const RUNNER_RECOVERY = 'If the next run meets it again, stop the daemon (`npx agent-device daemon stop`) and reboot the simulator (`xcrun simctl shutdown <udid>`, then `boot`).';
120
+ /** The runner-state entry for a failure, by top-level code or the folded runner wire code. */
121
+ function runnerState(cause) {
122
+ const normalized = normalizeAgentDeviceError(cause);
123
+ const wire = details(cause).runnerErrorCode;
124
+ return RUNNER_STATE.get(normalized.code) ?? (typeof wire === 'string' ? RUNNER_STATE.get(wire) : undefined);
125
+ }
126
+ /** True when the iOS runner acquired a snapshot and failed its own presentation check on it. */
127
+ function isPresentationFailure(cause) {
128
+ if (normalizeAgentDeviceError(cause).code === PRESENTATION_CODE)
129
+ return true;
130
+ const reason = details(cause).reason;
131
+ return typeof reason === 'string' && PRESENTATION_REASONS.has(reason);
132
+ }
133
+ /**
134
+ * The message for a fault of the automation runner itself: what the runner
135
+ * is doing, where (the session and device when the caller knows them),
136
+ * agent-device's own text, then the recovery. The harness reports an engine
137
+ * fault under the agent as `APP_UNREACHABLE`, so the message has to say the
138
+ * app is not the part that failed.
139
+ */
140
+ function runnerMessage(operation, where, state, cause) {
141
+ const location = where === undefined ? '' : ` (${where})`;
142
+ return `${operation} failed: ${state.headline}${location}: ${message(cause)} The app is fine. ${state.firstMove} ${RUNNER_RECOVERY}`;
143
+ }
144
+ /**
145
+ * Translates an unexpected agent-device error at the contract boundary.
146
+ * `where` names the session and device the command ran under, for the
147
+ * messages whose recovery is per device.
148
+ */
149
+ export function translateError(cause, operation, where) {
150
+ if (isClassified(cause))
151
+ return cause;
152
+ if (cause instanceof Error && cause.name === 'AbortError')
153
+ return cancelled(`${operation} cancelled`);
154
+ const normalized = normalizeAgentDeviceError(cause);
155
+ const text = `${operation} failed: ${withHint(cause, normalized.message)}`;
156
+ const options = { retryable: false, cause };
157
+ if (normalized.code === 'SESSION_NOT_FOUND' || NO_SESSION_PATTERN.test(normalized.message)) {
158
+ return new EngineError('INVALID_STATE', text, options);
159
+ }
160
+ if (UNSUPPORTED_CODES.has(normalized.code) || UNSUPPORTED_PATTERN.test(normalized.message)) {
161
+ return new EngineError('UNSUPPORTED_CAPABILITY', text, options);
162
+ }
163
+ const state = runnerState(cause);
164
+ if (state !== undefined)
165
+ return new EngineError('ENGINE_FAILURE', runnerMessage(operation, where, state, cause), options);
166
+ if (isPresentationFailure(cause)) {
167
+ return new EngineError('ENGINE_FAILURE', runnerMessage(operation, where, PRESENTATION, cause), options);
168
+ }
169
+ return new EngineError('ENGINE_FAILURE', text, options);
170
+ }
171
+ /**
172
+ * True for a translated failure of the iOS automation runner itself: busy,
173
+ * wedged, or past its watchdog. The runner, not the app, is what needs
174
+ * attention, so a caller that tolerates an app that did not open (warm-up)
175
+ * must not tolerate this.
176
+ */
177
+ export function isRunnerFailure(error) {
178
+ return error instanceof Error && runnerState(error.cause) !== undefined;
179
+ }
180
+ const NO_SESSION_APP_PATTERN = /requires an active app in (?:the )?session/i;
181
+ /**
182
+ * True for a translated settings command agent-device refused because its
183
+ * session is on no app: the one refusal a foreground open of the pinned app
184
+ * answers.
185
+ */
186
+ export function isNoSessionApp(error) {
187
+ return error instanceof Error && NO_SESSION_APP_PATTERN.test(normalizeAgentDeviceError(error.cause).message);
188
+ }
189
+ /**
190
+ * True for a translated snapshot the iOS runner acquired but could not
191
+ * present. The check is per capture and the capture is a read, so one retry
192
+ * is safe and usually enough.
193
+ */
194
+ export function isSnapshotPresentationFailure(error) {
195
+ return error instanceof Error && isPresentationFailure(error.cause);
196
+ }
197
+ /**
198
+ * Runs one agent-device command under an abort signal and translates its
199
+ * failure onto the engine taxonomy: the one boundary every command crosses.
200
+ */
201
+ export async function runCommand(label, work, signal, where) {
202
+ try {
203
+ return await raceAbort(work, signal, label);
204
+ }
205
+ catch (cause) {
206
+ throw translateError(cause, label, where);
207
+ }
208
+ }
209
+ /**
210
+ * Like translateError, but a ref the daemon no longer binds becomes retryable
211
+ * `NODE_STALE`: nothing was dispatched, so the harness may re-observe and
212
+ * re-resolve the node instead of failing the action.
213
+ */
214
+ export function staleOr(cause, operation, where) {
215
+ if (isClassified(cause))
216
+ return cause;
217
+ const normalized = normalizeAgentDeviceError(cause);
218
+ if (STALE_PATTERN.test(normalized.message)) {
219
+ return new EngineError('NODE_STALE', `${operation}: ${normalized.message}`, { retryable: true, cause });
220
+ }
221
+ return translateError(cause, operation, where);
222
+ }
223
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `@e2e-dev/mobile` public surface: the `mobile()` engine factory,
3
+ * the `device` fixture types, and a `test` typed with that fixture. `expect`
4
+ * and `credentials` still come from `e2e`; the agent-side tool pack lives on
5
+ * the `@e2e-dev/mobile/tools` subpath so this entry never loads the AI SDK.
6
+ */
7
+ import type { Device } from './device.ts';
8
+ export { mobile } from './engine.ts';
9
+ export type { DevicePermission, LaunchPermissions, MobileOptions, MobilePlatform, PermissionState } from './options.ts';
10
+ export type { DeviceClientConfig, DeviceConnection, DeviceDaemon } from './bindings.ts';
11
+ export type { DeviceLease, DeviceProvider, DeviceReleaseContext, DeviceRequest } from './provider.ts';
12
+ export type { InstallAppOptions, InstalledApp, OpenAppOptions } from './surface.ts';
13
+ export type { BiometricSensor, Device, DeviceOrientation, ForegroundApp } from './device.ts';
14
+ /**
15
+ * `test` typed with this engine's contributed `device` fixture. The same
16
+ * runtime `test` as `e2e`'s; only the fixture types differ.
17
+ */
18
+ export declare const test: import("e2e").TestAPI<import("e2e").TestFixtures & {
19
+ device: Device;
20
+ }>;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxH,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACxF,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACtG,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACpF,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7F;;;GAGG;AACH,eAAO,MAAM,IAAI;YAAyB,MAAM;EAAK,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@e2e-dev/mobile` public surface: the `mobile()` engine factory,
3
+ * the `device` fixture types, and a `test` typed with that fixture. `expect`
4
+ * and `credentials` still come from `e2e`; the agent-side tool pack lives on
5
+ * the `@e2e-dev/mobile/tools` subpath so this entry never loads the AI SDK.
6
+ */
7
+ import { test as base } from 'e2e';
8
+ export { mobile } from './engine.js';
9
+ /**
10
+ * `test` typed with this engine's contributed `device` fixture. The same
11
+ * runtime `test` as `e2e`'s; only the fixture types differ.
12
+ */
13
+ export const test = base.extend();
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,MAAM,KAAK,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAsB,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The links `device.openLink` takes: the scheme rule the runner applies to
3
+ * every navigation, the label a link enters the report under, and the guard
4
+ * that keeps a link out of `device.openApp`.
5
+ *
6
+ * The runner's own rule (`resolveNavigationUrl`, reached by a fixture as
7
+ * `context.app.resolveUrl`) first demands an app URL, which a device engine
8
+ * never declares, so the same small check lives here rather than behind a
9
+ * gate that would refuse every link.
10
+ */
11
+ /** Whether agent-device would open this string as a URL rather than resolve it as an app. */
12
+ export declare function isLink(value: string): boolean;
13
+ /**
14
+ * Parses a link a test asked to open. A string that is not an absolute URL
15
+ * is `INVALID_ARGUMENT`; a `file:`, `data:`, or `javascript:` link is
16
+ * `POLICY_DENIED`, as it is for `app.open` on the web.
17
+ */
18
+ export declare function linkTarget(input: string): URL;
19
+ /**
20
+ * Refuses a link handed to `openApp`, which opens an app by bundle id,
21
+ * package, or display name. agent-device opens any `scheme:rest` string as
22
+ * a URL, so the check runs before the device sees it: a `file:`, `data:`,
23
+ * or `javascript:` link is `POLICY_DENIED` as it is for `openLink`, any
24
+ * other link is `INVALID_ARGUMENT` pointing at `openLink`. The message
25
+ * never echoes the link, whose query may carry a magic-link token.
26
+ */
27
+ export declare function assertAppId(app: string): void;
28
+ /**
29
+ * Refuses a link in the engine's `app` option, which the pool opens on every
30
+ * device in `prepare`, before any attempt's `openApp` would. Config is the
31
+ * project's own code, so a link there is a mistake, not a policy breach:
32
+ * `INVALID_CONFIG` whatever the scheme, pointing at `device.openLink`.
33
+ */
34
+ export declare function assertConfiguredApp(app: string | undefined): void;
35
+ /**
36
+ * The link as the report shows it, cut before its query and fragment. A
37
+ * magic link carries its one-time token there, and a step label is kept for
38
+ * as long as the report is.
39
+ */
40
+ export declare function linkLabel(input: string): string;
41
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,6FAA6F;AAC7F,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7C;AAQD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAY7C;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAQ7C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMjE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C"}
package/dist/links.js ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The links `device.openLink` takes: the scheme rule the runner applies to
3
+ * every navigation, the label a link enters the report under, and the guard
4
+ * that keeps a link out of `device.openApp`.
5
+ *
6
+ * The runner's own rule (`resolveNavigationUrl`, reached by a fixture as
7
+ * `context.app.resolveUrl`) first demands an app URL, which a device engine
8
+ * never declares, so the same small check lives here rather than behind a
9
+ * gate that would refuse every link.
10
+ */
11
+ import { ConfigurationError, TestError } from 'e2e/engine';
12
+ const FORBIDDEN_PROTOCOLS = new Set(['file:', 'data:', 'javascript:']);
13
+ /**
14
+ * What agent-device opens as a URL instead of resolving as an app: a
15
+ * `scheme:rest` string with no whitespace. Every string the device would
16
+ * route as a link matches; a display name with a space (`Notes: Pro`) does
17
+ * not.
18
+ */
19
+ const LINK_SHAPE = /^([A-Za-z][A-Za-z0-9+.-]*):\S+$/;
20
+ /** Whether agent-device would open this string as a URL rather than resolve it as an app. */
21
+ export function isLink(value) {
22
+ return LINK_SHAPE.test(value.trim());
23
+ }
24
+ function denyForbiddenScheme(protocol) {
25
+ if (FORBIDDEN_PROTOCOLS.has(protocol)) {
26
+ throw new ConfigurationError('POLICY_DENIED', `forbidden URL scheme: ${protocol}`);
27
+ }
28
+ }
29
+ /**
30
+ * Parses a link a test asked to open. A string that is not an absolute URL
31
+ * is `INVALID_ARGUMENT`; a `file:`, `data:`, or `javascript:` link is
32
+ * `POLICY_DENIED`, as it is for `app.open` on the web.
33
+ */
34
+ export function linkTarget(input) {
35
+ let url;
36
+ try {
37
+ url = new URL(input);
38
+ }
39
+ catch {
40
+ throw new TestError('INVALID_ARGUMENT', `openLink needs an absolute URL such as myapp://orders/42 or https://example.com/verify, got "${input}"`);
41
+ }
42
+ denyForbiddenScheme(url.protocol);
43
+ return url;
44
+ }
45
+ /**
46
+ * Refuses a link handed to `openApp`, which opens an app by bundle id,
47
+ * package, or display name. agent-device opens any `scheme:rest` string as
48
+ * a URL, so the check runs before the device sees it: a `file:`, `data:`,
49
+ * or `javascript:` link is `POLICY_DENIED` as it is for `openLink`, any
50
+ * other link is `INVALID_ARGUMENT` pointing at `openLink`. The message
51
+ * never echoes the link, whose query may carry a magic-link token.
52
+ */
53
+ export function assertAppId(app) {
54
+ const link = LINK_SHAPE.exec(app.trim());
55
+ if (link === null)
56
+ return;
57
+ denyForbiddenScheme(`${(link[1] ?? '').toLowerCase()}:`);
58
+ throw new TestError('INVALID_ARGUMENT', 'openApp opens an app by bundle id, package, or display name; open a deep link or web link with device.openLink');
59
+ }
60
+ /**
61
+ * Refuses a link in the engine's `app` option, which the pool opens on every
62
+ * device in `prepare`, before any attempt's `openApp` would. Config is the
63
+ * project's own code, so a link there is a mistake, not a policy breach:
64
+ * `INVALID_CONFIG` whatever the scheme, pointing at `device.openLink`.
65
+ */
66
+ export function assertConfiguredApp(app) {
67
+ if (app === undefined || !isLink(app))
68
+ return;
69
+ throw new ConfigurationError('INVALID_CONFIG', 'mobile: `app` names an app by bundle id, package, or display name, not a link; a test opens a deep link or web link with device.openLink');
70
+ }
71
+ /**
72
+ * The link as the report shows it, cut before its query and fragment. A
73
+ * magic link carries its one-time token there, and a step label is kept for
74
+ * as long as the report is.
75
+ */
76
+ export function linkLabel(input) {
77
+ return input.replace(/[?#][\s\S]*$/, '');
78
+ }
79
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE3D,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,UAAU,GAAG,iCAAiC,CAAC;AAErD,6FAA6F;AAC7F,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAgB;IAC3C,IAAI,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,kBAAkB,CAAC,eAAe,EAAE,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CACjB,kBAAkB,EAClB,gGAAgG,KAAK,GAAG,CACzG,CAAC;IACJ,CAAC;IACD,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAC1B,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,IAAI,SAAS,CACjB,kBAAkB,EAClB,gHAAgH,CACjH,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAuB;IACzD,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,OAAO;IAC9C,MAAM,IAAI,kBAAkB,CAC1B,gBAAgB,EAChB,0IAA0I,CAC3I,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * LocatorExpression evaluation over one projected snapshot: the location
3
+ * capability's query language answered against the accessibility tree the
4
+ * device just reported. One immediate pass, every match in document order;
5
+ * polling, strictness, and staleness stay with the runner.
6
+ */
7
+ import { type LocatorExpression } from 'e2e/engine';
8
+ import { type ProjectedNode } from './nodes.ts';
9
+ /** Resolves one expression to the nodes it currently matches. */
10
+ export declare function resolveExpression(expression: LocatorExpression, index: readonly ProjectedNode[]): ProjectedNode[];
11
+ //# sourceMappingURL=locate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locate.d.ts","sourceRoot":"","sources":["../src/locate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA4B,KAAK,iBAAiB,EAAsB,MAAM,YAAY,CAAC;AAClG,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAG1D,iEAAiE;AACjE,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,EAAE,CAiCjH"}
package/dist/locate.js ADDED
@@ -0,0 +1,119 @@
1
+ /**
2
+ * LocatorExpression evaluation over one projected snapshot: the location
3
+ * capability's query language answered against the accessibility tree the
4
+ * device just reported. One immediate pass, every match in document order;
5
+ * polling, strictness, and staleness stay with the runner.
6
+ */
7
+ import { EngineError, matchesText } from 'e2e/engine';
8
+ import { isWithin } from './nodes.js';
9
+ import { compileSelector } from './selector.js';
10
+ /** Resolves one expression to the nodes it currently matches. */
11
+ export function resolveExpression(expression, index) {
12
+ switch (expression.kind) {
13
+ case 'query': {
14
+ const candidates = expression.scope === undefined ? index : descendantsOf(resolveExpression(expression.scope, index), index);
15
+ const matches = candidates.filter((entry) => matchesQuery(entry, expression.query));
16
+ return ECHOED_QUERY_KINDS.has(expression.query.kind) ? innermostOnly(matches) : matches;
17
+ }
18
+ case 'filter': {
19
+ const source = resolveExpression(expression.source, index);
20
+ return source.filter((entry) => {
21
+ if (expression.hasText !== undefined && !subtreeHasText(entry, index, expression.hasText))
22
+ return false;
23
+ if (expression.has !== undefined) {
24
+ const within = descendantsOf([entry], index);
25
+ if (resolveExpression(expression.has, within).length === 0)
26
+ return false;
27
+ }
28
+ return true;
29
+ });
30
+ }
31
+ case 'index': {
32
+ const source = resolveExpression(expression.source, index);
33
+ const position = expression.index === 'first' ? 0 : expression.index === 'last' ? source.length - 1 : expression.index;
34
+ const picked = source[position];
35
+ return picked === undefined ? [] : [picked];
36
+ }
37
+ case 'selector':
38
+ return compileSelector(expression.selector)(index);
39
+ case 'frame':
40
+ throw new EngineError('FRAME_NOT_FOUND', 'a device surface has no nested documents to scope a query into', {
41
+ retryable: false,
42
+ });
43
+ }
44
+ }
45
+ /** The query kinds a device answers with the innermost match, because it echoes what they match on up the tree. */
46
+ const ECHOED_QUERY_KINDS = new Set(['text', 'label']);
47
+ /**
48
+ * Drops every match that contains another match, the way a browser's text
49
+ * selector answers with the innermost element. A device tree echoes text and
50
+ * labels upwards: iOS reports a React Native Text host view and its
51
+ * StaticText child with the same label, a TextInput host view and the text
52
+ * field inside it with the same label, and a container view inherits its
53
+ * descendants' labels, so without this rule every `getByText` and
54
+ * `getByLabel` on such a screen is ambiguous.
55
+ */
56
+ function innermostOnly(matches) {
57
+ return matches.filter((entry) => !matches.some((other) => other !== entry && isWithin(other, entry)));
58
+ }
59
+ /** Strict descendants of any node in `ancestors`, in document order. */
60
+ function descendantsOf(ancestors, index) {
61
+ if (ancestors.length === 0)
62
+ return [];
63
+ return index.filter((entry) => ancestors.some((ancestor) => isWithin(entry, ancestor)));
64
+ }
65
+ function subtreeHasText(entry, index, pattern) {
66
+ const ownTexts = [entry.node.name, entry.node.text, entry.node.value];
67
+ if (ownTexts.some((text) => text !== undefined && matchesText(text, pattern)))
68
+ return true;
69
+ return descendantsOf([entry], index).some((child) => [child.node.name, child.node.text, child.node.value].some((text) => text !== undefined && matchesText(text, pattern)));
70
+ }
71
+ const STATE_KEYS = ['checked', 'disabled', 'selected', 'expanded', 'pressed'];
72
+ /**
73
+ * One node against one semantic query. Role queries skip hidden nodes, as a
74
+ * browser's role query does; the other kinds
75
+ * answer with every node and leave visibility to the action or assertion,
76
+ * unless the query says `visible`, which drops hidden nodes for every kind.
77
+ */
78
+ function matchesQuery(entry, query) {
79
+ const node = entry.node;
80
+ if (query.visible === true && node.states?.hidden === true)
81
+ return false;
82
+ switch (query.kind) {
83
+ case 'role': {
84
+ if (query.value.kind !== 'string') {
85
+ throw new EngineError('ENGINE_FAILURE', 'role query value must be a string', { retryable: false });
86
+ }
87
+ if ((node.role ?? '') !== query.value.value)
88
+ return false;
89
+ if (query.name !== undefined && !matchesText(node.name ?? '', query.name))
90
+ return false;
91
+ if (node.states?.hidden === true)
92
+ return false;
93
+ const wanted = query.states ?? {};
94
+ for (const key of STATE_KEYS) {
95
+ const expected = wanted[key];
96
+ if (expected !== undefined && (node.states?.[key] ?? false) !== expected)
97
+ return false;
98
+ }
99
+ // A device tree reports no heading levels, so a level query matches nothing rather than everything.
100
+ if (query.level !== undefined && node.level !== query.level)
101
+ return false;
102
+ return true;
103
+ }
104
+ case 'label':
105
+ return node.name !== undefined && matchesText(node.name, query.value);
106
+ case 'placeholder': {
107
+ const placeholder = node.attributes?.['placeholder'];
108
+ return placeholder !== undefined && matchesText(placeholder, query.value);
109
+ }
110
+ case 'text':
111
+ return ((node.name !== undefined && matchesText(node.name, query.value)) ||
112
+ (node.text !== undefined && matchesText(node.text, query.value)));
113
+ case 'displayValue':
114
+ return node.value !== undefined && matchesText(node.value, query.value);
115
+ case 'testId':
116
+ return node.testId !== undefined && matchesText(node.testId, query.value);
117
+ }
118
+ }
119
+ //# sourceMappingURL=locate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locate.js","sourceRoot":"","sources":["../src/locate.ts"],"names":[],"mappings":"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"}