@e2edev/mobile 0.8.0-canary-20260921180210
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 +149 -0
- package/dist/.build.json +1 -0
- package/dist/actions.d.ts +29 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +62 -0
- package/dist/actions.js.map +1 -0
- package/dist/bindings.d.ts +57 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +79 -0
- package/dist/bindings.js.map +1 -0
- package/dist/device.d.ts +77 -0
- package/dist/device.d.ts.map +1 -0
- package/dist/device.js +101 -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 +92 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +95 -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/locate.d.ts +11 -0
- package/dist/locate.d.ts.map +1 -0
- package/dist/locate.js +115 -0
- package/dist/locate.js.map +1 -0
- package/dist/nodes.d.ts +86 -0
- package/dist/nodes.d.ts.map +1 -0
- package/dist/nodes.js +315 -0
- package/dist/nodes.js.map +1 -0
- package/dist/options.d.ts +93 -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 +72 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +185 -0
- package/dist/pool.js.map +1 -0
- package/dist/provider.d.ts +105 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +98 -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 +58 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +82 -0
- package/dist/support.js.map +1 -0
- package/dist/surface.d.ts +243 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +837 -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
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Shared helpers for the agent-device engine: error constructors, filenames, PNG headers, gestures, the screen location and size. */
|
|
2
|
+
import { EngineError, type Momentum, type ScrollDirection, type ViewportSize } from 'e2e/engine';
|
|
3
|
+
export interface Point {
|
|
4
|
+
readonly x: number;
|
|
5
|
+
readonly y: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Rect {
|
|
8
|
+
readonly x: number;
|
|
9
|
+
readonly y: number;
|
|
10
|
+
readonly width: number;
|
|
11
|
+
readonly height: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function cancelled(text: string): EngineError;
|
|
14
|
+
export declare function invalidState(text: string): EngineError;
|
|
15
|
+
export declare function notActionable(text: string): EngineError;
|
|
16
|
+
export declare function unsupported(text: string): EngineError;
|
|
17
|
+
/** Constrains a caller-supplied artifact label to a safe filename. */
|
|
18
|
+
export declare function sanitizeFilename(name: string): string;
|
|
19
|
+
/** Reads the dimensions out of a PNG's IHDR chunk; undefined for anything else. */
|
|
20
|
+
export declare function readPngSize(data: Uint8Array): {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
} | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* The finger gesture that scrolls one rect's content in `direction`. Scrolling
|
|
26
|
+
* down reveals what is below, so the finger travels up; the travel is a share
|
|
27
|
+
* of the rect's extent scaled by momentum, and never leaves the rect.
|
|
28
|
+
*/
|
|
29
|
+
export declare function swipeWithin(rect: Rect, direction: ScrollDirection, momentum: Momentum | undefined): {
|
|
30
|
+
from: Point;
|
|
31
|
+
to: Point;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The location a device surface reports in a snapshot: the foreground app
|
|
35
|
+
* and the screen shown, `<app> / <screen title>`. A simulator has no address
|
|
36
|
+
* bar, so this is an opaque address the harness shows to the model and the
|
|
37
|
+
* report and anchors trace replay on; it changes exactly when the app or its
|
|
38
|
+
* screen changes. It is deliberately not a URL: no scheme, no colon, so the
|
|
39
|
+
* harness never mistakes it for one and applies an origin policy to it.
|
|
40
|
+
* Undefined when neither the app nor a title is known.
|
|
41
|
+
*/
|
|
42
|
+
export declare function screenLocation(app: string | undefined, title: string | undefined): string | undefined;
|
|
43
|
+
/** The screenshot fields a viewport probe reads off agent-device's response. */
|
|
44
|
+
export interface RawScreenshotResult {
|
|
45
|
+
readonly path?: string;
|
|
46
|
+
readonly width?: number;
|
|
47
|
+
readonly height?: number;
|
|
48
|
+
readonly logicalWidth?: number;
|
|
49
|
+
readonly logicalHeight?: number;
|
|
50
|
+
readonly pixelDensity?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The device's logical screen size as its screenshot reports it, in points:
|
|
54
|
+
* the logical dimensions when given, else the pixel dimensions over the
|
|
55
|
+
* density. Undefined when the response carries neither.
|
|
56
|
+
*/
|
|
57
|
+
export declare function logicalScreenSize(result: RawScreenshotResult): ViewportSize | undefined;
|
|
58
|
+
//# sourceMappingURL=support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../src/support.ts"],"names":[],"mappings":"AAAA,sIAAsI;AAEtI,OAAO,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEjG,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAEnD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAEtD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAEvD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAErD;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAID,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAO3F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAC7B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,CAe5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKrG;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,mBAAmB,GAC1B,YAAY,GAAG,SAAS,CAS1B"}
|
package/dist/support.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** Shared helpers for the agent-device engine: error constructors, filenames, PNG headers, gestures, the screen location and size. */
|
|
2
|
+
import { EngineError } from 'e2e/engine';
|
|
3
|
+
export function cancelled(text) {
|
|
4
|
+
return new EngineError('CANCELLED', text, { retryable: false });
|
|
5
|
+
}
|
|
6
|
+
export function invalidState(text) {
|
|
7
|
+
return new EngineError('INVALID_STATE', text, { retryable: false });
|
|
8
|
+
}
|
|
9
|
+
export function notActionable(text) {
|
|
10
|
+
return new EngineError('NOT_ACTIONABLE', text, { retryable: false });
|
|
11
|
+
}
|
|
12
|
+
export function unsupported(text) {
|
|
13
|
+
return new EngineError('UNSUPPORTED_CAPABILITY', text, { retryable: false });
|
|
14
|
+
}
|
|
15
|
+
/** Constrains a caller-supplied artifact label to a safe filename. */
|
|
16
|
+
export function sanitizeFilename(name) {
|
|
17
|
+
return name.replaceAll(/[^A-Za-z0-9._-]/g, '_').slice(0, 64) || 'artifact';
|
|
18
|
+
}
|
|
19
|
+
const PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];
|
|
20
|
+
/** Reads the dimensions out of a PNG's IHDR chunk; undefined for anything else. */
|
|
21
|
+
export function readPngSize(data) {
|
|
22
|
+
if (data.byteLength < 24)
|
|
23
|
+
return undefined;
|
|
24
|
+
for (const [offset, byte] of PNG_SIGNATURE.entries()) {
|
|
25
|
+
if (data[offset] !== byte)
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
29
|
+
return { width: view.getUint32(16), height: view.getUint32(20) };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The finger gesture that scrolls one rect's content in `direction`. Scrolling
|
|
33
|
+
* down reveals what is below, so the finger travels up; the travel is a share
|
|
34
|
+
* of the rect's extent scaled by momentum, and never leaves the rect.
|
|
35
|
+
*/
|
|
36
|
+
export function swipeWithin(rect, direction, momentum) {
|
|
37
|
+
const ratio = momentum === 'fast' ? 0.8 : momentum === 'slow' ? 0.25 : 0.5;
|
|
38
|
+
const centre = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
|
|
39
|
+
const dx = (rect.width * ratio) / 2;
|
|
40
|
+
const dy = (rect.height * ratio) / 2;
|
|
41
|
+
switch (direction) {
|
|
42
|
+
case 'down':
|
|
43
|
+
return { from: { x: centre.x, y: centre.y + dy }, to: { x: centre.x, y: centre.y - dy } };
|
|
44
|
+
case 'up':
|
|
45
|
+
return { from: { x: centre.x, y: centre.y - dy }, to: { x: centre.x, y: centre.y + dy } };
|
|
46
|
+
case 'right':
|
|
47
|
+
return { from: { x: centre.x + dx, y: centre.y }, to: { x: centre.x - dx, y: centre.y } };
|
|
48
|
+
case 'left':
|
|
49
|
+
return { from: { x: centre.x - dx, y: centre.y }, to: { x: centre.x + dx, y: centre.y } };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The location a device surface reports in a snapshot: the foreground app
|
|
54
|
+
* and the screen shown, `<app> / <screen title>`. A simulator has no address
|
|
55
|
+
* bar, so this is an opaque address the harness shows to the model and the
|
|
56
|
+
* report and anchors trace replay on; it changes exactly when the app or its
|
|
57
|
+
* screen changes. It is deliberately not a URL: no scheme, no colon, so the
|
|
58
|
+
* harness never mistakes it for one and applies an origin policy to it.
|
|
59
|
+
* Undefined when neither the app nor a title is known.
|
|
60
|
+
*/
|
|
61
|
+
export function screenLocation(app, title) {
|
|
62
|
+
const parts = [app, title]
|
|
63
|
+
.map((part) => (part === undefined ? '' : part.replaceAll(/\s+/g, ' ').trim()))
|
|
64
|
+
.filter((part) => part !== '');
|
|
65
|
+
return parts.length === 0 ? undefined : parts.join(' / ');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The device's logical screen size as its screenshot reports it, in points:
|
|
69
|
+
* the logical dimensions when given, else the pixel dimensions over the
|
|
70
|
+
* density. Undefined when the response carries neither.
|
|
71
|
+
*/
|
|
72
|
+
export function logicalScreenSize(result) {
|
|
73
|
+
const logical = result.logicalWidth !== undefined && result.logicalHeight !== undefined
|
|
74
|
+
? { width: result.logicalWidth, height: result.logicalHeight }
|
|
75
|
+
: result.width !== undefined && result.height !== undefined && result.pixelDensity !== undefined && result.pixelDensity > 0
|
|
76
|
+
? { width: result.width / result.pixelDensity, height: result.height / result.pixelDensity }
|
|
77
|
+
: undefined;
|
|
78
|
+
if (logical === undefined || logical.width <= 0 || logical.height <= 0)
|
|
79
|
+
return undefined;
|
|
80
|
+
return logical;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"support.js","sourceRoot":"","sources":["../src/support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent-device surface: one simulator or emulator session, driven through
|
|
3
|
+
* agent-device's typed client, exposed to the runner as the contract's
|
|
4
|
+
* observe/locate/perform members. It owns the id space (one fresh generation
|
|
5
|
+
* per observation), the attempt state (artifact directory, screenshot
|
|
6
|
+
* counter), and every translation between the contract's vocabulary and
|
|
7
|
+
* agent-device's commands. Its device and session come from the target's
|
|
8
|
+
* `DevicePool`, by worker slot. The runner owns everything else.
|
|
9
|
+
*
|
|
10
|
+
* Every observation is reported under one root of a stable id (`ROOT_ID`)
|
|
11
|
+
* wrapping the device's top-level elements; a `swipe` performed on that root
|
|
12
|
+
* scrolls the whole screen.
|
|
13
|
+
*/
|
|
14
|
+
import { type EngineAttemptContext, type EngineCleanupContext, type EngineInitInfo, type EngineObserveOptions, type EngineSnapshot, type LocatorAction, type LocatorExpression, type NodeRef, type OperationContext, type PointerAction, type VideoSegment, type SemanticNode, type ViewportPoint } from 'e2e/engine';
|
|
15
|
+
import type { AgentDeviceClient, MobileOptions, ClientFactory } from './options.ts';
|
|
16
|
+
import { DevicePool } from './pool.ts';
|
|
17
|
+
/** How `installApp` puts a build on the device. */
|
|
18
|
+
export interface InstallAppOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Bundle id or package of the build. `reinstall` needs one: agent-device
|
|
21
|
+
* removes that app before installing. Defaults to the pinned app.
|
|
22
|
+
*/
|
|
23
|
+
readonly app?: string;
|
|
24
|
+
/** Remove the installed app first so the build starts with no data. */
|
|
25
|
+
readonly reinstall?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** What an install put on the device, as agent-device identified it. */
|
|
28
|
+
export interface InstalledApp {
|
|
29
|
+
/** The bundle id or package to open the app by. */
|
|
30
|
+
readonly app: string;
|
|
31
|
+
readonly bundleId?: string;
|
|
32
|
+
}
|
|
33
|
+
/** What agent-device is told about settling after an action. */
|
|
34
|
+
type SettleOptions = {
|
|
35
|
+
readonly settle: true;
|
|
36
|
+
readonly settleQuietMs: number;
|
|
37
|
+
} | Record<never, never>;
|
|
38
|
+
export declare class AgentDeviceSurface {
|
|
39
|
+
readonly options: MobileOptions;
|
|
40
|
+
private readonly createClient;
|
|
41
|
+
private client;
|
|
42
|
+
private attempt;
|
|
43
|
+
/** The device this worker drives, the pool's entry for its slot; undefined leaves the choice to agent-device. */
|
|
44
|
+
private device;
|
|
45
|
+
private generation;
|
|
46
|
+
private readonly located;
|
|
47
|
+
private idCounter;
|
|
48
|
+
private appIdentity;
|
|
49
|
+
/** The app the build `appPath` installed, once `init` has, itself or through a lease. */
|
|
50
|
+
private installedApp;
|
|
51
|
+
/** Where relative build paths resolve; the run's project root once init has told us. */
|
|
52
|
+
private projectRoot;
|
|
53
|
+
/**
|
|
54
|
+
* Commands still running on the device. agent-device takes no abort
|
|
55
|
+
* signal, so a cancelled or timed-out call is only abandoned by its
|
|
56
|
+
* caller; it keeps executing. The next attempt waits for these to settle
|
|
57
|
+
* before it opens anything, so a ghost tap can never land in a retry.
|
|
58
|
+
*/
|
|
59
|
+
private readonly inflight;
|
|
60
|
+
/** The target's devices, one per worker slot; `init` takes this worker's from it. */
|
|
61
|
+
readonly pool: DevicePool;
|
|
62
|
+
/** The settle wait every action carries: quiet window from the `settle` option, or nothing when it is `false`. */
|
|
63
|
+
readonly settleOptions: SettleOptions;
|
|
64
|
+
/** When this surface last acted on the device (an input or an app launch); the screen may be in transition for a while after. */
|
|
65
|
+
private lastActionAt;
|
|
66
|
+
/** The screen as last projected before that action, to tell controls that were already there from ones that came with it. */
|
|
67
|
+
private indexBeforeAction;
|
|
68
|
+
/** The most recent projection of the screen, from any observe or locate. */
|
|
69
|
+
private latestIndex;
|
|
70
|
+
/** Budget a control that came with the last action gets to finish arriving; see DEFAULT_TRANSITION_MS. */
|
|
71
|
+
private readonly transitionMs;
|
|
72
|
+
/**
|
|
73
|
+
* The screen's logical size as last learned from a snapshot with geometry
|
|
74
|
+
* or from the device itself, so a snapshot without geometry (an empty
|
|
75
|
+
* screen before any app is open, a sparse tree) still reports the viewport
|
|
76
|
+
* every observation must carry.
|
|
77
|
+
*/
|
|
78
|
+
private knownViewport;
|
|
79
|
+
constructor(options: MobileOptions, createClient: ClientFactory);
|
|
80
|
+
/** Whether the manifest declares app restart and state clearing. */
|
|
81
|
+
get managesApp(): boolean;
|
|
82
|
+
/** The app opened fresh per attempt: the `app` option, else the build `appPath` installed. */
|
|
83
|
+
get pinnedApp(): string | undefined;
|
|
84
|
+
/** Whether an attempt is running on this surface right now. */
|
|
85
|
+
get attemptRunning(): boolean;
|
|
86
|
+
/** The live client; INVALID_STATE before init or after dispose. */
|
|
87
|
+
requireClient(): AgentDeviceClient;
|
|
88
|
+
/**
|
|
89
|
+
* Runs one agent-device command under an operation budget and translates
|
|
90
|
+
* its failure. Contributed-fixture methods route through here too, so the
|
|
91
|
+
* device fixture never carries its own error mapping.
|
|
92
|
+
*/
|
|
93
|
+
command<T>(label: string, run: (client: AgentDeviceClient) => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
94
|
+
/** Registers one device command as in flight until it settles. */
|
|
95
|
+
private track;
|
|
96
|
+
/**
|
|
97
|
+
* Waits for every abandoned command to settle, within the caller's
|
|
98
|
+
* budget. A command that never settles fails the attempt launch instead of
|
|
99
|
+
* racing it: the launch timeout is the honest bound on a stuck device.
|
|
100
|
+
*/
|
|
101
|
+
private settleInflight;
|
|
102
|
+
/** The device selection this worker's commands take. */
|
|
103
|
+
private selection;
|
|
104
|
+
init(info: EngineInitInfo): Promise<void>;
|
|
105
|
+
startAttempt(context: EngineAttemptContext): Promise<void>;
|
|
106
|
+
endAttempt(context: EngineCleanupContext): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Asks the device to record its screen into the attempt directory. Taps stay
|
|
109
|
+
* visible in the recording (agent-device's touch indicator), which is the
|
|
110
|
+
* closest a phone comes to a cursor.
|
|
111
|
+
*/
|
|
112
|
+
startVideo(operation: OperationContext): Promise<void>;
|
|
113
|
+
/** Stops the recording and returns its one segment, or none when the device wrote nothing. */
|
|
114
|
+
stopVideo(operation: OperationContext): Promise<readonly VideoSegment[]>;
|
|
115
|
+
dispose(context: EngineCleanupContext): Promise<void>;
|
|
116
|
+
/** Opens an app in the session, remembering its identity for the path anchor. */
|
|
117
|
+
openApp(app: string, relaunch: boolean, signal: AbortSignal): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Installs a build on the session's device. `reinstall` removes the app
|
|
120
|
+
* named by `options.app` (else the pinned app) first, so the build starts
|
|
121
|
+
* with no data; a plain install replaces the binary and keeps its data.
|
|
122
|
+
*/
|
|
123
|
+
installApp(appPath: string, options: InstallAppOptions, signal: AbortSignal): Promise<InstalledApp>;
|
|
124
|
+
private snapshot;
|
|
125
|
+
/**
|
|
126
|
+
* Snapshot for an observation. Without a pinned app, an observation before
|
|
127
|
+
* anything is open is an empty screen rather than a fault: the model's next
|
|
128
|
+
* move is the open tool, and failing the step would take that move away.
|
|
129
|
+
*/
|
|
130
|
+
private snapshotOrEmpty;
|
|
131
|
+
private project;
|
|
132
|
+
/**
|
|
133
|
+
* The viewport of a snapshot: its own geometry, else the last one this
|
|
134
|
+
* session learned, else the device's logical screen size read off one
|
|
135
|
+
* screenshot. A device whose size cannot be learned fails the observation:
|
|
136
|
+
* the harness measures every rect and point against the viewport, so an
|
|
137
|
+
* invented one would misplace every tap.
|
|
138
|
+
*/
|
|
139
|
+
private viewportFor;
|
|
140
|
+
/** The device's logical screen size as its screenshot reports it; undefined when it reports none. */
|
|
141
|
+
private probeViewport;
|
|
142
|
+
observe(operation: OperationContext, options?: EngineObserveOptions): Promise<EngineSnapshot>;
|
|
143
|
+
/** Retains only action bindings for matches, independently of the observation generation. */
|
|
144
|
+
locate(expression: LocatorExpression, operation: OperationContext): Promise<readonly SemanticNode[]>;
|
|
145
|
+
private resolveRef;
|
|
146
|
+
private actionTarget;
|
|
147
|
+
/**
|
|
148
|
+
* The node a toggle press must land on. UIKit reports a settings row as a
|
|
149
|
+
* labelled `Switch` spanning the whole row with the real control as an
|
|
150
|
+
* unlabelled `Switch` child at its trailing edge; a press at the row's
|
|
151
|
+
* centre hits the label and changes nothing. The innermost same-role
|
|
152
|
+
* descendant with a ref is the control; a node without one is its own.
|
|
153
|
+
*/
|
|
154
|
+
private controlOf;
|
|
155
|
+
/** Copies the fields actions use and pre-resolves a toggle's inner control. */
|
|
156
|
+
private bind;
|
|
157
|
+
/**
|
|
158
|
+
* The node a binding stands for, in a fresh snapshot: same role, same test
|
|
159
|
+
* id, same name and text, and of those the one closest to where it was.
|
|
160
|
+
*/
|
|
161
|
+
private refind;
|
|
162
|
+
/**
|
|
163
|
+
* Lets a control that came with the last action finish arriving before a
|
|
164
|
+
* test acts on it. A control already present at the same place in the
|
|
165
|
+
* snapshot the last action was resolved from is not in transition and is
|
|
166
|
+
* acted on at once; anything else waits out the remainder of the
|
|
167
|
+
* transition budget since that action. Nothing is observed here: the
|
|
168
|
+
* budget is the only signal, because the tree reports final frames.
|
|
169
|
+
*/
|
|
170
|
+
private awaitTransition;
|
|
171
|
+
/**
|
|
172
|
+
* Records an action the device received: the screen as it was projected
|
|
173
|
+
* before it, and when it returned. The transition budget counts from the
|
|
174
|
+
* return, since the input lands late in the command's own round trip.
|
|
175
|
+
*/
|
|
176
|
+
private markAction;
|
|
177
|
+
perform(ref: NodeRef, action: LocatorAction, operation: OperationContext): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* Keys on a touch surface, in the contract's key grammar: `Enter` submits
|
|
180
|
+
* through the soft keyboard, `Space` and any single character are typed
|
|
181
|
+
* into the focused field. agent-device exposes no key event bus, so
|
|
182
|
+
* modifiers and the other named keys (`Escape`, `Tab`, `Backspace`, the
|
|
183
|
+
* arrows) have nothing to land on and are refused.
|
|
184
|
+
*/
|
|
185
|
+
private pressKey;
|
|
186
|
+
/**
|
|
187
|
+
* One pointer action at a screen point in logical pixels, the space every
|
|
188
|
+
* node's bounds are in, with no element resolved behind it. `settle` waits
|
|
189
|
+
* for the UI to go quiet, as the node taps do.
|
|
190
|
+
*/
|
|
191
|
+
performAt(point: ViewportPoint, action: PointerAction, operation: OperationContext): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Types into whatever holds focus through the device's text-input path;
|
|
194
|
+
* agent-device's `type` lands on the focused field. `replace` is not a
|
|
195
|
+
* device primitive without a target, so it is refused rather than faked:
|
|
196
|
+
* the model clears a listed field by filling it by id.
|
|
197
|
+
*/
|
|
198
|
+
typeText(text: string, options: {
|
|
199
|
+
readonly replace: boolean;
|
|
200
|
+
}, operation: OperationContext): Promise<void>;
|
|
201
|
+
/**
|
|
202
|
+
* One key to the focused field, with the same reach as a node press: Enter
|
|
203
|
+
* submits through the soft keyboard, Space and single characters are typed.
|
|
204
|
+
* Modifiers and the other named keys have no event bus to land on.
|
|
205
|
+
*/
|
|
206
|
+
pressFocusedKey(key: string, operation: OperationContext): Promise<void>;
|
|
207
|
+
/** Hides the soft keyboard, so a control it covered can be reached. */
|
|
208
|
+
dismissKeyboard(operation: OperationContext): Promise<void>;
|
|
209
|
+
back(operation: OperationContext): Promise<void>;
|
|
210
|
+
restart(operation: OperationContext): Promise<void>;
|
|
211
|
+
/** Clears the pinned app's persisted state and relaunches it: the device equivalent of a fresh context. */
|
|
212
|
+
reset(operation: OperationContext): Promise<void>;
|
|
213
|
+
/**
|
|
214
|
+
* A redacted screenshot artifact. The device paints secure fields as dots,
|
|
215
|
+
* but the last typed character shows in clear, so every secure node's
|
|
216
|
+
* bounds are painted over before the file is kept. A secure node without
|
|
217
|
+
* bounds cannot be masked, and an image that cannot be redacted is not
|
|
218
|
+
* written at all.
|
|
219
|
+
*/
|
|
220
|
+
screenshot(label: string | undefined, operation: OperationContext): Promise<string>;
|
|
221
|
+
/** Raw device pixels; cleanup follows the capture even when its caller abandons it. */
|
|
222
|
+
private rawScreenshot;
|
|
223
|
+
/**
|
|
224
|
+
* One screenshot into a temp directory that is removed once `read` has
|
|
225
|
+
* taken what it needs from the response or the file, even when the caller
|
|
226
|
+
* abandons the capture.
|
|
227
|
+
*/
|
|
228
|
+
private captureScreenshot;
|
|
229
|
+
/**
|
|
230
|
+
* Screenshot with every secure node on the current screen painted over.
|
|
231
|
+
* Observes first so the regions describe the screen the pixels show;
|
|
232
|
+
* throws when a secure field cannot be covered, because an image that may
|
|
233
|
+
* hold a credential must not leave the engine.
|
|
234
|
+
*/
|
|
235
|
+
private maskedScreenshot;
|
|
236
|
+
/**
|
|
237
|
+
* Viewport pixels for an observation. Best-effort: a screenshot that cannot
|
|
238
|
+
* be produced or redacted costs the observation its image, not the step.
|
|
239
|
+
*/
|
|
240
|
+
private capturePixels;
|
|
241
|
+
}
|
|
242
|
+
export {};
|
|
243
|
+
//# sourceMappingURL=surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"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"}
|