obsidian-integration-testing 12.1.2 → 12.3.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.
Files changed (90) hide show
  1. package/README.md +1 -5
  2. package/dist/lib/cjs/app-config.cjs +137 -0
  3. package/dist/lib/cjs/app-config.d.cts +190 -0
  4. package/dist/lib/cjs/appium-session-config.cjs +7 -1
  5. package/dist/lib/cjs/appium-session-config.d.cts +20 -0
  6. package/dist/lib/cjs/cdp-command-timeout-error.cjs +50 -0
  7. package/dist/lib/cjs/cdp-command-timeout-error.d.cts +48 -0
  8. package/dist/lib/cjs/connect-to-cdp.cjs +1 -1
  9. package/dist/lib/cjs/connect-to-cdp.d.cts +5 -0
  10. package/dist/lib/cjs/emulator-arguments.cjs +19 -3
  11. package/dist/lib/cjs/emulator-arguments.d.cts +44 -0
  12. package/dist/lib/cjs/emulator-device-id.cjs +1 -1
  13. package/dist/lib/cjs/emulator-device-id.d.cts +7 -6
  14. package/dist/lib/cjs/emulator-marker.cjs +169 -0
  15. package/dist/lib/cjs/emulator-marker.d.cts +224 -0
  16. package/dist/lib/cjs/emulator-reaper.cjs +248 -0
  17. package/dist/lib/cjs/emulator-reaper.d.cts +225 -0
  18. package/dist/lib/cjs/emulator-reclaim.cjs +312 -0
  19. package/dist/lib/cjs/emulator-reclaim.d.cts +179 -0
  20. package/dist/lib/cjs/eval-cap-exceeded-error.cjs +61 -0
  21. package/dist/lib/cjs/eval-cap-exceeded-error.d.cts +92 -0
  22. package/dist/lib/cjs/eval-cap.cjs +29 -0
  23. package/dist/lib/cjs/eval-cap.d.cts +43 -0
  24. package/dist/lib/cjs/global-setup-core.cjs +2 -3
  25. package/dist/lib/cjs/index.cjs +21 -1
  26. package/dist/lib/cjs/index.d.cts +7 -0
  27. package/dist/lib/cjs/library.cjs +1 -1
  28. package/dist/lib/cjs/poll-in-obsidian.cjs +1 -1
  29. package/dist/lib/cjs/poll-in-obsidian.d.cts +7 -2
  30. package/dist/lib/cjs/setup-lock.cjs +56 -8
  31. package/dist/lib/cjs/setup-lock.d.cts +53 -0
  32. package/dist/lib/cjs/soft-keyboard-geometry.cjs +17 -8
  33. package/dist/lib/cjs/soft-keyboard-geometry.d.cts +46 -9
  34. package/dist/lib/cjs/soft-keyboard.cjs +7 -4
  35. package/dist/lib/cjs/soft-keyboard.d.cts +16 -2
  36. package/dist/lib/cjs/transport-appium.cjs +70 -5
  37. package/dist/lib/cjs/transport-appium.d.cts +35 -0
  38. package/dist/lib/cjs/transport-desktop-cdp.cjs +98 -19
  39. package/dist/lib/cjs/transport-desktop-cdp.d.cts +44 -1
  40. package/dist/lib/cjs/transport-factory.cjs +297 -190
  41. package/dist/lib/cjs/transport-factory.d.cts +15 -0
  42. package/dist/lib/cjs/transport-options.cjs +1 -1
  43. package/dist/lib/cjs/transport-options.d.cts +38 -1
  44. package/dist/lib/cjs/webview-cdp.cjs +45 -14
  45. package/dist/lib/cjs/webview-cdp.d.cts +17 -0
  46. package/dist/lib/esm/app-config.d.mts +190 -0
  47. package/dist/lib/esm/app-config.mjs +110 -0
  48. package/dist/lib/esm/appium-session-config.d.mts +20 -0
  49. package/dist/lib/esm/appium-session-config.mjs +6 -1
  50. package/dist/lib/esm/cdp-command-timeout-error.d.mts +48 -0
  51. package/dist/lib/esm/cdp-command-timeout-error.mjs +26 -0
  52. package/dist/lib/esm/connect-to-cdp.d.mts +5 -0
  53. package/dist/lib/esm/connect-to-cdp.mjs +1 -1
  54. package/dist/lib/esm/emulator-arguments.d.mts +44 -0
  55. package/dist/lib/esm/emulator-arguments.mjs +16 -2
  56. package/dist/lib/esm/emulator-device-id.d.mts +7 -6
  57. package/dist/lib/esm/emulator-device-id.mjs +1 -1
  58. package/dist/lib/esm/emulator-marker.d.mts +224 -0
  59. package/dist/lib/esm/emulator-marker.mjs +134 -0
  60. package/dist/lib/esm/emulator-reaper.d.mts +225 -0
  61. package/dist/lib/esm/emulator-reaper.mjs +211 -0
  62. package/dist/lib/esm/emulator-reclaim.d.mts +179 -0
  63. package/dist/lib/esm/emulator-reclaim.mjs +291 -0
  64. package/dist/lib/esm/eval-cap-exceeded-error.d.mts +92 -0
  65. package/dist/lib/esm/eval-cap-exceeded-error.mjs +36 -0
  66. package/dist/lib/esm/eval-cap.d.mts +43 -0
  67. package/dist/lib/esm/eval-cap.mjs +5 -0
  68. package/dist/lib/esm/global-setup-core.mjs +6 -4
  69. package/dist/lib/esm/index.d.mts +7 -0
  70. package/dist/lib/esm/index.mjs +21 -1
  71. package/dist/lib/esm/library.mjs +1 -1
  72. package/dist/lib/esm/poll-in-obsidian.d.mts +7 -2
  73. package/dist/lib/esm/poll-in-obsidian.mjs +1 -1
  74. package/dist/lib/esm/setup-lock.d.mts +53 -0
  75. package/dist/lib/esm/setup-lock.mjs +52 -7
  76. package/dist/lib/esm/soft-keyboard-geometry.d.mts +46 -9
  77. package/dist/lib/esm/soft-keyboard-geometry.mjs +17 -8
  78. package/dist/lib/esm/soft-keyboard.d.mts +16 -2
  79. package/dist/lib/esm/soft-keyboard.mjs +7 -4
  80. package/dist/lib/esm/transport-appium.d.mts +35 -0
  81. package/dist/lib/esm/transport-appium.mjs +73 -5
  82. package/dist/lib/esm/transport-desktop-cdp.d.mts +44 -1
  83. package/dist/lib/esm/transport-desktop-cdp.mjs +98 -19
  84. package/dist/lib/esm/transport-factory.d.mts +15 -0
  85. package/dist/lib/esm/transport-factory.mjs +305 -184
  86. package/dist/lib/esm/transport-options.d.mts +38 -1
  87. package/dist/lib/esm/transport-options.mjs +1 -1
  88. package/dist/lib/esm/webview-cdp.d.mts +17 -0
  89. package/dist/lib/esm/webview-cdp.mjs +45 -14
  90. package/package.json +4 -4
@@ -0,0 +1,179 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Stops the emulators this harness started, and **verifies** each stop — the
5
+ * marker-driven half of emulator ownership (`emulator-marker.ts`, **L56**).
6
+ *
7
+ * It lives apart from `transport-factory.ts` so that a process with no business
8
+ * loading the whole transport stack can still stop an emulator correctly. That
9
+ * process is the emulator reaper (`emulator-reaper.ts`): it runs detached from
10
+ * any test runner, and in this repo's own suites it runs straight from source
11
+ * under Node's type stripping, where a module reading the build-time
12
+ * `OBSIDIAN_METADATA` global — which the factory's import graph reaches —
13
+ * cannot load at all. So nothing this module imports may reach it either.
14
+ */
15
+ import type { ChildProcess } from 'node:child_process';
16
+ import type { ProcessListEntry } from './emulator-backend.cjs';
17
+ /**
18
+ * Budget for one quick `adb` call — `adb devices`, a console command.
19
+ */
20
+ export declare const ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS = 5000;
21
+ export declare const ADB_DUMPSYS_MAX_BUFFER_IN_BYTES = 8388608;
22
+ export declare const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 30000;
23
+ /**
24
+ * A host command and its arguments.
25
+ */
26
+ export interface HostCommandQuery {
27
+ /**
28
+ The executable to run.
29
+ */
30
+ readonly command: string;
31
+ /**
32
+ The command's arguments.
33
+ */
34
+ readonly commandArguments: string[];
35
+ }
36
+ /**
37
+ * Parameters for {@link EmulatorReclaimer.reclaimLeftoverEmulators}.
38
+ */
39
+ export interface ReclaimLeftoverEmulatorsParams {
40
+ /**
41
+ An AVD whose leftover is left alone — the one a preflight is about to adopt instead.
42
+ */
43
+ readonly exceptAvdName?: string | undefined;
44
+ /**
45
+ * `'preflight'` spares an emulator another live harness process still owns.
46
+ * `'end-of-run'` does not: the caller holds the `android` lock with no run in
47
+ * flight — the run's own global teardown, or the emulator reaper after the
48
+ * run is gone — so that owner can only be one of the finished run's
49
+ * processes, which no longer has a turn to stop it.
50
+ */
51
+ readonly scope: 'end-of-run' | 'preflight';
52
+ }
53
+ /**
54
+ * Parameters for {@link EmulatorReclaimer.stopEmulator}.
55
+ */
56
+ export interface StopEmulatorParams {
57
+ /**
58
+ The AVD name, named in the warning so the leftover is identifiable, and the key of its marker.
59
+ */
60
+ readonly avdName: string;
61
+ /**
62
+ * The device the emulator is serving, shut down over its console and polled
63
+ * to decide whether it actually stopped. `undefined` when the emulator failed
64
+ * before any device appeared.
65
+ */
66
+ readonly deviceId?: string | undefined;
67
+ /**
68
+ * The emulator launcher process this run spawned. `undefined` for a leftover
69
+ * this run took over, whose launcher belonged to another process.
70
+ */
71
+ readonly emulatorProcess?: ChildProcess | undefined;
72
+ /**
73
+ The emulator PIDs this run owns, escalated to when the console and the launcher's tree kill leave one behind.
74
+ */
75
+ readonly ownedEmulatorPids: readonly number[];
76
+ }
77
+ /**
78
+ * Finds, stops and verifies the harness's emulators, reporting through the
79
+ * caller's log so each caller keeps its own prefix.
80
+ */
81
+ export declare class EmulatorReclaimer {
82
+ private readonly log;
83
+ /**
84
+ * Creates a reclaimer that reports under the caller's own log prefix.
85
+ *
86
+ * @param log - Receives every progress and verdict line.
87
+ */
88
+ constructor(log: (message: string) => void);
89
+ /**
90
+ * Runs `adb devices` and returns its raw stdout.
91
+ *
92
+ * The raw listing is what teardown needs: `getConnectedDeviceIds` keeps only
93
+ * the `device` state, and an emulator on its way out answers `offline` while
94
+ * still holding the AVD — see `adb-device-list.ts`.
95
+ *
96
+ * @returns The raw `adb devices` output.
97
+ * @throws If adb could not be run at all.
98
+ */
99
+ getDevicesOutput(): Promise<string>;
100
+ /**
101
+ * Lists every process on the host.
102
+ *
103
+ * A host always has processes, so a listing that parses to **zero** rows is a
104
+ * failed query however it exited, and comes back as `undefined` exactly like
105
+ * one that did not run — never as an empty list a caller could read as "no
106
+ * emulator is running".
107
+ *
108
+ * @returns The host's processes, or `undefined` when the listing failed.
109
+ */
110
+ queryHostProcesses(): Promise<ProcessListEntry[] | undefined>;
111
+ /**
112
+ * Stops the emulators this harness started that no live run is responsible
113
+ * for, and drops the markers that no longer describe a running emulator.
114
+ *
115
+ * Only ever acts on a **marker-verified** emulator: one whose marker names a
116
+ * PID that is still a live emulator process. An emulator without a marker —
117
+ * booted by hand, by CI, or by another tool — is never touched, which keeps
118
+ * the L46 line: never a `qemu*` sweep.
119
+ *
120
+ * Callers must hold the `android` setup lock (L7), which is what makes a
121
+ * leftover safe to stop: no other Android run can be mid-flight on it.
122
+ *
123
+ * @param params - Which AVD to leave alone, and whether this run is ending.
124
+ */
125
+ reclaimLeftoverEmulators(params: ReclaimLeftoverEmulatorsParams): Promise<void>;
126
+ /**
127
+ * Stops an emulator this harness owns, and **verifies** it stopped.
128
+ *
129
+ * The console shutdown goes first because it is the only path that releases
130
+ * the AVD's `multiinstance.lock`; a `taskkill` leaves the lock behind, and a
131
+ * stale lock is what makes the next run fail with `Running multiple emulators
132
+ * with the same AVD` — a FATAL the emulator writes to its own stdout, where
133
+ * nobody sees it.
134
+ *
135
+ * Works without a launcher handle too: a leftover this run took over has only
136
+ * its PIDs, which is all the escalation below ever needed. The marker goes
137
+ * only with a **verified** stop, so an emulator that outlived this attempt
138
+ * stays convictable by the next one.
139
+ *
140
+ * @param params - The emulator process, the device it serves and the PIDs this run owns.
141
+ */
142
+ stopEmulator(params: StopEmulatorParams): Promise<void>;
143
+ /**
144
+ * Decides whether the emulator this run started is really gone.
145
+ *
146
+ * Two independent proofs, cheapest first: none of the PIDs this run owns is
147
+ * alive, and the device no longer appears in `adb devices` **in any state** (a
148
+ * dying emulator answers `offline` while it still holds the AVD).
149
+ *
150
+ * @param params - The device and the PIDs this run owns.
151
+ * @returns `true` when nothing of this run's emulator is left.
152
+ */
153
+ private checkIsEmulatorGone;
154
+ /**
155
+ * Asks the emulator to shut itself down over its console.
156
+ *
157
+ * Preferred over killing the process outright because it is the path that
158
+ * releases the AVD's `multiinstance.lock`. Best-effort: a console that does
159
+ * not answer is reported and the caller falls through to the kill.
160
+ *
161
+ * @param deviceId - The emulator's device ID.
162
+ */
163
+ private killEmulatorConsole;
164
+ /**
165
+ * Acts on one emulator marker for {@link reclaimLeftoverEmulators}.
166
+ *
167
+ * @param marker - The marker to judge.
168
+ * @param liveEmulatorPids - The emulator processes currently running on the host.
169
+ * @param scope - Whether an emulator another live harness process owns is spared.
170
+ */
171
+ private reclaimLeftoverEmulator;
172
+ /**
173
+ * Polls until this run's emulator is gone, or the budget elapses.
174
+ *
175
+ * @param params - The device, the PIDs this run owns, and the budget.
176
+ * @returns `true` when the emulator disappeared within the budget.
177
+ */
178
+ private waitForEmulatorStopped;
179
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var eval_cap_exceeded_error_exports = {};
20
+ __export(eval_cap_exceeded_error_exports, {
21
+ EvalCapExceededError: () => EvalCapExceededError,
22
+ isScriptTimeoutError: () => isScriptTimeoutError
23
+ });
24
+ module.exports = __toCommonJS(eval_cap_exceeded_error_exports);
25
+ const SCRIPT_TIMEOUT_PATTERN = /script\s*timeout/i;
26
+ class EvalCapExceededError extends Error {
27
+ /**
28
+ The per-eval cap the closure outran, in milliseconds.
29
+ */
30
+ capInMilliseconds;
31
+ /**
32
+ How the transport that enforced the cap was named in the message.
33
+ */
34
+ transportName;
35
+ /**
36
+ * Creates the error from the cap, the transport, and the raw error it replaces.
37
+ *
38
+ * @param params - The cap, the transport, the option that sets the cap, and the underlying error.
39
+ */
40
+ constructor(params) {
41
+ super(buildMessage(params), { cause: params.cause });
42
+ this.name = "EvalCapExceededError";
43
+ this.capInMilliseconds = params.capInMilliseconds;
44
+ this.transportName = params.transportName;
45
+ }
46
+ }
47
+ function isScriptTimeoutError(error) {
48
+ if (!(error instanceof Error)) {
49
+ return false;
50
+ }
51
+ return SCRIPT_TIMEOUT_PATTERN.test(error.message) || SCRIPT_TIMEOUT_PATTERN.test(error.name);
52
+ }
53
+ function buildMessage(params) {
54
+ return `A single evalInObsidian closure ran longer than the ${params.transportName} per-eval cap of ${String(params.capInMilliseconds)}ms, so it was killed mid-flight. This is a property of the closure, not of the device or the app: everything awaited inside one closure shares that one budget, including every \`lib.waitUntil\` timeout and every settle \`sleep\`. Do the waiting from Node instead \u2014 \`pollInObsidian\` runs a short \`poll\` closure repeatedly until a Node-side \`until\` accepts, so no single eval is ever long. Raise \`${params.optionName}\` only for a closure that genuinely cannot be split.`;
55
+ }
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ EvalCapExceededError,
59
+ isScriptTimeoutError
60
+ });
61
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2V2YWwtY2FwLWV4Y2VlZGVkLWVycm9yLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogVGhlIG9uZSBlcnJvciBib3RoIHRyYW5zcG9ydHMgcmFpc2Ugd2hlbiBhIHNpbmdsZSBgZXZhbEluT2JzaWRpYW5gIGNsb3N1cmVcbiAqIG91dHJ1bnMgdGhlIHBlci1ldmFsIGNhcCwgYW5kIHRoZSBwcmVkaWNhdGUgdGhhdCByZWNvZ25pemVzIHRoZSByYXcgdHJhbnNwb3J0XG4gKiBlcnJvciBpdCByZXBsYWNlcy5cbiAqXG4gKiBUaGUgY2FwIGl0c2VsZiBpcyBub3QgdGhlIHByb2JsZW0gdGhpcyBtb2R1bGUgc29sdmVzIFx1MjAxNCB0aGUgZGlhZ25vc2lzIGlzLlxuICogRGVza3RvcCBzdXJmYWNlcyB0aGUgb3ZlcnJ1biBhcyBhIGdlbmVyaWNcbiAqIGBDRFAgY29tbWFuZCB0aW1lZCBvdXQgLi4uIDogUnVudGltZS5ldmFsdWF0ZWAsIHdoaWNoIG5ldmVyIG5hbWVzIHRoZSB0ZXN0J3NcbiAqIG93biB3YWl0IGFuZCBzbyByZWFkcyBhcyBhIGJyb2tlbiBkZXZpY2Ugb3IgYSB3ZWRnZWQgYXBwIFx1MjAxNCBhIHBsdWdpbiByZWxlYXNlIHdhc1xuICogb25jZSBoZWxkIGZvciB0d28gZGF5cyBieSB0aGF0IHJlYWRpbmcsIHdpdGggYSBoZWFsdGh5IGVtdWxhdG9yIGJsYW1lZCBmb3JcbiAqIGhhdmluZyBubyBuZXR3b3JrLlxuICpcbiAqIEFuZHJvaWQgaXMgd29yc2UsIGJlY2F1c2UgaXQgc3VyZmFjZXMgTk9USElORy4gT24gYSBsaXZlIGVtdWxhdG9yIHRoZSBjbG9zdXJlXG4gKiB3YXMgbWVhc3VyZWQgY29tcGxldGluZyBpbiB0aGUgZ3Vlc3Qgb24gc2NoZWR1bGUgXHUyMDE0IHRpbWVycyBhcm1lZCBhdCAzMHMgYW5kIDQwcyBmaXJlZCB3aXRoaW5cbiAqIH4xM21zIG9mIG5vbWluYWwgb24gYSB2aXNpYmxlLCBmb2N1c2VkIHBhZ2UgXHUyMDE0IHdoaWxlIGl0cyBFeGVjdXRlIFNjcmlwdCByZXNwb25zZVxuICogbmV2ZXIgcmVhY2hlZCB0aGUgY2xpZW50LCBzbyB0aGUgY2FsbCBodW5nIHVudGlsIHdoaWNoZXZlciBvdXRlciBidWRnZXQgZ2F2ZSB1cFxuICogZmlyc3QuIEEgaGFuZyBuYW1lcyBub3RoaW5nIGF0IGFsbCwgd2hpY2ggaXMgd2h5IHRoZSBBbmRyb2lkIGNhcCBpcyBlbmZvcmNlZCBieVxuICogdGhlIHRyYW5zcG9ydCBvbiB0aGUgTm9kZSBzaWRlIHJhdGhlciB0aGFuIGJ5IHRoZSBgdGltZW91dHMuc2NyaXB0YCBjYXBhYmlsaXR5XG4gKiBpdCBhbHNvIGRlY2xhcmVzIGFuZCB0aGF0IG5vdGhpbmcgYWN0cyBvbi5cbiAqXG4gKiBCb3RoIHRyYW5zcG9ydHMgdGhlcmVmb3JlIGZ1bm5lbCBpbnRvIHRoZSBtZXNzYWdlIGJlbG93LCB3aGljaCBzYXlzIHdoYXQgdGhlIGNhcFxuICogaXMsIHdoaWNoIHRyYW5zcG9ydCBlbmZvcmNlZCBpdCwgYW5kIHdoYXQgdG8gZG8gaW5zdGVhZC5cbiAqXG4gKiBBIGNsb3N1cmUgdGhhdCBuZWVkcyB0byB3YWl0IGxvbmdlciB0aGFuIHRoZSBjYXAgc2hvdWxkIG5vdCBiZSB3YWl0aW5nIGluc2lkZVxuICogT2JzaWRpYW4gYXQgYWxsLiBgcG9sbEluT2JzaWRpYW5gIGlzIHRoZSBzYW5jdGlvbmVkIHNoYXBlOiBzaG9ydCBjbG9zdXJlcywgYW5kXG4gKiB0aGUgd2FpdGluZyBkb25lIGZyb20gTm9kZS5cbiAqL1xuXG4vKlxuICogVGhlIFczQyBlcnJvciBjb2RlIGlzIHRoZSBzcGFjZWQgYHNjcmlwdCB0aW1lb3V0YCwgd2hpbGUgYSBjbGllbnQgdGhhdCB0dXJucyBpdCBpbnRvIGEgdHlwZSBzcGVsbHMgdGhlXG4gKiBTYW1lIHRoaW5nIGFzIGBTY3JpcHRUaW1lb3V0RXJyb3JgIFx1MjAxNCBoZW5jZSB0aGUgb3B0aW9uYWwgd2hpdGVzcGFjZSwgd2hpY2ggbGV0cyBvbmUgcGF0dGVybiByZWFkIGJvdGguXG4gKi9cbmNvbnN0IFNDUklQVF9USU1FT1VUX1BBVFRFUk4gPSAvc2NyaXB0XFxzKnRpbWVvdXQvaTtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgRXZhbENhcEV4Y2VlZGVkRXJyb3J9J3MgY29uc3RydWN0b3IuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXZhbENhcEV4Y2VlZGVkRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgcGVyLWV2YWwgY2FwIHRoZSBjbG9zdXJlIG91dHJhbiwgaW4gbWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgcmVhZG9ubHkgY2FwSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgVGhlIHVuZGVybHlpbmcgdHJhbnNwb3J0IGVycm9yLCBrZXB0IGFzIHRoZSBgY2F1c2VgIHNvIHRoZSByYXcgZGlhZ25vc2lzIGlzIG5vdCBsb3N0LlxuICAgKi9cbiAgcmVhZG9ubHkgY2F1c2U6IHVua25vd247XG5cbiAgLyoqXG4gIFRoZSBuYW1lIG9mIHRoZSBvcHRpb24gdGhhdCBzZXRzIHRoZSBjYXAgb24gdGhpcyB0cmFuc3BvcnQsIHNvIHRoZSBtZXNzYWdlIGNhbiBuYW1lIHRoZSByZWFsIGtub2IuXG4gICAqL1xuICByZWFkb25seSBvcHRpb25OYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIEhvdyB0byByZWZlciB0byB0aGUgdHJhbnNwb3J0IHRoYXQgZW5mb3JjZWQgdGhlIGNhcCwgZS5nLiBgJ0FuZHJvaWQgKEFwcGl1bSknYC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE5hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBvbmUgYGV2YWxJbk9ic2lkaWFuYCBjbG9zdXJlIHJhbiBsb25nZXIgdGhhbiB0aGUgdHJhbnNwb3J0J3NcbiAqIHBlci1ldmFsIGNhcC5cbiAqXG4gKiBDYXJyaWVzIHRoZSBjYXAgYW5kIHRoZSB0cmFuc3BvcnQgc28gYSBjYWxsZXIgY2FuIGBpbnN0YW5jZW9mYC1tYXRjaCwgYW5kIHRoZVxuICogb3JpZ2luYWwgdHJhbnNwb3J0IGVycm9yIGFzIGBjYXVzZWAuXG4gKi9cbmV4cG9ydCBjbGFzcyBFdmFsQ2FwRXhjZWVkZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gIFRoZSBwZXItZXZhbCBjYXAgdGhlIGNsb3N1cmUgb3V0cmFuLCBpbiBtaWxsaXNlY29uZHMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2FwSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgSG93IHRoZSB0cmFuc3BvcnQgdGhhdCBlbmZvcmNlZCB0aGUgY2FwIHdhcyBuYW1lZCBpbiB0aGUgbWVzc2FnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB0cmFuc3BvcnROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGVycm9yIGZyb20gdGhlIGNhcCwgdGhlIHRyYW5zcG9ydCwgYW5kIHRoZSByYXcgZXJyb3IgaXQgcmVwbGFjZXMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY2FwLCB0aGUgdHJhbnNwb3J0LCB0aGUgb3B0aW9uIHRoYXQgc2V0cyB0aGUgY2FwLCBhbmQgdGhlIHVuZGVybHlpbmcgZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBFdmFsQ2FwRXhjZWVkZWRFcnJvckNvbnN0cnVjdG9yUGFyYW1zKSB7XG4gICAgc3VwZXIoYnVpbGRNZXNzYWdlKHBhcmFtcyksIHsgY2F1c2U6IHBhcmFtcy5jYXVzZSB9KTtcbiAgICB0aGlzLm5hbWUgPSAnRXZhbENhcEV4Y2VlZGVkRXJyb3InO1xuICAgIHRoaXMuY2FwSW5NaWxsaXNlY29uZHMgPSBwYXJhbXMuY2FwSW5NaWxsaXNlY29uZHM7XG4gICAgdGhpcy50cmFuc3BvcnROYW1lID0gcGFyYW1zLnRyYW5zcG9ydE5hbWU7XG4gIH1cbn1cblxuLyoqXG4gKiBXaGV0aGVyIGFuIGVycm9yIGlzIGEgV2ViRHJpdmVyIHNjcmlwdCB0aW1lb3V0IFx1MjAxNCB0aGUgVzNDIGVycm9yIGEgZHJpdmVyIHdvdWxkXG4gKiByYWlzZSBpZiBpdCBlbmZvcmNlZCBgdGltZW91dHMuc2NyaXB0YC5cbiAqXG4gKiBNYXRjaGVkIG9uIHRoZSBtZXNzYWdlIHJhdGhlciB0aGFuIG9uIGEgdHlwZSwgYmVjYXVzZSB0aGUgZXJyb3IgYXJyaXZlcyBhcyBhXG4gKiBnZW5lcmljIGBXZWJEcml2ZXJFcnJvcmAgd2hvc2Ugb25seSBkaXN0aW5ndWlzaGluZyBtYXJrIGlzIHRoZSBXM0MgZXJyb3IgY29kZVxuICogaW4gaXRzIHRleHQuXG4gKlxuICogKipUaGlzIGRyaXZlciBuZXZlciByYWlzZXMgaXQuKiogVWlBdXRvbWF0b3IyIHdhcyBtZWFzdXJlZCBhY2NlcHRpbmcgdGhlXG4gKiBjYXBhYmlsaXR5LCByZXBvcnRpbmcgaXQgYmFjaywgYW5kIGVuZm9yY2luZyBub3RoaW5nLiBUaGUgcHJlZGljYXRlIGlzIGtlcHRcbiAqIGJlY2F1c2UgaXQgY29zdHMgbm90aGluZywgaXQgaXMgdGhlIHJpZ2h0IHRyYW5zbGF0aW9uIGlmIGEgZnV0dXJlIGRyaXZlciBkb2VzXG4gKiBlbmZvcmNlIHRoZSBjYXBhYmlsaXR5LCBhbmQgaXQga2VlcHMgb25lIGVycm9yIGNvdmVyaW5nIG9uZSBjb25kaXRpb24gb24gYm90aFxuICogdHJhbnNwb3J0cyBcdTIwMTQgYnV0IHRoZSBBbmRyb2lkIGNhcCBpcyBlbmZvcmNlZCBOb2RlLXNpZGUsIGFuZCB0aGlzIGlzIG5vdCB3aGF0XG4gKiBlbmZvcmNlcyBpdC5cbiAqXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdGhyb3duIGJ5IHRoZSB0cmFuc3BvcnQuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgZXJyb3IgaXMgYSBzY3JpcHQgdGltZW91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2NyaXB0VGltZW91dEVycm9yKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICghKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIFNDUklQVF9USU1FT1VUX1BBVFRFUk4udGVzdChlcnJvci5tZXNzYWdlKSB8fCBTQ1JJUFRfVElNRU9VVF9QQVRURVJOLnRlc3QoZXJyb3IubmFtZSk7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBzaGFyZWQgbWVzc2FnZSBib3RoIHRyYW5zcG9ydHMgcmVwb3J0LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY2FwLCB0aGUgdHJhbnNwb3J0LCBhbmQgdGhlIG9wdGlvbiB0aGF0IHNldHMgdGhlIGNhcC5cbiAqIEByZXR1cm5zIFRoZSBtZXNzYWdlLlxuICovXG5mdW5jdGlvbiBidWlsZE1lc3NhZ2UocGFyYW1zOiBFdmFsQ2FwRXhjZWVkZWRFcnJvckNvbnN0cnVjdG9yUGFyYW1zKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBBIHNpbmdsZSBldmFsSW5PYnNpZGlhbiBjbG9zdXJlIHJhbiBsb25nZXIgdGhhbiB0aGUgJHtwYXJhbXMudHJhbnNwb3J0TmFtZX0gcGVyLWV2YWwgY2FwIG9mICR7U3RyaW5nKHBhcmFtcy5jYXBJbk1pbGxpc2Vjb25kcyl9bXMsIHNvIGl0IHdhcyBraWxsZWQgbWlkLWZsaWdodC4gVGhpcyBpcyBhIHByb3BlcnR5IG9mIHRoZSBjbG9zdXJlLCBub3Qgb2YgdGhlIGRldmljZSBvciB0aGUgYXBwOiBgXG4gICAgKyAnZXZlcnl0aGluZyBhd2FpdGVkIGluc2lkZSBvbmUgY2xvc3VyZSBzaGFyZXMgdGhhdCBvbmUgYnVkZ2V0LCBpbmNsdWRpbmcgZXZlcnkgYGxpYi53YWl0VW50aWxgIHRpbWVvdXQgJ1xuICAgICsgJ2FuZCBldmVyeSBzZXR0bGUgYHNsZWVwYC4gRG8gdGhlIHdhaXRpbmcgZnJvbSBOb2RlIGluc3RlYWQgXHUyMDE0IGBwb2xsSW5PYnNpZGlhbmAgcnVucyBhIHNob3J0IGBwb2xsYCAnXG4gICAgKyAnY2xvc3VyZSByZXBlYXRlZGx5IHVudGlsIGEgTm9kZS1zaWRlIGB1bnRpbGAgYWNjZXB0cywgc28gbm8gc2luZ2xlIGV2YWwgaXMgZXZlciBsb25nLiBSYWlzZSAnXG4gICAgKyBgXFxgJHtwYXJhbXMub3B0aW9uTmFtZX1cXGAgb25seSBmb3IgYSBjbG9zdXJlIHRoYXQgZ2VudWluZWx5IGNhbm5vdCBiZSBzcGxpdC5gO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBa0NBLE1BQU0seUJBQXlCO0FBa0N4QixNQUFNLDZCQUE2QixNQUFNO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJOUI7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT1QsWUFBWSxRQUErQztBQUNoRSxVQUFNLGFBQWEsTUFBTSxHQUFHLEVBQUUsT0FBTyxPQUFPLE1BQU0sQ0FBQztBQUNuRCxTQUFLLE9BQU87QUFDWixTQUFLLG9CQUFvQixPQUFPO0FBQ2hDLFNBQUssZ0JBQWdCLE9BQU87QUFBQSxFQUM5QjtBQUNGO0FBb0JPLFNBQVMscUJBQXFCLE9BQXlCO0FBQzVELE1BQUksRUFBRSxpQkFBaUIsUUFBUTtBQUM3QixXQUFPO0FBQUEsRUFDVDtBQUVBLFNBQU8sdUJBQXVCLEtBQUssTUFBTSxPQUFPLEtBQUssdUJBQXVCLEtBQUssTUFBTSxJQUFJO0FBQzdGO0FBUUEsU0FBUyxhQUFhLFFBQXVEO0FBQzNFLFNBQU8sdURBQXVELE9BQU8sYUFBYSxvQkFBb0IsT0FBTyxPQUFPLGlCQUFpQixDQUFDLDBaQUk3SCxPQUFPLFVBQVU7QUFDNUI7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * The one error both transports raise when a single `evalInObsidian` closure
5
+ * outruns the per-eval cap, and the predicate that recognizes the raw transport
6
+ * error it replaces.
7
+ *
8
+ * The cap itself is not the problem this module solves — the diagnosis is.
9
+ * Desktop surfaces the overrun as a generic
10
+ * `CDP command timed out ... : Runtime.evaluate`, which never names the test's
11
+ * own wait and so reads as a broken device or a wedged app — a plugin release was
12
+ * once held for two days by that reading, with a healthy emulator blamed for
13
+ * having no network.
14
+ *
15
+ * Android is worse, because it surfaces NOTHING. On a live emulator the closure
16
+ * was measured completing in the guest on schedule — timers armed at 30s and 40s fired within
17
+ * ~13ms of nominal on a visible, focused page — while its Execute Script response
18
+ * never reached the client, so the call hung until whichever outer budget gave up
19
+ * first. A hang names nothing at all, which is why the Android cap is enforced by
20
+ * the transport on the Node side rather than by the `timeouts.script` capability
21
+ * it also declares and that nothing acts on.
22
+ *
23
+ * Both transports therefore funnel into the message below, which says what the cap
24
+ * is, which transport enforced it, and what to do instead.
25
+ *
26
+ * A closure that needs to wait longer than the cap should not be waiting inside
27
+ * Obsidian at all. `pollInObsidian` is the sanctioned shape: short closures, and
28
+ * the waiting done from Node.
29
+ */
30
+ /**
31
+ * Parameters for {@link EvalCapExceededError}'s constructor.
32
+ */
33
+ export interface EvalCapExceededErrorConstructorParams {
34
+ /**
35
+ The per-eval cap the closure outran, in milliseconds.
36
+ */
37
+ readonly capInMilliseconds: number;
38
+ /**
39
+ The underlying transport error, kept as the `cause` so the raw diagnosis is not lost.
40
+ */
41
+ readonly cause: unknown;
42
+ /**
43
+ The name of the option that sets the cap on this transport, so the message can name the real knob.
44
+ */
45
+ readonly optionName: string;
46
+ /**
47
+ How to refer to the transport that enforced the cap, e.g. `'Android (Appium)'`.
48
+ */
49
+ readonly transportName: string;
50
+ }
51
+ /**
52
+ * Thrown when one `evalInObsidian` closure ran longer than the transport's
53
+ * per-eval cap.
54
+ *
55
+ * Carries the cap and the transport so a caller can `instanceof`-match, and the
56
+ * original transport error as `cause`.
57
+ */
58
+ export declare class EvalCapExceededError extends Error {
59
+ /**
60
+ The per-eval cap the closure outran, in milliseconds.
61
+ */
62
+ readonly capInMilliseconds: number;
63
+ /**
64
+ How the transport that enforced the cap was named in the message.
65
+ */
66
+ readonly transportName: string;
67
+ /**
68
+ * Creates the error from the cap, the transport, and the raw error it replaces.
69
+ *
70
+ * @param params - The cap, the transport, the option that sets the cap, and the underlying error.
71
+ */
72
+ constructor(params: EvalCapExceededErrorConstructorParams);
73
+ }
74
+ /**
75
+ * Whether an error is a WebDriver script timeout — the W3C error a driver would
76
+ * raise if it enforced `timeouts.script`.
77
+ *
78
+ * Matched on the message rather than on a type, because the error arrives as a
79
+ * generic `WebDriverError` whose only distinguishing mark is the W3C error code
80
+ * in its text.
81
+ *
82
+ * **This driver never raises it.** UiAutomator2 was measured accepting the
83
+ * capability, reporting it back, and enforcing nothing. The predicate is kept
84
+ * because it costs nothing, it is the right translation if a future driver does
85
+ * enforce the capability, and it keeps one error covering one condition on both
86
+ * transports — but the Android cap is enforced Node-side, and this is not what
87
+ * enforces it.
88
+ *
89
+ * @param error - The error thrown by the transport.
90
+ * @returns `true` when the error is a script timeout.
91
+ */
92
+ export declare function isScriptTimeoutError(error: unknown): boolean;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var eval_cap_exports = {};
20
+ __export(eval_cap_exports, {
21
+ DEFAULT_EVAL_CAP_IN_MILLISECONDS: () => DEFAULT_EVAL_CAP_IN_MILLISECONDS
22
+ });
23
+ module.exports = __toCommonJS(eval_cap_exports);
24
+ const DEFAULT_EVAL_CAP_IN_MILLISECONDS = 3e4;
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ DEFAULT_EVAL_CAP_IN_MILLISECONDS
28
+ });
29
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2V2YWwtY2FwLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogVGhlIHBlci1ldmFsIGNhcDogaG93IGxvbmcgYSBzaW5nbGUgYGV2YWxJbk9ic2lkaWFuYCBjbG9zdXJlIG1heSBydW4gYmVmb3JlXG4gKiB0aGUgdHJhbnNwb3J0IGNhcnJ5aW5nIGl0IGdpdmVzIHVwLlxuICpcbiAqIEl0IGxpdmVzIGluIGl0cyBvd24gbW9kdWxlLCBhbmQgaXMgcmUtZXhwb3J0ZWQgZnJvbSB0aGUgcGFja2FnZSByb290LCBiZWNhdXNlXG4gKiBpdCBpcyB0aGUgc2luZ2xlIG1vc3QgbG9hZC1iZWFyaW5nIG51bWJlciBhIHRlc3QgYXV0aG9yIGhhcyB0byByZXNwZWN0IFx1MjAxNCBhbmRcbiAqIHVudGlsIHRoaXMgbW9kdWxlIGV4aXN0ZWQgdGhlcmUgd2FzIG5vdGhpbmcgdG8gaW1wb3J0LiBCb3RoIHRyYW5zcG9ydHMgaGVsZFxuICogdGhlIHNhbWUgMzBzIHByaXZhdGVseSwgc28gZXZlcnkgY29uc3VtZXIgdGhhdCBuZWVkZWQgdG8gc2l6ZSBhIGNsb3N1cmVcbiAqIHJlc3RhdGVkIGl0IGFzIGEgbGl0ZXJhbCB3aXRoIGEgY29tbWVudCBzYXlpbmcgd2hlcmUgdGhlIG51bWJlciBjYW1lIGZyb20uXG4gKiBUaGF0IGlzIGEgbWlycm9yIG5vdGhpbmcgbWFpbnRhaW5zOiByYWlzZSBhIGNhcCBoZXJlIGFuZCBldmVyeSByZXN0YXRlbWVudCBpc1xuICogc2lsZW50bHkgd3JvbmcgaW4gdGhlIGRpcmVjdGlvbiB0aGF0IHByb2R1Y2VzIHRoZSB1bnJlYWRhYmxlIGZhaWx1cmUsIGJlY2F1c2VcbiAqIHRoZSBjb25zdW1lciBnb2VzIG9uIGJlbGlldmluZyBpdCBoYXMgaGVhZHJvb20gaXQgbm8gbG9uZ2VyIGhhcy5cbiAqXG4gKiAqKlRoZSB0d28gdHJhbnNwb3J0cyBzaGFyZSB0aGlzIE9ORSBjb25zdGFudCByYXRoZXIgdGhhbiBhZ3JlZWluZyBieVxuICogY29pbmNpZGVuY2UuKiogVGhleSBlbmZvcmNlIGl0IHRocm91Z2ggZGlmZmVyZW50IGtub2JzIFx1MjAxNCBkZXNrdG9wIGJvdW5kcyB0aGVcbiAqIGBSdW50aW1lLmV2YWx1YXRlYCBDRFAgY29tbWFuZCAoYGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHNgKSwgQW5kcm9pZFxuICogYm91bmRzIHRoZSBFeGVjdXRlIFNjcmlwdCBjYWxsIE5vZGUtc2lkZSAoYHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kc2ApIFx1MjAxNFxuICogYnV0IHRoZSBrbm9icyBhcmUgdHdvIGltcGxlbWVudGF0aW9ucyBvZiBvbmUgcG9saWN5LCBub3QgdHdvIHBvbGljaWVzIHRoYXRcbiAqIGhhcHBlbiB0byBhZ3JlZS4gQSByZWFkZXIgb2YgZWl0aGVyIGRlZmF1bHQgbm93IHNlZXMgd2hpY2ggaXQgaXMuXG4gKi9cblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBwZXItZXZhbCBjYXAsIGluIG1pbGxpc2Vjb25kczogdGhlIGJ1ZGdldCBvbmUgYGV2YWxJbk9ic2lkaWFuYFxuICogY2xvc3VyZSBoYXMgdG8gZml0IGluc2lkZS5cbiAqXG4gKiBFdmVyeXRoaW5nIGF3YWl0ZWQgaW5zaWRlIGEgc2luZ2xlIGNsb3N1cmUgc2hhcmVzIHRoaXMgb25lIGJ1ZGdldCBcdTIwMTQgZXZlcnlcbiAqIGBsaWIud2FpdFVudGlsYCB0aW1lb3V0IGFuZCBldmVyeSBzZXR0bGUgYHNsZWVwYCBcdTIwMTQgc28gYSBjbG9zdXJlJ3MgZGVjbGFyZWRcbiAqIHdhaXRzIGhhdmUgdG8gc3VtIHRvIGxlc3MgdGhhbiB0aGlzLCBub3QgbWVyZWx5IGJlIGluZGl2aWR1YWxseSBzaG9ydGVyLlxuICpcbiAqIEFuIG92ZXJydW4gaXMgcmVwb3J0ZWQgYXMgYEV2YWxDYXBFeGNlZWRlZEVycm9yYCwgd2hpY2ggbmFtZXMgdGhlIGNhcCwgdGhlXG4gKiB0cmFuc3BvcnQgdGhhdCBlbmZvcmNlZCBpdCwgYW5kIHRoZSBvcHRpb24gdGhhdCBzZXRzIGl0LiBSYWlzaW5nIHRoYXQgb3B0aW9uXG4gKiBpcyBhbG1vc3QgbmV2ZXIgdGhlIHJpZ2h0IGFuc3dlcjogYSBjbG9zdXJlIHRoYXQgbmVlZHMgdG8gd2FpdCBsb25nZXIgdGhhblxuICogdGhpcyBzaG91bGQgbm90IGJlIHdhaXRpbmcgaW5zaWRlIE9ic2lkaWFuIGF0IGFsbC4gYHBvbGxJbk9ic2lkaWFuYCBpcyB0aGVcbiAqIHNhbmN0aW9uZWQgc2hhcGUgXHUyMDE0IHNob3J0IGNsb3N1cmVzLCB3aXRoIHRoZSB3YWl0aW5nIGRvbmUgZnJvbSBOb2RlIFx1MjAxNCBhbmQgaXRcbiAqIGV4aXN0cyBwcmVjaXNlbHkgc28gbm8gc2luZ2xlIGV2YWwgaXMgZXZlciBsb25nLlxuICpcbiAqIEJvdGggdHJhbnNwb3J0cyBkZWZhdWx0IHRvIHRoaXMgdmFsdWU6IGl0IGlzIHdoYXRcbiAqIGBPYnNpZGlhbkNkcFRyYW5zcG9ydE9wdGlvbnMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kc2AgYW5kXG4gKiBgT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucy5zY3JpcHRUaW1lb3V0SW5NaWxsaXNlY29uZHNgIGZhbGwgYmFja1xuICogdG8gd2hlbiB0aGV5IGFyZSBvbWl0dGVkLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBMkNPLE1BQU0sbUNBQW1DOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * The per-eval cap: how long a single `evalInObsidian` closure may run before
5
+ * the transport carrying it gives up.
6
+ *
7
+ * It lives in its own module, and is re-exported from the package root, because
8
+ * it is the single most load-bearing number a test author has to respect — and
9
+ * until this module existed there was nothing to import. Both transports held
10
+ * the same 30s privately, so every consumer that needed to size a closure
11
+ * restated it as a literal with a comment saying where the number came from.
12
+ * That is a mirror nothing maintains: raise a cap here and every restatement is
13
+ * silently wrong in the direction that produces the unreadable failure, because
14
+ * the consumer goes on believing it has headroom it no longer has.
15
+ *
16
+ * **The two transports share this ONE constant rather than agreeing by
17
+ * coincidence.** They enforce it through different knobs — desktop bounds the
18
+ * `Runtime.evaluate` CDP command (`commandTimeoutInMilliseconds`), Android
19
+ * bounds the Execute Script call Node-side (`scriptTimeoutInMilliseconds`) —
20
+ * but the knobs are two implementations of one policy, not two policies that
21
+ * happen to agree. A reader of either default now sees which it is.
22
+ */
23
+ /**
24
+ * The default per-eval cap, in milliseconds: the budget one `evalInObsidian`
25
+ * closure has to fit inside.
26
+ *
27
+ * Everything awaited inside a single closure shares this one budget — every
28
+ * `lib.waitUntil` timeout and every settle `sleep` — so a closure's declared
29
+ * waits have to sum to less than this, not merely be individually shorter.
30
+ *
31
+ * An overrun is reported as `EvalCapExceededError`, which names the cap, the
32
+ * transport that enforced it, and the option that sets it. Raising that option
33
+ * is almost never the right answer: a closure that needs to wait longer than
34
+ * this should not be waiting inside Obsidian at all. `pollInObsidian` is the
35
+ * sanctioned shape — short closures, with the waiting done from Node — and it
36
+ * exists precisely so no single eval is ever long.
37
+ *
38
+ * Both transports default to this value: it is what
39
+ * `ObsidianCdpTransportOptions.commandTimeoutInMilliseconds` and
40
+ * `ObsidianAndroidAppiumTransportOptions.scriptTimeoutInMilliseconds` fall back
41
+ * to when they are omitted.
42
+ */
43
+ export declare const DEFAULT_EVAL_CAP_IN_MILLISECONDS = 30000;