@molecule/api-ai-tools 1.9.14 → 1.9.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -7
- package/dist/suite-overlap.d.ts.map +1 -1
- package/dist/suite-overlap.js +7 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +99 -23
- package/dist/trace-artifacts.d.ts.map +1 -1
- package/dist/trace-artifacts.js +56 -3
- package/dist/utilities.d.ts +27 -4
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +60 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
|
3
3
|
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
4
|
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
5
|
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
-
Generated: 2026-10-
|
|
6
|
+
Generated: 2026-10-18T11:04:38.283Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -2274,22 +2274,43 @@ into the log twice, which on X1 flash-m83 (2026-10-16) made a `--reporter=list,l
|
|
|
2274
2274
|
_(description truncated — read the full text in `node_modules/@molecule/api-ai-tools/dist/utilities.d.ts`.)_
|
|
2275
2275
|
|
|
2276
2276
|
```typescript
|
|
2277
|
-
function streamingBackgroundCommand(command: string): {
|
|
2277
|
+
function streamingBackgroundCommand(command: string): {
|
|
2278
|
+
command: string
|
|
2279
|
+
changes: string[]
|
|
2280
|
+
error?: string
|
|
2281
|
+
}
|
|
2278
2282
|
```
|
|
2279
2283
|
|
|
2280
2284
|
- `command` — The command as the executor sent it.
|
|
2281
2285
|
|
|
2282
|
-
**Returns:** The command to run and one sentence per change made (empty when none).
|
|
2286
|
+
**Returns:** The command to run and one sentence per change made (empty when none), or `error` when the command starts the suite more than once.
|
|
2283
2287
|
|
|
2284
|
-
#### `
|
|
2288
|
+
#### `suiteRunStatements(command)`
|
|
2285
2289
|
|
|
2286
|
-
|
|
2287
|
-
— rather than a build, an install or a one-off script.
|
|
2290
|
+
Every statement of a command that starts a whole test suite, in command order.
|
|
2288
2291
|
|
|
2289
|
-
|
|
2292
|
+
This is the ONE count of suite runs in a command: {@link isSuiteRunCommand} asks it,
|
|
2293
|
+
{@link streamingBackgroundCommand} refuses a command carrying more than one — each statement
|
|
2294
|
+
starts a whole walk of the same suite, and only the last of them is rewritten — and a re-run
|
|
2295
|
+
composed from a command ({@link ./suite-overlap.js} `scopedRerunCommand`) keeps only the first.
|
|
2296
|
+
|
|
2297
|
+
A statement that invokes a runner only to print is not one of these
|
|
2290
2298
|
({@link commandRunsNoTests}): `npx playwright test --list` prints the tests it would run and
|
|
2291
2299
|
exits, and `npx playwright install`, `vitest list` and `hurl --help` start no test either.
|
|
2292
2300
|
|
|
2301
|
+
```typescript
|
|
2302
|
+
function suiteRunStatements(command: string): string[]
|
|
2303
|
+
```
|
|
2304
|
+
|
|
2305
|
+
- `command` — The shell command.
|
|
2306
|
+
|
|
2307
|
+
**Returns:** One entry per suite-running statement, as the parser read it (empty when none).
|
|
2308
|
+
|
|
2309
|
+
#### `isSuiteRunCommand(command)`
|
|
2310
|
+
|
|
2311
|
+
Whether a command runs a whole test suite — a Playwright, Vitest or Hurl run
|
|
2312
|
+
— rather than a build, an install or a one-off script.
|
|
2313
|
+
|
|
2293
2314
|
```typescript
|
|
2294
2315
|
function isSuiteRunCommand(command: string): boolean
|
|
2295
2316
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite-overlap.d.ts","sourceRoot":"","sources":["../src/suite-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAKD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAc1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAClB,MAAM,
|
|
1
|
+
{"version":3,"file":"suite-overlap.d.ts","sourceRoot":"","sources":["../src/suite-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAKD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAc1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAClB,MAAM,CA0CR;AAgHD;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,SAAS,EAAE,OAAO,CAAA;IAClB,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,EACzD,SAAS,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAC7B,QAAQ,EAAE,SAAS,CAAC,EAAE,GACrB,CAAC,GAAG,IAAI,CAMV;AAqDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQvD"}
|
package/dist/suite-overlap.js
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
import { posix } from 'node:path';
|
|
32
32
|
import { commandSegments, locatedCommandSegments } from './command-position.js';
|
|
33
33
|
import { commandRunsNoTests } from './no-test-run.js';
|
|
34
|
-
import { shellQuote } from './utilities.js';
|
|
34
|
+
import { shellQuote, suiteRunStatements } from './utilities.js';
|
|
35
35
|
/**
|
|
36
36
|
* A command with its heredoc bodies removed: the runs, kills and hosts it names in a file it
|
|
37
37
|
* WRITES are not what the command itself does.
|
|
@@ -180,7 +180,12 @@ export function scopedRerunCommand(command, locations, excluded = [], config, cw
|
|
|
180
180
|
.replace(/\s*--last-failed\b/g, '')
|
|
181
181
|
.replace(/\s*--retries(?:[= ]\d+)?/g, '')
|
|
182
182
|
.replace(/^(playwright\s+test)\b/, `$1 ${narrowed.join(' ')} --retries=0${carry}${invert}`);
|
|
183
|
-
|
|
183
|
+
// A command that starts the suite AGAIN after this statement is a chain of walks, not a re-run:
|
|
184
|
+
// everything from the next suite runner on is dropped, so the composed command carries ONE walk.
|
|
185
|
+
// X1 xr-molecule-flash-m157 (+14:02) was handed a re-run that still carried the chain's second
|
|
186
|
+
// whole walk — 4.5 minutes measuring code it had not changed.
|
|
187
|
+
const rerunTail = suiteRunStatements(tail).length > 0 ? '' : tail;
|
|
188
|
+
return `${head}${scoped}${rerunTail}`;
|
|
184
189
|
}
|
|
185
190
|
/** A directory a `cd` can name literally: no `~`, no variable, no glob. */
|
|
186
191
|
const LITERAL_DIR = /^[A-Za-z0-9_./+-]+$/;
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAkJ9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAkJ9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAahG;AAiSD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAsEnE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAEA,CAAA;AAE9B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,QAI6C,CAAA;AAmBlF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAoBpF;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACxE,qBAAqB,CAkBvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,qBAAqB,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AA2GD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAqlFxF"}
|
package/dist/tools.js
CHANGED
|
@@ -192,6 +192,58 @@ function logProgress(log) {
|
|
|
192
192
|
const total = Number(last?.[2]);
|
|
193
193
|
return last && total > 0 && done >= 0 && done <= total ? { done, total } : null;
|
|
194
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Playwright's start-of-walk line, `Running 138 tests using 1 worker` — the first thing a walk
|
|
197
|
+
* prints, so a second one in one log is a second walk.
|
|
198
|
+
*/
|
|
199
|
+
const WALK_START = /^[ \t]*Running \d+ tests?\b/gm;
|
|
200
|
+
/**
|
|
201
|
+
* One status line of a runner's closing tally — ` 4 failed`, ` 70 passed (4.5m)`,
|
|
202
|
+
* ` 65 skipped`.
|
|
203
|
+
*/
|
|
204
|
+
const TALLY_STATUS = /^[ \t]*(\d+)[ \t]+(passed|failed|flaky|skipped|interrupted|timed out|did not run)\b[^\n]*/gm;
|
|
205
|
+
/**
|
|
206
|
+
* A runner's CLOSING tally, the line that only prints once a walk has finished: Playwright's
|
|
207
|
+
* duration-bearing `70 passed (4.5m)`, a `1 flaky` summary, or Hurl's `Executed files:` count.
|
|
208
|
+
*
|
|
209
|
+
* The same reading as molecule-dev's `suite-proof.ts` `FINAL_TALLY_RE` (the platform's finished-run
|
|
210
|
+
* detector); this package cannot import it, so the shape is mirrored here and nowhere else.
|
|
211
|
+
*/
|
|
212
|
+
const FINISHED_TALLY = /\b\d+[ \t]+(?:passed|failed)[ \t]+\(\d+(?:\.\d+)?(?:ms|s|m|h)\)|^[ \t]*\d+[ \t]+flaky\b|^[ \t]*Executed files:/m;
|
|
213
|
+
/**
|
|
214
|
+
* Whether a task's log holds a SECOND walk of the same suite — a finished tally followed by a
|
|
215
|
+
* fresh `Running N tests` header — and what the finished walk's tally said.
|
|
216
|
+
*
|
|
217
|
+
* A command that chained two suite runs starts the second walk the moment the first ends, and the
|
|
218
|
+
* wait used to read that log as one slow run ("slow, not stuck") for the whole second walk. X1
|
|
219
|
+
* xr-molecule-flash-m157 (+14:02) waited out 4.5 minutes of a duplicate walk that measured nothing:
|
|
220
|
+
* the first walk had already printed `4 failed / 65 skipped / 70 passed (4.5m)`.
|
|
221
|
+
*
|
|
222
|
+
* @param slice - The log slice this wait read.
|
|
223
|
+
* @returns The finished walk's tally lines, or null when the log shows one walk (or none).
|
|
224
|
+
*/
|
|
225
|
+
function secondSuiteWalk(slice) {
|
|
226
|
+
const header = [...slice.matchAll(WALK_START)].at(-1);
|
|
227
|
+
if (!header || header.index === undefined)
|
|
228
|
+
return null;
|
|
229
|
+
const finished = FINISHED_TALLY.exec(slice);
|
|
230
|
+
// One walk prints its header FIRST and its tally last, so a tally before the last header is
|
|
231
|
+
// another walk's. The slice repeats what it greps and then the log's own tail, so the same
|
|
232
|
+
// tally can appear twice; one line per status, taken at its last position, keeps it once.
|
|
233
|
+
if (!finished || finished.index === undefined || finished.index > header.index)
|
|
234
|
+
return null;
|
|
235
|
+
const seen = new Map();
|
|
236
|
+
for (const match of slice.matchAll(TALLY_STATUS)) {
|
|
237
|
+
if (match.index === undefined || match.index >= header.index)
|
|
238
|
+
continue;
|
|
239
|
+
seen.set(match[2] ?? '', { at: match.index, text: match[0].trim().replace(/\s+/g, ' ') });
|
|
240
|
+
}
|
|
241
|
+
const tally = [...seen.values()]
|
|
242
|
+
.sort((a, b) => a.at - b.at)
|
|
243
|
+
.map((v) => v.text)
|
|
244
|
+
.join(' / ');
|
|
245
|
+
return { tally: tally || 'its closing tally' };
|
|
246
|
+
}
|
|
195
247
|
/**
|
|
196
248
|
* What a wait knows about the command BESIDES "it has not exited": how long it
|
|
197
249
|
* has been running, whether its output is still growing, how far its own log
|
|
@@ -232,11 +284,17 @@ function waitProgressClauses(o) {
|
|
|
232
284
|
? `it has been running at least ${durationText(o.waitedMs)}`
|
|
233
285
|
: `it has been running ${durationText(sinceStart)}`,
|
|
234
286
|
];
|
|
235
|
-
|
|
287
|
+
// A log that already finished one walk and started another says so instead of "slow, not
|
|
288
|
+
// stuck": the growth is the SECOND walk printing, and its counter is not this run's progress.
|
|
289
|
+
const secondWalk = secondSuiteWalk(o.slice);
|
|
290
|
+
if (o.stillWriting && !secondWalk)
|
|
236
291
|
clauses.push(`its output is still growing (${o.bytes} bytes) — slow, not stuck`);
|
|
237
|
-
else if (o.bytes !== null)
|
|
292
|
+
else if (o.bytes !== null && !secondWalk)
|
|
238
293
|
clauses.push(`its log has not grown during this wait (${o.bytes} bytes)`);
|
|
239
|
-
|
|
294
|
+
if (secondWalk)
|
|
295
|
+
clauses.push(`the first walk in this command has finished (${secondWalk.tally}); the command started a ` +
|
|
296
|
+
'SECOND walk of the same suite — stop it (it measures nothing new) and read the first tally');
|
|
297
|
+
const counter = secondWalk ? null : logProgress(o.slice);
|
|
240
298
|
if (counter) {
|
|
241
299
|
clauses.push(`its log is at ${counter.done} of ${counter.total}`);
|
|
242
300
|
// The rate is the task's own elapsed time, never this call's wait: with no
|
|
@@ -2289,6 +2347,11 @@ export function buildTools(backend, config) {
|
|
|
2289
2347
|
// Keep the log growing while it runs (see streamingBackgroundCommand):
|
|
2290
2348
|
// an empty log is what wait_for_task reads as stuck.
|
|
2291
2349
|
const streaming = streamingBackgroundCommand(command);
|
|
2350
|
+
// A command that starts the suite more than once is refused here, before anything is
|
|
2351
|
+
// written or launched: each walk measures the same code, and only the last is rewritten
|
|
2352
|
+
// (X1 xr-molecule-flash-m157 +14:02 — two whole walks chained with `;`).
|
|
2353
|
+
if (streaming.error)
|
|
2354
|
+
return { error: streaming.error };
|
|
2292
2355
|
// …and the trace flag this tool added (above), which the streaming rewrite never saw:
|
|
2293
2356
|
// its changes are what this branch reports the run's own settings in.
|
|
2294
2357
|
if (traced.change)
|
|
@@ -2859,6 +2922,14 @@ export function buildTools(backend, config) {
|
|
|
2859
2922
|
// instruction — and not on a finished run's result, where `failureCausesNote` reads the
|
|
2860
2923
|
// whole log instead of the 40 KB tail a mid-run look is given.
|
|
2861
2924
|
const midRun = midRunNote ? ` ${midRunNote}` : '';
|
|
2925
|
+
// A log that already finished one walk and started a second is not a run to keep waiting
|
|
2926
|
+
// on: the first walk's tally is the measurement and the second only repeats it, so the
|
|
2927
|
+
// advice below hands over the stop instead of "keep waiting" (m157 +14:02).
|
|
2928
|
+
const secondWalk = secondSuiteWalk(soFar) !== null;
|
|
2929
|
+
const stopInstead = secondWalk
|
|
2930
|
+
? ` Stop it (\`exec_command: ${await taskStopCommand(backend, taskId)}\`) and read the ` +
|
|
2931
|
+
`first walk's tally in ${log} — the second walk measures nothing new.`
|
|
2932
|
+
: null;
|
|
2862
2933
|
if (stillWriting && waitedBefore + waitedMs >= stuckAfterMs()) {
|
|
2863
2934
|
waitedByTask.set(taskId, 0);
|
|
2864
2935
|
return {
|
|
@@ -2866,8 +2937,11 @@ export function buildTools(backend, config) {
|
|
|
2866
2937
|
status: 'running',
|
|
2867
2938
|
waitedMs,
|
|
2868
2939
|
...sliceField,
|
|
2869
|
-
note: `${progress}
|
|
2870
|
-
|
|
2940
|
+
note: `${progress}` +
|
|
2941
|
+
(stopInstead ??
|
|
2942
|
+
` Call wait_for_task again to keep waiting — it returns the moment the ` +
|
|
2943
|
+
`command ends and reports the failures as they appear.`) +
|
|
2944
|
+
`${midRun}`,
|
|
2871
2945
|
};
|
|
2872
2946
|
}
|
|
2873
2947
|
if (waitedBefore + waitedMs >= stuckAfterMs()) {
|
|
@@ -2889,24 +2963,26 @@ export function buildTools(backend, config) {
|
|
|
2889
2963
|
// No "Still running after Ns" lead here either: the clauses already say
|
|
2890
2964
|
// how long it has been running, and the lead said it a second time in
|
|
2891
2965
|
// the other format (X1 flash-m87 §+47:20).
|
|
2892
|
-
note: `${progress}
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2966
|
+
note: `${progress}` +
|
|
2967
|
+
(stopInstead ??
|
|
2968
|
+
` Call wait_for_task again to ` +
|
|
2969
|
+
`keep waiting — its result carries the log output. ` +
|
|
2970
|
+
(soFar.trim()
|
|
2971
|
+
? `outputSoFar is the failure lines so far (up to ${RUNNING_FAILURE_LINES}) and then the end of ` +
|
|
2972
|
+
`the log, not the whole run — \`grep -n '✘' ${log} | head -40\` lists every failure, ` +
|
|
2973
|
+
`\`grep -n -A 20 '<test name>' ${log}\` reads one failure's error: this run writes ` +
|
|
2974
|
+
`each failure's own report into the log as that test fails, right under its ✘ line, ` +
|
|
2975
|
+
`not only in the summary at the end. `
|
|
2976
|
+
: `Nothing has been printed yet — \`grep -n '✘' ${log} | head -40\` lists failures as they appear. `) +
|
|
2977
|
+
// What an edit does to this run depends on what the run MEASURES: the sandbox's own
|
|
2978
|
+
// app is re-served from app/src as it is edited, so the run's result stops counting; a
|
|
2979
|
+
// run against the deployed build is untouched by a local edit, and the executor can
|
|
2980
|
+
// spend the rest of the run fixing (xr-molecule-flash-m122 +19:00: a deployed run was
|
|
2981
|
+
// told editing changes what it tests, then handed "Start fixing it now" in the same
|
|
2982
|
+
// result — it waited out 1 min 11 s of free fixing time).
|
|
2983
|
+
(started !== undefined && suiteCommandTarget(started.command) !== 'local'
|
|
2984
|
+
? `Meanwhile fix what it has already named: this run tests the deployed build, so editing app/src or api/src now does not change what it tests — fix the causes it has already named while it walks, run nothing against the app until it ends, then deploy once.`
|
|
2985
|
+
: `Meanwhile do work that leaves the code under test alone (read the failures so far, plan the fixes): editing app/src or api/src now changes the code the run is testing, and its result no longer counts.`)) +
|
|
2910
2986
|
`${midRun}`,
|
|
2911
2987
|
};
|
|
2912
2988
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace-artifacts.d.ts","sourceRoot":"","sources":["../src/trace-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,iEAAiE;AACjE,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,iGAAiG;IACjG,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,GAAG,EAAE,MAAM,CAAA;IACX,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB;;;;OAIG;IACH,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,yFAAyF;IACzF,GAAG,EAAE,MAAM,CAAA;IACX,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACnB;AAED,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,0FAA0F;IAC1F,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,6FAA6F;IAC7F,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;;;OAIG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B;;;;OAIG;IACH,OAAO,EAAE,WAAW,EAAE,CAAA;CACvB;AAED,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAEpC,yFAAyF;AACzF,eAAO,MAAM,qBAAqB,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"trace-artifacts.d.ts","sourceRoot":"","sources":["../src/trace-artifacts.ts"],"names":[],"mappings":"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"}
|
package/dist/trace-artifacts.js
CHANGED
|
@@ -42,6 +42,13 @@ export const MAX_TRACED_CONSOLE = 4;
|
|
|
42
42
|
export const MAX_TRACED_ACTIONS = 40;
|
|
43
43
|
/** How much of a 4xx request's sent body (or its response body) the trace read keeps. */
|
|
44
44
|
export const MAX_TRACED_BODY_CHARS = 300;
|
|
45
|
+
/**
|
|
46
|
+
* How much of a websocket's frames the trace read keeps. Longer than {@link MAX_TRACED_BODY_CHARS}
|
|
47
|
+
* because a frame read back to its own message still has the message, the module id and the
|
|
48
|
+
* location to carry — Vite's transform error alone is a sentence longer than the plain body cap,
|
|
49
|
+
* and the note prints its first 120–200 characters anyway (xr-molecule-flash-m157).
|
|
50
|
+
*/
|
|
51
|
+
const MAX_TRACED_WEBSOCKET_CHARS = 600;
|
|
45
52
|
/** How many tests the note in a run's result names. */
|
|
46
53
|
export const MAX_TRACE_NOTE_TESTS = 5;
|
|
47
54
|
/** How many requests the note names per test. */
|
|
@@ -97,6 +104,7 @@ const MAX_NOTE = ${MAX_TRACE_NOTE_REQUESTS}
|
|
|
97
104
|
const MAX_CONSOLE = ${MAX_TRACED_CONSOLE}
|
|
98
105
|
const MAX_ACTIONS = ${MAX_TRACED_ACTIONS}
|
|
99
106
|
const MAX_BODY = ${MAX_TRACED_BODY_CHARS}
|
|
107
|
+
const MAX_WS = ${MAX_TRACED_WEBSOCKET_CHARS}
|
|
100
108
|
const MAX_URL = 200
|
|
101
109
|
// A console line that is not an error but still has to reach the note (m148): one a molecule
|
|
102
110
|
// package wrote — it names the package, the \`[molecule/…]\` prefix, or the \`[scope]\` prefix
|
|
@@ -199,6 +207,51 @@ function bodyText(buf, entries, value, max) {
|
|
|
199
207
|
return text.indexOf('\\u0000') === -1 ? text : ''
|
|
200
208
|
}
|
|
201
209
|
|
|
210
|
+
// A websocket's content is a JSONL stream of frames (\`{type, time, opcode, data}\`), and the data
|
|
211
|
+
// is the page's own message. The envelope is ~35 characters on every frame, so cutting the raw
|
|
212
|
+
// stream lands inside it and never reaches the text that names a cause: xr-molecule-flash-m157's
|
|
213
|
+
// Vite HMR error frame was \`{"type":"receive","time":…,"opcode":1,"data":"{\\"type\\":\\"error\\",
|
|
214
|
+
// \\"err\\":{\\"message\\":\\"Cannot import non-asset file /styles.css which is inside /public …\` and
|
|
215
|
+
// every note stopped at \`{"type":"error","err":{"message":"Cannot…\`. Read the frames and print
|
|
216
|
+
// what they carry — a Vite error's message, id and loc, or the JSON a frame sends — so the cut
|
|
217
|
+
// lands in the message itself.
|
|
218
|
+
function websocketText(raw) {
|
|
219
|
+
const errors = []
|
|
220
|
+
const others = []
|
|
221
|
+
for (const line of String(raw).split('\\n')) {
|
|
222
|
+
if (!line.trim()) continue
|
|
223
|
+
let frame
|
|
224
|
+
try { frame = JSON.parse(line) } catch (e) { continue }
|
|
225
|
+
if (!frame || typeof frame.data !== 'string') continue
|
|
226
|
+
let data = frame.data
|
|
227
|
+
try { data = JSON.parse(frame.data) } catch (e) { /* a text frame: print the data as it is */ }
|
|
228
|
+
const err = data && typeof data === 'object' && data.type === 'error' ? data.err : null
|
|
229
|
+
if (err && typeof err.message === 'string') {
|
|
230
|
+
let text = 'vite error: ' + err.message
|
|
231
|
+
if (err.id !== undefined && err.id !== null && err.id !== '')
|
|
232
|
+
text += ' (id: ' + String(err.id) + ')'
|
|
233
|
+
const loc = err.loc
|
|
234
|
+
if (loc && typeof loc === 'object') {
|
|
235
|
+
const file = typeof loc.file === 'string' && loc.file ? loc.file : String(err.id || '')
|
|
236
|
+
text += ' (loc: ' + file +
|
|
237
|
+
(typeof loc.line === 'number' ? ':' + loc.line + ':' + (typeof loc.column === 'number' ? loc.column : 0) : '') +
|
|
238
|
+
')'
|
|
239
|
+
} else if (typeof loc === 'string' && loc) text += ' (loc: ' + loc + ')'
|
|
240
|
+
errors.push(text)
|
|
241
|
+
} else if (typeof data === 'string') others.push(data)
|
|
242
|
+
else others.push(JSON.stringify(data))
|
|
243
|
+
}
|
|
244
|
+
return errors.concat(others).join(' ')
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// What a request got back, as the note reads it: a websocket's frames are read as the messages
|
|
248
|
+
// they carry (m157), every other request's body as stored.
|
|
249
|
+
function gotText(buf, entries, r) {
|
|
250
|
+
if (r.type !== 'websocket') return bodyText(buf, entries, r.content, MAX_BODY)
|
|
251
|
+
const raw = bodyText(buf, entries, r.content, 8000)
|
|
252
|
+
return (websocketText(raw) || raw).slice(0, MAX_WS)
|
|
253
|
+
}
|
|
254
|
+
|
|
202
255
|
let origin = ''
|
|
203
256
|
function pathOf(url) {
|
|
204
257
|
try {
|
|
@@ -431,7 +484,7 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
431
484
|
for (const i of actionIndexes) {
|
|
432
485
|
const r = requests[i]
|
|
433
486
|
const sent = bodyText(buf, entries, r.postData, MAX_BODY)
|
|
434
|
-
const got =
|
|
487
|
+
const got = gotText(buf, entries, r)
|
|
435
488
|
if (sent) r.sent = sent
|
|
436
489
|
if (got) r.got = got
|
|
437
490
|
}
|
|
@@ -439,7 +492,7 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
439
492
|
if (r.status < 400 || r.status >= 500) continue
|
|
440
493
|
if (/^https?:/i.test(r.path)) continue
|
|
441
494
|
const sent = bodyText(buf, entries, r.postData, MAX_BODY)
|
|
442
|
-
const got =
|
|
495
|
+
const got = gotText(buf, entries, r)
|
|
443
496
|
if (sent) r.sent = sent
|
|
444
497
|
if (got) r.got = got
|
|
445
498
|
}
|
|
@@ -509,7 +562,7 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
509
562
|
if (leadIndex !== -1) {
|
|
510
563
|
const r = requests[leadIndex]
|
|
511
564
|
const sent = bodyText(buf, entries, r.postData, MAX_BODY)
|
|
512
|
-
const got =
|
|
565
|
+
const got = gotText(buf, entries, r)
|
|
513
566
|
lead = wire(r)
|
|
514
567
|
if (sent) lead.sent = sent
|
|
515
568
|
if (got) lead.got = got
|
package/dist/utilities.d.ts
CHANGED
|
@@ -174,22 +174,45 @@ export declare const PLAYWRIGHT_FAILURES_INLINE_ENV = "PLAYWRIGHT_LIST_PRINT_FAI
|
|
|
174
174
|
* something: `npx playwright test --list` takes two seconds and writes nothing per test, so
|
|
175
175
|
* neither reporter nor `--retries=0` is added to it ({@link isPlaywrightRunCommand}).
|
|
176
176
|
*
|
|
177
|
+
* A command that starts the suite MORE THAN ONCE is not launched at all: every run it carries is
|
|
178
|
+
* a whole walk of the same suite against the same app, and only the last step is rewritten, so the
|
|
179
|
+
* earlier walks run unmeasured for nothing. X1 xr-molecule-flash-m157 (+14:02) chained two whole
|
|
180
|
+
* walks of one 138-test suite with `;` — 4.5 minutes each — and the second measured nothing the
|
|
181
|
+
* first had not. The platform already refuses a second CONCURRENT run against one app; this is the
|
|
182
|
+
* same hazard inside one command ({@link suiteRunStatements}). `error` then carries the refusal,
|
|
183
|
+
* naming each suite step and the ONE command to send instead (the last suite step, rewritten as
|
|
184
|
+
* this function rewrites a run), and nothing is launched.
|
|
185
|
+
*
|
|
177
186
|
* @param command - The command as the executor sent it.
|
|
178
|
-
* @returns The command to run and one sentence per change made (empty when none)
|
|
187
|
+
* @returns The command to run and one sentence per change made (empty when none), or `error` when
|
|
188
|
+
* the command starts the suite more than once.
|
|
179
189
|
*/
|
|
180
190
|
export declare function streamingBackgroundCommand(command: string): {
|
|
181
191
|
command: string;
|
|
182
192
|
changes: string[];
|
|
193
|
+
error?: string;
|
|
183
194
|
};
|
|
184
195
|
/**
|
|
185
|
-
*
|
|
186
|
-
* — rather than a build, an install or a one-off script.
|
|
196
|
+
* Every statement of a command that starts a whole test suite, in command order.
|
|
187
197
|
*
|
|
188
|
-
*
|
|
198
|
+
* This is the ONE count of suite runs in a command: {@link isSuiteRunCommand} asks it,
|
|
199
|
+
* {@link streamingBackgroundCommand} refuses a command carrying more than one — each statement
|
|
200
|
+
* starts a whole walk of the same suite, and only the last of them is rewritten — and a re-run
|
|
201
|
+
* composed from a command ({@link ./suite-overlap.js} `scopedRerunCommand`) keeps only the first.
|
|
202
|
+
*
|
|
203
|
+
* A statement that invokes a runner only to print is not one of these
|
|
189
204
|
* ({@link commandRunsNoTests}): `npx playwright test --list` prints the tests it would run and
|
|
190
205
|
* exits, and `npx playwright install`, `vitest list` and `hurl --help` start no test either.
|
|
191
206
|
*
|
|
192
207
|
* @param command - The shell command.
|
|
208
|
+
* @returns One entry per suite-running statement, as the parser read it (empty when none).
|
|
209
|
+
*/
|
|
210
|
+
export declare function suiteRunStatements(command: string): string[];
|
|
211
|
+
/**
|
|
212
|
+
* Whether a command runs a whole test suite — a Playwright, Vitest or Hurl run
|
|
213
|
+
* — rather than a build, an install or a one-off script.
|
|
214
|
+
*
|
|
215
|
+
* @param command - The shell command.
|
|
193
216
|
* @returns True when the command starts one of those runners.
|
|
194
217
|
*/
|
|
195
218
|
export declare function isSuiteRunCommand(command: string): boolean;
|
package/dist/utilities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAW3E;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAEE,CAAA;AAuGhD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsCzD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CAUpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQnE;AAuDD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,8BAA8B,0CAA0C,CAAA;AAErF
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
|
package/dist/utilities.js
CHANGED
|
@@ -388,8 +388,18 @@ export const PLAYWRIGHT_FAILURES_INLINE_ENV = 'PLAYWRIGHT_LIST_PRINT_FAILURES_IN
|
|
|
388
388
|
* something: `npx playwright test --list` takes two seconds and writes nothing per test, so
|
|
389
389
|
* neither reporter nor `--retries=0` is added to it ({@link isPlaywrightRunCommand}).
|
|
390
390
|
*
|
|
391
|
+
* A command that starts the suite MORE THAN ONCE is not launched at all: every run it carries is
|
|
392
|
+
* a whole walk of the same suite against the same app, and only the last step is rewritten, so the
|
|
393
|
+
* earlier walks run unmeasured for nothing. X1 xr-molecule-flash-m157 (+14:02) chained two whole
|
|
394
|
+
* walks of one 138-test suite with `;` — 4.5 minutes each — and the second measured nothing the
|
|
395
|
+
* first had not. The platform already refuses a second CONCURRENT run against one app; this is the
|
|
396
|
+
* same hazard inside one command ({@link suiteRunStatements}). `error` then carries the refusal,
|
|
397
|
+
* naming each suite step and the ONE command to send instead (the last suite step, rewritten as
|
|
398
|
+
* this function rewrites a run), and nothing is launched.
|
|
399
|
+
*
|
|
391
400
|
* @param command - The command as the executor sent it.
|
|
392
|
-
* @returns The command to run and one sentence per change made (empty when none)
|
|
401
|
+
* @returns The command to run and one sentence per change made (empty when none), or `error` when
|
|
402
|
+
* the command starts the suite more than once.
|
|
393
403
|
*/
|
|
394
404
|
export function streamingBackgroundCommand(command) {
|
|
395
405
|
// A command that runs no test is not a run to keep a growing log for: nothing about it is
|
|
@@ -442,6 +452,30 @@ export function streamingBackgroundCommand(command) {
|
|
|
442
452
|
// options are parsed and placed against this text, while the closer is kept in the command.
|
|
443
453
|
const lastStep = rawLastStep.replace(/[\s)}]+$/, '');
|
|
444
454
|
const stepStart = rawLastStep === '' ? out.length : Math.max(0, out.lastIndexOf(rawLastStep));
|
|
455
|
+
// A command that starts the suite more than once is not launched: each statement is a whole walk
|
|
456
|
+
// of the same suite against the same app, only the last of them is rewritten, and the earlier
|
|
457
|
+
// ones measure nothing the first did. X1 xr-molecule-flash-m157 (+14:02) chained two whole walks
|
|
458
|
+
// of one 138-test suite with `;` (4.5 minutes each); the platform already refuses a second
|
|
459
|
+
// CONCURRENT run against one app, and this is the same hazard inside one command.
|
|
460
|
+
const suiteSteps = suiteRunStatements(out);
|
|
461
|
+
if (suiteSteps.length > 1) {
|
|
462
|
+
// The ONE run to send instead: the last step that runs the suite, rewritten exactly as this
|
|
463
|
+
// function rewrites a run (its own count is one — guarded, so this cannot recurse).
|
|
464
|
+
const lastSuitePart = [...parts]
|
|
465
|
+
.reverse()
|
|
466
|
+
.map((p) => p.trim())
|
|
467
|
+
.find((p) => isSuiteRunCommand(p));
|
|
468
|
+
const single = lastSuitePart && suiteRunStatements(lastSuitePart).length === 1
|
|
469
|
+
? streamingBackgroundCommand(lastSuitePart).command
|
|
470
|
+
: (lastSuitePart ?? '');
|
|
471
|
+
return {
|
|
472
|
+
command: out,
|
|
473
|
+
changes: [],
|
|
474
|
+
error: `This command runs the suite ${suiteSteps.length === 2 ? 'twice' : `${suiteSteps.length} times`} ` +
|
|
475
|
+
`(${suiteSteps.map((s, i) => `step ${i + 1}: \`${s}\``).join(', ')}). One walk is the ` +
|
|
476
|
+
`measurement; run exactly one: \`${single}\``,
|
|
477
|
+
};
|
|
478
|
+
}
|
|
445
479
|
// The last step runs Playwright — whether or not anything is piped from it. Keying this on
|
|
446
480
|
// "nothing is piped out of the last step" withheld the reporter, the inline-failure switch and
|
|
447
481
|
// `--retries=0` from exactly the runs whose output was filtered (xr-molecule-flash-m101
|
|
@@ -581,20 +615,39 @@ const SUITE_RUN_COMMANDS = [
|
|
|
581
615
|
/^hurl\s+[^|\n]*(?:--test|\.hurl)/,
|
|
582
616
|
];
|
|
583
617
|
/**
|
|
584
|
-
*
|
|
585
|
-
*
|
|
618
|
+
* Every statement of a command that starts a whole test suite, in command order.
|
|
619
|
+
*
|
|
620
|
+
* This is the ONE count of suite runs in a command: {@link isSuiteRunCommand} asks it,
|
|
621
|
+
* {@link streamingBackgroundCommand} refuses a command carrying more than one — each statement
|
|
622
|
+
* starts a whole walk of the same suite, and only the last of them is rewritten — and a re-run
|
|
623
|
+
* composed from a command ({@link ./suite-overlap.js} `scopedRerunCommand`) keeps only the first.
|
|
586
624
|
*
|
|
587
|
-
* A
|
|
625
|
+
* A statement that invokes a runner only to print is not one of these
|
|
588
626
|
* ({@link commandRunsNoTests}): `npx playwright test --list` prints the tests it would run and
|
|
589
627
|
* exits, and `npx playwright install`, `vitest list` and `hurl --help` start no test either.
|
|
590
628
|
*
|
|
591
629
|
* @param command - The shell command.
|
|
630
|
+
* @returns One entry per suite-running statement, as the parser read it (empty when none).
|
|
631
|
+
*/
|
|
632
|
+
export function suiteRunStatements(command) {
|
|
633
|
+
if (commandRunsNoTests(command))
|
|
634
|
+
return [];
|
|
635
|
+
return commandSegments(command)
|
|
636
|
+
.filter((segment) => SUITE_RUN_COMMANDS.some((re) => re.test(segment.text)) &&
|
|
637
|
+
// A statement that only PRINTS (`playwright test --list`) is not a walk, so
|
|
638
|
+
// `npx playwright test --list && npx playwright test` is one run, not two.
|
|
639
|
+
!commandRunsNoTests(segment.text))
|
|
640
|
+
.map((segment) => segment.text);
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Whether a command runs a whole test suite — a Playwright, Vitest or Hurl run
|
|
644
|
+
* — rather than a build, an install or a one-off script.
|
|
645
|
+
*
|
|
646
|
+
* @param command - The shell command.
|
|
592
647
|
* @returns True when the command starts one of those runners.
|
|
593
648
|
*/
|
|
594
649
|
export function isSuiteRunCommand(command) {
|
|
595
|
-
|
|
596
|
-
return false;
|
|
597
|
-
return commandSegments(command).some((segment) => SUITE_RUN_COMMANDS.some((re) => re.test(segment.text)));
|
|
650
|
+
return suiteRunStatements(command).length > 0;
|
|
598
651
|
}
|
|
599
652
|
/**
|
|
600
653
|
* The command with the `timeout <N>` wrapper lifted off the statement that runs the suite, and the
|