@ait-co/devtools 0.1.144 → 0.2.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.en.md +33 -217
- package/README.md +33 -246
- package/dist/in-app/auto.d.ts +1 -138
- package/dist/in-app/auto.js +28 -1102
- package/dist/in-app/auto.js.map +1 -1
- package/dist/in-app/index.d.ts +38 -547
- package/dist/in-app/index.d.ts.map +1 -1
- package/dist/in-app/index.js +62 -939
- package/dist/in-app/index.js.map +1 -1
- package/dist/mcp/cli.d.ts +1 -54
- package/dist/mcp/cli.js +33 -9720
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -88
- package/dist/mcp/server.js +36 -1076
- package/dist/mcp/server.js.map +1 -1
- package/dist/mock/index.d.ts +19 -20
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js.map +1 -1
- package/dist/panel/index.js +1 -103
- package/dist/panel/index.js.map +1 -1
- package/dist/relay-url-store-CPZAn-T5.js +107 -0
- package/dist/relay-url-store-CPZAn-T5.js.map +1 -0
- package/dist/relay-url-store-DLjlvMSA.cjs +108 -0
- package/dist/relay-url-store-DLjlvMSA.cjs.map +1 -0
- package/dist/stubs/bin-devtools-mcp.js +58 -0
- package/dist/stubs/bin-devtools-mcp.js.map +1 -0
- package/dist/stubs/bin-devtools-test.d.ts +2 -0
- package/dist/stubs/bin-devtools-test.js +55 -0
- package/dist/stubs/bin-devtools-test.js.map +1 -0
- package/dist/test-runner/config.d.ts +1 -231
- package/dist/test-runner/config.js +41 -45
- package/dist/test-runner/config.js.map +1 -1
- package/dist/{tunnel-BGT9Curk.cjs → tunnel-BKZkOyQp.cjs} +1 -1
- package/dist/{tunnel-BGT9Curk.cjs.map → tunnel-BKZkOyQp.cjs.map} +1 -1
- package/dist/{tunnel-BOKmLzBO.js → tunnel-CqSCIrdU.js} +1 -1
- package/dist/{tunnel-BOKmLzBO.js.map → tunnel-CqSCIrdU.js.map} +1 -1
- package/dist/unplugin/index.cjs +9 -18
- package/dist/unplugin/index.cjs.map +1 -1
- package/dist/unplugin/index.d.cts +22 -3
- package/dist/unplugin/index.d.cts.map +1 -1
- package/dist/unplugin/index.d.ts +23 -4
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +10 -19
- package/dist/unplugin/index.js.map +1 -1
- package/package.json +10 -25
- package/dist/attach-orchestrator-0F0m_UqQ.js +0 -1845
- package/dist/attach-orchestrator-0F0m_UqQ.js.map +0 -1
- package/dist/attach-orchestrator-D65KxFy_.js +0 -1831
- package/dist/attach-orchestrator-D65KxFy_.js.map +0 -1
- package/dist/attach-orchestrator-DL3NQ9ca.js +0 -1846
- package/dist/attach-orchestrator-DL3NQ9ca.js.map +0 -1
- package/dist/bundle-C796JIwG.d.ts +0 -159
- package/dist/bundle-C796JIwG.d.ts.map +0 -1
- package/dist/capture-DsP525OZ.d.ts +0 -58
- package/dist/capture-DsP525OZ.d.ts.map +0 -1
- package/dist/cdp-connection-rP1WdnH5.d.ts +0 -287
- package/dist/cdp-connection-rP1WdnH5.d.ts.map +0 -1
- package/dist/cell-BaLvusOl.js +0 -68
- package/dist/cell-BaLvusOl.js.map +0 -1
- package/dist/cell-CBUS3-nT.js +0 -274
- package/dist/cell-CBUS3-nT.js.map +0 -1
- package/dist/cell-EBKKpAAT.js +0 -307
- package/dist/cell-EBKKpAAT.js.map +0 -1
- package/dist/chii-relay-B3ZhjGMi.js +0 -304
- package/dist/chii-relay-B3ZhjGMi.js.map +0 -1
- package/dist/chii-relay-CGMlePMd.cjs +0 -304
- package/dist/chii-relay-CGMlePMd.cjs.map +0 -1
- package/dist/debug-server-B3ABDrRI.js +0 -456
- package/dist/debug-server-B3ABDrRI.js.map +0 -1
- package/dist/debug-server-BWhwrVXa.js +0 -1158
- package/dist/debug-server-BWhwrVXa.js.map +0 -1
- package/dist/debug-server-CfQNxxGW.js +0 -600
- package/dist/debug-server-CfQNxxGW.js.map +0 -1
- package/dist/devtools-opener-3Drge_RJ.js +0 -75
- package/dist/devtools-opener-3Drge_RJ.js.map +0 -1
- package/dist/devtools-opener-CJpEsXXQ.js +0 -76
- package/dist/devtools-opener-CJpEsXXQ.js.map +0 -1
- package/dist/devtools-opener-CxtryS8c.js +0 -75
- package/dist/devtools-opener-CxtryS8c.js.map +0 -1
- package/dist/in-app/auto.d.ts.map +0 -1
- package/dist/mcp/cli.d.ts.map +0 -1
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/pool-DcaaOwUq.d.ts +0 -14761
- package/dist/pool-DcaaOwUq.d.ts.map +0 -1
- package/dist/qr-http-server-C_lqOrgc.js +0 -1644
- package/dist/qr-http-server-C_lqOrgc.js.map +0 -1
- package/dist/qr-http-server-CopuMbub.js +0 -1644
- package/dist/qr-http-server-CopuMbub.js.map +0 -1
- package/dist/qr-http-server-DrbIVDjO.js +0 -1645
- package/dist/qr-http-server-DrbIVDjO.js.map +0 -1
- package/dist/relay-factory-N9QobQxG.js +0 -206
- package/dist/relay-factory-N9QobQxG.js.map +0 -1
- package/dist/relay-secret-store-BR0YIkNv.cjs +0 -241
- package/dist/relay-secret-store-BR0YIkNv.cjs.map +0 -1
- package/dist/relay-secret-store-Bmyleu0A.js +0 -154
- package/dist/relay-secret-store-Bmyleu0A.js.map +0 -1
- package/dist/relay-secret-store-CQenfcSL.js +0 -154
- package/dist/relay-secret-store-CQenfcSL.js.map +0 -1
- package/dist/relay-secret-store-CYM8CBIF.js +0 -240
- package/dist/relay-secret-store-CYM8CBIF.js.map +0 -1
- package/dist/relay-secret-store-DKxs7zwq.js +0 -153
- package/dist/relay-secret-store-DKxs7zwq.js.map +0 -1
- package/dist/relay-secret-store-WJ8EGkIl.js +0 -153
- package/dist/relay-secret-store-WJ8EGkIl.js.map +0 -1
- package/dist/relay-url-store-BR2XodiO.js +0 -123
- package/dist/relay-url-store-BR2XodiO.js.map +0 -1
- package/dist/relay-url-store-C1as_m5G.cjs +0 -115
- package/dist/relay-url-store-C1as_m5G.cjs.map +0 -1
- package/dist/relay-url-store-CH63fVCm.js +0 -122
- package/dist/relay-url-store-CH63fVCm.js.map +0 -1
- package/dist/relay-url-store-CzFo_84F.js +0 -114
- package/dist/relay-url-store-CzFo_84F.js.map +0 -1
- package/dist/relay-url-store-DaY1QPes.js +0 -123
- package/dist/relay-url-store-DaY1QPes.js.map +0 -1
- package/dist/relay-url-store-xmUuTjXA.js +0 -122
- package/dist/relay-url-store-xmUuTjXA.js.map +0 -1
- package/dist/relay-worker-B5HKkGUY.js +0 -832
- package/dist/relay-worker-B5HKkGUY.js.map +0 -1
- package/dist/relay-worker-YdlpZQl9.d.ts +0 -214
- package/dist/relay-worker-YdlpZQl9.d.ts.map +0 -1
- package/dist/rolldown-runtime-DGkTqVfb.js +0 -15
- package/dist/rolldown-runtime-DUslC3ob.js +0 -14
- package/dist/runtime-kn9DxOeg.d.ts +0 -249
- package/dist/runtime-kn9DxOeg.d.ts.map +0 -1
- package/dist/test-runner/bin.js +0 -2584
- package/dist/test-runner/bin.js.map +0 -1
- package/dist/test-runner/bridge-stub.d.ts +0 -125
- package/dist/test-runner/bridge-stub.d.ts.map +0 -1
- package/dist/test-runner/bridge-stub.js +0 -92
- package/dist/test-runner/bridge-stub.js.map +0 -1
- package/dist/test-runner/bundle.d.ts +0 -2
- package/dist/test-runner/bundle.js +0 -439
- package/dist/test-runner/bundle.js.map +0 -1
- package/dist/test-runner/capture.d.ts +0 -2
- package/dist/test-runner/capture.js +0 -44
- package/dist/test-runner/capture.js.map +0 -1
- package/dist/test-runner/config.d.ts.map +0 -1
- package/dist/test-runner/method-pace.d.ts +0 -82
- package/dist/test-runner/method-pace.d.ts.map +0 -1
- package/dist/test-runner/method-pace.js +0 -120
- package/dist/test-runner/method-pace.js.map +0 -1
- package/dist/test-runner/pool.d.ts +0 -2
- package/dist/test-runner/pool.js +0 -136
- package/dist/test-runner/pool.js.map +0 -1
- package/dist/test-runner/relay-factory.d.ts +0 -11245
- package/dist/test-runner/relay-factory.d.ts.map +0 -1
- package/dist/test-runner/relay-factory.js +0 -206
- package/dist/test-runner/relay-factory.js.map +0 -1
- package/dist/test-runner/relay-worker.d.ts +0 -2
- package/dist/test-runner/relay-worker.js +0 -2
- package/dist/test-runner/report.d.ts +0 -163
- package/dist/test-runner/report.d.ts.map +0 -1
- package/dist/test-runner/report.js +0 -198
- package/dist/test-runner/report.js.map +0 -1
- package/dist/test-runner/rpc.d.ts +0 -56
- package/dist/test-runner/rpc.d.ts.map +0 -1
- package/dist/test-runner/rpc.js +0 -98
- package/dist/test-runner/rpc.js.map +0 -1
- package/dist/test-runner/runtime.d.ts +0 -2
- package/dist/test-runner/runtime.js +0 -659
- package/dist/test-runner/runtime.js.map +0 -1
- package/dist/test-runner/task-graph.d.ts +0 -38
- package/dist/test-runner/task-graph.d.ts.map +0 -1
- package/dist/test-runner/task-graph.js +0 -182
- package/dist/test-runner/task-graph.js.map +0 -1
- package/dist/throttle-DKKzX1qC.js +0 -59
- package/dist/throttle-DKKzX1qC.js.map +0 -1
- package/dist/totp-BqmCLSNA.js +0 -189
- package/dist/totp-BqmCLSNA.js.map +0 -1
- package/dist/totp-CMHR5lsW.cjs +0 -191
- package/dist/totp-CMHR5lsW.cjs.map +0 -1
- package/dist/totp-CZLLKfOC.js +0 -200
- package/dist/totp-CZLLKfOC.js.map +0 -1
- package/dist/totp-DAxys-r0.js +0 -199
- package/dist/totp-DAxys-r0.js.map +0 -1
- package/dist/totp-DfekTBk3.js +0 -211
- package/dist/totp-DfekTBk3.js.map +0 -1
- package/dist/totp-Dwft0Kz7.js +0 -3
- package/dist/totp-WY6l0ysP.js +0 -190
- package/dist/totp-WY6l0ysP.js.map +0 -1
- /package/dist/{test-runner/bin.d.ts → stubs/bin-devtools-mcp.d.ts} +0 -0
|
@@ -1,659 +0,0 @@
|
|
|
1
|
-
import { r as isThrottledError } from "../throttle-DKKzX1qC.js";
|
|
2
|
-
//#region src/test-runner/runtime.ts
|
|
3
|
-
/**
|
|
4
|
-
* Thin test runtime for WebView execution.
|
|
5
|
-
*
|
|
6
|
-
* This file is bundled by `bundle.ts` together with the user's test file
|
|
7
|
-
* into a single IIFE injected into the WebView via `Runtime.evaluate`.
|
|
8
|
-
* It MUST stay browser-compatible — no Node.js APIs allowed.
|
|
9
|
-
*
|
|
10
|
-
* Design: rather than shipping @vitest/runner verbatim into a WebView (where
|
|
11
|
-
* its Node-side internals cause issues), this runtime provides a minimal
|
|
12
|
-
* compatible API surface — describe/it/test/expect globals — collects results
|
|
13
|
-
* into a plain JSON-safe object, and exports `runTestModule` as the entry point.
|
|
14
|
-
*
|
|
15
|
-
* @vitest/runner and @vitest/expect are listed as dependencies so that the
|
|
16
|
-
* package's type contracts are available and so the browser-compatible subsets
|
|
17
|
-
* can be referenced. The Vitest custom pool that drives this runtime through
|
|
18
|
-
* Vitest's `PoolRunnerInitializer` lives in `pool.ts`.
|
|
19
|
-
*
|
|
20
|
-
* NOTE: this file is imported by type from Node-side code (rpc.ts / relay-worker.ts)
|
|
21
|
-
* for the RunReport / TestResult type shapes. The runtime ITSELF is not imported
|
|
22
|
-
* at runtime on the Node side — only the types are used.
|
|
23
|
-
*/
|
|
24
|
-
/** Backoff delays (ms) between throttle-retry attempts: 1s, then 2s. */
|
|
25
|
-
const TEST_RETRY_BACKOFF_MS = [1e3, 2e3];
|
|
26
|
-
/** Max retry attempts per test after the initial run (devtools#767: "최대 2회 재시도"). */
|
|
27
|
-
const TEST_MAX_RETRIES = TEST_RETRY_BACKOFF_MS.length;
|
|
28
|
-
/** Real `setTimeout`-backed sleep — the production default for {@link RunTestModuleOptions.sleep}. */
|
|
29
|
-
const DEFAULT_SLEEP = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
30
|
-
/**
|
|
31
|
-
* Renders a thrown value into a `TestResult.error` string. Handles three
|
|
32
|
-
* shapes:
|
|
33
|
-
* - a real `Error` (or subclass) — its `.message`;
|
|
34
|
-
* - an error-LIKE plain object with a string `.message` (the 2.x native
|
|
35
|
-
* bridge envelope this test-runner observes, e.g.
|
|
36
|
-
* `{name, code, userInfo, moduleName, __isError}` — devtools#767's
|
|
37
|
-
* `APP_BRIDGE_THROTTLED` rejections are exactly this shape, not an
|
|
38
|
-
* `Error` instance) — its `.message` field;
|
|
39
|
-
* - anything else — `String(e)` (the pre-#767 fallback, unchanged).
|
|
40
|
-
*
|
|
41
|
-
* Without the middle case, a native envelope's `.message` (the only useful
|
|
42
|
-
* diagnostic text) was discarded in favor of the useless `"[object Object]"`.
|
|
43
|
-
*/
|
|
44
|
-
function stringifyThrown(e) {
|
|
45
|
-
if (e instanceof Error) return e.message;
|
|
46
|
-
if (typeof e === "object" && e !== null) {
|
|
47
|
-
const rec = e;
|
|
48
|
-
if (typeof rec.message === "string") return rec.message;
|
|
49
|
-
}
|
|
50
|
-
return String(e);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Brand property that tags asymmetric matcher markers (`expect.any(String)`,
|
|
54
|
-
* `expect.objectContaining(...)`, etc). A reserved string key is used as the
|
|
55
|
-
* brand so the guard stays a plain own-property check — markers are only ever
|
|
56
|
-
* compared in-process by reference, so no cross-realm Symbol coordination is
|
|
57
|
-
* needed.
|
|
58
|
-
*/
|
|
59
|
-
const ASYMMETRIC_BRAND = "$$asymmetricMatch";
|
|
60
|
-
/** Narrowing guard: is `v` an asymmetric matcher marker? */
|
|
61
|
-
function isAsymmetric(v) {
|
|
62
|
-
return typeof v === "object" && v !== null && v[ASYMMETRIC_BRAND] === true && typeof v.asymmetricMatch === "function";
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* `expect.any(Ctor)` — matches a value by its constructor. Primitive wrappers
|
|
66
|
-
* (`String`/`Number`/`Boolean`) are matched by `typeof` (so the unboxed
|
|
67
|
-
* primitive matches) AND by `instanceof` (so a boxed wrapper instance also
|
|
68
|
-
* matches). `BigInt`/`Symbol` match by `typeof`. `Object` matches any non-null
|
|
69
|
-
* object (NOT functions, matching vitest), `Array` uses `Array.isArray`,
|
|
70
|
-
* `Function` uses `typeof === 'function'`, and any other constructor (user
|
|
71
|
-
* classes) falls back to `instanceof`.
|
|
72
|
-
*/
|
|
73
|
-
function makeAny(ctor) {
|
|
74
|
-
const name = ctor.name ?? String(ctor);
|
|
75
|
-
const ctorAsFn = ctor;
|
|
76
|
-
return {
|
|
77
|
-
[ASYMMETRIC_BRAND]: true,
|
|
78
|
-
toString: () => `Any<${name}>`,
|
|
79
|
-
asymmetricMatch(actual) {
|
|
80
|
-
if (actual === null || actual === void 0) return false;
|
|
81
|
-
switch (ctor) {
|
|
82
|
-
case String: return typeof actual === "string" || actual instanceof String;
|
|
83
|
-
case Number: return typeof actual === "number" || actual instanceof Number;
|
|
84
|
-
case Boolean: return typeof actual === "boolean" || actual instanceof Boolean;
|
|
85
|
-
case BigInt: return typeof actual === "bigint";
|
|
86
|
-
case Symbol: return typeof actual === "symbol";
|
|
87
|
-
case Function: return typeof actual === "function";
|
|
88
|
-
case Object: return typeof actual === "object";
|
|
89
|
-
case Array: return Array.isArray(actual);
|
|
90
|
-
default: return ctorAsFn ? actual instanceof ctorAsFn : false;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
/** `expect.anything()` — matches any value except `null`/`undefined`. */
|
|
96
|
-
function makeAnything() {
|
|
97
|
-
return {
|
|
98
|
-
[ASYMMETRIC_BRAND]: true,
|
|
99
|
-
toString: () => "Anything",
|
|
100
|
-
asymmetricMatch: (actual) => actual !== null && actual !== void 0
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
/** `expect.objectContaining(obj)` — partial-match every key of `obj` on `actual`. */
|
|
104
|
-
function makeObjectContaining(expected) {
|
|
105
|
-
return {
|
|
106
|
-
[ASYMMETRIC_BRAND]: true,
|
|
107
|
-
toString: () => `ObjectContaining<${safeStringify(expected)}>`,
|
|
108
|
-
asymmetricMatch: (actual) => deepMatchObject(actual, expected)
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
/** `expect.arrayContaining(arr)` — `actual` is an array containing each element of `arr`. */
|
|
112
|
-
function makeArrayContaining(expected) {
|
|
113
|
-
return {
|
|
114
|
-
[ASYMMETRIC_BRAND]: true,
|
|
115
|
-
toString: () => `ArrayContaining<${safeStringify(expected)}>`,
|
|
116
|
-
asymmetricMatch(actual) {
|
|
117
|
-
if (!Array.isArray(actual)) return false;
|
|
118
|
-
return expected.every((exp) => actual.some((act) => isAsymmetric(exp) ? exp.asymmetricMatch(act) : deepEqual(act, exp)));
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
/** `expect.stringContaining(sub)` — `actual` is a string containing `sub`. */
|
|
123
|
-
function makeStringContaining(sub) {
|
|
124
|
-
return {
|
|
125
|
-
[ASYMMETRIC_BRAND]: true,
|
|
126
|
-
toString: () => `StringContaining<${sub}>`,
|
|
127
|
-
asymmetricMatch: (actual) => typeof actual === "string" && actual.includes(sub)
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
/** `expect.stringMatching(re)` — `actual` is a string matching `re` (string or RegExp). */
|
|
131
|
-
function makeStringMatching(re) {
|
|
132
|
-
const pattern = typeof re === "string" ? new RegExp(re) : re;
|
|
133
|
-
return {
|
|
134
|
-
[ASYMMETRIC_BRAND]: true,
|
|
135
|
-
toString: () => `StringMatching<${String(pattern)}>`,
|
|
136
|
-
asymmetricMatch: (actual) => typeof actual === "string" && pattern.test(actual)
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
/** JSON.stringify that never throws (cycles/BigInt) — for failure messages. */
|
|
140
|
-
function safeStringify(v) {
|
|
141
|
-
try {
|
|
142
|
-
return JSON.stringify(v, (_k, val) => isAsymmetric(val) ? val.toString() : typeof val === "bigint" ? `${val}n` : val) ?? String(v);
|
|
143
|
-
} catch {
|
|
144
|
-
return String(v);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Recursive structural equality — replaces JSON.stringify comparison to
|
|
149
|
-
* handle key-order differences and undefined values correctly.
|
|
150
|
-
*
|
|
151
|
-
* When the `b` (expected) side is an asymmetric marker, its `asymmetricMatch`
|
|
152
|
-
* predicate decides the result instead of structural comparison — markers are
|
|
153
|
-
* placeholders, not plain objects, so deep-comparing them never matches.
|
|
154
|
-
*/
|
|
155
|
-
function deepEqual(a, b) {
|
|
156
|
-
if (isAsymmetric(b)) return b.asymmetricMatch(a);
|
|
157
|
-
if (Object.is(a, b)) return true;
|
|
158
|
-
if (a === null || b === null) return false;
|
|
159
|
-
if (typeof a !== "object" || typeof b !== "object") return false;
|
|
160
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
161
|
-
if (a.length !== b.length) return false;
|
|
162
|
-
for (let i = 0; i < a.length; i++) if (!deepEqual(a[i], b[i])) return false;
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
if (Array.isArray(a) || Array.isArray(b)) return false;
|
|
166
|
-
const aObj = a;
|
|
167
|
-
const bObj = b;
|
|
168
|
-
const aKeys = Object.keys(aObj);
|
|
169
|
-
const bKeys = Object.keys(bObj);
|
|
170
|
-
if (aKeys.length !== bKeys.length) return false;
|
|
171
|
-
for (const key of aKeys) {
|
|
172
|
-
if (!Object.hasOwn(bObj, key)) return false;
|
|
173
|
-
if (!deepEqual(aObj[key], bObj[key])) return false;
|
|
174
|
-
}
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Partial-match: every key in `expected` must exist in `received` with a
|
|
179
|
-
* recursively matching value. Extra keys in `received` are ignored.
|
|
180
|
-
*
|
|
181
|
-
* As in `deepEqual`, an asymmetric marker on the `expected` side delegates to
|
|
182
|
-
* its `asymmetricMatch` predicate rather than being compared structurally.
|
|
183
|
-
*/
|
|
184
|
-
function deepMatchObject(received, expected) {
|
|
185
|
-
if (isAsymmetric(expected)) return expected.asymmetricMatch(received);
|
|
186
|
-
if (Object.is(received, expected)) return true;
|
|
187
|
-
if (expected === null || received === null) return Object.is(received, expected);
|
|
188
|
-
if (typeof expected !== "object" || typeof received !== "object") return Object.is(received, expected);
|
|
189
|
-
if (Array.isArray(expected) && Array.isArray(received)) {
|
|
190
|
-
if (expected.length !== received.length) return false;
|
|
191
|
-
for (let i = 0; i < expected.length; i++) if (!deepMatchObject(received[i], expected[i])) return false;
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
if (Array.isArray(expected) || Array.isArray(received)) return false;
|
|
195
|
-
const expObj = expected;
|
|
196
|
-
const recObj = received;
|
|
197
|
-
for (const key of Object.keys(expObj)) {
|
|
198
|
-
if (!Object.hasOwn(recObj, key)) return false;
|
|
199
|
-
if (!deepMatchObject(recObj[key], expObj[key])) return false;
|
|
200
|
-
}
|
|
201
|
-
return true;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Resolves a dot-separated property path on an object.
|
|
205
|
-
* Returns `{ found: true, value }` or `{ found: false }`.
|
|
206
|
-
*/
|
|
207
|
-
function resolvePath(obj, dotPath) {
|
|
208
|
-
const parts = dotPath.split(".");
|
|
209
|
-
let cur = obj;
|
|
210
|
-
for (const part of parts) {
|
|
211
|
-
if (cur === null || cur === void 0 || typeof cur !== "object") return { found: false };
|
|
212
|
-
const record = cur;
|
|
213
|
-
if (!Object.hasOwn(record, part)) return { found: false };
|
|
214
|
-
cur = record[part];
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
found: true,
|
|
218
|
-
value: cur
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
/** Thrown by expect matchers on failure. */
|
|
222
|
-
var AssertionError = class extends Error {
|
|
223
|
-
constructor(message) {
|
|
224
|
-
super(message);
|
|
225
|
-
this.name = "AssertionError";
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
/** Minimal expect builder compatible with Vitest's jest-style API. */
|
|
229
|
-
var Expectation = class Expectation {
|
|
230
|
-
#received;
|
|
231
|
-
#negated = false;
|
|
232
|
-
constructor(received) {
|
|
233
|
-
this.#received = received;
|
|
234
|
-
}
|
|
235
|
-
get not() {
|
|
236
|
-
const neg = new Expectation(this.#received);
|
|
237
|
-
neg.#negated = true;
|
|
238
|
-
return neg;
|
|
239
|
-
}
|
|
240
|
-
#assert(pass, msg) {
|
|
241
|
-
if (!(this.#negated ? !pass : pass)) throw new AssertionError(this.#negated ? `Expected NOT: ${msg}` : msg);
|
|
242
|
-
}
|
|
243
|
-
toBe(expected) {
|
|
244
|
-
this.#assert(Object.is(this.#received, expected), `Expected ${String(expected)}, received ${String(this.#received)}`);
|
|
245
|
-
}
|
|
246
|
-
toEqual(expected) {
|
|
247
|
-
this.#assert(deepEqual(this.#received, expected), `Expected ${JSON.stringify(expected)}, received ${JSON.stringify(this.#received)}`);
|
|
248
|
-
}
|
|
249
|
-
toBeTruthy() {
|
|
250
|
-
this.#assert(Boolean(this.#received), `Expected truthy, received ${String(this.#received)}`);
|
|
251
|
-
}
|
|
252
|
-
toBeFalsy() {
|
|
253
|
-
this.#assert(!this.#received, `Expected falsy, received ${String(this.#received)}`);
|
|
254
|
-
}
|
|
255
|
-
toBeNull() {
|
|
256
|
-
this.#assert(this.#received === null, `Expected null, received ${String(this.#received)}`);
|
|
257
|
-
}
|
|
258
|
-
toBeUndefined() {
|
|
259
|
-
this.#assert(this.#received === void 0, `Expected undefined, received ${String(this.#received)}`);
|
|
260
|
-
}
|
|
261
|
-
toBeGreaterThan(n) {
|
|
262
|
-
this.#assert(typeof this.#received === "number" && this.#received > n, `Expected > ${n}, received ${String(this.#received)}`);
|
|
263
|
-
}
|
|
264
|
-
toBeLessThan(n) {
|
|
265
|
-
this.#assert(typeof this.#received === "number" && this.#received < n, `Expected < ${n}, received ${String(this.#received)}`);
|
|
266
|
-
}
|
|
267
|
-
toContain(sub) {
|
|
268
|
-
if (Array.isArray(this.#received)) {
|
|
269
|
-
this.#assert(this.#received.includes(sub), `Expected array to contain ${JSON.stringify(sub)}, received ${JSON.stringify(this.#received)}`);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
this.#assert(typeof this.#received === "string" && typeof sub === "string" && this.#received.includes(sub), `Expected to contain "${String(sub)}", received "${String(this.#received)}"`);
|
|
273
|
-
}
|
|
274
|
-
toThrow(msgFragment) {
|
|
275
|
-
if (typeof this.#received !== "function") throw new AssertionError("toThrow: expected a function");
|
|
276
|
-
let threw = false;
|
|
277
|
-
let errorMsg = "";
|
|
278
|
-
try {
|
|
279
|
-
this.#received();
|
|
280
|
-
} catch (e) {
|
|
281
|
-
threw = true;
|
|
282
|
-
errorMsg = e instanceof Error ? e.message : String(e);
|
|
283
|
-
}
|
|
284
|
-
if (msgFragment !== void 0) this.#assert(threw && errorMsg.includes(msgFragment), `Expected to throw containing "${msgFragment}", got "${errorMsg}"`);
|
|
285
|
-
else this.#assert(threw, "Expected function to throw");
|
|
286
|
-
}
|
|
287
|
-
toMatchObject(expected) {
|
|
288
|
-
this.#assert(deepMatchObject(this.#received, expected), `Expected object to match ${JSON.stringify(expected)}, received ${JSON.stringify(this.#received)}`);
|
|
289
|
-
}
|
|
290
|
-
toHaveProperty(dotPath, ...rest) {
|
|
291
|
-
const { found, value: actual } = resolvePath(this.#received, dotPath);
|
|
292
|
-
if (rest.length > 0) {
|
|
293
|
-
const value = rest[0];
|
|
294
|
-
this.#assert(found && deepEqual(actual, value), `Expected property "${dotPath}" to equal ${JSON.stringify(value)}, got ${JSON.stringify(actual)}`);
|
|
295
|
-
} else this.#assert(found, `Expected property "${dotPath}" to exist`);
|
|
296
|
-
}
|
|
297
|
-
toBeInstanceOf(ctor) {
|
|
298
|
-
this.#assert(this.#received instanceof ctor, `Expected instance of ${ctor.name ?? String(ctor)}, received ${String(this.#received)}`);
|
|
299
|
-
}
|
|
300
|
-
toBeTypeOf(typeStr) {
|
|
301
|
-
this.#assert(typeof this.#received === typeStr, `Expected typeof "${typeStr}", received "${typeof this.#received}"`);
|
|
302
|
-
}
|
|
303
|
-
toHaveLength(n) {
|
|
304
|
-
const length = this.#received?.length;
|
|
305
|
-
this.#assert(typeof length === "number" && length === n, `Expected length ${n}, received ${typeof length === "number" ? length : String(this.#received)}`);
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
/** The `expect` function installed as a global. */
|
|
309
|
-
const expect = ((received) => new Expectation(received));
|
|
310
|
-
expect.any = makeAny;
|
|
311
|
-
expect.anything = makeAnything;
|
|
312
|
-
expect.objectContaining = makeObjectContaining;
|
|
313
|
-
expect.arrayContaining = makeArrayContaining;
|
|
314
|
-
expect.stringContaining = makeStringContaining;
|
|
315
|
-
expect.stringMatching = makeStringMatching;
|
|
316
|
-
/**
|
|
317
|
-
* Internal sentinel thrown by `ctx.skip()` to unwind the test body early.
|
|
318
|
-
* Caught by the run loop (never surfaced as a failure) — see `runTestModule`'s
|
|
319
|
-
* test-execution `catch` branch.
|
|
320
|
-
*/
|
|
321
|
-
var InPageSkipSentinel = class {
|
|
322
|
-
constructor(note) {
|
|
323
|
-
this.note = note;
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
function _makeTestContext(name) {
|
|
327
|
-
return {
|
|
328
|
-
skip(condition, note) {
|
|
329
|
-
if (condition === void 0 || condition) throw new InPageSkipSentinel(note);
|
|
330
|
-
},
|
|
331
|
-
task: { name }
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
const _pendingTests = [];
|
|
335
|
-
const _suiteStack = [];
|
|
336
|
-
/** Registers a suite scope; calls `fn` synchronously to collect inner tests. */
|
|
337
|
-
function describe(name, fn) {
|
|
338
|
-
_suiteStack.push(name);
|
|
339
|
-
fn();
|
|
340
|
-
_suiteStack.pop();
|
|
341
|
-
}
|
|
342
|
-
/** Registers a test. */
|
|
343
|
-
function it(name, fn) {
|
|
344
|
-
_pendingTests.push({
|
|
345
|
-
suitePath: [..._suiteStack],
|
|
346
|
-
name,
|
|
347
|
-
fn,
|
|
348
|
-
skip: false
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
/** Alias for `it`. */
|
|
352
|
-
const test = it;
|
|
353
|
-
/** Skipped test — registered but not executed. */
|
|
354
|
-
describe.skip = (name, _fn) => {};
|
|
355
|
-
it.skip = (name, _fn) => {
|
|
356
|
-
_pendingTests.push({
|
|
357
|
-
suitePath: [..._suiteStack],
|
|
358
|
-
name,
|
|
359
|
-
fn: () => {},
|
|
360
|
-
skip: true
|
|
361
|
-
});
|
|
362
|
-
};
|
|
363
|
-
test.skip = it.skip;
|
|
364
|
-
function _conditionalIt(skip) {
|
|
365
|
-
return (name, fn) => {
|
|
366
|
-
_pendingTests.push({
|
|
367
|
-
suitePath: [..._suiteStack],
|
|
368
|
-
name,
|
|
369
|
-
fn,
|
|
370
|
-
skip
|
|
371
|
-
});
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
it.skipIf = (cond) => _conditionalIt(Boolean(cond));
|
|
375
|
-
it.runIf = (cond) => _conditionalIt(!cond);
|
|
376
|
-
test.skipIf = it.skipIf;
|
|
377
|
-
test.runIf = it.runIf;
|
|
378
|
-
describe.skipIf = (cond) => cond ? (name, _fn) => void 0 : (name, fn) => describe(name, fn);
|
|
379
|
-
describe.runIf = (cond) => cond ? (name, fn) => describe(name, fn) : (name, _fn) => void 0;
|
|
380
|
-
const _hooks = [];
|
|
381
|
-
function _registerHook(type, fn) {
|
|
382
|
-
_hooks.push({
|
|
383
|
-
suitePath: [..._suiteStack],
|
|
384
|
-
type,
|
|
385
|
-
fn
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Returns hooks whose suitePath is a prefix of `testSuitePath`
|
|
390
|
-
* (i.e. the hook's scope contains the test).
|
|
391
|
-
*/
|
|
392
|
-
function _hooksFor(type, testSuitePath) {
|
|
393
|
-
return _hooks.filter((h) => {
|
|
394
|
-
if (h.type !== type) return false;
|
|
395
|
-
if (h.suitePath.length > testSuitePath.length) return false;
|
|
396
|
-
for (let i = 0; i < h.suitePath.length; i++) if (h.suitePath[i] !== testSuitePath[i]) return false;
|
|
397
|
-
return true;
|
|
398
|
-
}).map((h) => h.fn);
|
|
399
|
-
}
|
|
400
|
-
/** Runs an array of hook functions in order, awaiting each. */
|
|
401
|
-
async function _runHooks(fns) {
|
|
402
|
-
for (const fn of fns) try {
|
|
403
|
-
await fn();
|
|
404
|
-
} catch (e) {
|
|
405
|
-
return e instanceof Error ? e : new Error(String(e));
|
|
406
|
-
}
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
function beforeAll(fn) {
|
|
410
|
-
_registerHook("beforeAll", fn);
|
|
411
|
-
}
|
|
412
|
-
function afterAll(fn) {
|
|
413
|
-
_registerHook("afterAll", fn);
|
|
414
|
-
}
|
|
415
|
-
function beforeEach(fn) {
|
|
416
|
-
_registerHook("beforeEach", fn);
|
|
417
|
-
}
|
|
418
|
-
function afterEach(fn) {
|
|
419
|
-
_registerHook("afterEach", fn);
|
|
420
|
-
}
|
|
421
|
-
const _spyRegistry = [];
|
|
422
|
-
function _createMockFn(impl) {
|
|
423
|
-
let currentImpl = impl;
|
|
424
|
-
const calls = [];
|
|
425
|
-
const mockFn = ((...args) => {
|
|
426
|
-
const returnValue = currentImpl ? currentImpl(...args) : void 0;
|
|
427
|
-
calls.push({
|
|
428
|
-
args,
|
|
429
|
-
returnValue
|
|
430
|
-
});
|
|
431
|
-
return returnValue;
|
|
432
|
-
});
|
|
433
|
-
mockFn.mock = { calls };
|
|
434
|
-
mockFn.mockImplementation = function(fn) {
|
|
435
|
-
currentImpl = fn;
|
|
436
|
-
return this;
|
|
437
|
-
};
|
|
438
|
-
mockFn.mockReturnValue = function(value) {
|
|
439
|
-
currentImpl = () => value;
|
|
440
|
-
return this;
|
|
441
|
-
};
|
|
442
|
-
mockFn.mockRestore = () => {};
|
|
443
|
-
return mockFn;
|
|
444
|
-
}
|
|
445
|
-
const vi = {
|
|
446
|
-
spyOn(obj, method) {
|
|
447
|
-
const original = obj[method];
|
|
448
|
-
const spy = _createMockFn(typeof original === "function" ? original : void 0);
|
|
449
|
-
spy.mockRestore = () => {
|
|
450
|
-
obj[method] = original;
|
|
451
|
-
};
|
|
452
|
-
_spyRegistry.push({
|
|
453
|
-
obj,
|
|
454
|
-
method,
|
|
455
|
-
original
|
|
456
|
-
});
|
|
457
|
-
obj[method] = spy;
|
|
458
|
-
return spy;
|
|
459
|
-
},
|
|
460
|
-
fn(impl) {
|
|
461
|
-
return _createMockFn(impl);
|
|
462
|
-
},
|
|
463
|
-
restoreAllMocks() {
|
|
464
|
-
for (const { obj, method, original } of _spyRegistry) obj[method] = original;
|
|
465
|
-
_spyRegistry.length = 0;
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
/**
|
|
469
|
-
* Runtime globals object — exported for direct use in unit tests so that
|
|
470
|
-
* test factories can reference runtime's own `it`/`expect`/`beforeAll`/etc.
|
|
471
|
-
* without depending on `globalThis` injection.
|
|
472
|
-
*
|
|
473
|
-
* In a real WebView bundle these are accessed via globals installed by
|
|
474
|
-
* `runTestModule`; in Node tests, import from here directly.
|
|
475
|
-
*/
|
|
476
|
-
const runtimeGlobals = {
|
|
477
|
-
describe,
|
|
478
|
-
it,
|
|
479
|
-
test,
|
|
480
|
-
expect,
|
|
481
|
-
beforeAll,
|
|
482
|
-
afterAll,
|
|
483
|
-
beforeEach,
|
|
484
|
-
afterEach,
|
|
485
|
-
vi
|
|
486
|
-
};
|
|
487
|
-
/**
|
|
488
|
-
* Installs describe/it/test/expect/afterAll/afterEach/beforeAll/beforeEach/vi
|
|
489
|
-
* as globals, invokes `moduleFactory` to register the user's tests, then
|
|
490
|
-
* executes them and returns a RunReport.
|
|
491
|
-
*
|
|
492
|
-
* This function is exported as `__testBundle.runTestModule` by the IIFE wrapper
|
|
493
|
-
* that bundle.ts generates. The Node-side rpc.ts calls it via `Runtime.evaluate`.
|
|
494
|
-
*
|
|
495
|
-
* @param moduleFactory - A zero-argument function that contains the user's
|
|
496
|
-
* top-level test code (describe/it/test calls). The bundler wraps the entire
|
|
497
|
-
* test module so that its top-level statements become the body of this factory.
|
|
498
|
-
* @param opts - Test-only overrides (see {@link RunTestModuleOptions}). Never
|
|
499
|
-
* passed by the generated bundle (`rpc.ts#buildRunTestsExpression` calls
|
|
500
|
-
* `runTestModule(__userFactory)` with exactly one argument) — this second
|
|
501
|
-
* parameter exists so unit tests can inject a fake sleep and assert the
|
|
502
|
-
* THROTTLED-retry timing without real delays.
|
|
503
|
-
*/
|
|
504
|
-
async function runTestModule(moduleFactory, opts) {
|
|
505
|
-
const sleep = opts?.sleep ?? DEFAULT_SLEEP;
|
|
506
|
-
_pendingTests.length = 0;
|
|
507
|
-
_suiteStack.length = 0;
|
|
508
|
-
_hooks.length = 0;
|
|
509
|
-
_spyRegistry.length = 0;
|
|
510
|
-
const g = globalThis;
|
|
511
|
-
g.describe = describe;
|
|
512
|
-
g.it = it;
|
|
513
|
-
g.test = test;
|
|
514
|
-
g.expect = expect;
|
|
515
|
-
g.beforeAll = beforeAll;
|
|
516
|
-
g.afterAll = afterAll;
|
|
517
|
-
g.beforeEach = beforeEach;
|
|
518
|
-
g.afterEach = afterEach;
|
|
519
|
-
g.vi = vi;
|
|
520
|
-
if (moduleFactory) await moduleFactory();
|
|
521
|
-
const wallStart = Date.now();
|
|
522
|
-
const startedAt = new Date(wallStart).toISOString();
|
|
523
|
-
const results = [];
|
|
524
|
-
const firedBeforeAll = /* @__PURE__ */ new Set();
|
|
525
|
-
const lastIndexForScope = /* @__PURE__ */ new Map();
|
|
526
|
-
for (let i = 0; i < _pendingTests.length; i++) {
|
|
527
|
-
const key = _pendingTests[i].suitePath.join("\0");
|
|
528
|
-
lastIndexForScope.set(key, i);
|
|
529
|
-
const path = _pendingTests[i].suitePath;
|
|
530
|
-
for (let depth = 0; depth < path.length; depth++) {
|
|
531
|
-
const parentKey = path.slice(0, depth).join("\0");
|
|
532
|
-
const cur = lastIndexForScope.get(parentKey) ?? -1;
|
|
533
|
-
if (i > cur) lastIndexForScope.set(parentKey, i);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
const MODULE_KEY = "";
|
|
537
|
-
if (!lastIndexForScope.has(MODULE_KEY) && _pendingTests.length > 0) lastIndexForScope.set(MODULE_KEY, _pendingTests.length - 1);
|
|
538
|
-
if (_pendingTests.length > 0) {
|
|
539
|
-
const baErr = await _runHooks(_hooksFor("beforeAll", []));
|
|
540
|
-
firedBeforeAll.add(MODULE_KEY);
|
|
541
|
-
if (baErr) {
|
|
542
|
-
for (const pending of _pendingTests) {
|
|
543
|
-
const fullName = [...pending.suitePath, pending.name].join(" > ");
|
|
544
|
-
results.push({
|
|
545
|
-
name: fullName,
|
|
546
|
-
status: "fail",
|
|
547
|
-
duration: 0,
|
|
548
|
-
error: `beforeAll failed: ${baErr.message}`
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
const duration = Date.now() - wallStart;
|
|
552
|
-
const passed = results.filter((r) => r.status === "pass").length;
|
|
553
|
-
const failed = results.filter((r) => r.status === "fail").length;
|
|
554
|
-
const skipped = results.filter((r) => r.status === "skip").length;
|
|
555
|
-
await _runHooks(_hooksFor("afterAll", []));
|
|
556
|
-
return {
|
|
557
|
-
startedAt,
|
|
558
|
-
duration,
|
|
559
|
-
passed,
|
|
560
|
-
failed,
|
|
561
|
-
skipped,
|
|
562
|
-
tests: results
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
const paceMs = (() => {
|
|
567
|
-
const raw = globalThis.__AIT_PACE_MS__;
|
|
568
|
-
return typeof raw === "number" && raw > 0 ? raw : 0;
|
|
569
|
-
})();
|
|
570
|
-
let ranFirstTest = false;
|
|
571
|
-
for (let i = 0; i < _pendingTests.length; i++) {
|
|
572
|
-
const pending = _pendingTests[i];
|
|
573
|
-
const fullName = [...pending.suitePath, pending.name].join(" > ");
|
|
574
|
-
if (pending.skip) {
|
|
575
|
-
results.push({
|
|
576
|
-
name: fullName,
|
|
577
|
-
status: "skip",
|
|
578
|
-
duration: 0
|
|
579
|
-
});
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
if (paceMs > 0 && ranFirstTest) await sleep(paceMs);
|
|
583
|
-
ranFirstTest = true;
|
|
584
|
-
for (let depth = 1; depth <= pending.suitePath.length; depth++) {
|
|
585
|
-
const scopeKey = pending.suitePath.slice(0, depth).join("\0");
|
|
586
|
-
if (!firedBeforeAll.has(scopeKey)) {
|
|
587
|
-
const baErr = await _runHooks(_hooks.filter((h) => h.type === "beforeAll" && h.suitePath.join("\0") === scopeKey).map((h) => h.fn));
|
|
588
|
-
firedBeforeAll.add(scopeKey);
|
|
589
|
-
if (baErr) results.push({
|
|
590
|
-
name: fullName,
|
|
591
|
-
status: "fail",
|
|
592
|
-
duration: 0,
|
|
593
|
-
error: `beforeAll failed: ${baErr.message}`
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
const beErr = await _runHooks(_hooksFor("beforeEach", pending.suitePath));
|
|
598
|
-
const tStart = Date.now();
|
|
599
|
-
let testErr;
|
|
600
|
-
let inPageSkip;
|
|
601
|
-
let throttleRetries = 0;
|
|
602
|
-
if (beErr) testErr = `beforeEach failed: ${beErr.message}`;
|
|
603
|
-
else for (let attempt = 0;; attempt++) try {
|
|
604
|
-
await pending.fn(_makeTestContext(fullName));
|
|
605
|
-
testErr = void 0;
|
|
606
|
-
break;
|
|
607
|
-
} catch (e) {
|
|
608
|
-
if (e instanceof InPageSkipSentinel) {
|
|
609
|
-
inPageSkip = e;
|
|
610
|
-
break;
|
|
611
|
-
}
|
|
612
|
-
testErr = stringifyThrown(e);
|
|
613
|
-
if (isThrottledError(e) && attempt < TEST_MAX_RETRIES) {
|
|
614
|
-
throttleRetries += 1;
|
|
615
|
-
await sleep(TEST_RETRY_BACKOFF_MS[attempt]);
|
|
616
|
-
continue;
|
|
617
|
-
}
|
|
618
|
-
break;
|
|
619
|
-
}
|
|
620
|
-
const aeErr = await _runHooks(_hooksFor("afterEach", pending.suitePath));
|
|
621
|
-
if (aeErr && !testErr && !inPageSkip) testErr = `afterEach failed: ${aeErr.message}`;
|
|
622
|
-
if (inPageSkip) results.push({
|
|
623
|
-
name: fullName,
|
|
624
|
-
status: "skip",
|
|
625
|
-
duration: Date.now() - tStart,
|
|
626
|
-
...inPageSkip.note !== void 0 ? { note: inPageSkip.note } : {}
|
|
627
|
-
});
|
|
628
|
-
else if (testErr !== void 0) results.push({
|
|
629
|
-
name: fullName,
|
|
630
|
-
status: "fail",
|
|
631
|
-
duration: Date.now() - tStart,
|
|
632
|
-
error: testErr,
|
|
633
|
-
...throttleRetries > 0 ? { throttleRetries } : {}
|
|
634
|
-
});
|
|
635
|
-
else results.push({
|
|
636
|
-
name: fullName,
|
|
637
|
-
status: "pass",
|
|
638
|
-
duration: Date.now() - tStart,
|
|
639
|
-
...throttleRetries > 0 ? { throttleRetries } : {}
|
|
640
|
-
});
|
|
641
|
-
for (let depth = pending.suitePath.length; depth >= 1; depth--) {
|
|
642
|
-
const scopeKey = pending.suitePath.slice(0, depth).join("\0");
|
|
643
|
-
if ((lastIndexForScope.get(scopeKey) ?? -1) === i) await _runHooks(_hooks.filter((h) => h.type === "afterAll" && h.suitePath.join("\0") === scopeKey).map((h) => h.fn));
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
await _runHooks(_hooks.filter((h) => h.type === "afterAll" && h.suitePath.length === 0).map((h) => h.fn));
|
|
647
|
-
return {
|
|
648
|
-
startedAt,
|
|
649
|
-
duration: Date.now() - wallStart,
|
|
650
|
-
passed: results.filter((r) => r.status === "pass").length,
|
|
651
|
-
failed: results.filter((r) => r.status === "fail").length,
|
|
652
|
-
skipped: results.filter((r) => r.status === "skip").length,
|
|
653
|
-
tests: results
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
//#endregion
|
|
657
|
-
export { runTestModule, runtimeGlobals };
|
|
658
|
-
|
|
659
|
-
//# sourceMappingURL=runtime.js.map
|