@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.
- package/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.md +159 -0
- package/dist/.build.json +1 -0
- package/dist/actions.d.ts +41 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +70 -0
- package/dist/actions.js.map +1 -0
- package/dist/bindings.d.ts +87 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +112 -0
- package/dist/bindings.js.map +1 -0
- package/dist/device.d.ts +117 -0
- package/dist/device.d.ts.map +1 -0
- package/dist/device.js +116 -0
- package/dist/device.js.map +1 -0
- package/dist/engine.d.ts +17 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +98 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +61 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +223 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/links.d.ts +41 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +79 -0
- package/dist/links.js.map +1 -0
- package/dist/locate.d.ts +11 -0
- package/dist/locate.d.ts.map +1 -0
- package/dist/locate.js +119 -0
- package/dist/locate.js.map +1 -0
- package/dist/nodes.d.ts +107 -0
- package/dist/nodes.d.ts.map +1 -0
- package/dist/nodes.js +530 -0
- package/dist/nodes.js.map +1 -0
- package/dist/options.d.ts +134 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +7 -0
- package/dist/options.js.map +1 -0
- package/dist/png.d.ts +4 -0
- package/dist/png.d.ts.map +1 -0
- package/dist/png.js +25 -0
- package/dist/png.js.map +1 -0
- package/dist/pool.d.ts +99 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +235 -0
- package/dist/pool.js.map +1 -0
- package/dist/provider.d.ts +119 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +112 -0
- package/dist/provider.js.map +1 -0
- package/dist/selector.d.ts +17 -0
- package/dist/selector.d.ts.map +1 -0
- package/dist/selector.js +84 -0
- package/dist/selector.js.map +1 -0
- package/dist/support.d.ts +63 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +87 -0
- package/dist/support.js.map +1 -0
- package/dist/surface.d.ts +405 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +1159 -0
- package/dist/surface.js.map +1 -0
- package/dist/tools.d.ts +24 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +90 -0
- package/dist/tools.js.map +1 -0
- package/package.json +83 -0
package/dist/bindings.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one worker slot drives, and how it travels from the runner's `prepare`
|
|
3
|
+
* to the worker's `init`. Every way a pool comes by devices (a configured
|
|
4
|
+
* list, the booted devices it discovered, the leases a provider granted) is
|
|
5
|
+
* one `DeviceSource` that ends in one `SlotBinding` per slot, so the worker
|
|
6
|
+
* reads one shape through one environment variable, whatever produced it.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
import { EngineError, obj } from 'e2e/engine';
|
|
10
|
+
/** What a binding calls its device in progress and error lines: the name, else the id, else nothing. */
|
|
11
|
+
export function deviceLabel(binding) {
|
|
12
|
+
return binding?.device ?? binding?.deviceId;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The app a slot's `app.open()` launches, and its warm-up opens once: the
|
|
16
|
+
* `app` option, else the app the build `appPath` installed, once the suite's
|
|
17
|
+
* `device.installApp()` (or a device provider) has. `undefined` with a build
|
|
18
|
+
* nobody has installed and no `app`.
|
|
19
|
+
*/
|
|
20
|
+
export function pinnedApp(options, installedApp) {
|
|
21
|
+
return options.app ?? installedApp;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The most the serialized bindings of one target may occupy in a worker's
|
|
25
|
+
* environment: a lease comes from third-party code, and an oversized
|
|
26
|
+
* environment fails the worker spawn with an opaque error.
|
|
27
|
+
*/
|
|
28
|
+
const MAX_BINDINGS_ENV_BYTES = 16 * 1024;
|
|
29
|
+
/**
|
|
30
|
+
* The environment variable a target's bindings travel to the workers in: the
|
|
31
|
+
* name made environment-safe for reading, plus a digest of the exact name so
|
|
32
|
+
* `ios-a` and `ios.a` never share a key.
|
|
33
|
+
*/
|
|
34
|
+
export function bindingsVariable(targetName) {
|
|
35
|
+
const readable = targetName.replace(/[^A-Za-z0-9]/g, '_').toUpperCase();
|
|
36
|
+
const digest = createHash('sha256').update(targetName).digest('hex').slice(0, 8).toUpperCase();
|
|
37
|
+
return `E2E_AGENT_DEVICE_POOL_${readable}_${digest}`;
|
|
38
|
+
}
|
|
39
|
+
/** Serializes the bindings for the environment: declared fields only, bounded. */
|
|
40
|
+
export function encodeBindings(bindings) {
|
|
41
|
+
const encoded = JSON.stringify(bindings.map((binding) => obj({
|
|
42
|
+
device: binding.device,
|
|
43
|
+
deviceId: binding.deviceId,
|
|
44
|
+
daemon: binding.daemon === undefined ? undefined : obj({ baseUrl: binding.daemon.baseUrl, authToken: binding.daemon.authToken }),
|
|
45
|
+
client: binding.client,
|
|
46
|
+
installedApp: binding.installedApp,
|
|
47
|
+
sessionApp: binding.sessionApp,
|
|
48
|
+
})));
|
|
49
|
+
const bytes = Buffer.byteLength(encoded);
|
|
50
|
+
if (bytes > MAX_BINDINGS_ENV_BYTES) {
|
|
51
|
+
throw new EngineError('ENGINE_FAILURE', `the device bindings take ${bytes} bytes; the worker environment carries at most ${MAX_BINDINGS_ENV_BYTES}`, { retryable: false });
|
|
52
|
+
}
|
|
53
|
+
return encoded;
|
|
54
|
+
}
|
|
55
|
+
/** The bindings a `prepare` left in the environment, or `undefined` when there are none it can read. */
|
|
56
|
+
export function decodeBindings(raw) {
|
|
57
|
+
if (raw === undefined)
|
|
58
|
+
return undefined;
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(raw);
|
|
61
|
+
if (Array.isArray(parsed) && parsed.every(isSlotBinding))
|
|
62
|
+
return parsed;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Not ours to read.
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
function isOptionalString(value) {
|
|
70
|
+
return value === undefined || typeof value === 'string';
|
|
71
|
+
}
|
|
72
|
+
/** A binding as JSON parses it back, or as a provider returned it: nothing the engine did not write is trusted. */
|
|
73
|
+
export function isSlotBinding(value) {
|
|
74
|
+
if (typeof value !== 'object' || value === null)
|
|
75
|
+
return false;
|
|
76
|
+
const { device, deviceId, daemon, client, installedApp, sessionApp } = value;
|
|
77
|
+
return (isOptionalString(device) &&
|
|
78
|
+
isOptionalString(deviceId) &&
|
|
79
|
+
isOptionalString(installedApp) &&
|
|
80
|
+
isOptionalString(sessionApp) &&
|
|
81
|
+
(daemon === undefined || isDaemon(daemon)) &&
|
|
82
|
+
(client === undefined || isClientConfig(client)));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Reserved for the engine and the `daemon` field, where a provider's value would be
|
|
86
|
+
* silently overruled; the transport is how the worker reaches the daemon, not a device fact.
|
|
87
|
+
*/
|
|
88
|
+
const RESERVED_CLIENT_KEYS = new Set(['session', 'daemonBaseUrl', 'daemonAuthToken', 'daemonTransport']);
|
|
89
|
+
/** Plain JSON data with none of the reserved keys: what survives the environment and what the engine will not override. */
|
|
90
|
+
function isClientConfig(value) {
|
|
91
|
+
return isJsonObject(value) && Object.keys(value).every((key) => !RESERVED_CLIENT_KEYS.has(key));
|
|
92
|
+
}
|
|
93
|
+
function isJsonObject(value) {
|
|
94
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.values(value).every(isJsonValue);
|
|
95
|
+
}
|
|
96
|
+
/** What survives `JSON.stringify` unchanged: a non-finite number would reach the worker as `null`. */
|
|
97
|
+
function isJsonValue(value) {
|
|
98
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
99
|
+
return true;
|
|
100
|
+
if (typeof value === 'number')
|
|
101
|
+
return Number.isFinite(value);
|
|
102
|
+
if (Array.isArray(value))
|
|
103
|
+
return value.every(isJsonValue);
|
|
104
|
+
return isJsonObject(value);
|
|
105
|
+
}
|
|
106
|
+
function isDaemon(value) {
|
|
107
|
+
if (typeof value !== 'object' || value === null)
|
|
108
|
+
return false;
|
|
109
|
+
const { baseUrl, authToken } = value;
|
|
110
|
+
return typeof baseUrl === 'string' && isOptionalString(authToken);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=bindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bindings.js","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
|
package/dist/device.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `device` fixture: deterministic device management this engine
|
|
3
|
+
* contributes. Not an agent tool; a test calls these directly to arrange or
|
|
4
|
+
* assert device state, and the harness records each call as a
|
|
5
|
+
* `device.<method>` step bounded by the action timeout.
|
|
6
|
+
*/
|
|
7
|
+
import type { EngineFixtureContext, Locator } from 'e2e/engine';
|
|
8
|
+
import type { DevicePermission, PermissionState } from './options.ts';
|
|
9
|
+
import type { AgentDeviceSurface, InstallAppOptions, InstalledApp, OpenAppOptions } from './surface.ts';
|
|
10
|
+
/** Orientations `setOrientation` accepts. */
|
|
11
|
+
export type DeviceOrientation = 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right';
|
|
12
|
+
export type BiometricSensor = 'faceid' | 'touchid' | 'fingerprint';
|
|
13
|
+
export interface ForegroundApp {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly bundleId?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Deterministic device management exposed to tests as `device`. */
|
|
18
|
+
export interface Device {
|
|
19
|
+
/**
|
|
20
|
+
* A locator from an agent-device selector (`'id=SW_VERSION_SPECIFIER'`,
|
|
21
|
+
* `'role=StaticText label="26.2"'`), for nodes the closed `screen` query
|
|
22
|
+
* vocabulary cannot name. Same polling and strictness as any locator.
|
|
23
|
+
*/
|
|
24
|
+
locator(selector: string): Locator;
|
|
25
|
+
/** Toggles the device's Wi-Fi. */
|
|
26
|
+
setNetwork(state: 'online' | 'offline'): Promise<void>;
|
|
27
|
+
/** Toggles airplane mode. */
|
|
28
|
+
setAirplaneMode(enabled: boolean): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Grants, denies, or resets one permission for the pinned app, brought to
|
|
31
|
+
* the foreground first when the session is on no app. A change terminates
|
|
32
|
+
* a running app on iOS, a revoke one on Android, so it goes before the
|
|
33
|
+
* `app.open()` a test starts with.
|
|
34
|
+
*/
|
|
35
|
+
setPermission(permission: DevicePermission, state: PermissionState): Promise<void>;
|
|
36
|
+
/** Sets the simulated location, switching location services on first on Android. */
|
|
37
|
+
setLocation(coordinates: {
|
|
38
|
+
latitude: number;
|
|
39
|
+
longitude: number;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
/** Turns simulated location off; on Android that is location services off, until the next `setLocation`. */
|
|
42
|
+
clearLocation(): Promise<void>;
|
|
43
|
+
/** Sets the system appearance. */
|
|
44
|
+
setAppearance(mode: 'light' | 'dark'): Promise<void>;
|
|
45
|
+
/** Rotates the device. */
|
|
46
|
+
setOrientation(orientation: DeviceOrientation): Promise<void>;
|
|
47
|
+
/** Simulates one biometric attempt on the open app. */
|
|
48
|
+
setBiometrics(sensor: BiometricSensor, result: 'match' | 'nonmatch'): Promise<void>;
|
|
49
|
+
/** Enrolls or unenrolls the simulator's Face ID or Touch ID. */
|
|
50
|
+
enrollBiometrics(sensor: 'faceid' | 'touchid', enrolled: boolean): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Installs a build (an iOS `.app` bundle or an Android `.apk`, resolved
|
|
53
|
+
* against the project root) on the device; without a path, the engine's
|
|
54
|
+
* `appPath`. The engine installs nothing on its own, so a suite that runs
|
|
55
|
+
* against a build calls this once per device, in a fixture or a test.
|
|
56
|
+
* `reinstall: true` removes the app first so it starts with no data; a
|
|
57
|
+
* plain install replaces the binary and keeps its data. Resolves to the
|
|
58
|
+
* identity to `openApp` it by, which becomes the app `app.open()` launches
|
|
59
|
+
* when the engine's build is installed and no `app` is pinned.
|
|
60
|
+
*/
|
|
61
|
+
installApp(appPath?: string, options?: InstallAppOptions): Promise<InstalledApp>;
|
|
62
|
+
/**
|
|
63
|
+
* Brings an app to the foreground; `relaunch` restarts it fresh.
|
|
64
|
+
* `launchArguments` and `permissions` apply to this launch alone; the
|
|
65
|
+
* engine's configured ones apply to a `relaunch` of the pinned app, and
|
|
66
|
+
* to no foreground-only open.
|
|
67
|
+
*/
|
|
68
|
+
openApp(app: string, options?: OpenAppOptions): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Opens a deep link (`myapp://orders/42`) or a web link (`https://...`)
|
|
71
|
+
* into `app` (default: the pinned app), which the session observes
|
|
72
|
+
* afterwards. iOS launches the app for a web link and then opens the URL;
|
|
73
|
+
* a web link the app does not claim goes to Safari, and the next
|
|
74
|
+
* observation brings the app back. Android starts the link on that
|
|
75
|
+
* package. Without an app, Android lets the OS route the link; iOS needs
|
|
76
|
+
* one (`INVALID_ARGUMENT` without). `file:`, `data:`, and `javascript:`
|
|
77
|
+
* links are `POLICY_DENIED`.
|
|
78
|
+
*/
|
|
79
|
+
openLink(url: string, options?: {
|
|
80
|
+
app?: string;
|
|
81
|
+
}): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Terminates the session's app and ends the session, so the next
|
|
84
|
+
* `openApp` launches it fresh. Until then the screen is unobservable and
|
|
85
|
+
* `foregroundApp` is `APP_NOT_OPEN`.
|
|
86
|
+
*/
|
|
87
|
+
closeApp(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Resets the simulator's keychain, every app's, since simctl has no
|
|
90
|
+
* per-app reset: what `app.clearState()` leaves behind (a session token, a
|
|
91
|
+
* Firebase sign-in). iOS simulator only; Android is
|
|
92
|
+
* `UNSUPPORTED_CAPABILITY`. Launch the app afterwards to see it signed out.
|
|
93
|
+
*/
|
|
94
|
+
clearKeychain(): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* The app the session is on. iOS answers from the session, not the
|
|
97
|
+
* device, so it names the app the session opened even after `home()`;
|
|
98
|
+
* Android reads the device's foreground activity. `APP_NOT_OPEN` once
|
|
99
|
+
* `closeApp` ended the session.
|
|
100
|
+
*/
|
|
101
|
+
foregroundApp(): Promise<ForegroundApp>;
|
|
102
|
+
/** Sends the device to its home screen. */
|
|
103
|
+
home(): Promise<void>;
|
|
104
|
+
/** Navigates back once (in-app back). */
|
|
105
|
+
back(): Promise<void>;
|
|
106
|
+
/** Accepts or dismisses the visible system alert. */
|
|
107
|
+
alert(action: 'accept' | 'dismiss'): Promise<void>;
|
|
108
|
+
/** Dismisses the soft keyboard. */
|
|
109
|
+
dismissKeyboard(): Promise<void>;
|
|
110
|
+
/** Reads the clipboard. */
|
|
111
|
+
clipboard(): Promise<string>;
|
|
112
|
+
/** Writes the clipboard. */
|
|
113
|
+
setClipboard(text: string): Promise<void>;
|
|
114
|
+
}
|
|
115
|
+
/** Builds the device fixture for one attempt. */
|
|
116
|
+
export declare function createDeviceFixture(surface: AgentDeviceSurface, context: EngineFixtureContext): Device;
|
|
117
|
+
//# sourceMappingURL=device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}
|
package/dist/device.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `device` fixture: deterministic device management this engine
|
|
3
|
+
* contributes. Not an agent tool; a test calls these directly to arrange or
|
|
4
|
+
* assert device state, and the harness records each call as a
|
|
5
|
+
* `device.<method>` step bounded by the action timeout.
|
|
6
|
+
*/
|
|
7
|
+
import { linkLabel, linkTarget } from './links.js';
|
|
8
|
+
/** Builds the device fixture for one attempt. */
|
|
9
|
+
export function createDeviceFixture(surface, context) {
|
|
10
|
+
const device = {
|
|
11
|
+
locator: (selector) => context.locator({ kind: 'selector', selector }),
|
|
12
|
+
async setNetwork(state) {
|
|
13
|
+
await surface.command('device.setNetwork', (client) => client.settings.update({ setting: 'wifi', state: state === 'offline' ? 'off' : 'on' }), context.signal);
|
|
14
|
+
},
|
|
15
|
+
async setAirplaneMode(enabled) {
|
|
16
|
+
await surface.command('device.setAirplaneMode', (client) => client.settings.update({ setting: 'airplane', state: enabled ? 'on' : 'off' }), context.signal);
|
|
17
|
+
},
|
|
18
|
+
async setPermission(permission, state) {
|
|
19
|
+
await surface.setPermission(permission, state, context.signal);
|
|
20
|
+
},
|
|
21
|
+
async setLocation({ latitude, longitude }) {
|
|
22
|
+
// Android reads a fix only while location services are on, and
|
|
23
|
+
// `clearLocation` switched them off for good on the emulator (the
|
|
24
|
+
// setting outlives the app); iOS has no such switch.
|
|
25
|
+
if (surface.options.platform === 'android') {
|
|
26
|
+
await surface.command('device.setLocation', (client) => client.settings.update({ setting: 'location', state: 'on' }), context.signal);
|
|
27
|
+
}
|
|
28
|
+
await surface.command('device.setLocation', (client) => client.settings.update({ setting: 'location', state: 'set', latitude, longitude }), context.signal);
|
|
29
|
+
},
|
|
30
|
+
async clearLocation() {
|
|
31
|
+
await surface.command('device.clearLocation', (client) => client.settings.update({ setting: 'location', state: 'off' }), context.signal);
|
|
32
|
+
},
|
|
33
|
+
async setAppearance(mode) {
|
|
34
|
+
await surface.command('device.setAppearance', (client) => client.settings.update({ setting: 'appearance', state: mode }), context.signal);
|
|
35
|
+
},
|
|
36
|
+
async setOrientation(orientation) {
|
|
37
|
+
await surface.screenCommand('device.setOrientation', (client) => client.command.orientation({ orientation }), context.signal);
|
|
38
|
+
},
|
|
39
|
+
async setBiometrics(sensor, result) {
|
|
40
|
+
await surface.command('device.setBiometrics', (client) => sensor === 'fingerprint'
|
|
41
|
+
? client.settings.update({ setting: 'fingerprint', state: result })
|
|
42
|
+
: client.settings.update({ setting: sensor, state: result }), context.signal);
|
|
43
|
+
},
|
|
44
|
+
async enrollBiometrics(sensor, enrolled) {
|
|
45
|
+
await surface.command('device.enrollBiometrics', (client) => client.settings.update({ setting: sensor, state: enrolled ? 'enroll' : 'unenroll' }), context.signal);
|
|
46
|
+
},
|
|
47
|
+
async installApp(appPath, options) {
|
|
48
|
+
return surface.installApp(appPath, options ?? {}, context.signal);
|
|
49
|
+
},
|
|
50
|
+
async openApp(app, options) {
|
|
51
|
+
await surface.openApp(app, options ?? {}, context.signal);
|
|
52
|
+
},
|
|
53
|
+
async openLink(url, options) {
|
|
54
|
+
await surface.openLink(linkTarget(url), options?.app, context.signal);
|
|
55
|
+
},
|
|
56
|
+
async closeApp() {
|
|
57
|
+
await surface.closeApp(context.signal);
|
|
58
|
+
},
|
|
59
|
+
async clearKeychain() {
|
|
60
|
+
await surface.clearKeychain(context.signal);
|
|
61
|
+
},
|
|
62
|
+
async foregroundApp() {
|
|
63
|
+
const state = await surface.command('device.foregroundApp', (client) => client.command.appState({}), context.signal);
|
|
64
|
+
if ('package' in state)
|
|
65
|
+
return { name: state.package, bundleId: state.package };
|
|
66
|
+
return {
|
|
67
|
+
name: state.appName,
|
|
68
|
+
...(state.appBundleId === undefined ? {} : { bundleId: state.appBundleId }),
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
async home() {
|
|
72
|
+
await surface.screenCommand('device.home', (client) => client.command.home({}), context.signal);
|
|
73
|
+
},
|
|
74
|
+
async back() {
|
|
75
|
+
await surface.screenCommand('device.back', (client) => client.command.back({ ...surface.settleOptions }), context.signal);
|
|
76
|
+
},
|
|
77
|
+
async alert(action) {
|
|
78
|
+
await surface.screenCommand('device.alert', (client) => client.command.alert({ action }), context.signal);
|
|
79
|
+
},
|
|
80
|
+
async dismissKeyboard() {
|
|
81
|
+
await surface.dismissKeyboard(context.signal);
|
|
82
|
+
},
|
|
83
|
+
async clipboard() {
|
|
84
|
+
const result = await surface.command('device.clipboard', (client) => client.command.clipboard({ action: 'read' }), context.signal);
|
|
85
|
+
return result.action === 'read' ? result.text : '';
|
|
86
|
+
},
|
|
87
|
+
async setClipboard(text) {
|
|
88
|
+
await surface.command('device.setClipboard', (client) => client.command.clipboard({ action: 'write', text }), context.signal);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const action = { kind: 'resource' };
|
|
92
|
+
return context.fixture('device', device, {
|
|
93
|
+
setNetwork: { ...action, label: (state) => state },
|
|
94
|
+
setAirplaneMode: action,
|
|
95
|
+
setPermission: { ...action, label: (permission) => permission },
|
|
96
|
+
setLocation: action,
|
|
97
|
+
clearLocation: action,
|
|
98
|
+
setAppearance: { ...action, label: (mode) => mode },
|
|
99
|
+
setOrientation: { ...action, label: (orientation) => orientation },
|
|
100
|
+
setBiometrics: action,
|
|
101
|
+
enrollBiometrics: action,
|
|
102
|
+
installApp: { ...action, label: (appPath) => appPath ?? surface.options.appPath ?? 'appPath' },
|
|
103
|
+
openApp: { ...action, label: (app) => linkLabel(app) },
|
|
104
|
+
openLink: { ...action, label: (url) => linkLabel(url) },
|
|
105
|
+
closeApp: action,
|
|
106
|
+
clearKeychain: action,
|
|
107
|
+
foregroundApp: action,
|
|
108
|
+
home: action,
|
|
109
|
+
back: action,
|
|
110
|
+
alert: { ...action, label: (value) => value },
|
|
111
|
+
dismissKeyboard: action,
|
|
112
|
+
clipboard: action,
|
|
113
|
+
setClipboard: { ...action, label: (text) => `${text.length} chars` },
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent-device engine for e2e: a mobile body built with the
|
|
3
|
+
* public `defineEngine`, validated by the same rules and graded by the same
|
|
4
|
+
* capabilities as any other engine. Core imports nothing from here; this
|
|
5
|
+
* package imports the contract from `e2e/engine` and contributes the
|
|
6
|
+
* `device` fixture the way the browser engine contributes `web`.
|
|
7
|
+
*/
|
|
8
|
+
import { type EngineHandle } from 'e2e/engine';
|
|
9
|
+
import type { MobileOptions } from './options.ts';
|
|
10
|
+
import { AgentDeviceSurface } from './surface.ts';
|
|
11
|
+
/** Assembles the manifest for one surface. Exported for tests that script the client. */
|
|
12
|
+
export declare function buildEngine(surface: AgentDeviceSurface): EngineHandle;
|
|
13
|
+
/** Creates one agent-device engine: one device session per worker; a test launches the pinned app with `app.open()`. */
|
|
14
|
+
export declare function mobile(options: MobileOptions): EngineHandle;
|
|
15
|
+
/** The surface behind a handle this package created; undefined for any other engine. */
|
|
16
|
+
export declare function surfaceOf(engine: EngineHandle): AgentDeviceSurface | undefined;
|
|
17
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAgD,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE7F,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIlD,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,YAAY,CAgDrE;AAED,wHAAwH;AACxH,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAW3D;AAaD,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,kBAAkB,GAAG,SAAS,CAE9E"}
|
package/dist/engine.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent-device engine for e2e: a mobile body built with the
|
|
3
|
+
* public `defineEngine`, validated by the same rules and graded by the same
|
|
4
|
+
* capabilities as any other engine. Core imports nothing from here; this
|
|
5
|
+
* package imports the contract from `e2e/engine` and contributes the
|
|
6
|
+
* `device` fixture the way the browser engine contributes `web`.
|
|
7
|
+
*/
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { createAgentDeviceClient } from 'agent-device';
|
|
10
|
+
import { defineEngine, obj } from 'e2e/engine';
|
|
11
|
+
import { createDeviceFixture } from './device.js';
|
|
12
|
+
import { DEVICE_ACTIONS, DEVICE_POINTER_ACTIONS } from './actions.js';
|
|
13
|
+
import { AgentDeviceSurface } from './surface.js';
|
|
14
|
+
const surfaces = new WeakMap();
|
|
15
|
+
/** Assembles the manifest for one surface. Exported for tests that script the client. */
|
|
16
|
+
export function buildEngine(surface) {
|
|
17
|
+
const handle = defineEngine({
|
|
18
|
+
name: 'mobile',
|
|
19
|
+
version: ownVersion(),
|
|
20
|
+
spiVersion: 1,
|
|
21
|
+
platform: surface.options.platform,
|
|
22
|
+
...(surface.pool.size === undefined ? {} : { workers: surface.pool.size }),
|
|
23
|
+
prepare: (info) => surface.pool.prepare(info),
|
|
24
|
+
finish: (info) => surface.pool.finish(info),
|
|
25
|
+
init: (info) => surface.init(info),
|
|
26
|
+
startAttempt: (context) => surface.startAttempt(context),
|
|
27
|
+
endAttempt: (context) => surface.endAttempt(context),
|
|
28
|
+
dispose: (context) => surface.dispose(context),
|
|
29
|
+
observe: (operation, options) => surface.observe(operation, options),
|
|
30
|
+
locate: (expression, operation) => surface.locate(expression, operation),
|
|
31
|
+
perform: (ref, action, operation) => surface.perform(ref, action, operation),
|
|
32
|
+
actions: DEVICE_ACTIONS,
|
|
33
|
+
performAt: (point, action, operation) => surface.performAt(point, action, operation),
|
|
34
|
+
pointerActions: DEVICE_POINTER_ACTIONS,
|
|
35
|
+
keyboard: {
|
|
36
|
+
type: (text, keyboardOptions, operation) => surface.typeText(text, keyboardOptions, operation),
|
|
37
|
+
press: (key, operation) => surface.pressFocusedKey(key, operation),
|
|
38
|
+
dismiss: (operation) => surface.dismissKeyboard(operation.signal),
|
|
39
|
+
},
|
|
40
|
+
app: declaredApp(surface.options),
|
|
41
|
+
// No `open`: a device app has no URL to open, so the runner serves
|
|
42
|
+
// `app.open()` with `restart`, the fresh launch of the pinned app, which
|
|
43
|
+
// is also the device's "recreate the context"; restart and reset need one.
|
|
44
|
+
session: {
|
|
45
|
+
back: (operation) => surface.back(operation),
|
|
46
|
+
...(surface.managesApp
|
|
47
|
+
? {
|
|
48
|
+
restart: (operation) => surface.restart(operation),
|
|
49
|
+
reset: (operation) => surface.reset(operation),
|
|
50
|
+
}
|
|
51
|
+
: {}),
|
|
52
|
+
},
|
|
53
|
+
artifacts: {
|
|
54
|
+
screenshot: (label, operation) => surface.screenshot(label, operation),
|
|
55
|
+
startVideo: (operation) => surface.startVideo(operation),
|
|
56
|
+
stopVideo: (operation) => surface.stopVideo(operation),
|
|
57
|
+
},
|
|
58
|
+
fixtures: {
|
|
59
|
+
device: (context) => createDeviceFixture(surface, context),
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
surfaces.set(handle, surface);
|
|
63
|
+
return handle;
|
|
64
|
+
}
|
|
65
|
+
/** Creates one agent-device engine: one device session per worker; a test launches the pinned app with `app.open()`. */
|
|
66
|
+
export function mobile(options) {
|
|
67
|
+
const factory = (session, connection) => createAgentDeviceClient(obj({
|
|
68
|
+
...connection?.client,
|
|
69
|
+
session,
|
|
70
|
+
daemonBaseUrl: connection?.daemon?.baseUrl,
|
|
71
|
+
daemonAuthToken: connection?.daemon?.authToken,
|
|
72
|
+
}));
|
|
73
|
+
return buildEngine(new AgentDeviceSurface(options, factory));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* What the device engine declares about its app: the pinned app (else the
|
|
77
|
+
* build it installs) is the identity cache and session entries key on.
|
|
78
|
+
*/
|
|
79
|
+
function declaredApp(options) {
|
|
80
|
+
return obj({
|
|
81
|
+
identity: options.identity ?? options.app ?? options.appPath,
|
|
82
|
+
environment: options.environment,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/** The surface behind a handle this package created; undefined for any other engine. */
|
|
86
|
+
export function surfaceOf(engine) {
|
|
87
|
+
return surfaces.get(engine);
|
|
88
|
+
}
|
|
89
|
+
/** This package's published version, read through require resolution. */
|
|
90
|
+
function ownVersion() {
|
|
91
|
+
try {
|
|
92
|
+
return createRequire(import.meta.url)('../package.json').version;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return 'unknown';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
/** A failure's message in agent-device's normalized form. */
|
|
24
|
+
export declare function message(cause: unknown): string;
|
|
25
|
+
/**
|
|
26
|
+
* Translates an unexpected agent-device error at the contract boundary.
|
|
27
|
+
* `where` names the session and device the command ran under, for the
|
|
28
|
+
* messages whose recovery is per device.
|
|
29
|
+
*/
|
|
30
|
+
export declare function translateError(cause: unknown, operation: string, where?: string): Error;
|
|
31
|
+
/**
|
|
32
|
+
* True for a translated failure of the iOS automation runner itself: busy,
|
|
33
|
+
* wedged, or past its watchdog. The runner, not the app, is what needs
|
|
34
|
+
* attention, so a caller that tolerates an app that did not open (warm-up)
|
|
35
|
+
* must not tolerate this.
|
|
36
|
+
*/
|
|
37
|
+
export declare function isRunnerFailure(error: unknown): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* True for a translated settings command agent-device refused because its
|
|
40
|
+
* session is on no app: the one refusal a foreground open of the pinned app
|
|
41
|
+
* answers.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isNoSessionApp(error: unknown): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* True for a translated snapshot the iOS runner acquired but could not
|
|
46
|
+
* present. The check is per capture and the capture is a read, so one retry
|
|
47
|
+
* is safe and usually enough.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isSnapshotPresentationFailure(error: unknown): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Runs one agent-device command under an abort signal and translates its
|
|
52
|
+
* failure onto the engine taxonomy: the one boundary every command crosses.
|
|
53
|
+
*/
|
|
54
|
+
export declare function runCommand<T>(label: string, work: () => Promise<T>, signal: AbortSignal, where?: string): Promise<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Like translateError, but a ref the daemon no longer binds becomes retryable
|
|
57
|
+
* `NODE_STALE`: nothing was dispatched, so the harness may re-observe and
|
|
58
|
+
* re-resolve the node instead of failing the action.
|
|
59
|
+
*/
|
|
60
|
+
export declare function staleOr(cause: unknown, operation: string, where?: string): Error;
|
|
61
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAiBH,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE9C;AAwHD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAkBvF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvD;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAErE;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAM1H;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAOhF"}
|