@molecule/api-ai-tools 1.9.6 → 1.9.7
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 +98 -8
- package/dist/command-position.d.ts +12 -0
- package/dist/command-position.d.ts.map +1 -1
- package/dist/command-position.js +111 -19
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +28 -10
- package/dist/trace-artifacts.d.ts +46 -0
- package/dist/trace-artifacts.d.ts.map +1 -1
- package/dist/trace-artifacts.js +260 -39
- package/dist/utilities.d.ts +39 -5
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +134 -14
- package/package.json +1 -1
package/dist/trace-artifacts.js
CHANGED
|
@@ -49,6 +49,12 @@ export const TRACE_NOTE_URL_CHARS = 96;
|
|
|
49
49
|
export const TRACE_NOTE_SENT_CHARS = 160;
|
|
50
50
|
/** How much of the response body the note prints — the API's first error line. */
|
|
51
51
|
export const TRACE_NOTE_GOT_CHARS = 120;
|
|
52
|
+
/**
|
|
53
|
+
* How much of the FAILING STEP's response body the note prints. Longer than
|
|
54
|
+
* {@link TRACE_NOTE_GOT_CHARS}: it is the one line that answers "what did the click actually get
|
|
55
|
+
* back", and an app's own body (`{"profile":{…}}`) can carry the answer past its first clause.
|
|
56
|
+
*/
|
|
57
|
+
export const TRACE_NOTE_LEAD_GOT_CHARS = 200;
|
|
52
58
|
/** How much of a network error's own text (`net::ERR_CONNECTION_REFUSED`) the note prints. */
|
|
53
59
|
const TRACE_NOTE_FAILURE_CHARS = 120;
|
|
54
60
|
/**
|
|
@@ -244,10 +250,38 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
244
250
|
if (sent) r.sent = sent
|
|
245
251
|
if (got) r.got = got
|
|
246
252
|
}
|
|
253
|
+
// The page's own actions, timed. before/after pair on the call id, and only the LIBRARY
|
|
254
|
+
// traces carry a class and a method (Frame.goto, Locator.fill); the test runner's own
|
|
255
|
+
// trace times its hooks and fixtures with class Test, which is not a page action. Read BEFORE
|
|
256
|
+
// the request buckets: whether the navigation itself finished decides whether a subresource
|
|
257
|
+
// with no response is evidence (see \`navigationOpen\` below).
|
|
258
|
+
const ended = {}
|
|
259
|
+
for (const entry of trace) {
|
|
260
|
+
if (entry && entry.type === 'after' && typeof entry.callId === 'string' && typeof entry.endTime === 'number')
|
|
261
|
+
ended[entry.callId] = entry.endTime
|
|
262
|
+
}
|
|
263
|
+
const actions = []
|
|
264
|
+
for (const entry of trace) {
|
|
265
|
+
if (!entry || entry.type !== 'before') continue
|
|
266
|
+
if (typeof entry.class !== 'string' || typeof entry.method !== 'string') continue
|
|
267
|
+
if (entry.class === 'Test' || typeof entry.startTime !== 'number') continue
|
|
268
|
+
actions.push({
|
|
269
|
+
api: entry.class + '.' + entry.method,
|
|
270
|
+
start: entry.startTime,
|
|
271
|
+
end: typeof ended[entry.callId] === 'number' ? ended[entry.callId] : null,
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
// A \`page.goto\` that has no end time: the page never finished loading. When that is the
|
|
275
|
+
// failure, a document subresource with no response is the reason — the navigation waits for
|
|
276
|
+
// its stylesheets and scripts — and it is evidence, not the aborted noise a finished
|
|
277
|
+
// navigation leaves behind (xr-molecule-flash-m135: three goto timeouts on a deployed app
|
|
278
|
+
// where one 88 KB stylesheet fetch stalled 27 s, and the trace of each held the pending CSS).
|
|
279
|
+
const navigationOpen = actions.some(function (a) { return /\\.goto$/.test(a.api) && a.end === null })
|
|
247
280
|
// The page shell's own requests (a service worker probe, a manifest, a font) are not the
|
|
248
281
|
// failing step's dependencies: a 404 on one, or no response at all, is not a cause and takes
|
|
249
282
|
// no row (xr-molecule-flash-m125 +29:33 — "GET /sw.js; GET /fonts/ionicons.woff" sent the
|
|
250
|
-
// model to write a caching service worker into the app).
|
|
283
|
+
// model to write a caching service worker into the app). A document's OWN stylesheet or
|
|
284
|
+
// script is not shell noise: the navigation blocks on it.
|
|
251
285
|
const SHELL_TYPE = { font: 1, image: 1, stylesheet: 1, script: 1, manifest: 1 }
|
|
252
286
|
function shellPath(path) {
|
|
253
287
|
return /^\\/(?:sw|service-worker)\\.js(?:[?#]|$)|\\/manifest\\.webmanifest(?:[?#]|$)|\\/favicon[^/]*(?:[?#]|$)|\\/fonts?\\//.test(path) ||
|
|
@@ -257,6 +291,13 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
257
291
|
if (r.type === 'document') return false
|
|
258
292
|
return SHELL_TYPE[r.type] === 1 || shellPath(r.path)
|
|
259
293
|
}
|
|
294
|
+
// The shell requests that stay noise even when they never finished: the PWA worker, the
|
|
295
|
+
// manifest, a favicon, a font. A pending \`/assets/*.css\` is the document's dependency.
|
|
296
|
+
function incidentalShell(r) {
|
|
297
|
+
if (r.type === 'document') return false
|
|
298
|
+
return r.type === 'font' || r.type === 'manifest' ||
|
|
299
|
+
/^\\/(?:sw|service-worker)\\.js(?:[?#]|$)|\\/manifest\\.webmanifest(?:[?#]|$)|\\/favicon[^/]*(?:[?#]|$)|\\/fonts?\\//.test(r.path)
|
|
300
|
+
}
|
|
260
301
|
// A failed request: a 4xx/5xx, or no response at all WITH Playwright's error text (a refused
|
|
261
302
|
// connection). No response and no text is an aborted/pending request, not a failure. A 404 on
|
|
262
303
|
// the page shell is excepted, for the reason above.
|
|
@@ -264,18 +305,72 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
264
305
|
if (shellRequest(r) && r.status === 404) return false
|
|
265
306
|
return r.status >= 400 || (r.status <= 0 && typeof r.failure === 'string')
|
|
266
307
|
}
|
|
308
|
+
// No response and no error text at all — still in flight when the test ended.
|
|
309
|
+
function neverFinished(r) {
|
|
310
|
+
return r.status <= 0 && typeof r.failure !== 'string'
|
|
311
|
+
}
|
|
312
|
+
// The request the failing step itself sent: the page's LAST call to the app's own origin (a
|
|
313
|
+
// click's fetch/xhr), else the document load. It leads the test's line, because the request a
|
|
314
|
+
// click sent answers "why did nothing change?" — xr-molecule-flash-m135 clicked Follow and sent
|
|
315
|
+
// a DELETE (its \`following\` state was stale), and the trace held the whole exchange while the
|
|
316
|
+
// result listed only the test's earlier, answered requests.
|
|
317
|
+
//
|
|
318
|
+
// Never a request that is still in flight (no response, no error text): it says nothing about
|
|
319
|
+
// what came back, and the note has its own honest row for it (m112 +30:45). Never the page
|
|
320
|
+
// shell's own probe (a refused \`/sw.js\` is not the step's request — m125 +29:33).
|
|
321
|
+
function leadCandidate(r) {
|
|
322
|
+
if (r.status <= 0 && typeof r.failure !== 'string') return false
|
|
323
|
+
if (r.type === 'document') return true
|
|
324
|
+
if (r.type !== 'fetch' && r.type !== 'xhr') return false
|
|
325
|
+
// The request the page makes for its own shell is not the step's (m125 +29:33). The recorded
|
|
326
|
+
// path can be an absolute URL when the probe's origin differs from the document's, so judge
|
|
327
|
+
// its pathname.
|
|
328
|
+
var p = r.path
|
|
329
|
+
try { p = new URL(r.path, 'http://trace.local').pathname } catch (e) { p = String(r.path).split(/[?#]/)[0] }
|
|
330
|
+
return !shellPath(p)
|
|
331
|
+
}
|
|
332
|
+
let leadIndex = -1
|
|
333
|
+
for (let i = requests.length - 1; i >= 0; i--) {
|
|
334
|
+
const r = requests[i]
|
|
335
|
+
if ((r.type === 'fetch' || r.type === 'xhr') && leadCandidate(r)) { leadIndex = i; break }
|
|
336
|
+
}
|
|
337
|
+
if (leadIndex === -1) {
|
|
338
|
+
for (let i = requests.length - 1; i >= 0; i--) {
|
|
339
|
+
if (requests[i].type === 'document' && leadCandidate(requests[i])) { leadIndex = i; break }
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
let lead = null
|
|
343
|
+
if (leadIndex !== -1) {
|
|
344
|
+
const r = requests[leadIndex]
|
|
345
|
+
const sent = bodyText(buf, entries, r.postData, MAX_BODY)
|
|
346
|
+
const got = bodyText(buf, entries, r.content, MAX_BODY)
|
|
347
|
+
lead = {
|
|
348
|
+
method: r.method,
|
|
349
|
+
path: r.path,
|
|
350
|
+
status: r.status,
|
|
351
|
+
failure: r.failure,
|
|
352
|
+
type: r.type || undefined,
|
|
353
|
+
...(sent ? { sent: sent } : {}),
|
|
354
|
+
...(got ? { got: got } : {}),
|
|
355
|
+
}
|
|
356
|
+
}
|
|
267
357
|
const failing = []
|
|
268
358
|
const api = []
|
|
359
|
+
const pending = []
|
|
269
360
|
const rest = []
|
|
270
361
|
for (let i = 0; i < requests.length; i++) {
|
|
271
362
|
const r = requests[i]
|
|
272
363
|
// An answered/aborted shell request is no evidence at all — do not spend a kept row on it.
|
|
273
|
-
|
|
364
|
+
// The exception is a document subresource that never finished while the navigation was
|
|
365
|
+
// still open: that IS what the timeout waited on.
|
|
366
|
+
if (shellRequest(r) && !failedRequest(r) && !(navigationOpen && neverFinished(r) && !incidentalShell(r))) continue
|
|
274
367
|
if (failedRequest(r)) failing.push(i)
|
|
275
368
|
else if (r.type === 'fetch' || r.type === 'xhr' || r.type === 'document') api.push(i)
|
|
369
|
+
else if (navigationOpen && neverFinished(r)) pending.push(i)
|
|
276
370
|
else rest.push(i)
|
|
277
371
|
}
|
|
278
|
-
const keep = failing.slice(-MAX_REQUESTS).concat(api.slice(-MAX_REQUESTS))
|
|
372
|
+
const keep = failing.slice(-MAX_REQUESTS).concat(api.slice(-MAX_REQUESTS))
|
|
373
|
+
.concat(pending.slice(-MAX_REQUESTS)).concat(rest.slice(-2))
|
|
279
374
|
const chosen = []
|
|
280
375
|
const seen = new Set()
|
|
281
376
|
for (const i of keep.sort(function (a, b) {
|
|
@@ -297,25 +392,6 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
297
392
|
type: r.type || undefined,
|
|
298
393
|
})
|
|
299
394
|
}
|
|
300
|
-
// The page's own actions, timed. before/after pair on the call id, and only the LIBRARY
|
|
301
|
-
// traces carry a class and a method (Frame.goto, Locator.fill); the test runner's own
|
|
302
|
-
// trace times its hooks and fixtures with class Test, which is not a page action.
|
|
303
|
-
const ended = {}
|
|
304
|
-
for (const entry of trace) {
|
|
305
|
-
if (entry && entry.type === 'after' && typeof entry.callId === 'string' && typeof entry.endTime === 'number')
|
|
306
|
-
ended[entry.callId] = entry.endTime
|
|
307
|
-
}
|
|
308
|
-
const actions = []
|
|
309
|
-
for (const entry of trace) {
|
|
310
|
-
if (!entry || entry.type !== 'before') continue
|
|
311
|
-
if (typeof entry.class !== 'string' || typeof entry.method !== 'string') continue
|
|
312
|
-
if (entry.class === 'Test' || typeof entry.startTime !== 'number') continue
|
|
313
|
-
actions.push({
|
|
314
|
-
api: entry.class + '.' + entry.method,
|
|
315
|
-
start: entry.startTime,
|
|
316
|
-
end: typeof ended[entry.callId] === 'number' ? ended[entry.callId] : null,
|
|
317
|
-
})
|
|
318
|
-
}
|
|
319
395
|
const consoleErrors = []
|
|
320
396
|
let spec = null
|
|
321
397
|
let line = 0
|
|
@@ -343,6 +419,7 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
343
419
|
dir: path.relative(ROOT, path.dirname(one.file)),
|
|
344
420
|
spec: spec,
|
|
345
421
|
line: line,
|
|
422
|
+
lead: lead,
|
|
346
423
|
// Failures first, per the sort above; the keep-window is the HEAD of that order. Taking the
|
|
347
424
|
// tail here dropped every failed request as soon as a page made more than MAX_REQUESTS of them
|
|
348
425
|
// plus the answered ones (xr-molecule-flash-m112's note listed only -1s and 200s).
|
|
@@ -352,6 +429,26 @@ for (const one of found.slice(0, MAX_TRACES)) {
|
|
|
352
429
|
}) + '\\n')
|
|
353
430
|
}
|
|
354
431
|
`;
|
|
432
|
+
/**
|
|
433
|
+
* One request out of a `TRACE` line's json, or null when the value is not an object.
|
|
434
|
+
*
|
|
435
|
+
* @param value - One entry of the line's `requests` array, or its `lead`.
|
|
436
|
+
* @returns The request, or null.
|
|
437
|
+
*/
|
|
438
|
+
function parseTraceRequest(value) {
|
|
439
|
+
if (typeof value !== 'object' || value === null)
|
|
440
|
+
return null;
|
|
441
|
+
const r = value;
|
|
442
|
+
return {
|
|
443
|
+
method: String(r.method ?? ''),
|
|
444
|
+
path: String(r.path ?? ''),
|
|
445
|
+
status: Number(r.status ?? 0) || 0,
|
|
446
|
+
...(typeof r.failure === 'string' && r.failure ? { failure: r.failure } : {}),
|
|
447
|
+
...(typeof r.sent === 'string' && r.sent ? { sent: r.sent } : {}),
|
|
448
|
+
...(typeof r.got === 'string' && r.got ? { got: r.got } : {}),
|
|
449
|
+
...(typeof r.type === 'string' && r.type ? { type: r.type } : {}),
|
|
450
|
+
};
|
|
451
|
+
}
|
|
355
452
|
/**
|
|
356
453
|
* The traces {@link traceArtifactsScript} printed, parsed.
|
|
357
454
|
*
|
|
@@ -371,20 +468,14 @@ export function parseTraceArtifacts(stdout) {
|
|
|
371
468
|
const requests = Array.isArray(raw.requests) ? raw.requests : [];
|
|
372
469
|
const consoleMessages = Array.isArray(raw.console) ? raw.console : [];
|
|
373
470
|
const actions = Array.isArray(raw.actions) ? raw.actions : [];
|
|
471
|
+
const lead = parseTraceRequest(raw.lead);
|
|
374
472
|
out.push({
|
|
375
473
|
spec: typeof raw.spec === 'string' ? raw.spec : null,
|
|
376
474
|
line: typeof raw.line === 'number' ? raw.line : 0,
|
|
377
475
|
requests: requests
|
|
378
|
-
.
|
|
379
|
-
.
|
|
380
|
-
|
|
381
|
-
path: String(r.path ?? ''),
|
|
382
|
-
status: Number(r.status ?? 0) || 0,
|
|
383
|
-
...(typeof r.failure === 'string' && r.failure ? { failure: r.failure } : {}),
|
|
384
|
-
...(typeof r.sent === 'string' && r.sent ? { sent: r.sent } : {}),
|
|
385
|
-
...(typeof r.got === 'string' && r.got ? { got: r.got } : {}),
|
|
386
|
-
...(typeof r.type === 'string' && r.type ? { type: r.type } : {}),
|
|
387
|
-
})),
|
|
476
|
+
.map(parseTraceRequest)
|
|
477
|
+
.filter((request) => request !== null),
|
|
478
|
+
...(lead === null ? {} : { lead }),
|
|
388
479
|
console: consoleMessages.map(String),
|
|
389
480
|
actions: actions
|
|
390
481
|
.filter((a) => typeof a === 'object' && a !== null)
|
|
@@ -445,6 +536,31 @@ function requestLine(request) {
|
|
|
445
536
|
: '';
|
|
446
537
|
return `${head}${sent}${got}`;
|
|
447
538
|
}
|
|
539
|
+
/**
|
|
540
|
+
* The failing step's own request as the note writes it first: `the failing step sent DELETE
|
|
541
|
+
* /api/profiles/x/follow → 200 got {"profile":{…}}`.
|
|
542
|
+
*
|
|
543
|
+
* It prints the response body whatever the status — an ANSWERED request is the point: m135's
|
|
544
|
+
* Follow click sent the DELETE an unfollow sends, got a 200 and a profile with `following: false`,
|
|
545
|
+
* and nothing in the result said which verb the click used.
|
|
546
|
+
*
|
|
547
|
+
* @param request - The trace's `lead` request.
|
|
548
|
+
* @returns The clause the test's row opens with.
|
|
549
|
+
*/
|
|
550
|
+
function leadRequestLine(request) {
|
|
551
|
+
const status = request.status > 0
|
|
552
|
+
? String(request.status)
|
|
553
|
+
: request.failure
|
|
554
|
+
? `no response (${bodyLine(redactSecrets(request.failure), TRACE_NOTE_FAILURE_CHARS)})`
|
|
555
|
+
: 'no response';
|
|
556
|
+
const sent = request.sent
|
|
557
|
+
? ` sent ${bodyLine(redactSecrets(request.sent), TRACE_NOTE_SENT_CHARS)}`
|
|
558
|
+
: '';
|
|
559
|
+
const got = request.got
|
|
560
|
+
? ` got ${bodyLine(redactSecrets(request.got), TRACE_NOTE_LEAD_GOT_CHARS)}`
|
|
561
|
+
: '';
|
|
562
|
+
return `the failing step sent ${requestLabel(request)} → ${status}${sent}${got}`;
|
|
563
|
+
}
|
|
448
564
|
/** Whether a sent body is an object whose only top-level key is `data` — the wrapped-body trap. */
|
|
449
565
|
function wrappedInData(text) {
|
|
450
566
|
try {
|
|
@@ -534,6 +650,33 @@ export function unansweredRequest(request) {
|
|
|
534
650
|
return false;
|
|
535
651
|
return request.status <= 0 && request.failure === undefined;
|
|
536
652
|
}
|
|
653
|
+
/**
|
|
654
|
+
* Whether a trace recorded a DOCUMENT SUBRESOURCE that never finished: a stylesheet, script or
|
|
655
|
+
* other asset the page itself loads, with no response and no error text — still in flight when
|
|
656
|
+
* the navigation timed out.
|
|
657
|
+
*
|
|
658
|
+
* The page shell's own incidental requests (`/sw.js`, the manifest, a favicon, a font) are
|
|
659
|
+
* excepted for the reason {@link isStaticAssetRequest} documents: m125's run was sent to write a
|
|
660
|
+
* caching service worker by an aborted `/sw.js`. A pending `/assets/*.css` is different — the
|
|
661
|
+
* navigation blocks on it, so it is the reason `page.goto` ran out of time rather than one of the
|
|
662
|
+
* app's API calls (xr-molecule-flash-m135 +34:10: three deployed `page.goto` timeouts on tests that
|
|
663
|
+
* pass locally, one 88 KB stylesheet fetch measured at 27 s, and the failing tests' traces each
|
|
664
|
+
* held the never-answered CSS while the note said "the cause is in the page").
|
|
665
|
+
*
|
|
666
|
+
* @param request - One request a trace recorded.
|
|
667
|
+
* @returns True when the request is a document subresource that never finished.
|
|
668
|
+
*/
|
|
669
|
+
export function stalledDocumentSubresource(request) {
|
|
670
|
+
if (request.status > 0 || request.failure !== undefined)
|
|
671
|
+
return false;
|
|
672
|
+
if (request.type === 'document')
|
|
673
|
+
return false;
|
|
674
|
+
if (request.type === 'font' || request.type === 'manifest')
|
|
675
|
+
return false;
|
|
676
|
+
if (STATIC_ASSET_PATH.test(requestPath(request)))
|
|
677
|
+
return false;
|
|
678
|
+
return isStaticAssetRequest(request);
|
|
679
|
+
}
|
|
537
680
|
/**
|
|
538
681
|
* How far a trace's last recorded step can sit after an earlier walk's failing test and still be
|
|
539
682
|
* that test. The trace names the LINE of the last step it recorded (the click, the wait), while the
|
|
@@ -591,14 +734,19 @@ function repeatsEarlierFailure(item, earlier) {
|
|
|
591
734
|
* hidden in "… and 7 more traced failures".
|
|
592
735
|
*
|
|
593
736
|
* A request the page shell made (m125 +29:33: `/sw.js`, a font) is not evidence about the step
|
|
594
|
-
* either, answered or not.
|
|
737
|
+
* either, answered or not. The exception is a document subresource that never finished while the
|
|
738
|
+
* page's own navigation was still open: the navigation waits on it, so it is the reason the
|
|
739
|
+
* `page.goto` timed out ({@link stalledDocumentSubresource}).
|
|
595
740
|
*
|
|
596
741
|
* @param item - One traced failure.
|
|
597
742
|
* @returns True when the trace holds a request or console error worth a row.
|
|
598
743
|
*/
|
|
599
744
|
function traceRowEvidence(item) {
|
|
600
745
|
return (item.console.length > 0 ||
|
|
601
|
-
item.requests.some((request) => !isStaticAssetRequest(request) && !unansweredRequest(request))
|
|
746
|
+
item.requests.some((request) => !isStaticAssetRequest(request) && !unansweredRequest(request)) ||
|
|
747
|
+
// The one shape in which a subresource with no response IS the cause: the navigation it was
|
|
748
|
+
// part of never finished (see {@link stalledDocumentSubresource}).
|
|
749
|
+
(navigationNeverFinished(item) && item.requests.some(stalledDocumentSubresource)));
|
|
602
750
|
}
|
|
603
751
|
/**
|
|
604
752
|
* The note's row order: a row with a REAL failure first, then a row whose failure an earlier walk
|
|
@@ -609,6 +757,10 @@ function traceRowEvidence(item) {
|
|
|
609
757
|
function traceRowTier(item, earlier) {
|
|
610
758
|
if (item.requests.some(failedRequest))
|
|
611
759
|
return 0;
|
|
760
|
+
// A navigation that never finished because its own subresource never got a response is as
|
|
761
|
+
// strong a cause as a failed request — it is the one fact the timeout was waiting on (m135).
|
|
762
|
+
if (navigationNeverFinished(item) && item.requests.some(stalledDocumentSubresource))
|
|
763
|
+
return 0;
|
|
612
764
|
if (repeatsEarlierFailure(item, earlier))
|
|
613
765
|
return 1;
|
|
614
766
|
return 2;
|
|
@@ -678,6 +830,12 @@ function transportFailure(items) {
|
|
|
678
830
|
* line rather than inferred from the status; when one of those bodies is an object whose only key
|
|
679
831
|
* is `data`, the note names the call shape that produces it (xr-molecule-flash-m111 +11:36).
|
|
680
832
|
*
|
|
833
|
+
* Every row opens with the request the failing step ITSELF sent ({@link TraceArtifact.lead}) and
|
|
834
|
+
* its response — whatever its status — because the question a `waiting for locator` failure asks
|
|
835
|
+
* is what the click did: xr-molecule-flash-m135's Follow click sent `DELETE …/follow → 200` (an
|
|
836
|
+
* unfollow, from a stale `following` state) and the run's result named only the test's earlier
|
|
837
|
+
* answered requests, so the executor spent 14 minutes on its own browser probes.
|
|
838
|
+
*
|
|
681
839
|
* WHICH rows it spends is evidence, not artifact order (xr-molecule-flash-m112 +53:46): a row
|
|
682
840
|
* needs a recorded response, a real failure or a console error ({@link traceRowEvidence}), rows are
|
|
683
841
|
* deduplicated by the test's location, and they are ordered real failure → repeated from an
|
|
@@ -689,6 +847,13 @@ function transportFailure(items) {
|
|
|
689
847
|
* transport error (`net::ERR_CONTENT_DECODING_FAILED` and friends) and the document it hit: nothing
|
|
690
848
|
* rendered, so no row below is app evidence (xr-molecule-flash-m118 +37:09).
|
|
691
849
|
*
|
|
850
|
+
* When a navigation never finished and one of the document's own subresources (a stylesheet, a
|
|
851
|
+
* script, an asset under `/assets/`) never got a response either, that request takes a row and the
|
|
852
|
+
* note says the page was waiting on it. It is not an API call, but on a `page.goto` timeout it is
|
|
853
|
+
* the only request that can explain the timeout — the deployed app was serving the page while one
|
|
854
|
+
* fetch stalled for 27 s (xr-molecule-flash-m135 +34:10). The page shell's incidental requests
|
|
855
|
+
* (`/sw.js`, the manifest, a favicon, a font) stay out, for m125's reason.
|
|
856
|
+
*
|
|
692
857
|
* @param items - The traces {@link parseTraceArtifacts} read.
|
|
693
858
|
* @param target - Where the run went — the deployed host, as the note names it.
|
|
694
859
|
* @param earlierFailures - The failing `file:line`s earlier walks of this suite left, so a repeat
|
|
@@ -720,21 +885,52 @@ export function failureTraceNote(items, target, earlierFailures = []) {
|
|
|
720
885
|
const wrapped = traced.some((item) => item.requests.some((request) => request.sent !== undefined && wrappedInData(request.sent)));
|
|
721
886
|
// The "one of these requests failing" answer is only honest when a listed request really failed.
|
|
722
887
|
const anyFailed = traced.some((item) => item.requests.some(failedRequest));
|
|
888
|
+
// The document subresources that never finished anywhere in this read — the assets a timed-out
|
|
889
|
+
// navigation was waiting on, when there is no failed request to explain the timeout.
|
|
890
|
+
const stalledAssets = [
|
|
891
|
+
...new Set(traced
|
|
892
|
+
.filter(navigationNeverFinished)
|
|
893
|
+
.flatMap((item) => item.requests.filter(stalledDocumentSubresource))
|
|
894
|
+
.map(requestLabel)),
|
|
895
|
+
];
|
|
723
896
|
const rows = [];
|
|
724
897
|
for (const [index, item] of traced.entries()) {
|
|
898
|
+
// The request the failing step itself sent LEADS the row (m135): a click that changed nothing
|
|
899
|
+
// is answered by the request it sent and what came back, whether or not that request failed.
|
|
900
|
+
// It is not repeated in the buckets below.
|
|
901
|
+
const lead = item.lead;
|
|
902
|
+
const isLead = (request) => lead !== undefined &&
|
|
903
|
+
request.method === lead.method &&
|
|
904
|
+
request.path === lead.path &&
|
|
905
|
+
request.status === lead.status;
|
|
725
906
|
// The page shell's own requests take no row, in any bucket: an aborted `/sw.js` would
|
|
726
907
|
// otherwise be printed as an "answered" request with no response (m125 +29:33).
|
|
727
|
-
const requests = item.requests.filter((request) => !isStaticAssetRequest(request));
|
|
908
|
+
const requests = item.requests.filter((request) => !isStaticAssetRequest(request) && !isLead(request));
|
|
728
909
|
const failed = requests.filter(failedRequest);
|
|
729
910
|
const unanswered = requests.filter(unansweredRequest);
|
|
730
911
|
const answered = requests.filter((request) => !failedRequest(request) && !unansweredRequest(request));
|
|
912
|
+
// A document subresource that never finished, on a trace whose navigation never finished:
|
|
913
|
+
// the page was waiting on it when the test's budget ran out (m135).
|
|
914
|
+
const stalled = navigationNeverFinished(item)
|
|
915
|
+
? item.requests.filter(stalledDocumentSubresource)
|
|
916
|
+
: [];
|
|
731
917
|
let room = MAX_TRACE_NOTE_REQUESTS;
|
|
732
918
|
const parts = [];
|
|
919
|
+
if (lead !== undefined) {
|
|
920
|
+
parts.push(leadRequestLine(lead));
|
|
921
|
+
room -= 1;
|
|
922
|
+
}
|
|
733
923
|
if (failed.length > 0) {
|
|
734
924
|
const shown = failed.slice(0, room);
|
|
735
925
|
room -= shown.length;
|
|
736
926
|
parts.push(`failed: ${shown.map(requestLine).join('; ')}`);
|
|
737
927
|
}
|
|
928
|
+
if (stalled.length > 0 && room > 0) {
|
|
929
|
+
const shown = stalled.slice(0, room);
|
|
930
|
+
room -= shown.length;
|
|
931
|
+
parts.push(`never finished: ${shown.map(requestLabel).join('; ')} — a document subresource with no ` +
|
|
932
|
+
'response, still in flight when the navigation timed out');
|
|
933
|
+
}
|
|
738
934
|
if (unanswered.length > 0 && room > 0) {
|
|
739
935
|
const shown = unanswered.slice(0, room);
|
|
740
936
|
room -= shown.length;
|
|
@@ -775,17 +971,42 @@ export function failureTraceNote(items, target, earlierFailures = []) {
|
|
|
775
971
|
'`MOL_E2E_PREVIEW_PLUGIN=0 npx vite preview --host 127.0.0.1 --port 4173 --strictPort`. '
|
|
776
972
|
: '') +
|
|
777
973
|
'Fix the server before the app.\n\n';
|
|
974
|
+
// A navigation that never finished WITH a subresource that never got a response, and no
|
|
975
|
+
// transport error: the page was waiting on the asset when the budget ran out. That is the host
|
|
976
|
+
// or the network serving that file, not the app's state — say it before any app-side reading
|
|
977
|
+
// (xr-molecule-flash-m135 +34:10: three deployed goto timeouts on tests passing locally in
|
|
978
|
+
// 1.2-5.6 s, one 88 KB stylesheet fetch measured at 27 s, and the note said "the cause is in
|
|
979
|
+
// the page").
|
|
980
|
+
const stalledLead = transport !== null || stalledAssets.length === 0
|
|
981
|
+
? ''
|
|
982
|
+
: `Every failure this run traced is a \`page.goto\` that never finished, and the document's ` +
|
|
983
|
+
`own ${stalledAssets.length === 1 ? 'subresource' : 'subresources'} ${stalledAssets.join(', ')} ` +
|
|
984
|
+
`never got a response — the navigation was waiting on ${stalledAssets.length === 1 ? 'it' : 'them'} ` +
|
|
985
|
+
`when the test's budget ran out. That is the host or the network serving the asset, not the ` +
|
|
986
|
+
`app's state or a selector: re-run the same tests once, unchanged, against ${target} before ` +
|
|
987
|
+
`editing anything, and if the stall repeats measure that exact fetch ` +
|
|
988
|
+
`(\`curl -o /dev/null -w '%{time_starttransfer} %{time_total}' <url>\`) before treating it as ` +
|
|
989
|
+
`the app's.\n\n`;
|
|
778
990
|
return (transportLead +
|
|
991
|
+
stalledLead +
|
|
779
992
|
`The platform read the failing tests' own Playwright traces from the run against ${target} ` +
|
|
780
|
-
`(what each page sent and got
|
|
781
|
-
`its last answered ones):\n` +
|
|
993
|
+
`(what each page sent and got — first the request the failing step itself sent, then the ` +
|
|
994
|
+
`requests that failed, the ones that got no response, and its last answered ones):\n` +
|
|
782
995
|
`${rows.join('\n')}${more}\n` +
|
|
783
996
|
(anyFailed
|
|
784
997
|
? 'A click that changed nothing is usually one of these requests failing, not the selector: ' +
|
|
785
998
|
'read the handler this route reaches in your own source, and stop `catch`-ing the request of a ' +
|
|
786
999
|
'user action silently — log it.'
|
|
787
|
-
:
|
|
788
|
-
'
|
|
1000
|
+
: stalledAssets.length > 0
|
|
1001
|
+
? 'No listed request failed — none got a 4xx/5xx or a network error — but the document did ' +
|
|
1002
|
+
'not finish loading because its own subresource never answered. Do not read this as a ' +
|
|
1003
|
+
'page-state bug: re-run these tests against the same URL first, and change the app only ' +
|
|
1004
|
+
'if the same navigation times out again with no stalled asset in the trace.'
|
|
1005
|
+
: 'No listed request failed — none got a 4xx/5xx or a network error — so the cause is in the ' +
|
|
1006
|
+
'page, not the API. Start with the request the failing step sent (the first line of each ' +
|
|
1007
|
+
'row): if it is not the request the test meant — an unfollow sent where the test clicked ' +
|
|
1008
|
+
'follow — the state the click read was stale before it. Otherwise read the state the ' +
|
|
1009
|
+
'failing test waited on.') +
|
|
789
1010
|
(wrapped
|
|
790
1011
|
? ' The API received a body wrapped in `data`: app-http’s `post(url, data, config)` / ' +
|
|
791
1012
|
'`put(url, data, config)` / `patch(url, data, config)` take the body as their SECOND ' +
|
package/dist/utilities.d.ts
CHANGED
|
@@ -107,8 +107,19 @@ export declare function outputIsWithheldUntilExit(command: string): boolean;
|
|
|
107
107
|
* this leaves its task log empty, so the log is the wrong place to look and an empty
|
|
108
108
|
* log proves nothing (X1 flash-m29).
|
|
109
109
|
*
|
|
110
|
+
* Which redirect counts is decided by the command's own shell structure, from the same
|
|
111
|
+
* parse every other command reader uses: a redirect written in a BACKGROUNDED statement
|
|
112
|
+
* (`… &`) or inside a `( … )` / `{ … }` group writes that process's or group's output, not
|
|
113
|
+
* the command's. The platform's own preview launch is exactly that — the preview server is
|
|
114
|
+
* started with `>/tmp/mol-preview-4173.log 2>&1 &` inside the build/serve prelude, and the
|
|
115
|
+
* suite's foreground command follows it — so a reader that took the last `>` in the whole
|
|
116
|
+
* text told a run its output went to the PREVIEW's log (X1 flash-m136 +18:31).
|
|
117
|
+
*
|
|
118
|
+
* The target comes back without its shell quotes: `> '/tmp/x.log'` is `/tmp/x.log`, and
|
|
119
|
+
* the callers resolve a relative one against the command's cwd.
|
|
120
|
+
*
|
|
110
121
|
* @param command - The shell command.
|
|
111
|
-
* @returns The target
|
|
122
|
+
* @returns The target, or null (`/dev/null` and `&1`/`&2` are not files).
|
|
112
123
|
*/
|
|
113
124
|
export declare function outputRedirectTarget(command: string): string | null;
|
|
114
125
|
/**
|
|
@@ -825,7 +836,28 @@ export interface UniversalCause {
|
|
|
825
836
|
count: number;
|
|
826
837
|
/** The distinct spec files they live in, in the order the log named them. */
|
|
827
838
|
files: string[];
|
|
839
|
+
/**
|
|
840
|
+
* The cause is that the page rendered NOTHING: every failure so far is a wait for an element
|
|
841
|
+
* the page never painted, whatever the selector asked for ({@link emptyPageCause}). One cause
|
|
842
|
+
* is failing every test even though no two failures share an error signature, so the note says
|
|
843
|
+
* so in the page's terms instead of naming one locator as the signature.
|
|
844
|
+
*/
|
|
845
|
+
pageRendersNothing?: true;
|
|
846
|
+
/** The page's own uncaught error, when the run printed one. */
|
|
847
|
+
pageError?: string;
|
|
848
|
+
/**
|
|
849
|
+
* The distinct failures this cause covers, in log order — the rows a note lists for
|
|
850
|
+
* {@link pageRendersNothing}. Absent for a signature cause, whose rows are the repeating
|
|
851
|
+
* failure's own tests.
|
|
852
|
+
*/
|
|
853
|
+
tests?: FailedTest[];
|
|
828
854
|
}
|
|
855
|
+
/**
|
|
856
|
+
* How many tests a run must have walked — with nothing passing since its first failure — before
|
|
857
|
+
* "the page renders nothing" can be its one cause. A handful of failures is a handful of bugs;
|
|
858
|
+
* a page that never painted fails every spec that reaches it, and m141's walk had 36 by +20:30.
|
|
859
|
+
*/
|
|
860
|
+
export declare const EMPTY_PAGE_CAUSE_TESTS = 15;
|
|
829
861
|
/**
|
|
830
862
|
* How many tests a connection-class cause must cover before the run is stopped even when they
|
|
831
863
|
* are all in one file — see {@link universalCause}.
|
|
@@ -875,12 +907,14 @@ export declare function specFilesSelected(command: string): number | null;
|
|
|
875
907
|
* alongside the others.
|
|
876
908
|
*
|
|
877
909
|
* @param log - The log so far.
|
|
878
|
-
* @param found - The repeating cause {@link repeatingFailure} found in it
|
|
910
|
+
* @param found - The repeating cause {@link repeatingFailure} found in it, or null when no two
|
|
911
|
+
* failures share a signature (a page that renders nothing fails each spec at its own first
|
|
912
|
+
* locator — {@link emptyPageCause} still reads that run).
|
|
879
913
|
* @param command - How the run was started, when the caller knows it: its spec-file selection
|
|
880
914
|
* scales the file threshold ({@link specFilesSelected}).
|
|
881
915
|
* @returns The cause's count and files, or null when the run is not failing whole.
|
|
882
916
|
*/
|
|
883
|
-
export declare function universalCause(log: string, found: RepeatingFailure, command?: string | null): UniversalCause | null;
|
|
917
|
+
export declare function universalCause(log: string, found: RepeatingFailure | null, command?: string | null): UniversalCause | null;
|
|
884
918
|
/**
|
|
885
919
|
* The ONE finding that ends a wait early, and the only one a note may hand a stop command over
|
|
886
920
|
* for: a PROVEN cause that is failing the whole run.
|
|
@@ -909,12 +943,12 @@ export declare function universalCause(log: string, found: RepeatingFailure, com
|
|
|
909
943
|
* needs — is the run over as a measuring instrument — and it is THE one predicate behind both
|
|
910
944
|
* that decision and the note's wording, so the two cannot come to different verdicts.
|
|
911
945
|
*
|
|
912
|
-
* @param found - What {@link repeatingFailure} found mid-run.
|
|
946
|
+
* @param found - What {@link repeatingFailure} found mid-run, or null when no signature repeats.
|
|
913
947
|
* @param universal - What {@link universalCause} found for it, if anything.
|
|
914
948
|
* @returns The cause to stop the run over, or null — in which case nothing may be stopped, the
|
|
915
949
|
* wait keeps going, and the finding rides the run's result as a note.
|
|
916
950
|
*/
|
|
917
|
-
export declare function earlyReturnCause(found: RepeatingFailure, universal: UniversalCause | null | undefined): UniversalCause | null;
|
|
951
|
+
export declare function earlyReturnCause(found: RepeatingFailure | null, universal: UniversalCause | null | undefined): UniversalCause | null;
|
|
918
952
|
/**
|
|
919
953
|
* The titles a request excludes that a test's heading names — the ONE matcher for "is this
|
|
920
954
|
* failure one the request does not count?".
|
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;AAUH,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
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"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"}
|