@keepsnappy/appium-driver 0.1.0-alpha.12 → 0.1.0-alpha.14

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @keepsnappy/appium-driver
2
2
 
3
- KeepSnappy's built-in Appium driver for `perflab farm run --driver appium --journey-module <file>` (BrowserStack App Automate, iOS and Android; `--platform ios|android`, default ios). A thin step vocabulary over W3C WebDriver: you write the journey, the driver owns the session, run tokens, step markers, the readiness wait (`expectNext`) after a touch and the result files. Design: `docs/plans/54b-appium-driver.md`.
3
+ KeepSnappy's built-in Appium driver for `keepsnappy farm run --driver appium --journey-module <file>` (BrowserStack App Automate, iOS and Android; `--platform ios|android`, default ios). A thin step vocabulary over W3C WebDriver: you write the journey, the driver owns the session, run tokens, step markers, the readiness wait (`expectNext`) after a touch and the result files. Design: `docs/plans/54b-appium-driver.md`.
4
4
 
5
5
  A journey module default-exports `defineJourney({ app, home, options?, setup?, journeys })`; see the plan for the full shape. A journey needs no import from this package: selectors are plain objects (`{ id }`, `{ text }`, `{ ...sel, childOf }`, or a bare string) and everything else is on the `t` it is given (`t.acceptAlert`, `t.openLink`, ...). `defineJourney` is only an identity helper for editor types. The CLI runs its own bundled copy, so do not `instanceof` driver errors (`WdError`) from your own copy; test `e.wdError`.
6
6
 
@@ -20,7 +20,7 @@ How to write journeys that run fast on Android, with measured costs: `docs/writi
20
20
 
21
21
  With `--action-gc on` the driver asks the app for a full garbage collection before every declared step, after the step's readiness wait and before its start marker, and once more before the run's flush. Design: `docs/plans/gc-before-action.md`; device checks: `docs/plans/gc-before-action-measurement.md`.
22
22
 
23
- - Each command has a number `n`, unique in the session. Android sends it as a broadcast (`mobile: broadcast`, action `<bundleId>.perflab.COMMAND`, extras `cmd=gc`, `n`) and reads the answer `gc:<n> ...` from the broadcast's result. iOS opens `<scheme>devtools/perf-lab?cmd=gc&n=<n>` and waits up to 10 s for the element `perflab.ack` whose label starts with `gc:<n> `.
23
+ - Each command has a number `n`, unique in the session. Android sends it as a broadcast (`mobile: broadcast`, action `<bundleId>.keepsnappy.COMMAND`, extras `cmd=gc`, `n`) and reads the answer `gc:<n> ...` from the broadcast's result. iOS opens `<scheme>devtools/keepsnappy?cmd=gc&n=<n>` and waits up to 10 s for the element `keepsnappy.ack` whose label starts with `gc:<n> `.
24
24
  - The step's start marker carries `gc_n`, so the backend (derivation 18) pairs the step with its GC record without mapping clocks.
25
25
  - No answer turns the command off for the rest of the session (`actionGc: unsupported` in `driver-log.json`); the test still passes. Safari link mode sends none (`safari`).
26
26
  - The GC command ends the app's open windows: runs with and without it are a different instrument (`actionGc` aspect), never compared as an app change.
@@ -32,7 +32,12 @@ One GC command at the end of every run, after the journey's last step and its re
32
32
  - Same command and fallbacks as above; an app that does not answer turns it off for the rest of the session.
33
33
  - The command ends the last open window (end reason `gc-command`) instead of the flush: that one window per run is shorter than on a driver without it. Driver 0.2.0 carries both commands, so runs before and after it are a different instrument already (`driverVersion` aspect).
34
34
  - On by default (REQ-MEAS-35, REQ-FARM-28; driver 0.3.0); `--end-gc off` or `endGc: false` turns it off. It changes the memory readings only (it runs after the last window): a main without it still judges a PR's render, commit and component measures; only the memory verdict needs end-GC runs on both sides (`endGc` setup aspect, memory measures only). Older SDKs do not answer and send no line.
35
+ - Right after the GC's answer the driver sends `memread` (same n) and waits for its answer before it sends the markers and the flush link, which background the app. The SDK takes one memory sample at once (`endgc-read:<n>`); memory kept is derived from it (derivation 23). No answer: logged as `memread` status 1, the run goes on, and later runs of the session do not ask.
35
36
 
36
37
  ## The default run configuration (`links.ts`)
37
38
 
38
- `RUN_DEFAULTS` and the link builders are the one source of the activation, flush and GC links (REQ-FARM-28): `profile=1`, `diag=1` (the React export), ttl 3600, no `cpuprof`, and the end GC on (`END_GC_DEFAULT`). A journey module's `sdkArgs` (`k=v&...`) are set over the defaults key by key, so `sdkArgs: 'profile=1'` still gets `diag=1`; `diag=0` turns the export off explicitly. `perflab activation-link | flush-link | gc-link` print the same links for runners that are not this driver, and `perflab farm open` writes the settings into `tokens.js` (`output.perflabLinkArgs`) for Maestro flows. Maestro runs send no GC for now. A guard test in `apps/agent` fails on a hand-written activation link anywhere else in the repo.
39
+ `RUN_DEFAULTS` and the link builders are the one source of the activation, flush and GC links (REQ-FARM-28): `profile=1`, `diag=1` (the React export), ttl 3600, no `cpuprof`, and the end GC on (`END_GC_DEFAULT`). A journey module's `sdkArgs` (`k=v&...`) are set over the defaults key by key, so `sdkArgs: 'profile=1'` still gets `diag=1`; `diag=0` turns the export off explicitly. `keepsnappy activation-link | flush-link | gc-link` print the same links for runners that are not this driver, and `keepsnappy farm open` writes the settings into `tokens.js` (`output.keepsnappyLinkArgs`) for Maestro flows. Maestro runs send no GC for now. A guard test in `apps/agent` fails on a hand-written activation link anywhere else in the repo.
40
+
41
+ ## driver-log.json while the run goes
42
+
43
+ `<out>/driver-log.json` is rewritten atomically at every top-level step and iteration boundary, so a killed run still leaves a valid log. `status` is `running`, `done`, `terminated` or `error`; `lastStep` names the last step started and `steps` times every step (`ms: null` while one runs). On SIGTERM or SIGINT (the farm's step timeout) the driver flushes the log as `terminated` with the signal, captures the failure screen and source (at most 20 s), ends the session as failed (at most 10 s) and exits 143 or 130, within 45 s in all; a second signal exits at once. `keepsnappy farm run` counts a driver that exits non-zero as infrastructure.
@@ -36,7 +36,7 @@ export function sessionCaps(i) {
36
36
  ...(i.platform ?? IOS).caps(i.device),
37
37
  'appium:app': i.appUrl,
38
38
  'bstack:options': {
39
- projectName: 'perflab',
39
+ projectName: 'keepsnappy',
40
40
  buildName: i.buildName,
41
41
  sessionName: i.sessionName,
42
42
  ...tunnel,
@@ -1 +1 @@
1
- {"version":3,"file":"browserstack.js","sourceRoot":"","sources":["../../src/browserstack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browserstack.js","sourceRoot":"","sources":["../../src/browserstack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,GAAG,EAAiB,MAAM,eAAe,CAAC;AAGnD,qGAAqG;AACrG,MAAM,CAAC,MAAM,GAAG,GAAG,2CAA2C,CAAC;AAC/D,MAAM,CAAC,MAAM,MAAM,GAAG,iDAAiD,CAAC;AAExE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,GAAW,EAAU,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AAE5H,mGAAmG;AACnG,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,QAAgB,EAAE,IAAY,EAAE,SAAoB,EAAE,WAAqB,GAAG;IAC1H,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,GAAG,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,gBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAClG,MAAM,IAAI,GAAY,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAsC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QACrG,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;IACtB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,IAAI,QAAQ;QAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACjD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAyB,CAAC;IAC1E,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpG,OAAO,IAAI,CAAC,OAAO,CAAC;AACtB,CAAC;AAaD,mHAAmH;AACnH,MAAM,UAAU,WAAW,CAAC,CAAY;IACtC,MAAM,MAAM,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,OAAO;QACL,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QACrC,YAAY,EAAE,CAAC,CAAC,MAAM;QACtB,gBAAgB,EAAE;YAChB,WAAW,EAAE,YAAY;YACzB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,GAAG,MAAM;YACT,WAAW,EAAE,GAAG;YAChB,aAAa,EAAE,CAAC,CAAC,aAAa;SAC/B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,IAAY,EAAE,SAAoB;IACvF,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,aAAa,SAAS,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5H,IAAI,CAAC,GAAG,EAAE,EAAE;QAAE,OAAO,EAAE,CAAC;IACxB,OAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqD,CAAC,kBAAkB,IAAI,EAAE,CAAC;AAC1G,CAAC"}
package/dist/src/cli.js CHANGED
File without changes
@@ -3,7 +3,7 @@ export { END_GC_DEFAULT, RUN_DEFAULTS, acceptAlert, activationLink, flushLink, g
3
3
  export { defineJourney, type JourneyContext, type JourneyFn, type JourneyModule } from './journey.js';
4
4
  export { ANDROID, IOS, PLATFORMS, platformOf, type Platform, type PlatformName } from './platform.js';
5
5
  export { androidLocators, childOf, describeSelector, id, idText, locator, text, toSelector, type Selector, type SelectorLike } from './selectors.js';
6
- export { FLUSH_WAIT_MS, HOST_CLOCK_TRIPS, Session, sendMarkers, type ActionGc, type ClockTrip, type Condition, type Marker } from './session.js';
6
+ export { FLUSH_END_RUN_FAILED, FLUSH_ERROR, FLUSH_OFF, FLUSH_NOT_ACKNOWLEDGED, FLUSH_RESEND_MS, FLUSH_UNREADABLE, FLUSH_WAIT_MS, type FlushEvidence, HOST_CLOCK_TRIPS, Session, sendMarkers, type ActionGc, type ClockTrip, type Condition, type Marker } from './session.js';
7
7
  export { loadElements, parseTokensJs, plan, type PlannedRun } from './tokens.js';
8
8
  export { runDriver, DRIVER_OPTIONS, type IterationRecord, type RunDeps } from './run.js';
9
9
  export { loadJourneyModule, main } from './load.js';
package/dist/src/index.js CHANGED
@@ -3,7 +3,7 @@ export { END_GC_DEFAULT, RUN_DEFAULTS, acceptAlert, activationLink, flushLink, g
3
3
  export { defineJourney } from './journey.js';
4
4
  export { ANDROID, IOS, PLATFORMS, platformOf } from './platform.js';
5
5
  export { androidLocators, childOf, describeSelector, id, idText, locator, text, toSelector } from './selectors.js';
6
- export { FLUSH_WAIT_MS, HOST_CLOCK_TRIPS, Session, sendMarkers } from './session.js';
6
+ export { FLUSH_END_RUN_FAILED, FLUSH_ERROR, FLUSH_OFF, FLUSH_NOT_ACKNOWLEDGED, FLUSH_RESEND_MS, FLUSH_UNREADABLE, FLUSH_WAIT_MS, HOST_CLOCK_TRIPS, Session, sendMarkers } from './session.js';
7
7
  export { loadElements, parseTokensJs, plan } from './tokens.js';
8
8
  export { runDriver, DRIVER_OPTIONS } from './run.js';
9
9
  export { loadJourneyModule, main } from './load.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAmD,MAAM,gBAAgB,CAAC;AAC7G,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAkB,MAAM,YAAY,CAAC;AAC5J,OAAO,EAAE,aAAa,EAA2D,MAAM,cAAc,CAAC;AACtG,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAoC,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAoC,MAAM,gBAAgB,CAAC;AACrJ,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAA8D,MAAM,cAAc,CAAC;AACjJ,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAmB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAsC,MAAM,UAAU,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAmD,MAAM,gBAAgB,CAAC;AAC7G,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAkB,MAAM,YAAY,CAAC;AAC5J,OAAO,EAAE,aAAa,EAA2D,MAAM,cAAc,CAAC;AACtG,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAoC,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAoC,MAAM,gBAAgB,CAAC;AACrJ,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,SAAS,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAsB,gBAAgB,EAAE,OAAO,EAAE,WAAW,EAA8D,MAAM,cAAc,CAAC;AAC9Q,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAmB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,cAAc,EAAsC,MAAM,UAAU,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -19,9 +19,12 @@ export declare function parseSdkArgs(args: string): Array<[string, string]>;
19
19
  */
20
20
  export declare function linkArgs(args?: string): string;
21
21
  export declare const activationLink: (scheme: string, token: string, args?: string) => string;
22
- export declare const flushLink: (scheme: string) => string;
22
+ /** `ack` names this flush link; the SDK echoes it at the end of its answer's detail. */
23
+ export declare const flushLink: (scheme: string, ack?: string) => string;
23
24
  /** Command n (a GC); the SDK takes it as a link on both platforms, and Android drivers send the same command as a broadcast. */
24
25
  export declare const gcLink: (scheme: string, n: number) => string;
26
+ /** Command n again, `memread`: the end GC's memory read, sent with the GC's own n after the GC's answer. */
27
+ export declare const memReadLink: (scheme: string, n: number) => string;
25
28
  /** Taps the button of a system alert if one shows within `waitMs` ("Open in ...?" and any permission prompt). Returns the label tapped, or null. */
26
29
  export declare function acceptAlert(driver: Driver, labels: readonly string[], waitMs: number): Promise<string | null>;
27
30
  export interface LinkState {
package/dist/src/links.js CHANGED
@@ -7,7 +7,7 @@ export const ALERT_POLL_MS = 250;
7
7
  export const RUN_DEFAULTS = { ttl: 3600, profile: 1, diag: 1 };
8
8
  export const END_GC_DEFAULT = true;
9
9
  // The SDK's link route under the app's own URL scheme (e.g. `myapp://`).
10
- const route = (scheme) => `${scheme}devtools/perf-lab`;
10
+ const route = (scheme) => `${scheme}devtools/keepsnappy`;
11
11
  /** `k=v&k2=v2` into pairs; an empty string gives none. */
12
12
  export function parseSdkArgs(args) {
13
13
  return args
@@ -30,9 +30,12 @@ export function linkArgs(args = '') {
30
30
  return [...fields].map(([k, v]) => `${k}=${v}`).join('&');
31
31
  }
32
32
  export const activationLink = (scheme, token, args = '') => `${route(scheme)}?activate=1&${linkArgs(args)}&runToken=${token}`;
33
- export const flushLink = (scheme) => `${route(scheme)}?flush=1&activate=0`;
33
+ /** `ack` names this flush link; the SDK echoes it at the end of its answer's detail. */
34
+ export const flushLink = (scheme, ack) => `${route(scheme)}?flush=1&activate=0${ack === undefined ? '' : `&ack=${ack}`}`;
34
35
  /** Command n (a GC); the SDK takes it as a link on both platforms, and Android drivers send the same command as a broadcast. */
35
36
  export const gcLink = (scheme, n) => `${route(scheme)}?cmd=gc&n=${n}`;
37
+ /** Command n again, `memread`: the end GC's memory read, sent with the GC's own n after the GC's answer. */
38
+ export const memReadLink = (scheme, n) => `${route(scheme)}?cmd=memread&n=${n}`;
36
39
  /** Taps the button of a system alert if one shows within `waitMs` ("Open in ...?" and any permission prompt). Returns the label tapped, or null. */
37
40
  export async function acceptAlert(driver, labels, waitMs) {
38
41
  const deadline = driver.now() + waitMs;
@@ -1 +1 @@
1
- {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/links.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/links.ts"],"names":[],"mappings":"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"}
@@ -21,12 +21,13 @@ export interface Platform {
21
21
  /** Accepts a system prompt if one shows within `waitMs`; returns what it accepted, or null. */
22
22
  acceptAlert(driver: Driver, labels: readonly string[], waitMs: number): Promise<string | null>;
23
23
  /**
24
- * `perflab.flushed`: the lookup tried on every poll, which attribute holds the status, and a heavier lookup tried now and
24
+ * `keepsnappy.flushed`: the lookup tried on every poll, which attribute holds the status, and a heavier lookup tried now and
25
25
  * then when the cheap one misses (it needs `setting` on while it runs).
26
26
  */
27
27
  readonly flush: {
28
28
  lookup: Locator;
29
29
  statusAttribute: string;
30
+ detailAttribute: string;
30
31
  fallback?: {
31
32
  lookup: Locator;
32
33
  setting: string;
@@ -53,11 +54,19 @@ export interface Platform {
53
54
  * Returns the SDK's answer (`gc:<n> ok` or `gc:<n> unavailable`), or null when no answer came (an SDK without the command).
54
55
  */
55
56
  gcCommand(driver: Driver, n: number, scheme: string, state: LinkState): Promise<string | null>;
57
+ /**
58
+ * The end GC's manual memory read, asked for after the GC's answer with the GC's own n: the SDK takes one sample at once and
59
+ * answers `memread:<n> ok` (or `unavailable`). Returns the answer, or null when none came (an SDK without the command).
60
+ */
61
+ memReadCommand(driver: Driver, n: number, scheme: string, state: LinkState): Promise<string | null>;
56
62
  }
57
63
  export declare const GC_ANSWER_WAIT_MS = 10000;
64
+ export declare const MEMREAD_ANSWER_WAIT_MS = 3000;
65
+ type Command = 'gc' | 'memread';
58
66
  /** The answer for command n out of `am broadcast` output (`Broadcast completed: result=-1, data="gc:3 ok"`). */
59
- export declare function parseBroadcastAnswer(out: unknown, n: number): string | null;
67
+ export declare function parseBroadcastAnswer(out: unknown, n: number, cmd?: Command): string | null;
60
68
  export declare const IOS: Platform;
61
69
  export declare const ANDROID: Platform;
62
70
  export declare const PLATFORMS: Record<PlatformName, Platform>;
63
71
  export declare function platformOf(name: string): Platform;
72
+ export {};
@@ -1,21 +1,23 @@
1
- import { ALERT_POLL_MS, acceptAlert as acceptIosAlert, gcLink, openLink as openIosLink } from './links.js';
1
+ import { ALERT_POLL_MS, acceptAlert as acceptIosAlert, gcLink, memReadLink, openLink as openIosLink } from './links.js';
2
2
  import { androidAnyOfIds, androidLocators, id, locator } from './selectors.js';
3
3
  import { Screen, parseAndroidSource } from './snapshot.js';
4
4
  import { WdError } from './webdriver.js';
5
5
  // The split of `model-os` is BrowserStack's: the last dash starts the OS version.
6
6
  const modelOf = (device) => device.replace(/-[^-]*$/, '');
7
7
  const versionOf = (device) => device.replace(/^.*-/, '');
8
- const FLUSH_ID = 'perflab.flushed';
9
- const ACK_ID = 'perflab.ack';
8
+ const FLUSH_ID = 'keepsnappy.flushed';
9
+ const ACK_ID = 'keepsnappy.ack';
10
10
  // Only ends the wait for an iOS answer that never comes (an SDK without the command); no window edge depends on it.
11
11
  export const GC_ANSWER_WAIT_MS = 10_000;
12
12
  const GC_POLL_MS = 100;
13
+ // The read is one native call answered after a JS tick; the bound only ends the wait for an SDK that does not know the command.
14
+ export const MEMREAD_ANSWER_WAIT_MS = 3000;
13
15
  /** The answer for command n out of `am broadcast` output (`Broadcast completed: result=-1, data="gc:3 ok"`). */
14
- export function parseBroadcastAnswer(out, n) {
16
+ export function parseBroadcastAnswer(out, n, cmd = 'gc') {
15
17
  const data = /data="([^"]*)"/.exec(String(out ?? ''))?.[1];
16
- return data !== undefined && data.startsWith(`gc:${n} `) ? data : null;
18
+ return data !== undefined && data.startsWith(`${cmd}:${n} `) ? data : null;
17
19
  }
18
- // A command waits for the app to go idle by default; PerfLab must not change the app's pace (docs/plans/61-android-support.md 1.2).
20
+ // A command waits for the app to go idle by default; KeepSnappy must not change the app's pace (docs/plans/61-android-support.md 1.2).
19
21
  const NO_WAIT_MS = 0;
20
22
  // Appium's own session-idle limit, the same on both platforms.
21
23
  const NEW_COMMAND_TIMEOUT_S = 300;
@@ -38,30 +40,32 @@ export const IOS = {
38
40
  appArg: (bundleId) => ({ bundleId }),
39
41
  openLink: (driver, url, state) => openIosLink(driver, url, state),
40
42
  acceptAlert: (driver, labels, waitMs) => acceptIosAlert(driver, labels, waitMs),
41
- flush: { lookup: { using: 'accessibility id', value: FLUSH_ID }, statusAttribute: 'label' },
43
+ flush: { lookup: { using: 'accessibility id', value: FLUSH_ID }, statusAttribute: 'label', detailAttribute: 'value' },
42
44
  uploadFields: { ios_keychain_support: 'true' },
43
- // The link, then the `perflab.ack` element. The trailing space keeps `gc:1` from matching the answer to 10.
44
- async gcCommand(driver, n, scheme, state) {
45
- await openIosLink(driver, gcLink(scheme, n), state);
46
- const want = `type == "XCUIElementTypeStaticText" AND name == "${ACK_ID}" AND label BEGINSWITH "gc:${n} "`;
47
- const deadline = driver.now() + GC_ANSWER_WAIT_MS;
48
- for (;;) {
49
- const el = await driver.find('-ios predicate string', want);
50
- // The predicate already matched `gc:<n> `; an unreadable label is taken as ok and logged, so a run that relied on it can be found.
51
- if (el)
52
- return driver
53
- .cmd('GET', `/element/${el}/attribute/label`)
54
- .then(String)
55
- .catch(() => {
56
- driver.log.push({ ...driver.context, cmd: 'gc-ack-label', t: driver.now(), ms: 0, status: 1 });
57
- return `gc:${n} ok`;
58
- });
59
- if (driver.now() > deadline)
60
- return null;
61
- await driver.sleep(GC_POLL_MS);
62
- }
63
- },
45
+ // The link, then the `keepsnappy.ack` element. The trailing space keeps `gc:1` from matching the answer to 10.
46
+ gcCommand: (driver, n, scheme, state) => iosCommand(driver, gcLink(scheme, n), 'gc', n, state, GC_ANSWER_WAIT_MS),
47
+ memReadCommand: (driver, n, scheme, state) => iosCommand(driver, memReadLink(scheme, n), 'memread', n, state, MEMREAD_ANSWER_WAIT_MS),
64
48
  };
49
+ async function iosCommand(driver, link, cmd, n, state, waitMs) {
50
+ await openIosLink(driver, link, state);
51
+ const want = `type == "XCUIElementTypeStaticText" AND name == "${ACK_ID}" AND label BEGINSWITH "${cmd}:${n} "`;
52
+ const deadline = driver.now() + waitMs;
53
+ for (;;) {
54
+ const el = await driver.find('-ios predicate string', want);
55
+ // The predicate already matched `<cmd>:<n> `; an unreadable label is taken as ok and logged, so a run that relied on it can be found.
56
+ if (el)
57
+ return driver
58
+ .cmd('GET', `/element/${el}/attribute/label`)
59
+ .then(String)
60
+ .catch(() => {
61
+ driver.log.push({ ...driver.context, cmd: `${cmd}-ack-label`, t: driver.now(), ms: 0, status: 1 });
62
+ return `${cmd}:${n} ok`;
63
+ });
64
+ if (driver.now() > deadline)
65
+ return null;
66
+ await driver.sleep(GC_POLL_MS);
67
+ }
68
+ }
65
69
  export const ANDROID = {
66
70
  name: 'android',
67
71
  // The phone of the TapIn farm workflow (docs/plans/61-android-support.md 1.2).
@@ -106,6 +110,7 @@ export const ANDROID = {
106
110
  flush: {
107
111
  lookup: { using: '-android uiautomator', value: `new UiSelector().description("${FLUSH_ID}")` },
108
112
  statusAttribute: 'text',
113
+ detailAttribute: 'hint',
109
114
  fallback: { lookup: { using: 'xpath', value: `//*[@content-desc="${FLUSH_ID}"]` }, setting: 'allowInvisibleElements' },
110
115
  },
111
116
  async readScreen(driver) {
@@ -125,17 +130,19 @@ export const ANDROID = {
125
130
  anyOfIds: androidAnyOfIds,
126
131
  uploadFields: {},
127
132
  // A broadcast pauses no activity (a link does). `am broadcast` returns once the SDK finished the receiver, so its output is the answer.
128
- async gcCommand(driver, n) {
129
- const out = await driver.execute('mobile: broadcast', {
130
- action: `${driver.bundleId}.perflab.COMMAND`,
131
- package: driver.bundleId,
132
- extras: [['s', 'cmd', 'gc'], ['i', 'n', String(n)]],
133
- // FLAG_RECEIVER_FOREGROUND: the foreground broadcast queue, not the background one that other apps' broadcasts can delay.
134
- flags: '0x10000000',
135
- });
136
- return parseBroadcastAnswer(out, n);
137
- },
133
+ gcCommand: (driver, n) => androidCommand(driver, 'gc', n),
134
+ memReadCommand: (driver, n) => androidCommand(driver, 'memread', n),
138
135
  };
136
+ async function androidCommand(driver, cmd, n) {
137
+ const out = await driver.execute('mobile: broadcast', {
138
+ action: `${driver.bundleId}.keepsnappy.COMMAND`,
139
+ package: driver.bundleId,
140
+ extras: [['s', 'cmd', cmd], ['i', 'n', String(n)]],
141
+ // FLAG_RECEIVER_FOREGROUND: the foreground broadcast queue, not the background one that other apps' broadcasts can delay.
142
+ flags: '0x10000000',
143
+ });
144
+ return parseBroadcastAnswer(out, n, cmd);
145
+ }
139
146
  export const PLATFORMS = { ios: IOS, android: ANDROID };
140
147
  export function platformOf(name) {
141
148
  if (!Object.hasOwn(PLATFORMS, name))
@@ -1 +1 @@
1
- {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/platform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/platform.ts"],"names":[],"mappings":"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"}
package/dist/src/run.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { JourneyModule } from './journey.js';
2
+ import { type FlushEvidence } from './session.js';
2
3
  import { type FetchLike } from './webdriver.js';
3
4
  export interface IterationRecord {
4
5
  journey: string;
@@ -11,6 +12,7 @@ export interface IterationRecord {
11
12
  ms: number;
12
13
  };
13
14
  flushed?: string | null;
15
+ flush?: FlushEvidence | null;
14
16
  t_start?: number;
15
17
  begin_ms?: number;
16
18
  journey_ms?: number;
@@ -24,9 +26,28 @@ export interface RunDeps {
24
26
  sleep: (ms: number) => Promise<void>;
25
27
  print: (line: string) => void;
26
28
  error: (line: string) => void;
29
+ /** The signals and the exit; absent in a test that does not exercise them (no handler is installed then). */
30
+ process?: ProcessHooks;
31
+ /** How long a SIGTERM may spend before the process exits (the farm kills 2 minutes after its TERM). */
32
+ term?: Partial<TerminationBudget>;
27
33
  }
34
+ export type TerminationSignal = 'SIGTERM' | 'SIGINT';
35
+ export interface ProcessHooks {
36
+ on(signal: TerminationSignal, handler: () => unknown): void;
37
+ off(signal: TerminationSignal, handler: () => unknown): void;
38
+ exit(code: number): void;
39
+ }
40
+ /** After a signal: the failure screen and source, the session end, and the hard deadline for all of it. */
41
+ export interface TerminationBudget {
42
+ captureMs: number;
43
+ endMs: number;
44
+ hardMs: number;
45
+ }
46
+ export declare const TERMINATION_BUDGET: TerminationBudget;
47
+ export type DriverStatus = 'running' | 'done' | 'terminated' | 'error';
48
+ export declare const realProcessHooks: ProcessHooks;
28
49
  export declare const realRunDeps: () => RunDeps;
29
- /** The flags `perflab farm run` passes (docs/plans/54a section 4); a journey module adds its own through `options`. */
50
+ /** The flags `keepsnappy farm run` passes (docs/plans/54a section 4); a journey module adds its own through `options`. */
30
51
  export declare const DRIVER_OPTIONS: {
31
52
  readonly 'journey-module': {
32
53
  readonly type: "string";
@@ -85,8 +106,12 @@ export declare function parseDriverArgs(argv: readonly string[], module: Journey
85
106
  export declare function journeyModulePath(argv: readonly string[]): string | undefined;
86
107
  /**
87
108
  * One BrowserStack App Automate session that runs every iteration of the module's journeys, then a final flush, and
88
- * writes <out>/driver-log.json and <out>/browserstack.<platform>.json in the shape `perflab farm close --bs-build`
109
+ * writes <out>/driver-log.json and <out>/browserstack.<platform>.json in the shape `keepsnappy farm close --bs-build`
89
110
  * reads. Returns the exit code: 0, or 1 when the session or an iteration failed (the result files are written anyway).
111
+ *
112
+ * driver-log.json is rewritten (atomically) at every step and iteration boundary, `status` saying where the run is. A SIGTERM or
113
+ * SIGINT flushes it as `terminated` first, then captures the failure screen and ends the session within `TERMINATION_BUDGET`, and
114
+ * exits; a second signal exits at once.
90
115
  */
91
116
  export declare function runDriver(argv: readonly string[], module: JourneyModule, deps?: RunDeps): Promise<number>;
92
117
  export {};