@goliapkg/smix 1.0.26 → 2.0.0
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/README.md +53 -130
- package/dist/A11yNode.d.ts.map +1 -1
- package/dist/A11yNode.js +2 -3
- package/dist/A11yNode.js.map +1 -1
- package/dist/App.d.ts +37 -22
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +72 -66
- package/dist/App.js.map +1 -1
- package/dist/ExpectationFailure.d.ts +8 -1
- package/dist/ExpectationFailure.d.ts.map +1 -1
- package/dist/ExpectationFailure.js +7 -7
- package/dist/ExpectationFailure.js.map +1 -1
- package/dist/HttpRunner.d.ts +9 -31
- package/dist/HttpRunner.d.ts.map +1 -1
- package/dist/HttpRunner.js +14 -100
- package/dist/HttpRunner.js.map +1 -1
- package/dist/Locator.d.ts +7 -9
- package/dist/Locator.d.ts.map +1 -1
- package/dist/Locator.js +17 -18
- package/dist/Locator.js.map +1 -1
- package/dist/NodeDriver.d.ts +53 -0
- package/dist/NodeDriver.d.ts.map +1 -0
- package/dist/NodeDriver.js +70 -0
- package/dist/NodeDriver.js.map +1 -0
- package/dist/Pattern.js +2 -2
- package/dist/Pattern.js.map +1 -1
- package/dist/Selector.d.ts.map +1 -1
- package/dist/Selector.js +5 -8
- package/dist/Selector.js.map +1 -1
- package/dist/SelectorResolver.d.ts +4 -6
- package/dist/SelectorResolver.d.ts.map +1 -1
- package/dist/SelectorResolver.js +5 -8
- package/dist/SelectorResolver.js.map +1 -1
- package/dist/Smix.d.ts +12 -4
- package/dist/Smix.d.ts.map +1 -1
- package/dist/Smix.js +25 -23
- package/dist/Smix.js.map +1 -1
- package/dist/SystemPopup.d.ts +18 -0
- package/dist/SystemPopup.d.ts.map +1 -0
- package/dist/SystemPopup.js +7 -0
- package/dist/SystemPopup.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/loadNodeDriver.d.ts +21 -0
- package/dist/loadNodeDriver.d.ts.map +1 -0
- package/dist/loadNodeDriver.js +33 -0
- package/dist/loadNodeDriver.js.map +1 -0
- package/package.json +5 -2
- package/src/A11yNode.ts +2 -3
- package/src/App.ts +75 -78
- package/src/ExpectationFailure.ts +23 -13
- package/src/HttpRunner.ts +15 -126
- package/src/Locator.ts +17 -18
- package/src/NodeDriver.ts +109 -0
- package/src/Pattern.ts +2 -2
- package/src/Selector.ts +5 -8
- package/src/SelectorResolver.ts +7 -11
- package/src/Smix.ts +30 -26
- package/src/SystemPopup.ts +24 -0
- package/src/__tests__/AppDriving.test.ts +106 -0
- package/src/__tests__/MvpApiShape.test.ts +78 -46
- package/src/__tests__/ReadmeSnippets.test.ts +132 -0
- package/src/__tests__/RealAddonLoopback.test.ts +81 -0
- package/src/__tests__/SelectorFullSchema.test.ts +2 -4
- package/src/index.ts +19 -8
- package/src/loadNodeDriver.ts +41 -0
- package/src/SimRuntime.ts +0 -145
- package/src/__tests__/AppFullApi.test.ts +0 -168
- package/src/__tests__/AppTapMock.test.ts +0 -122
- package/src/__tests__/HttpRunner.test.ts +0 -121
- package/src/__tests__/Locator.test.ts +0 -128
- package/src/__tests__/LocatorToHave.test.ts +0 -118
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpectationFailure.js","sourceRoot":"","sources":["../src/ExpectationFailure.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"ExpectationFailure.js","sourceRoot":"","sources":["../src/ExpectationFailure.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,wDAAwD;AAsBxD,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,mBAAmB,EAAE,aAAa,EAAE,aAAa;IACjD,WAAW,EAAE,SAAS,EAAE,kBAAkB;IAC1C,iBAAiB,EAAE,sBAAsB,EAAE,YAAY,EAAE,cAAc;CAC/D,CAAA;AAEV;;;;GAIG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,CAAa;IACjB,YAAY,CAAe;IAC3B,eAAe,CAAqB;IACpC,WAAW,CAAmB;IAC9B,SAAS,CAAQ;IAE1B,YAAY,IAOX;QACC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACnB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAA;QAC7C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,EAAE,CAAA;QACjD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAA;QACzC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IAC/C,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,YAAY;YAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC,CAAA;IACJ,CAAC;CACF"}
|
package/dist/HttpRunner.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { type A11yNode } from './A11yNode.js';
|
|
2
|
-
import type { KeyName, SmixSimRuntime, SwipeDirection } from './SimRuntime.js';
|
|
3
1
|
import type { LabelsResolver, SelectorResolver } from './SelectorResolver.js';
|
|
4
2
|
/**
|
|
5
3
|
* Minimal HTTP client surface — overridable for testing. fetch-compatible
|
|
@@ -20,18 +18,18 @@ export type HttpFetch = (input: string, init: {
|
|
|
20
18
|
};
|
|
21
19
|
}>;
|
|
22
20
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* SelectorResolver + session client over the smix-runner HTTP server.
|
|
22
|
+
* Resolves selectors against a treeJson supplied by the caller and carries
|
|
23
|
+
* the `Session-Id` header for the {@link Session} lifecycle. Used in
|
|
24
|
+
* production RN/Expo test targets via fetch.
|
|
25
25
|
*/
|
|
26
|
-
export declare class HttpSimRuntime
|
|
26
|
+
export declare class HttpSimRuntime {
|
|
27
27
|
readonly baseUrl: string;
|
|
28
28
|
readonly fetchImpl: HttpFetch;
|
|
29
29
|
readonly resolver: SelectorResolver;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* `Locator.toHaveCount` (count = labels.length) + Locator.toHaveLabel.
|
|
34
|
-
* Pass directly to App constructor or Smix.launchApp.
|
|
31
|
+
* Backs toHaveCount (count = labels.length) and toHaveLabel. Pass it to
|
|
32
|
+
* the App constructor or to Smix.launchApp.
|
|
35
33
|
*/
|
|
36
34
|
readonly labelsResolver: LabelsResolver;
|
|
37
35
|
/**
|
|
@@ -69,30 +67,10 @@ export declare class HttpSimRuntime implements SmixSimRuntime {
|
|
|
69
67
|
*/
|
|
70
68
|
attachSessionState(setter: (state: SessionState) => void): void;
|
|
71
69
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* `resolve_selector_count`. Locator.toHaveCount can prefer this over
|
|
75
|
-
* `labelsResolver` if it needs only count, not the labels themselves.
|
|
70
|
+
* Counts matches without building the id list, for callers that want a
|
|
71
|
+
* count and nothing else.
|
|
76
72
|
*/
|
|
77
73
|
resolveCount(treeJson: string, selectorJson: string): Promise<number>;
|
|
78
|
-
launch(bundleId: string): Promise<void>;
|
|
79
|
-
terminate(bundleId: string): Promise<void>;
|
|
80
|
-
snapshotTree(): Promise<A11yNode>;
|
|
81
|
-
synthesizeTap(x: number, y: number): Promise<void>;
|
|
82
|
-
sendString(text: string): Promise<void>;
|
|
83
|
-
pressKey(key: KeyName): Promise<void>;
|
|
84
|
-
swipe(direction: SwipeDirection): Promise<void>;
|
|
85
|
-
screenshot(): Promise<Uint8Array>;
|
|
86
|
-
systemPopups(): Promise<A11yNode[]>;
|
|
87
|
-
openUrl(url: string): Promise<void>;
|
|
88
|
-
launchFresh(opts: {
|
|
89
|
-
bundleId: string;
|
|
90
|
-
clearState: boolean;
|
|
91
|
-
clearKeychain: boolean;
|
|
92
|
-
appPath?: string | undefined;
|
|
93
|
-
}): Promise<void>;
|
|
94
|
-
launchFromPath(appPath: string): Promise<void>;
|
|
95
|
-
synthesizeTapAtNormalized(nx: number, ny: number): Promise<void>;
|
|
96
74
|
private post;
|
|
97
75
|
}
|
|
98
76
|
/** v1.0.4 §D7 — re-export from Session.ts so this file's use compiles. */
|
package/dist/HttpRunner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpRunner.d.ts","sourceRoot":"","sources":["../src/HttpRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"HttpRunner.d.ts","sourceRoot":"","sources":["../src/HttpRunner.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7E;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KACpE,OAAO,CAAC;IACX,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACxB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,2EAA2E;IAC3E,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CAC/C,CAAC,CAAA;AAEF;;;;;GAKG;AACH,qBAAa,cAAc;aAmCP,OAAO,EAAE,MAAM;aACf,SAAS,EAAE,SAAS;IAnCtC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IAEvC;;;;;;OAMG;IACH,OAAO,CAAC,SAAS,CAAsB;IAEvC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB,CAA+C;IAEzE;;;;OAIG;IACH,IAAI,KAAK,IAAI,SAAS,CAErB;gBAGiB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,SAAoD;IAYjF;;;;OAIG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIrC;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAI/D;;;OAGG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAK7D,IAAI;CAuCnB;AAED,0EAA0E;AAC1E,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAA"}
|
package/dist/HttpRunner.js
CHANGED
|
@@ -1,47 +1,22 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// Wire contract (mirrors smix-runner-client v3+):
|
|
9
|
-
// POST /sim/launch { bundleId } → 200
|
|
10
|
-
// POST /sim/terminate { bundleId } → 200
|
|
11
|
-
// POST /sim/launch-fresh { bundleId, clearState, clearKeychain, appPath? } → 200
|
|
12
|
-
// POST /sim/launch-from-path { appPath } → 200
|
|
13
|
-
// POST /sim/screenshot {} → 200 { png: base64 }
|
|
14
|
-
// POST /sim/system-popups {} → 200 { nodes: A11yNode[] }
|
|
15
|
-
// POST /sim/open-url { url } → 200
|
|
16
|
-
// POST /a11y/snapshot {} → 200 { tree: A11yNode }
|
|
17
|
-
// POST /input/tap { x, y } → 200
|
|
18
|
-
// POST /input/tap-normalized { nx, ny } → 200
|
|
19
|
-
// POST /input/swipe { direction } → 200
|
|
20
|
-
// POST /input/send-string { text } → 200
|
|
21
|
-
// POST /input/press-key { key } → 200
|
|
22
|
-
// POST /select/resolve { treeJson, selectorJson } → 200 { ids: string[] }
|
|
23
|
-
//
|
|
24
|
-
// v7.7 c1 contract additions (server impl deferred):
|
|
25
|
-
// POST /select/resolve-count { treeJson, selectorJson } → 200 { count: u32 }
|
|
26
|
-
// POST /select/resolve-labels { treeJson, selectorJson } → 200 { labels: string[] }
|
|
27
|
-
//
|
|
28
|
-
// The exact endpoint shapes are negotiated with smix-runner-server in
|
|
29
|
-
// follow-up Swift work; for v7.5-v7.7 c1 we wire the TS-side fetch +
|
|
30
|
-
// decode and a MockHttpRunnerClient stub that lets vitest exercise the
|
|
31
|
-
// runtime without booting a real server.
|
|
1
|
+
// The HTTP-backed SelectorResolver + session client: one POST per call
|
|
2
|
+
// against a running smix-runner. Every route it sends is one the runner
|
|
3
|
+
// serves — /select/resolve{,-count,-labels} for resolution and /session/*
|
|
4
|
+
// (driven by the Session class through this client's fetch + Session-Id
|
|
5
|
+
// plumbing). Live driving and sense (launch / tap / snapshot) are not here;
|
|
6
|
+
// they are pending the napi axis.
|
|
32
7
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
8
|
+
* SelectorResolver + session client over the smix-runner HTTP server.
|
|
9
|
+
* Resolves selectors against a treeJson supplied by the caller and carries
|
|
10
|
+
* the `Session-Id` header for the {@link Session} lifecycle. Used in
|
|
11
|
+
* production RN/Expo test targets via fetch.
|
|
35
12
|
*/
|
|
36
13
|
export class HttpSimRuntime {
|
|
37
14
|
baseUrl;
|
|
38
15
|
fetchImpl;
|
|
39
16
|
resolver;
|
|
40
17
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* `Locator.toHaveCount` (count = labels.length) + Locator.toHaveLabel.
|
|
44
|
-
* Pass directly to App constructor or Smix.launchApp.
|
|
18
|
+
* Backs toHaveCount (count = labels.length) and toHaveLabel. Pass it to
|
|
19
|
+
* the App constructor or to Smix.launchApp.
|
|
45
20
|
*/
|
|
46
21
|
labelsResolver;
|
|
47
22
|
/**
|
|
@@ -96,63 +71,13 @@ export class HttpSimRuntime {
|
|
|
96
71
|
this.sessionStateSetter = setter;
|
|
97
72
|
}
|
|
98
73
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* `resolve_selector_count`. Locator.toHaveCount can prefer this over
|
|
102
|
-
* `labelsResolver` if it needs only count, not the labels themselves.
|
|
74
|
+
* Counts matches without building the id list, for callers that want a
|
|
75
|
+
* count and nothing else.
|
|
103
76
|
*/
|
|
104
77
|
async resolveCount(treeJson, selectorJson) {
|
|
105
78
|
const r = await this.post('/select/resolve-count', { treeJson, selectorJson });
|
|
106
79
|
return r.count;
|
|
107
80
|
}
|
|
108
|
-
async launch(bundleId) {
|
|
109
|
-
await this.post('/sim/launch', { bundleId });
|
|
110
|
-
}
|
|
111
|
-
async terminate(bundleId) {
|
|
112
|
-
await this.post('/sim/terminate', { bundleId });
|
|
113
|
-
}
|
|
114
|
-
async snapshotTree() {
|
|
115
|
-
const r = await this.post('/a11y/snapshot', {});
|
|
116
|
-
return r.tree;
|
|
117
|
-
}
|
|
118
|
-
async synthesizeTap(x, y) {
|
|
119
|
-
await this.post('/input/tap', { x, y });
|
|
120
|
-
}
|
|
121
|
-
async sendString(text) {
|
|
122
|
-
await this.post('/input/send-string', { text });
|
|
123
|
-
}
|
|
124
|
-
async pressKey(key) {
|
|
125
|
-
await this.post('/input/press-key', { key });
|
|
126
|
-
}
|
|
127
|
-
async swipe(direction) {
|
|
128
|
-
await this.post('/input/swipe', { direction });
|
|
129
|
-
}
|
|
130
|
-
async screenshot() {
|
|
131
|
-
const r = await this.post('/sim/screenshot', {});
|
|
132
|
-
return base64ToBytes(r.png);
|
|
133
|
-
}
|
|
134
|
-
async systemPopups() {
|
|
135
|
-
const r = await this.post('/sim/system-popups', {});
|
|
136
|
-
return r.nodes;
|
|
137
|
-
}
|
|
138
|
-
async openUrl(url) {
|
|
139
|
-
await this.post('/sim/open-url', { url });
|
|
140
|
-
}
|
|
141
|
-
async launchFresh(opts) {
|
|
142
|
-
const payload = {
|
|
143
|
-
bundleId: opts.bundleId,
|
|
144
|
-
clearState: opts.clearState,
|
|
145
|
-
clearKeychain: opts.clearKeychain,
|
|
146
|
-
appPath: opts.appPath,
|
|
147
|
-
};
|
|
148
|
-
await this.post('/sim/launch-fresh', payload);
|
|
149
|
-
}
|
|
150
|
-
async launchFromPath(appPath) {
|
|
151
|
-
await this.post('/sim/launch-from-path', { appPath });
|
|
152
|
-
}
|
|
153
|
-
async synthesizeTapAtNormalized(nx, ny) {
|
|
154
|
-
await this.post('/input/tap-normalized', { nx, ny });
|
|
155
|
-
}
|
|
156
81
|
async post(path, body) {
|
|
157
82
|
const url = `${this.baseUrl}${path}`;
|
|
158
83
|
const headers = {
|
|
@@ -192,15 +117,4 @@ export class HttpSimRuntime {
|
|
|
192
117
|
}
|
|
193
118
|
}
|
|
194
119
|
}
|
|
195
|
-
function base64ToBytes(b64) {
|
|
196
|
-
if (typeof globalThis.atob === 'function') {
|
|
197
|
-
const bin = globalThis.atob(b64);
|
|
198
|
-
const out = new Uint8Array(bin.length);
|
|
199
|
-
for (let i = 0; i < bin.length; i++)
|
|
200
|
-
out[i] = bin.charCodeAt(i);
|
|
201
|
-
return out;
|
|
202
|
-
}
|
|
203
|
-
// Node fallback
|
|
204
|
-
return Uint8Array.from(Buffer.from(b64, 'base64'));
|
|
205
|
-
}
|
|
206
120
|
//# sourceMappingURL=HttpRunner.js.map
|
package/dist/HttpRunner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpRunner.js","sourceRoot":"","sources":["../src/HttpRunner.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"HttpRunner.js","sourceRoot":"","sources":["../src/HttpRunner.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,wEAAwE;AACxE,0EAA0E;AAC1E,wEAAwE;AACxE,4EAA4E;AAC5E,kCAAkC;AAoBlC;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IAmCP;IACA;IAnCT,QAAQ,CAAkB;IACnC;;;OAGG;IACM,cAAc,CAAgB;IAEvC;;;;;;OAMG;IACK,SAAS,GAAkB,IAAI,CAAA;IAEvC;;;;;OAKG;IACK,kBAAkB,GAA2C,IAAI,CAAA;IAEzE;;;;OAIG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED,YACkB,OAAe,EACf,YAAuB,UAAU,CAAC,KAA6B;QAD/D,YAAO,GAAP,OAAO,CAAQ;QACf,cAAS,GAAT,SAAS,CAAsD;QAE/E,IAAI,CAAC,QAAQ,GAAG,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE;YAC/C,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;YACxE,OAAQ,CAAgC,CAAC,GAAG,CAAA;QAC9C,CAAC,CAAA;QACD,IAAI,CAAC,cAAc,GAAG,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE;YACrD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;YAC/E,OAAQ,CAAmC,CAAC,MAAM,CAAA;QACpD,CAAC,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,EAAiB;QAC5B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;IACrB,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,MAAqC;QACtD,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAA;IAClC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,YAAoB;QACvD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;QAC9E,OAAQ,CAAuB,CAAC,KAAK,CAAA;IACvC,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAa;QAC5C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAA;QACpC,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAA;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC5B,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,CAAA;QACxC,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAA;QACF,4DAA4D;QAC5D,0DAA0D;QAC1D,gEAAgE;QAChE,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,CAAA;QAC3D,IAAI,eAAe,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/C,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YACvD,IACE,UAAU,KAAK,SAAS;gBACxB,UAAU,KAAK,UAAU;gBACzB,UAAU,KAAK,SAAS;gBACxB,UAAU,KAAK,MAAM,EACrB,CAAC;gBACD,IAAI,CAAC,kBAAkB,CAAC,UAA0B,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;YAC9B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,WAAW,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAA;QACvE,CAAC;QACD,8DAA8D;QAC9D,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;CACF"}
|
package/dist/Locator.d.ts
CHANGED
|
@@ -19,19 +19,17 @@ export declare class Locator {
|
|
|
19
19
|
timeoutMs?: number;
|
|
20
20
|
}): Promise<void>;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* resolver which is more useful for count-based assertions).
|
|
22
|
+
* Resolve [selector] until a match exists and its label equals
|
|
23
|
+
* [label]. Reads the label off the snapshot node rather than the
|
|
24
|
+
* labels resolver, which answers about the whole match set.
|
|
26
25
|
*/
|
|
27
26
|
toHaveLabel(label: string, opts?: {
|
|
28
27
|
timeoutMs?: number;
|
|
29
28
|
}): Promise<void>;
|
|
30
29
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* modifier per Playwright "match all" behavior.
|
|
30
|
+
* Resolve [selector] until the labels resolver returns exactly [n]
|
|
31
|
+
* matches. Goes through the labels resolver so the count ignores any
|
|
32
|
+
* index modifier — counting asks about all matches, as in Playwright.
|
|
35
33
|
*/
|
|
36
34
|
toHaveCount(n: number, opts?: {
|
|
37
35
|
timeoutMs?: number;
|
|
@@ -41,7 +39,7 @@ export declare class Locator {
|
|
|
41
39
|
* app's runtime + resolver, then check predicates.
|
|
42
40
|
*
|
|
43
41
|
* - [successPredicate] returns true → return immediately
|
|
44
|
-
* - [wrongStatePredicate] returns true → throw
|
|
42
|
+
* - [wrongStatePredicate] returns true → throw NOT_VISIBLE
|
|
45
43
|
* - Otherwise, continue polling.
|
|
46
44
|
*
|
|
47
45
|
* On timeout, throws timeout with the last tree's first-20 nodes.
|
package/dist/Locator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Locator.d.ts","sourceRoot":"","sources":["../src/Locator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Locator.d.ts","sourceRoot":"","sources":["../src/Locator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAEnC,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,eAAe,CAAA;AAKtB,qBAAa,OAAO;aAEA,GAAG,EAAE,GAAG;aACR,QAAQ,EAAE,QAAQ;gBADlB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ;IAGpC;;;OAGG;IACG,WAAW,CAAC,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IASnE;;;OAGG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnF;;;;OAIG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IASlF;;;;OAIG;IACG,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC9E;;;;;;;;;OASG;YACW,SAAS;CAuDxB;AAMD;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,KAAK,EAAE,MAAM;aAAkB,GAAG,EAAE,MAAM;gBAA1C,KAAK,EAAE,MAAM,EAAkB,GAAG,EAAE,MAAM;CAIvE"}
|
package/dist/Locator.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// v7.5 c3 — Locator poll loop, mirror Kotlin v7.4 c3 + Swift v7.1 c3.
|
|
2
|
-
//
|
|
3
1
|
// 250ms tick over a millisecond deadline. On timeout, throws
|
|
4
2
|
// ExpectationFailure with the last tree's first-20 visible elements
|
|
5
3
|
// populated for AI agent diagnosis.
|
|
@@ -42,10 +40,9 @@ export class Locator {
|
|
|
42
40
|
});
|
|
43
41
|
}
|
|
44
42
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* resolver which is more useful for count-based assertions).
|
|
43
|
+
* Resolve [selector] until a match exists and its label equals
|
|
44
|
+
* [label]. Reads the label off the snapshot node rather than the
|
|
45
|
+
* labels resolver, which answers about the whole match set.
|
|
49
46
|
*/
|
|
50
47
|
async toHaveLabel(label, opts = {}) {
|
|
51
48
|
return this.pollUntil({
|
|
@@ -56,10 +53,9 @@ export class Locator {
|
|
|
56
53
|
});
|
|
57
54
|
}
|
|
58
55
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* modifier per Playwright "match all" behavior.
|
|
56
|
+
* Resolve [selector] until the labels resolver returns exactly [n]
|
|
57
|
+
* matches. Goes through the labels resolver so the count ignores any
|
|
58
|
+
* index modifier — counting asks about all matches, as in Playwright.
|
|
63
59
|
*/
|
|
64
60
|
async toHaveCount(n, opts = {}) {
|
|
65
61
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -68,7 +64,7 @@ export class Locator {
|
|
|
68
64
|
let lastTree = null;
|
|
69
65
|
const selectorJson = encodeSelectorJson(this.selector);
|
|
70
66
|
while (true) {
|
|
71
|
-
const tree = await this.app.
|
|
67
|
+
const tree = await this.app.snapshotTree();
|
|
72
68
|
lastTree = tree;
|
|
73
69
|
let labels;
|
|
74
70
|
try {
|
|
@@ -77,7 +73,7 @@ export class Locator {
|
|
|
77
73
|
catch (e) {
|
|
78
74
|
const msg = e instanceof Error ? e.message : String(e);
|
|
79
75
|
throw new ExpectationFailure({
|
|
80
|
-
code: '
|
|
76
|
+
code: 'DRIVER_ERROR',
|
|
81
77
|
message: `FFI resolveSelectorLabels raised during poll: ${msg}`,
|
|
82
78
|
selectorJson,
|
|
83
79
|
});
|
|
@@ -90,7 +86,7 @@ export class Locator {
|
|
|
90
86
|
await delay(POLL_INTERVAL_MS);
|
|
91
87
|
}
|
|
92
88
|
throw new ExpectationFailure({
|
|
93
|
-
code: '
|
|
89
|
+
code: 'ASSERTION_FAILED',
|
|
94
90
|
message: `expected ${n} matches, last poll saw ${lastCount}`,
|
|
95
91
|
selectorJson,
|
|
96
92
|
visibleElements: lastTree !== null ? flatten(lastTree).slice(0, 20) : [],
|
|
@@ -105,7 +101,7 @@ export class Locator {
|
|
|
105
101
|
* app's runtime + resolver, then check predicates.
|
|
106
102
|
*
|
|
107
103
|
* - [successPredicate] returns true → return immediately
|
|
108
|
-
* - [wrongStatePredicate] returns true → throw
|
|
104
|
+
* - [wrongStatePredicate] returns true → throw NOT_VISIBLE
|
|
109
105
|
* - Otherwise, continue polling.
|
|
110
106
|
*
|
|
111
107
|
* On timeout, throws timeout with the last tree's first-20 nodes.
|
|
@@ -114,7 +110,7 @@ export class Locator {
|
|
|
114
110
|
const deadline = Date.now() + opts.timeoutMs;
|
|
115
111
|
let lastTree = null;
|
|
116
112
|
while (true) {
|
|
117
|
-
const tree = await this.app.
|
|
113
|
+
const tree = await this.app.snapshotTree();
|
|
118
114
|
lastTree = tree;
|
|
119
115
|
const selectorJson = encodeSelectorJson(this.selector);
|
|
120
116
|
let matches;
|
|
@@ -124,7 +120,7 @@ export class Locator {
|
|
|
124
120
|
catch (e) {
|
|
125
121
|
const msg = e instanceof Error ? e.message : String(e);
|
|
126
122
|
throw new ExpectationFailure({
|
|
127
|
-
code: '
|
|
123
|
+
code: 'DRIVER_ERROR',
|
|
128
124
|
message: `FFI resolveSelector raised during poll: ${msg}`,
|
|
129
125
|
selectorJson,
|
|
130
126
|
});
|
|
@@ -133,7 +129,10 @@ export class Locator {
|
|
|
133
129
|
const node = firstId !== undefined ? findById(tree, firstId) : null;
|
|
134
130
|
if (opts.wrongStatePredicate(node)) {
|
|
135
131
|
throw new ExpectationFailure({
|
|
136
|
-
|
|
132
|
+
// toBeVisible is the only caller that supplies a firing
|
|
133
|
+
// wrongStatePredicate, so this branch always means
|
|
134
|
+
// "matched, but not visible".
|
|
135
|
+
code: 'NOT_VISIBLE',
|
|
137
136
|
message: 'element matched but predicate failed (e.g. not visible)',
|
|
138
137
|
selectorJson,
|
|
139
138
|
visibleElements: node !== null ? [node, ...flatten(tree).slice(0, 19)] : flatten(tree).slice(0, 20),
|
|
@@ -146,7 +145,7 @@ export class Locator {
|
|
|
146
145
|
await delay(POLL_INTERVAL_MS);
|
|
147
146
|
}
|
|
148
147
|
throw new ExpectationFailure({
|
|
149
|
-
code: '
|
|
148
|
+
code: 'TIMEOUT',
|
|
150
149
|
message: opts.timeoutMessage,
|
|
151
150
|
selectorJson: encodeSelectorJson(this.selector),
|
|
152
151
|
visibleElements: lastTree !== null ? flatten(lastTree).slice(0, 20) : [],
|
package/dist/Locator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Locator.js","sourceRoot":"","sources":["../src/Locator.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"Locator.js","sourceRoot":"","sources":["../src/Locator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** A live driver: the stateless act + sense verbs, plus session opening. */
|
|
2
|
+
export interface NodeDriver {
|
|
3
|
+
tapById(id: string): Promise<boolean>;
|
|
4
|
+
inputText(text: string): Promise<void>;
|
|
5
|
+
pressKey(key: string): Promise<void>;
|
|
6
|
+
swipe(direction: string): Promise<void>;
|
|
7
|
+
tapAtCoord(nx: number, ny: number): Promise<string>;
|
|
8
|
+
snapshotTree(): Promise<string>;
|
|
9
|
+
systemPopups(): Promise<string>;
|
|
10
|
+
openSession(bundleId: string): Promise<NodeSession>;
|
|
11
|
+
}
|
|
12
|
+
/** A handle to an open session: the lifecycle verbs. */
|
|
13
|
+
export interface NodeSession {
|
|
14
|
+
launchApp(): Promise<void>;
|
|
15
|
+
terminateApp(): Promise<void>;
|
|
16
|
+
relaunchApp(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/** A recorded call: the verb name and the arguments it was given. */
|
|
19
|
+
export interface RecordedCall {
|
|
20
|
+
readonly verb: string;
|
|
21
|
+
readonly args: readonly unknown[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Mock session for vitest. Records every lifecycle call; resolves them all.
|
|
25
|
+
*/
|
|
26
|
+
export declare class MockNodeSession implements NodeSession {
|
|
27
|
+
readonly calls: RecordedCall[];
|
|
28
|
+
launchApp(): Promise<void>;
|
|
29
|
+
terminateApp(): Promise<void>;
|
|
30
|
+
relaunchApp(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Mock driver for vitest. Pre-set the tree / popups JSON it returns; records
|
|
34
|
+
* every call; `tapById` reports a hit by default. `openSession` hands back a
|
|
35
|
+
* fresh (or supplied) MockNodeSession so lifecycle calls are inspectable.
|
|
36
|
+
*/
|
|
37
|
+
export declare class MockNodeDriver implements NodeDriver {
|
|
38
|
+
readonly calls: RecordedCall[];
|
|
39
|
+
treeJson: string;
|
|
40
|
+
popupsJson: string;
|
|
41
|
+
tapByIdResult: boolean;
|
|
42
|
+
readonly session: MockNodeSession;
|
|
43
|
+
constructor(session?: MockNodeSession);
|
|
44
|
+
tapById(id: string): Promise<boolean>;
|
|
45
|
+
inputText(text: string): Promise<void>;
|
|
46
|
+
pressKey(key: string): Promise<void>;
|
|
47
|
+
swipe(direction: string): Promise<void>;
|
|
48
|
+
tapAtCoord(nx: number, ny: number): Promise<string>;
|
|
49
|
+
snapshotTree(): Promise<string>;
|
|
50
|
+
systemPopups(): Promise<string>;
|
|
51
|
+
openSession(bundleId: string): Promise<NodeSession>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=NodeDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeDriver.d.ts","sourceRoot":"","sources":["../src/NodeDriver.ts"],"names":[],"mappings":"AAWA,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACrC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/B,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CACpD;AAED,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;CAClC;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,CAAK;IAE7B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAI1B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAGnC;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,UAAU;IAC/C,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,CAAK;IACnC,QAAQ,SACwH;IAChI,UAAU,SAAO;IACjB,aAAa,UAAO;IACpB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;gBAErB,OAAO,GAAE,eAAuC;IAItD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKnD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAK/B,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAK/B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAI1D"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// The seam where live driving is supplied. The real driver is the napi
|
|
2
|
+
// addon (`@goliapkg/smix-node`, wired in with the prebuild matrix — the C4
|
|
3
|
+
// axis); its `SmixNodeDriver` / `SmixNodeSession` classes satisfy these
|
|
4
|
+
// interfaces structurally. The mocks answer from memory so the App's
|
|
5
|
+
// assembly logic (snapshot -> resolve -> tapById, range checks, enter ->
|
|
6
|
+
// return) is unit-tested without the native addon and without a device —
|
|
7
|
+
// the same seam-injection pattern as SelectorResolver.
|
|
8
|
+
//
|
|
9
|
+
// Every method returns what `crates/smix-node/index.d.ts` returns; the tree
|
|
10
|
+
// and popups cross as JSON strings, parsed on this side.
|
|
11
|
+
/**
|
|
12
|
+
* Mock session for vitest. Records every lifecycle call; resolves them all.
|
|
13
|
+
*/
|
|
14
|
+
export class MockNodeSession {
|
|
15
|
+
calls = [];
|
|
16
|
+
async launchApp() {
|
|
17
|
+
this.calls.push({ verb: 'launchApp', args: [] });
|
|
18
|
+
}
|
|
19
|
+
async terminateApp() {
|
|
20
|
+
this.calls.push({ verb: 'terminateApp', args: [] });
|
|
21
|
+
}
|
|
22
|
+
async relaunchApp() {
|
|
23
|
+
this.calls.push({ verb: 'relaunchApp', args: [] });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Mock driver for vitest. Pre-set the tree / popups JSON it returns; records
|
|
28
|
+
* every call; `tapById` reports a hit by default. `openSession` hands back a
|
|
29
|
+
* fresh (or supplied) MockNodeSession so lifecycle calls are inspectable.
|
|
30
|
+
*/
|
|
31
|
+
export class MockNodeDriver {
|
|
32
|
+
calls = [];
|
|
33
|
+
treeJson = '{"rawType":"application","enabled":true,"selected":false,"hasFocus":false,"visible":true,"bounds":{"x":0,"y":0,"w":0,"h":0}}';
|
|
34
|
+
popupsJson = '[]';
|
|
35
|
+
tapByIdResult = true;
|
|
36
|
+
session;
|
|
37
|
+
constructor(session = new MockNodeSession()) {
|
|
38
|
+
this.session = session;
|
|
39
|
+
}
|
|
40
|
+
async tapById(id) {
|
|
41
|
+
this.calls.push({ verb: 'tapById', args: [id] });
|
|
42
|
+
return this.tapByIdResult;
|
|
43
|
+
}
|
|
44
|
+
async inputText(text) {
|
|
45
|
+
this.calls.push({ verb: 'inputText', args: [text] });
|
|
46
|
+
}
|
|
47
|
+
async pressKey(key) {
|
|
48
|
+
this.calls.push({ verb: 'pressKey', args: [key] });
|
|
49
|
+
}
|
|
50
|
+
async swipe(direction) {
|
|
51
|
+
this.calls.push({ verb: 'swipe', args: [direction] });
|
|
52
|
+
}
|
|
53
|
+
async tapAtCoord(nx, ny) {
|
|
54
|
+
this.calls.push({ verb: 'tapAtCoord', args: [nx, ny] });
|
|
55
|
+
return '{"chain":[]}';
|
|
56
|
+
}
|
|
57
|
+
async snapshotTree() {
|
|
58
|
+
this.calls.push({ verb: 'snapshotTree', args: [] });
|
|
59
|
+
return this.treeJson;
|
|
60
|
+
}
|
|
61
|
+
async systemPopups() {
|
|
62
|
+
this.calls.push({ verb: 'systemPopups', args: [] });
|
|
63
|
+
return this.popupsJson;
|
|
64
|
+
}
|
|
65
|
+
async openSession(bundleId) {
|
|
66
|
+
this.calls.push({ verb: 'openSession', args: [bundleId] });
|
|
67
|
+
return this.session;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=NodeDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeDriver.js","sourceRoot":"","sources":["../src/NodeDriver.ts"],"names":[],"mappings":"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"}
|
package/dist/Pattern.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
1
|
+
// The wire form of `smix-selector`'s untagged `Pattern` enum. Untagged
|
|
2
|
+
// means the shape alone says which case it is, so these forms are exact:
|
|
3
3
|
//
|
|
4
4
|
// Wire JSON forms (untagged):
|
|
5
5
|
// Literal: bare string e.g. "hello"
|
package/dist/Pattern.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pattern.js","sourceRoot":"","sources":["../src/Pattern.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"Pattern.js","sourceRoot":"","sources":["../src/Pattern.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yEAAyE;AACzE,EAAE;AACF,8BAA8B;AAC9B,wDAAwD;AACxD,gEAAgE;AAMhE,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;AACnC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,KAAK,GAAG,GAAG;IAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,CAAC,CAAC,KAAK,CAAA;QAChB,KAAK,OAAO;YACV,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;IACnC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QACpE,MAAM,GAAG,GAAG,KAAgC,CAAA;QAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAA;QACpB,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,sCAAsC,OAAO,EAAE,EAAE,CAAC,CAAA;QACpE,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAA;QAC7D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;IAC5C,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,0DAA0D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AACpG,CAAC"}
|
package/dist/Selector.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Selector.d.ts","sourceRoot":"","sources":["../src/Selector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Selector.d.ts","sourceRoot":"","sources":["../src/Selector.ts"],"names":[],"mappings":"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"}
|
package/dist/Selector.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
//
|
|
1
|
+
// The wire form of `smix-selector`'s untagged `Selector` enum, with
|
|
2
|
+
// `Modifiers` flattened onto the Text/Id/Label/Role/LocalizedText bases.
|
|
3
|
+
// Focused takes no modifiers; Anchor carries AnchorBox + IndexModifiers.
|
|
2
4
|
//
|
|
3
|
-
// Mirror Swift v7.2 c3 + Kotlin v7.4 c4 + Rust smix-selector
|
|
4
|
-
// `#[serde(untagged)] enum Selector` with full `Modifiers` flatten on
|
|
5
|
-
// Text/Id/Label/Role/LocalizedText bases. Focused has no modifiers.
|
|
6
|
-
// Anchor uses AnchorBox + IndexModifiers.
|
|
7
|
-
//
|
|
8
|
-
// Class-based API (mirrors Kotlin sealed interface 1:1):
|
|
9
5
|
// sel.id('btn-login')
|
|
10
6
|
// .below(sel.text(literal('Sign In')))
|
|
11
7
|
// .nth(0)
|
|
12
8
|
//
|
|
13
|
-
// Each fluent method returns a NEW Selector
|
|
9
|
+
// Each fluent method returns a NEW Selector, so a partly-built selector
|
|
10
|
+
// can be shared and specialised without the branches affecting each other.
|
|
14
11
|
import { patternFromJson, patternToJson } from './Pattern.js';
|
|
15
12
|
/**
|
|
16
13
|
* A11y selector — identifies a node in the tree.
|