doc-detective 4.28.0 → 4.29.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 (57) hide show
  1. package/dist/cli.js +13 -4
  2. package/dist/cli.js.map +1 -1
  3. package/dist/common/src/detectTests.d.ts +9 -0
  4. package/dist/common/src/detectTests.d.ts.map +1 -1
  5. package/dist/common/src/detectTests.js +22 -9
  6. package/dist/common/src/detectTests.js.map +1 -1
  7. package/dist/common/src/schemas/schemas.json +85 -1
  8. package/dist/common/src/types/generated/report_v3.d.ts +34 -0
  9. package/dist/common/src/types/generated/report_v3.d.ts.map +1 -1
  10. package/dist/core/detectTests.d.ts.map +1 -1
  11. package/dist/core/detectTests.js +37 -13
  12. package/dist/core/detectTests.js.map +1 -1
  13. package/dist/core/expressions.d.ts.map +1 -1
  14. package/dist/core/expressions.js +24 -1
  15. package/dist/core/expressions.js.map +1 -1
  16. package/dist/core/index.d.ts +2 -1
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/core/index.js +2 -2
  19. package/dist/core/index.js.map +1 -1
  20. package/dist/core/resolveTests.js +23 -12
  21. package/dist/core/resolveTests.js.map +1 -1
  22. package/dist/core/telem.d.ts +2 -1
  23. package/dist/core/telem.d.ts.map +1 -1
  24. package/dist/core/telem.js +26 -2
  25. package/dist/core/telem.js.map +1 -1
  26. package/dist/core/tests/androidEmulator.d.ts.map +1 -1
  27. package/dist/core/tests/androidEmulator.js +13 -0
  28. package/dist/core/tests/androidEmulator.js.map +1 -1
  29. package/dist/core/tests/appSurface.d.ts +23 -0
  30. package/dist/core/tests/appSurface.d.ts.map +1 -1
  31. package/dist/core/tests/appSurface.js +3 -1
  32. package/dist/core/tests/appSurface.js.map +1 -1
  33. package/dist/core/tests/iosSimulator.d.ts.map +1 -1
  34. package/dist/core/tests/iosSimulator.js +13 -0
  35. package/dist/core/tests/iosSimulator.js.map +1 -1
  36. package/dist/core/tests/mobileBrowser.d.ts +1 -0
  37. package/dist/core/tests/mobileBrowser.d.ts.map +1 -1
  38. package/dist/core/tests/mobileBrowser.js +8 -0
  39. package/dist/core/tests/mobileBrowser.js.map +1 -1
  40. package/dist/core/tests.d.ts +83 -2
  41. package/dist/core/tests.d.ts.map +1 -1
  42. package/dist/core/tests.js +572 -70
  43. package/dist/core/tests.js.map +1 -1
  44. package/dist/core/utils.d.ts +3 -2
  45. package/dist/core/utils.d.ts.map +1 -1
  46. package/dist/core/utils.js +37 -29
  47. package/dist/core/utils.js.map +1 -1
  48. package/dist/core/warmPhase.d.ts +161 -0
  49. package/dist/core/warmPhase.d.ts.map +1 -0
  50. package/dist/core/warmPhase.js +341 -0
  51. package/dist/core/warmPhase.js.map +1 -0
  52. package/dist/index.cjs +776 -90
  53. package/dist/utils.d.ts +2 -1
  54. package/dist/utils.d.ts.map +1 -1
  55. package/dist/utils.js +11 -3
  56. package/dist/utils.js.map +1 -1
  57. package/package.json +1 -1
@@ -0,0 +1,341 @@
1
+ // Inline warm phase (docs/design/warm-phase.md, phase B1): the pure planner
2
+ // and executor for the always-on provisioning pass that runs in runSpecs
3
+ // between test resolution and test execution. The planner derives every
4
+ // provisioning task the run will need — driver installs, browser installs,
5
+ // device boots, the managed-WDA availability check, the mobile chromedriver
6
+ // prefetch, and the folded-in driver session probe — strictly from the
7
+ // resolved sizing jobs, so a run warms only what its contexts already
8
+ // JIT-provision today. The executor runs those tasks concurrently through the
9
+ // run's resource-aware pool, best-effort: warm pre-pays work, it never gates
10
+ // work (a failed task is a warning; the per-context paths retry/fail with
11
+ // exactly today's semantics).
12
+ //
13
+ // This module is pure by design (unit-testable without drivers): the
14
+ // effectful per-task bodies live in tests.ts (buildWarmTaskRunner), and the
15
+ // predicates the planner needs are injected via WarmPlanDeps (bound to the
16
+ // real implementations by tests.ts's buildWarmPlanDeps) because they live in
17
+ // tests.ts — a direct import would create a module cycle.
18
+ import { runResourceAware } from "./utils.js";
19
+ // Warm tasks are I/O-heavy (npm installs, downloads, boot spawns), not
20
+ // display-heavy, so the ceiling is a small constant independent of
21
+ // concurrentRunners — even a fully serial test run benefits from boot ∥
22
+ // install ∥ download overlap during warm.
23
+ export const WARM_POOL_LIMIT = 4;
24
+ // Every task that mutates the shared runtime/app cache serializes on this
25
+ // tag: concurrent npm installs into the managed runtime dir are exactly the
26
+ // npm-prune hazard (src/runtime/AGENTS.md, issue #501), and concurrent
27
+ // browser installs raced before warmUpContexts serialized them.
28
+ export const RUNTIME_INSTALL_RESOURCE = "runtime-install";
29
+ /**
30
+ * The single identity a warm device task is deduped, named, and
31
+ * tag-serialized by. It mirrors how the acquisition planners converge on a
32
+ * device: a NAMED descriptor always resolves to that registry name (whatever
33
+ * its other fields say), so two same-named descriptors are one device even
34
+ * when their osVersions differ — a second boot task would just registry-hit
35
+ * and block a warm worker on the full boot. Unnamed (default) descriptors
36
+ * resolve by deviceType + osVersion, so those fields distinguish devices.
37
+ */
38
+ export function deviceIdentity(platform, desc) {
39
+ if (desc?.name)
40
+ return `${platform}:name:${desc.name}`;
41
+ return `${platform}:default:${desc?.deviceType ?? "<any>"}:${desc?.osVersion ?? "<latest>"}`;
42
+ }
43
+ // One exclusivity tag per device identity: boots for the same device
44
+ // serialize (the registries would converge them anyway — the tag just avoids
45
+ // two acquires racing to plan), and the chromedriver prefetch queues behind
46
+ // its device's boot task, which releases at boot *initiation*.
47
+ export function deviceResourceTag(platform, desc) {
48
+ return `warm-device:${deviceIdentity(platform, desc)}`;
49
+ }
50
+ /**
51
+ * Re-wrap the named effect functions on an acquire-deps object so the first
52
+ * invocation of any of them fires `signal` — the boot-initiation hook
53
+ * raceBootInitiation races against. Shared by the android (createAvd/boot)
54
+ * and ios (create/boot) device-boot bodies so the initiation contract lives
55
+ * in one place.
56
+ */
57
+ export function wrapInitiationEffects(deps, keys, signal) {
58
+ const wrapped = { ...deps };
59
+ for (const key of keys) {
60
+ const original = deps[key];
61
+ if (typeof original !== "function")
62
+ continue;
63
+ wrapped[key] = (...args) => {
64
+ // Invoke the effect FIRST: a synchronous throw must reach the acquire
65
+ // path (→ failed) rather than racing the task to "boot initiated".
66
+ const result = original(...args);
67
+ signal();
68
+ return result;
69
+ };
70
+ }
71
+ return wrapped;
72
+ }
73
+ /**
74
+ * Derive the warm tasks a run needs from its sizing jobs (flat + routed).
75
+ * Pure: no I/O of its own, and — unlike selectWarmUpTargets — it never
76
+ * writes defaults onto the job contexts; effective platform/browser are
77
+ * computed locally so planning leaves the jobs byte-identical for the
78
+ * execution paths that own those mutations.
79
+ *
80
+ * Derivation is strictly "what the run's own paths would JIT-provision":
81
+ * a pure-web run plans only the browser installs (and, at limit > 1 with a
82
+ * pool, the session probe) that today's pre-pass already performs; mobile
83
+ * and app contexts add their driver installs, device boots, WDA check, and
84
+ * chromedriver prefetch. Anything the run's own gates would refuse before
85
+ * provisioning — an unmet `requires` gate, an ios context off darwin, a
86
+ * windows app context off windows, a mobile context the browser gate
87
+ * skips/fails — is not planned, mirroring the per-context gates.
88
+ */
89
+ export function planWarmTasks({ sizingJobs, runnerDetails, limit, hasAppiumPool, deps, }) {
90
+ // The runner's platform in runOn vocabulary ("windows" | "mac" | "linux") —
91
+ // the same source every peer (selectWarmUpTargets, runContext) reads.
92
+ const hostPlatform = runnerDetails?.environment?.platform;
93
+ const tasks = [];
94
+ const seen = new Set();
95
+ const addTask = (task) => {
96
+ if (seen.has(task.name))
97
+ return;
98
+ seen.add(task.name);
99
+ tasks.push(task);
100
+ };
101
+ let probeEligible = false;
102
+ // The run-constant default browser, resolved at most once.
103
+ let defaultBrowser;
104
+ const getDefaultBrowser = () => (defaultBrowser ??= deps.getDefaultBrowser({ runnerDetails }));
105
+ // Warm boots at most ONE device per mobile platform: emulator/simulator
106
+ // boots are the heaviest thing a CI host runs, and overlapping them
107
+ // starves everything (four concurrent emulator boots on a 2-core KVM
108
+ // runner starve the very sessions the tests need). The first device's
109
+ // boot overlaps the install tasks — the win the phase exists for — and
110
+ // every additional device boots exactly where it does today: inside its
111
+ // consuming context, serialized on the Phase-2 exclusivity tags.
112
+ const bootPlannedFor = new Set();
113
+ for (const job of sizingJobs ?? []) {
114
+ const context = job?.context;
115
+ if (!context)
116
+ continue;
117
+ // runContext evaluates the `requires` capability gate before ANY
118
+ // provisioning (install, preflight, boot) — a context it would skip
119
+ // must warm nothing.
120
+ if (deps.contextRequirementsSkipMessage({ context }))
121
+ continue;
122
+ const effPlatform = context.platform || hostPlatform;
123
+ const mobileTarget = deps.isMobileTargetPlatform(effPlatform);
124
+ if (mobileTarget) {
125
+ // ios (and its WDA/simulator toolchain) only provisions on a mac host;
126
+ // android emulators run anywhere the SDK does.
127
+ if (mobileTarget === "ios" && hostPlatform !== "mac")
128
+ continue;
129
+ const hasAppStep = deps.isAppDriverRequired({ test: context });
130
+ const gate = deps.mobileBrowserGate({
131
+ platform: mobileTarget,
132
+ browser: context.browser,
133
+ hasBrowserStep: deps.isBrowserRequired({ test: context }),
134
+ hasAppStep,
135
+ });
136
+ // A context the gate would SKIP/FAIL never reaches device work in
137
+ // runContext — warm nothing for it.
138
+ if (gate.action !== "proceed")
139
+ continue;
140
+ const isMobileWeb = typeof gate.browserName === "string";
141
+ if (!isMobileWeb && !hasAppStep)
142
+ continue;
143
+ const driverPackage = deps.appDriverPlatforms[mobileTarget]?.driverPackage;
144
+ if (driverPackage) {
145
+ addTask({
146
+ name: `driver-install:${driverPackage}`,
147
+ kind: "driver-install",
148
+ exclusiveResources: [RUNTIME_INSTALL_RESOURCE],
149
+ payload: { driverPackage, platform: mobileTarget },
150
+ });
151
+ }
152
+ for (const stepDevice of deps.collectDeviceDescriptors(context)) {
153
+ const desc = deps.normalizeDeviceDescriptor({
154
+ contextDevice: context.device,
155
+ stepDevice,
156
+ platform: mobileTarget,
157
+ });
158
+ const identity = deviceIdentity(mobileTarget, desc);
159
+ const tag = deviceResourceTag(mobileTarget, desc);
160
+ if (!bootPlannedFor.has(mobileTarget)) {
161
+ bootPlannedFor.add(mobileTarget);
162
+ // No "android-emulator" tag here: runResourceAware would release
163
+ // it at task resolution (boot initiation), before the boot
164
+ // finishes. The runner instead holds a manual lease on that name
165
+ // from initiation until the boot settles, so Phase-2 jobs (which
166
+ // tag it) still see one-emulator-at-a-time across phases.
167
+ addTask({
168
+ name: `device-boot:${identity}`,
169
+ kind: "device-boot",
170
+ exclusiveResources: [tag],
171
+ payload: { platform: mobileTarget, desc },
172
+ });
173
+ }
174
+ // The chromedriver autodownload is a mobile-WEB-android cost: the
175
+ // UiAutomator2 server fetches a chromedriver matching the device's
176
+ // Chrome at session creation. One prefetch per device. Only the
177
+ // device tag: its cache-mutating preflight half runs under a
178
+ // manually-acquired runtime-install lease inside the task body, so
179
+ // the long device-ready await never holds the install mutex.
180
+ if (mobileTarget === "android" && isMobileWeb) {
181
+ addTask({
182
+ name: `chromedriver-prefetch:${identity}`,
183
+ kind: "chromedriver-prefetch",
184
+ exclusiveResources: [tag],
185
+ payload: { platform: mobileTarget, desc },
186
+ });
187
+ }
188
+ }
189
+ if (mobileTarget === "ios") {
190
+ addTask({
191
+ name: "wda-check",
192
+ kind: "wda-check",
193
+ // Read-only (plus the last-used stamp) — contends with nothing.
194
+ exclusiveResources: [],
195
+ payload: {},
196
+ });
197
+ }
198
+ continue;
199
+ }
200
+ // Desktop contexts.
201
+ if (deps.isBrowserRequired({ test: context })) {
202
+ const effBrowser = context.browser ?? getDefaultBrowser();
203
+ const browserName = effBrowser?.name;
204
+ // Only host-platform contexts can actually be probed or installed
205
+ // for; a context pinned to another platform is skipped per-context
206
+ // and must trigger neither.
207
+ if (browserName && effPlatform === hostPlatform) {
208
+ probeEligible = true;
209
+ if (deps.requiredBrowserAssets(browserName).length > 0) {
210
+ addTask({
211
+ name: `browser-install:${browserName.toLowerCase()}`,
212
+ kind: "browser-install",
213
+ exclusiveResources: [RUNTIME_INSTALL_RESOURCE],
214
+ payload: { browserName },
215
+ });
216
+ }
217
+ }
218
+ }
219
+ if ((effPlatform === "windows" || effPlatform === "mac") &&
220
+ effPlatform === hostPlatform &&
221
+ deps.isAppDriverRequired({ test: context })) {
222
+ const driverPackage = deps.appDriverPlatforms[effPlatform]?.driverPackage;
223
+ if (driverPackage) {
224
+ addTask({
225
+ name: `driver-install:${driverPackage}`,
226
+ kind: "driver-install",
227
+ exclusiveResources: [RUNTIME_INSTALL_RESOURCE],
228
+ payload: { driverPackage, platform: effPlatform },
229
+ });
230
+ }
231
+ }
232
+ }
233
+ // The folded-in session probe keeps its historical gate: a throwaway
234
+ // driver session is only worth paying when it prevents concurrent
235
+ // first-session races (limit > 1), and it needs the browser Appium pool.
236
+ // The warm PHASE always runs; only this task kind stays gated — preserving
237
+ // the documented byte-identical serial-run behavior.
238
+ if (limit > 1 && hasAppiumPool && probeEligible) {
239
+ addTask({
240
+ name: "session-probe",
241
+ kind: "session-probe",
242
+ // Its install half mutates the shared caches, exactly like the
243
+ // dedicated install tasks (usually a memo hit by the time it runs).
244
+ exclusiveResources: [RUNTIME_INSTALL_RESOURCE],
245
+ payload: {},
246
+ });
247
+ }
248
+ return tasks;
249
+ }
250
+ /**
251
+ * Run planned warm tasks through the run's resource registry, bounded by
252
+ * WARM_POOL_LIMIT. Best-effort by contract: a task that throws is recorded
253
+ * as failed and logged as a warning — the returned promise never rejects,
254
+ * and nothing here can gate the run.
255
+ */
256
+ export async function executeWarmTasks({ tasks, registry, runTask, log, now = Date.now, }) {
257
+ const results = [];
258
+ const start = now();
259
+ await runResourceAware(tasks, WARM_POOL_LIMIT, registry, async (task) => {
260
+ const taskStart = now();
261
+ try {
262
+ const { outcome, note } = await runTask(task);
263
+ results.push({
264
+ name: task.name,
265
+ kind: task.kind,
266
+ outcome,
267
+ durationMs: now() - taskStart,
268
+ ...(note ? { note } : {}),
269
+ });
270
+ if (outcome === "failed") {
271
+ log("warning", `Warm task '${task.name}' failed (continuing)${note ? `: ${note}` : "."}`);
272
+ }
273
+ else {
274
+ log("debug", `Warm task '${task.name}': ${outcome}${note ? ` (${note})` : ""}.`);
275
+ }
276
+ }
277
+ catch (error) {
278
+ const note = error?.message ?? String(error);
279
+ results.push({
280
+ name: task.name,
281
+ kind: task.kind,
282
+ outcome: "failed",
283
+ durationMs: now() - taskStart,
284
+ note,
285
+ });
286
+ log("warning", `Warm task '${task.name}' failed (continuing): ${note}`);
287
+ }
288
+ });
289
+ return { durationMs: now() - start, tasks: results };
290
+ }
291
+ /**
292
+ * Resolve a device-boot task at boot INITIATION rather than boot completion:
293
+ * warm's job is to start the clock early, not to block on it — the first
294
+ * consuming context awaits the registry entry's `ready` promise exactly
295
+ * where it does today.
296
+ *
297
+ * `startAcquire` receives a `signalInitiated` callback the caller wires into
298
+ * the acquire deps' create/boot effects (wrapInitiationEffects).
299
+ * acquireDevice/acquireSimulator invoke those effects synchronously inside
300
+ * the ready-promise body and then synchronously register the
301
+ * `bootedByUs: true` placeholder before any microtask runs — so by the time
302
+ * the race resolves on the signal, the registry entry (with its in-flight
303
+ * `ready`) is already visible to consumers. Fast paths (registry hit,
304
+ * reuse-running, plan skip) never signal and settle through the acquire
305
+ * promise itself.
306
+ *
307
+ * The catch is chained onto the acquire promise BEFORE the race, so a boot
308
+ * that fails after the task already resolved can never surface as an
309
+ * unhandled rejection; `onError` is the caller's warn hook. acquire deletes
310
+ * its registry placeholder on failure, so a consuming context retries fresh.
311
+ */
312
+ export function raceBootInitiation({ startAcquire, onError, }) {
313
+ let initiatedResolve;
314
+ const initiated = new Promise((resolve) => {
315
+ initiatedResolve = resolve;
316
+ });
317
+ const acquired = (async () => {
318
+ try {
319
+ const result = await startAcquire(() => initiatedResolve());
320
+ if (result && typeof result === "object" && "skip" in result) {
321
+ return { outcome: "skipped", note: result.skip };
322
+ }
323
+ return { outcome: "warmed", note: "device ready" };
324
+ }
325
+ catch (error) {
326
+ onError(error);
327
+ return {
328
+ outcome: "failed",
329
+ note: error?.message ?? String(error),
330
+ };
331
+ }
332
+ })();
333
+ return Promise.race([
334
+ initiated.then(() => ({
335
+ outcome: "warmed",
336
+ note: "boot initiated",
337
+ })),
338
+ acquired,
339
+ ]);
340
+ }
341
+ //# sourceMappingURL=warmPhase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warmPhase.js","sourceRoot":"","sources":["../../src/core/warmPhase.ts"],"names":[],"mappings":"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"}