@tracelane/report 0.1.0-alpha.10 → 0.1.0-alpha.12
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 +3 -1
- package/dist/build-report.d.ts +6 -0
- package/dist/build-report.d.ts.map +1 -1
- package/dist/build-report.js +2 -1
- package/dist/build-report.js.map +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +5 -1
- package/dist/metadata.js.map +1 -1
- package/dist/panels.d.ts +23 -9
- package/dist/panels.d.ts.map +1 -1
- package/dist/panels.js +112 -36
- package/dist/panels.js.map +1 -1
- package/dist/template.d.ts +5 -0
- package/dist/template.d.ts.map +1 -1
- package/dist/template.js +67 -26
- package/dist/template.js.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
<img src="https://raw.githubusercontent.com/Cubenest/rrweb-stack/main/assets/brand/sub-tracelane.svg" height="40" alt="tracelane">
|
|
2
|
+
|
|
1
3
|
# @tracelane/report
|
|
2
4
|
|
|
3
|
-
> The reporter for your WebdriverIO
|
|
5
|
+
> The reporter for your WebdriverIO tests — Playwright and Cypress on the roadmap. Self-contained HTML for every run — replay failures, audit successes, attach to any bug tracker. No SaaS, no dashboard, no signup.
|
|
4
6
|
|
|
5
7
|
The self-contained, offline HTML report builder for [`tracelane`](https://github.com/Cubenest/rrweb-stack). Given a captured rrweb event stream plus test metadata, it produces a **single `.html` file** that:
|
|
6
8
|
|
package/dist/build-report.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ export interface BuildReportOptions {
|
|
|
7
7
|
* Pass `false` only when the caller has already applied the size guard.
|
|
8
8
|
*/
|
|
9
9
|
enforceSizeBudget?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Render the self-marketing footer in the report. Default true. Pass `false`
|
|
12
|
+
* to suppress it (surfaces the wdio `report: { footer: false }` opt-out —
|
|
13
|
+
* audit A-8).
|
|
14
|
+
*/
|
|
15
|
+
footer?: boolean;
|
|
10
16
|
}
|
|
11
17
|
/**
|
|
12
18
|
* Build a self-contained HTML report for one test run.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-report.d.ts","sourceRoot":"","sources":["../src/build-report.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAO1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"build-report.d.ts","sourceRoot":"","sources":["../src/build-report.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAO1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,EAAE,EACvB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAkCR"}
|
package/dist/build-report.js
CHANGED
|
@@ -27,7 +27,7 @@ import { renderReportHtml } from './template.js';
|
|
|
27
27
|
* @returns a complete `.html` document string — write it to disk as-is
|
|
28
28
|
*/
|
|
29
29
|
export function buildReport(events, meta, options = {}) {
|
|
30
|
-
const { enforceSizeBudget = true } = options;
|
|
30
|
+
const { enforceSizeBudget = true, footer = true } = options;
|
|
31
31
|
// Keep the report within budget; surface a banner if anything was dropped.
|
|
32
32
|
const { events: sized, pruned } = enforceSizeBudget
|
|
33
33
|
? pruneToSizeBudget(events)
|
|
@@ -54,6 +54,7 @@ export function buildReport(events, meta, options = {}) {
|
|
|
54
54
|
eventCount: sized.length,
|
|
55
55
|
firstTs,
|
|
56
56
|
lastTs,
|
|
57
|
+
footer,
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
//# sourceMappingURL=build-report.js.map
|
package/dist/build-report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-report.js","sourceRoot":"","sources":["../src/build-report.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,wCAAwC;AACxC,yEAAyE;AACzE,gEAAgE;AAChE,iEAAiE;AACjE,iEAAiE;AACjE,iEAAiE;AACjE,iDAAiD;AACjD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,kDAAkD;AAGlD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"build-report.js","sourceRoot":"","sources":["../src/build-report.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,yEAAyE;AACzE,8EAA8E;AAC9E,wCAAwC;AACxC,yEAAyE;AACzE,gEAAgE;AAChE,iEAAiE;AACjE,iEAAiE;AACjE,iEAAiE;AACjE,iDAAiD;AACjD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,kDAAkD;AAGlD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAkBjD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,MAAuB,EACvB,IAAgB,EAChB,UAA8B,EAAE;IAEhC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAE5D,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB;QACjD,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAC3B,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAE9B,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,aAAa,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAEhF,yEAAyE;IACzE,uEAAuE;IACvE,oEAAoE;IACpE,qEAAqE;IACrE,gEAAgE;IAChE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;IAEvD,OAAO,gBAAgB,CAAC;QACtB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC;QACpC,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE,WAAW;QACpB,QAAQ;QACR,MAAM;QACN,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,OAAO;QACP,MAAM;QACN,MAAM;KACP,CAAC,CAAC;AACL,CAAC"}
|
package/dist/metadata.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA4B7C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAQ9D;AAwDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA4B7C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAQ9D;AAwDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAyD3F"}
|
package/dist/metadata.js
CHANGED
|
@@ -122,6 +122,10 @@ export function renderHero(meta, eventCount, capturedAt) {
|
|
|
122
122
|
// ---- Eyebrow row -------------------------------------------------------
|
|
123
123
|
// Status pill (always shown), then spec / duration / browser separated by
|
|
124
124
|
// thin dividers. Each piece is optional except the status.
|
|
125
|
+
const TRACELANE_MARK = `<svg class="tracelane-mark" xmlns="http://www.w3.org/2000/svg" viewBox="36 96 184 64" height="14" role="img" aria-label="tracelane" style="display:inline-block;vertical-align:middle;flex-shrink:0"><g fill="none" stroke="#C2563D" stroke-width="8" stroke-linecap="round" stroke-linejoin="round"><rect x="40" y="100" width="176" height="56" rx="4"/><path d="M64 128L96 128"/><path d="M112 128L144 128"/><path d="M160 128L192 128"/></g><circle cx="208" cy="128" r="6" fill="#C2563D"/></svg>`;
|
|
126
|
+
// The brand mark is NOT part of the separator-joined bits — joining it would
|
|
127
|
+
// render a stray "/" between the logo and the status pill (audit A-11). It is
|
|
128
|
+
// prepended verbatim; the first visible "/" should be between status and spec.
|
|
125
129
|
const eyebrowBits = [
|
|
126
130
|
`<span class="dot" aria-hidden="true"></span><span class="status ${escapeHtml(meta.status)}">test ${escapeHtml(statusVerb(meta.status))}</span>`,
|
|
127
131
|
];
|
|
@@ -139,7 +143,7 @@ export function renderHero(meta, eventCount, capturedAt) {
|
|
|
139
143
|
.join(' · ');
|
|
140
144
|
eyebrowBits.push(`<span>${escapeHtml(browserBits)}</span>`);
|
|
141
145
|
}
|
|
142
|
-
const eyebrow = `<div class="eyebrow">${eyebrowBits.join('<span class="sep" aria-hidden="true">/</span>')}</div>`;
|
|
146
|
+
const eyebrow = `<div class="eyebrow">${TRACELANE_MARK}${eyebrowBits.join('<span class="sep" aria-hidden="true">/</span>')}</div>`;
|
|
143
147
|
// ---- Headline ----------------------------------------------------------
|
|
144
148
|
// Format: "<test title> — <emphasized status verb>." Always one sentence; the
|
|
145
149
|
// emphasized clause is the colour-of-the-failure-state moment.
|
package/dist/metadata.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"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"}
|
package/dist/panels.d.ts
CHANGED
|
@@ -25,18 +25,32 @@ export declare const NETWORK_EVENT_TAG = "tracelane.test.network-error";
|
|
|
25
25
|
/** console.error prefix for the v1 network fallback (P1 PRD §E.2). */
|
|
26
26
|
export declare const NETWORK_CONSOLE_PREFIX = "[tracelane.net]";
|
|
27
27
|
/**
|
|
28
|
-
* Extract console rows
|
|
29
|
-
*
|
|
28
|
+
* Extract console panel rows. Drops the CDP network-scrape lines
|
|
29
|
+
* ('[tracelane.net] …'): they are a *network* signal that `extractNetwork`
|
|
30
|
+
* already surfaces as structured rows in the Network panel. Letting them
|
|
31
|
+
* through here double-renders the same failure as a raw console string,
|
|
32
|
+
* inconsistently with the structured row (audit A-4).
|
|
30
33
|
*/
|
|
31
34
|
export declare function extractConsole(events: readonly eventWithTime[]): ConsoleEntry[];
|
|
32
35
|
/**
|
|
33
|
-
* Extract network-error rows.
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
36
|
+
* Extract network-error rows.
|
|
37
|
+
*
|
|
38
|
+
* The in-page rrweb network plugin (`rrweb/network@1`, the Phase 5 default)
|
|
39
|
+
* captures via PerformanceObserver, so its rows are status-poor for
|
|
40
|
+
* cross-origin requests. The legacy CDP `[tracelane.net]` console-scrape, when
|
|
41
|
+
* present, carries the AUTHORITATIVE HTTP status. So rather than "first
|
|
42
|
+
* non-empty source wins" — which would shadow the authoritative CDP rows
|
|
43
|
+
* whenever the plugin emitted anything (audit A-4) — we UNION the plugin + CDP
|
|
44
|
+
* sources, with CDP rows replacing an overlapping plugin row for the same URL.
|
|
45
|
+
*
|
|
46
|
+
* Resolution:
|
|
47
|
+
* 1. Failed rows from the in-page network plugin (EventType.Plugin) merged
|
|
48
|
+
* with the v1 CDP console-scrape ('[tracelane.net]'), where a CDP row
|
|
49
|
+
* REPLACES an overlapping plugin row for the same request (real status
|
|
50
|
+
* wins over a PerformanceObserver 0). Output ordered by timestamp.
|
|
51
|
+
* 2. If neither produced any rows, fall back to the v1.1 custom-event path
|
|
52
|
+
* (EventType.Custom) — pre-Phase-5 recorders that used neither the plugin
|
|
53
|
+
* nor the CDP console-scrape.
|
|
40
54
|
*/
|
|
41
55
|
export declare function extractNetwork(events: readonly eventWithTime[]): NetworkEntry[];
|
|
42
56
|
//# sourceMappingURL=panels.d.ts.map
|
package/dist/panels.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../src/panels.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../src/panels.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAuC,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE/F,2BAA2B;AAC3B,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8CAA8C;AAC9C,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAChD;;;;GAIG;AACH,eAAO,MAAM,cAAc,mBAAsB,CAAC;AAClD,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAChE,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AA+ExD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,YAAY,EAAE,CAE/E;AAkGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,YAAY,EAAE,CAmD/E"}
|
package/dist/panels.js
CHANGED
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
//
|
|
8
8
|
// Sources (P1 PRD §F.3 / §E.2 + Phase 5 network-plugin integration):
|
|
9
9
|
// • Console — EventType.Plugin (6) with data.plugin === 'rrweb/console@1'.
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// EventType.
|
|
14
|
-
//
|
|
15
|
-
//
|
|
10
|
+
// The CDP network-scrape lines ('[tracelane.net] …') are filtered OUT of
|
|
11
|
+
// the console panel (they're a network signal, surfaced as Network rows).
|
|
12
|
+
// • Network — UNION of the framework-agnostic in-page plugin
|
|
13
|
+
// (EventType.Plugin (6), data.plugin === 'rrweb/network@1'; ships in
|
|
14
|
+
// `@cubenest/rrweb-core`) and the v1 CDP console-scrape
|
|
15
|
+
// ('[tracelane.net]'), where the CDP row's AUTHORITATIVE status wins for
|
|
16
|
+
// an overlapping request. Falls back to the v1.1 EventType.Custom (5)
|
|
17
|
+
// path (tag 'tracelane.test.network-error') for pre-Phase-5 recorders
|
|
18
|
+
// that emitted neither source.
|
|
16
19
|
import { EventType, NETWORK_PLUGIN_NAME } from '@cubenest/rrweb-core';
|
|
17
20
|
/** rrweb console plugin tag (P1 PRD §F.3). */
|
|
18
21
|
export const CONSOLE_PLUGIN = 'rrweb/console@1';
|
|
@@ -65,10 +68,13 @@ function safeStringify(value) {
|
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
/**
|
|
68
|
-
*
|
|
69
|
-
* plugin. The plugin nests the level + serialized args under
|
|
71
|
+
* All console-plugin rows, UNFILTERED — EventType.Plugin events emitted by the
|
|
72
|
+
* rrweb console plugin. The plugin nests the level + serialized args under
|
|
73
|
+
* `data.payload`. This includes the CDP network-scrape lines
|
|
74
|
+
* ('[tracelane.net] …'); `extractNetwork` reads those here to recover the
|
|
75
|
+
* authoritative status, while `extractConsole` filters them out for its panel.
|
|
70
76
|
*/
|
|
71
|
-
|
|
77
|
+
function extractConsoleRows(events) {
|
|
72
78
|
const rows = [];
|
|
73
79
|
for (const e of events) {
|
|
74
80
|
if (!isPlugin(e))
|
|
@@ -83,6 +89,16 @@ export function extractConsole(events) {
|
|
|
83
89
|
}
|
|
84
90
|
return rows;
|
|
85
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Extract console panel rows. Drops the CDP network-scrape lines
|
|
94
|
+
* ('[tracelane.net] …'): they are a *network* signal that `extractNetwork`
|
|
95
|
+
* already surfaces as structured rows in the Network panel. Letting them
|
|
96
|
+
* through here double-renders the same failure as a raw console string,
|
|
97
|
+
* inconsistently with the structured row (audit A-4).
|
|
98
|
+
*/
|
|
99
|
+
export function extractConsole(events) {
|
|
100
|
+
return extractConsoleRows(events).filter((row) => !row.message.includes(NETWORK_CONSOLE_PREFIX));
|
|
101
|
+
}
|
|
86
102
|
/** Parse a '[tracelane.net] <METHOD> <STATUS> <URL>' console line, if it is one. */
|
|
87
103
|
function parseNetConsoleLine(message, timestamp) {
|
|
88
104
|
const idx = message.indexOf(NETWORK_CONSOLE_PREFIX);
|
|
@@ -100,12 +116,48 @@ function parseNetConsoleLine(message, timestamp) {
|
|
|
100
116
|
timestamp,
|
|
101
117
|
};
|
|
102
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* initiatorTypes that come from a true fetch/XHR error path. The plugin tags
|
|
121
|
+
* fetch/XHR wrapper rows with exactly these; everything else (img/script/link/
|
|
122
|
+
* css/font/navigation/…) is a PerformanceObserver timing entry.
|
|
123
|
+
*/
|
|
124
|
+
const ERROR_PATH_INITIATORS = new Set(['fetch', 'xmlhttprequest']);
|
|
125
|
+
/**
|
|
126
|
+
* Whether a `status === 0` request came from a *true* error path rather than
|
|
127
|
+
* a PerformanceObserver timing entry (audit A-1).
|
|
128
|
+
*
|
|
129
|
+
* The in-page `rrweb/network@1` plugin's default mode is PerformanceObserver:
|
|
130
|
+
* successful cross-origin SUB-resources (img/script/link/css/font — analytics,
|
|
131
|
+
* CDN, Google Fonts) report `responseStatus: 0` per the Resource Timing spec
|
|
132
|
+
* **even though they loaded with HTTP 200**. Treating those as failures
|
|
133
|
+
* surfaces PHANTOM network errors. Only the fetch/XHR wrappers (and CDP rows)
|
|
134
|
+
* report a real status, so a status-0 there is a genuine network error.
|
|
135
|
+
*
|
|
136
|
+
* Discriminator: an error-path row has `initiatorType` of `'fetch'` /
|
|
137
|
+
* `'xmlhttprequest'` (and typically a `method`); a PerformanceObserver
|
|
138
|
+
* sub-resource has a resource-type `initiatorType` (img/script/css/…) and no
|
|
139
|
+
* `method`. We require either an explicit fetch/XHR initiatorType OR (no
|
|
140
|
+
* initiatorType at all AND a `method`) — the latter covers older substrates
|
|
141
|
+
* that omitted initiatorType on the wrapper rows.
|
|
142
|
+
*/
|
|
143
|
+
function isTrueErrorPath(req) {
|
|
144
|
+
const initiator = typeof req.initiatorType === 'string' ? req.initiatorType : undefined;
|
|
145
|
+
if (initiator !== undefined)
|
|
146
|
+
return ERROR_PATH_INITIATORS.has(initiator);
|
|
147
|
+
// No initiatorType: a `method` indicates a fetch/XHR wrapper row (a true
|
|
148
|
+
// request), whereas a PerformanceObserver entry never carries a method.
|
|
149
|
+
return typeof req.method === 'string';
|
|
150
|
+
}
|
|
103
151
|
/**
|
|
104
152
|
* Coerce a `CapturedNetworkRequest` from the network plugin into a
|
|
105
|
-
* panel-visible `NetworkEntry`. Treats network errors (`status === 0`
|
|
106
|
-
* 4xx/5xx responses as "failed" — matches
|
|
107
|
-
* errors" panel semantics. Returns `undefined`
|
|
108
|
-
* the caller can skip them.
|
|
153
|
+
* panel-visible `NetworkEntry`. Treats genuine network errors (`status === 0`
|
|
154
|
+
* on a true fetch/XHR error path) and 4xx/5xx responses as "failed" — matches
|
|
155
|
+
* the report's existing "Network errors" panel semantics. Returns `undefined`
|
|
156
|
+
* for non-failed requests so the caller can skip them.
|
|
157
|
+
*
|
|
158
|
+
* A `status === 0` PerformanceObserver sub-resource is NOT a failure (see
|
|
159
|
+
* {@link isTrueErrorPath}) — those are cross-origin resources that loaded fine
|
|
160
|
+
* but report 0 per the Resource Timing spec.
|
|
109
161
|
*
|
|
110
162
|
* `fallbackTs` is the wrapping rrweb event's `timestamp` (wall-clock ms);
|
|
111
163
|
* we prefer the captured request's `timestamp` field when present (also
|
|
@@ -118,8 +170,10 @@ function networkEntryFromCapturedRequest(req, fallbackTs) {
|
|
|
118
170
|
// Filter to FAILED requests only — the renderer's panel is "Network errors"
|
|
119
171
|
// and the v1/v1.1 paths only ever surfaced failures. Successful 2xx/3xx
|
|
120
172
|
// responses captured by the plugin's broader PerformanceObserver path are
|
|
121
|
-
// intentionally dropped here.
|
|
122
|
-
|
|
173
|
+
// intentionally dropped here. A status of 0 only counts as a failure when it
|
|
174
|
+
// came from a true error path (fetch/XHR), never a PerformanceObserver
|
|
175
|
+
// sub-resource that reports 0 per the Resource Timing spec (audit A-1).
|
|
176
|
+
const isFailed = (status === 0 && isTrueErrorPath(req)) || (status !== undefined && status >= 400);
|
|
123
177
|
if (!isFailed)
|
|
124
178
|
return undefined;
|
|
125
179
|
const ts = typeof req.timestamp === 'number' ? req.timestamp : fallbackTs;
|
|
@@ -131,17 +185,32 @@ function networkEntryFromCapturedRequest(req, fallbackTs) {
|
|
|
131
185
|
timestamp: ts,
|
|
132
186
|
};
|
|
133
187
|
}
|
|
188
|
+
/** Normalize a URL for cross-source dedup (drop trailing slash + fragment). */
|
|
189
|
+
function networkKey(url) {
|
|
190
|
+
return url.replace(/#.*$/, '').replace(/\/$/, '');
|
|
191
|
+
}
|
|
134
192
|
/**
|
|
135
|
-
* Extract network-error rows.
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
193
|
+
* Extract network-error rows.
|
|
194
|
+
*
|
|
195
|
+
* The in-page rrweb network plugin (`rrweb/network@1`, the Phase 5 default)
|
|
196
|
+
* captures via PerformanceObserver, so its rows are status-poor for
|
|
197
|
+
* cross-origin requests. The legacy CDP `[tracelane.net]` console-scrape, when
|
|
198
|
+
* present, carries the AUTHORITATIVE HTTP status. So rather than "first
|
|
199
|
+
* non-empty source wins" — which would shadow the authoritative CDP rows
|
|
200
|
+
* whenever the plugin emitted anything (audit A-4) — we UNION the plugin + CDP
|
|
201
|
+
* sources, with CDP rows replacing an overlapping plugin row for the same URL.
|
|
202
|
+
*
|
|
203
|
+
* Resolution:
|
|
204
|
+
* 1. Failed rows from the in-page network plugin (EventType.Plugin) merged
|
|
205
|
+
* with the v1 CDP console-scrape ('[tracelane.net]'), where a CDP row
|
|
206
|
+
* REPLACES an overlapping plugin row for the same request (real status
|
|
207
|
+
* wins over a PerformanceObserver 0). Output ordered by timestamp.
|
|
208
|
+
* 2. If neither produced any rows, fall back to the v1.1 custom-event path
|
|
209
|
+
* (EventType.Custom) — pre-Phase-5 recorders that used neither the plugin
|
|
210
|
+
* nor the CDP console-scrape.
|
|
142
211
|
*/
|
|
143
212
|
export function extractNetwork(events) {
|
|
144
|
-
//
|
|
213
|
+
// 1a. The in-page network plugin (framework-agnostic; PerformanceObserver).
|
|
145
214
|
const fromPlugin = [];
|
|
146
215
|
for (const e of events) {
|
|
147
216
|
if (!isPlugin(e))
|
|
@@ -158,9 +227,25 @@ export function extractNetwork(events) {
|
|
|
158
227
|
fromPlugin.push(entry);
|
|
159
228
|
}
|
|
160
229
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
230
|
+
// 1b. v1 CDP console-scrape — AUTHORITATIVE status. Read the unfiltered
|
|
231
|
+
// console rows here (extractConsole() drops these lines for its panel).
|
|
232
|
+
const scraped = [];
|
|
233
|
+
for (const row of extractConsoleRows(events)) {
|
|
234
|
+
const parsed = parseNetConsoleLine(row.message, row.timestamp);
|
|
235
|
+
if (parsed)
|
|
236
|
+
scraped.push(parsed);
|
|
237
|
+
}
|
|
238
|
+
if (fromPlugin.length > 0 || scraped.length > 0) {
|
|
239
|
+
// Merge: CDP rows are authoritative and replace an overlapping plugin row
|
|
240
|
+
// for the same URL; everything non-overlapping from both is retained.
|
|
241
|
+
const byKey = new Map();
|
|
242
|
+
for (const entry of fromPlugin)
|
|
243
|
+
byKey.set(networkKey(entry.url), entry);
|
|
244
|
+
for (const entry of scraped)
|
|
245
|
+
byKey.set(networkKey(entry.url), entry);
|
|
246
|
+
return [...byKey.values()].sort((a, b) => a.timestamp - b.timestamp);
|
|
247
|
+
}
|
|
248
|
+
// 2. v1.1 fallback: rich custom events (pre-Phase-5 recorders).
|
|
164
249
|
const rich = [];
|
|
165
250
|
for (const e of events) {
|
|
166
251
|
if (!isCustom(e))
|
|
@@ -176,15 +261,6 @@ export function extractNetwork(events) {
|
|
|
176
261
|
timestamp: e.timestamp,
|
|
177
262
|
});
|
|
178
263
|
}
|
|
179
|
-
|
|
180
|
-
return rich;
|
|
181
|
-
// 3. v1 fallback: scrape the console.
|
|
182
|
-
const scraped = [];
|
|
183
|
-
for (const row of extractConsole(events)) {
|
|
184
|
-
const parsed = parseNetConsoleLine(row.message, row.timestamp);
|
|
185
|
-
if (parsed)
|
|
186
|
-
scraped.push(parsed);
|
|
187
|
-
}
|
|
188
|
-
return scraped;
|
|
264
|
+
return rich;
|
|
189
265
|
}
|
|
190
266
|
//# sourceMappingURL=panels.js.map
|
package/dist/panels.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panels.js","sourceRoot":"","sources":["../src/panels.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,2EAA2E;AAC3E,6EAA6E;AAC7E,EAAE;AACF,qEAAqE;AACrE,6EAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"panels.js","sourceRoot":"","sources":["../src/panels.ts"],"names":[],"mappings":"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"}
|
package/dist/template.d.ts
CHANGED
|
@@ -20,6 +20,11 @@ export interface ReportTemplateData {
|
|
|
20
20
|
/** Latest event timestamp (wall-clock ms) or 0 if no events. Treated as the
|
|
21
21
|
* "failure" moment for the timeline marker when the test failed. */
|
|
22
22
|
lastTs: number;
|
|
23
|
+
/**
|
|
24
|
+
* Render the self-marketing footer. Default true. Pass false to suppress it
|
|
25
|
+
* (`report: { footer: false }` opt-out — audit A-8).
|
|
26
|
+
*/
|
|
27
|
+
footer?: boolean;
|
|
23
28
|
}
|
|
24
29
|
/** Compose the full self-contained HTML document. */
|
|
25
30
|
export declare function renderReportHtml(data: ReportTemplateData): string;
|
package/dist/template.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,CAAC;IACjB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,gDAAgD;IAChD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;IAChB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB;yEACqE;IACrE,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,CAAC;IACjB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,gDAAgD;IAChD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;IAChB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB;yEACqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA43BD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CA2HjE"}
|
package/dist/template.js
CHANGED
|
@@ -305,6 +305,21 @@ main.investigation {
|
|
|
305
305
|
font-weight: 600;
|
|
306
306
|
}
|
|
307
307
|
.tab.active .count { background: var(--teal-dim); color: var(--teal); }
|
|
308
|
+
/* "soon" pill on the placeholder Actions / Timeline tabs (audit A-10) — warns
|
|
309
|
+
the visitor the pane is a coming-soon stub before they click it. */
|
|
310
|
+
.tab .soon-pill {
|
|
311
|
+
margin-left: 6px;
|
|
312
|
+
padding: 1px 6px;
|
|
313
|
+
border-radius: 8px;
|
|
314
|
+
border: 1px solid var(--border-strong);
|
|
315
|
+
background: transparent;
|
|
316
|
+
color: var(--muted);
|
|
317
|
+
font-size: 9px;
|
|
318
|
+
font-weight: 600;
|
|
319
|
+
text-transform: uppercase;
|
|
320
|
+
letter-spacing: 0.08em;
|
|
321
|
+
vertical-align: middle;
|
|
322
|
+
}
|
|
308
323
|
|
|
309
324
|
.panel-toolbar {
|
|
310
325
|
padding: 10px 16px;
|
|
@@ -580,7 +595,7 @@ const BOOTSTRAP = `
|
|
|
580
595
|
});
|
|
581
596
|
// Expose for headless probes (visible to dev-tools; no runtime impact on
|
|
582
597
|
// end users — the report HTML is read-only static content).
|
|
583
|
-
try { window.
|
|
598
|
+
try { window.__tracelanePlayer = rrPlayer; } catch (_) {}
|
|
584
599
|
} else {
|
|
585
600
|
var msg = document.createElement('div');
|
|
586
601
|
msg.className = 'empty';
|
|
@@ -623,6 +638,10 @@ const BOOTSTRAP = `
|
|
|
623
638
|
var row = el('div', 'row is-future ' + lvl);
|
|
624
639
|
var relMs = firstTs ? Math.max(0, r.timestamp - firstTs) : 0;
|
|
625
640
|
row.setAttribute('data-time', String(relMs));
|
|
641
|
+
// a11y: rows are click-to-seek; expose them to keyboard + AT users.
|
|
642
|
+
row.setAttribute('tabindex', '0');
|
|
643
|
+
row.setAttribute('role', 'button');
|
|
644
|
+
row.setAttribute('aria-label', 'Seek to ' + fmtRelTs(r.timestamp, firstTs));
|
|
626
645
|
row.appendChild(el('span', 'ts', fmtRelTs(r.timestamp, firstTs)));
|
|
627
646
|
row.appendChild(el('span', 'lvl', lvl));
|
|
628
647
|
row.appendChild(el('span', 'msg', r.message));
|
|
@@ -642,6 +661,10 @@ const BOOTSTRAP = `
|
|
|
642
661
|
var row = el('div', 'row row-net is-future error');
|
|
643
662
|
var relMs = firstTs ? Math.max(0, r.timestamp - firstTs) : 0;
|
|
644
663
|
row.setAttribute('data-time', String(relMs));
|
|
664
|
+
// a11y: rows are click-to-seek; expose them to keyboard + AT users.
|
|
665
|
+
row.setAttribute('tabindex', '0');
|
|
666
|
+
row.setAttribute('role', 'button');
|
|
667
|
+
row.setAttribute('aria-label', 'Seek to ' + fmtRelTs(r.timestamp, firstTs));
|
|
645
668
|
row.appendChild(el('span', 'ts', fmtRelTs(r.timestamp, firstTs)));
|
|
646
669
|
var stCls = 'lvl st-' + String(r.status).charAt(0);
|
|
647
670
|
row.appendChild(el('span', stCls, String(r.status)));
|
|
@@ -662,6 +685,10 @@ const BOOTSTRAP = `
|
|
|
662
685
|
renderNetwork(document.getElementById('network-rows'), NETWORK, FIRST_TS);
|
|
663
686
|
|
|
664
687
|
// ---- Time-sync: reveal rows as playback advances ----------------------
|
|
688
|
+
// TODO(perf): re-queries DOM and re-parses data-time on every tick (~30 Hz).
|
|
689
|
+
// Fine at current demo scale (~10 rows). When Actions / Timeline panels ship
|
|
690
|
+
// and reports start carrying hundreds of entries, cache [rows, times] once
|
|
691
|
+
// after render and skip work when t === lastT.
|
|
665
692
|
function tickPanels(currentMs) {
|
|
666
693
|
var t = Math.max(0, Math.floor(currentMs || 0));
|
|
667
694
|
var names = ['console', 'network'];
|
|
@@ -711,23 +738,34 @@ const BOOTSTRAP = `
|
|
|
711
738
|
}
|
|
712
739
|
tickPanels(0);
|
|
713
740
|
|
|
714
|
-
// ---- Click-to-seek:
|
|
741
|
+
// ---- Click/keyboard-to-seek: activating a row jumps the player ---------
|
|
742
|
+
// Rows are role="button" tabindex="0", so they're keyboard-focusable; Enter
|
|
743
|
+
// and Space activate them the same way a click does (a11y — audit A-7).
|
|
715
744
|
if (rrPlayer && typeof rrPlayer.goto === 'function') {
|
|
716
745
|
var seekContainers = ['console-rows', 'network-rows'];
|
|
746
|
+
var seekFromEvent = function (ctr, ev) {
|
|
747
|
+
var target = ev.target;
|
|
748
|
+
// Walk up to the .row ancestor (events may land on inner spans).
|
|
749
|
+
while (target && target !== ctr && !target.classList.contains('row')) {
|
|
750
|
+
target = target.parentNode;
|
|
751
|
+
}
|
|
752
|
+
if (!target || target === ctr) return;
|
|
753
|
+
var t = parseInt(target.getAttribute('data-time') || '0', 10);
|
|
754
|
+
if (isFinite(t) && t >= 0) {
|
|
755
|
+
rrPlayer.goto(t, false);
|
|
756
|
+
}
|
|
757
|
+
};
|
|
717
758
|
for (var sc = 0; sc < seekContainers.length; sc++) {
|
|
718
759
|
(function (containerId) {
|
|
719
760
|
var ctr = document.getElementById(containerId);
|
|
720
761
|
if (!ctr) return;
|
|
721
762
|
ctr.addEventListener('click', function (ev) {
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
var t = parseInt(target.getAttribute('data-time') || '0', 10);
|
|
729
|
-
if (isFinite(t) && t >= 0) {
|
|
730
|
-
rrPlayer.goto(t, false);
|
|
763
|
+
seekFromEvent(ctr, ev);
|
|
764
|
+
});
|
|
765
|
+
ctr.addEventListener('keydown', function (ev) {
|
|
766
|
+
if (ev.key === 'Enter' || ev.key === ' ' || ev.key === 'Spacebar') {
|
|
767
|
+
ev.preventDefault();
|
|
768
|
+
seekFromEvent(ctr, ev);
|
|
731
769
|
}
|
|
732
770
|
});
|
|
733
771
|
})(seekContainers[sc]);
|
|
@@ -741,7 +779,10 @@ const BOOTSTRAP = `
|
|
|
741
779
|
(function (tab) {
|
|
742
780
|
tab.addEventListener('click', function () {
|
|
743
781
|
var targetId = tab.getAttribute('data-pane');
|
|
744
|
-
for (var i = 0; i < tabs.length; i++)
|
|
782
|
+
for (var i = 0; i < tabs.length; i++) {
|
|
783
|
+
tabs[i].classList.remove('active');
|
|
784
|
+
tabs[i].setAttribute('aria-selected', tabs[i] === tab ? 'true' : 'false');
|
|
785
|
+
}
|
|
745
786
|
for (var j = 0; j < panes.length; j++) {
|
|
746
787
|
panes[j].classList.toggle('active', panes[j].id === targetId);
|
|
747
788
|
}
|
|
@@ -853,7 +894,7 @@ function formatRelativeMs(ms) {
|
|
|
853
894
|
}
|
|
854
895
|
/** Compose the full self-contained HTML document. */
|
|
855
896
|
export function renderReportHtml(data) {
|
|
856
|
-
const { meta, eventsGzB64, console: consoleRows, network, markdown, pruned, eventCount, firstTs, lastTs, } = data;
|
|
897
|
+
const { meta, eventsGzB64, console: consoleRows, network, markdown, pruned, eventCount, firstTs, lastTs, footer = true, } = data;
|
|
857
898
|
const title = `tracelane — ${meta.spec ?? '(no spec)'} :: ${meta.title} (${meta.status})`;
|
|
858
899
|
// Banner only when the events were pruned to fit the size cap (ADR-0005).
|
|
859
900
|
const banner = pruned
|
|
@@ -894,39 +935,39 @@ ${banner}
|
|
|
894
935
|
</section>
|
|
895
936
|
<aside class="panels" aria-label="Investigation panels">
|
|
896
937
|
<div class="tabs" role="tablist">
|
|
897
|
-
<button class="tab active" type="button" role="tab" data-pane="pane-console">
|
|
938
|
+
<button class="tab active" type="button" role="tab" id="tab-console" aria-selected="true" aria-controls="pane-console" data-pane="pane-console">
|
|
898
939
|
Console <span class="count">0</span><span class="count-total">/ ${consoleCount}</span>
|
|
899
940
|
</button>
|
|
900
|
-
<button class="tab" type="button" role="tab" data-pane="pane-network">
|
|
941
|
+
<button class="tab" type="button" role="tab" id="tab-network" aria-selected="false" aria-controls="pane-network" data-pane="pane-network">
|
|
901
942
|
Network <span class="count">0</span><span class="count-total">/ ${networkCount}</span>
|
|
902
943
|
</button>
|
|
903
|
-
<button class="tab" type="button" role="tab" data-pane="pane-actions">
|
|
904
|
-
Actions
|
|
944
|
+
<button class="tab" type="button" role="tab" id="tab-actions" aria-selected="false" aria-controls="pane-actions" data-pane="pane-actions">
|
|
945
|
+
Actions <span class="soon-pill">soon</span>
|
|
905
946
|
</button>
|
|
906
|
-
<button class="tab" type="button" role="tab" data-pane="pane-timeline">
|
|
907
|
-
Timeline
|
|
947
|
+
<button class="tab" type="button" role="tab" id="tab-timeline" aria-selected="false" aria-controls="pane-timeline" data-pane="pane-timeline">
|
|
948
|
+
Timeline <span class="soon-pill">soon</span>
|
|
908
949
|
</button>
|
|
909
950
|
</div>
|
|
910
951
|
|
|
911
|
-
<div class="panel-pane active" id="pane-console" role="tabpanel">
|
|
952
|
+
<div class="panel-pane active" id="pane-console" role="tabpanel" aria-labelledby="tab-console">
|
|
912
953
|
<div class="panel-toolbar">
|
|
913
954
|
<input type="text" class="panel-filter" placeholder="Filter console…" aria-label="Filter console messages" />
|
|
914
955
|
<button class="filter-chip" type="button" data-level="error">errors</button>
|
|
915
956
|
<button class="filter-chip" type="button" data-level="warn">warn</button>
|
|
916
957
|
</div>
|
|
917
958
|
<div id="console-rows" class="panel-content"></div>
|
|
918
|
-
<div class="panel-pending" id="console-pending">Console output will appear during playback.</div>
|
|
959
|
+
<div class="panel-pending" id="console-pending" role="status" aria-live="polite">Console output will appear during playback.</div>
|
|
919
960
|
</div>
|
|
920
961
|
|
|
921
|
-
<div class="panel-pane" id="pane-network" role="tabpanel">
|
|
962
|
+
<div class="panel-pane" id="pane-network" role="tabpanel" aria-labelledby="tab-network">
|
|
922
963
|
<div class="panel-toolbar">
|
|
923
964
|
<input type="text" class="panel-filter" placeholder="Filter URLs…" aria-label="Filter network requests" />
|
|
924
965
|
</div>
|
|
925
966
|
<div id="network-rows" class="panel-content"></div>
|
|
926
|
-
<div class="panel-pending" id="network-pending">Network errors will appear during playback.</div>
|
|
967
|
+
<div class="panel-pending" id="network-pending" role="status" aria-live="polite">Network errors will appear during playback.</div>
|
|
927
968
|
</div>
|
|
928
969
|
|
|
929
|
-
<div class="panel-pane" id="pane-actions" role="tabpanel">
|
|
970
|
+
<div class="panel-pane" id="pane-actions" role="tabpanel" aria-labelledby="tab-actions">
|
|
930
971
|
<div class="coming-soon">
|
|
931
972
|
<strong>Actions panel — coming soon</strong>
|
|
932
973
|
<span>User-input event extraction lands in a follow-up changeset.</span>
|
|
@@ -934,7 +975,7 @@ ${banner}
|
|
|
934
975
|
</div>
|
|
935
976
|
</div>
|
|
936
977
|
|
|
937
|
-
<div class="panel-pane" id="pane-timeline" role="tabpanel">
|
|
978
|
+
<div class="panel-pane" id="pane-timeline" role="tabpanel" aria-labelledby="tab-timeline">
|
|
938
979
|
<div class="coming-soon">
|
|
939
980
|
<strong>Timeline panel — coming soon</strong>
|
|
940
981
|
<span>Use the rrweb-player scrubber above to navigate the recording today.</span>
|
|
@@ -953,7 +994,7 @@ ${banner}
|
|
|
953
994
|
<script>${loadPlayerUmd()}</script>
|
|
954
995
|
<script>${dataScript}</script>
|
|
955
996
|
<script>${BOOTSTRAP}</script>
|
|
956
|
-
${FOOTER_HTML}
|
|
997
|
+
${footer ? FOOTER_HTML : ''}
|
|
957
998
|
</body>
|
|
958
999
|
</html>`;
|
|
959
1000
|
}
|
package/dist/template.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,gCAAgC;AAChC,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,0EAA0E;AAC1E,4EAA4E;AAC5E,8CAA8C;AAE9C,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracelane/report",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.12",
|
|
4
4
|
"description": "Self-contained, offline HTML report builder for tracelane. Embeds the rrweb player and a gzipped event blob into a single .html file.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tracelane",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"@fontsource-variable/jetbrains-mono": "^5.2.7",
|
|
35
35
|
"fflate": "^0.8.2",
|
|
36
36
|
"rrweb-player": "1.0.0-alpha.4",
|
|
37
|
-
"@cubenest/rrweb-core": "0.1.0-alpha.
|
|
38
|
-
"@tracelane/core": "0.1.0-alpha.
|
|
37
|
+
"@cubenest/rrweb-core": "0.1.0-alpha.5",
|
|
38
|
+
"@tracelane/core": "0.1.0-alpha.10"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"jsdom": "^25.0.1"
|
|
@@ -49,7 +49,13 @@
|
|
|
49
49
|
"url": "https://github.com/Cubenest/rrweb-stack",
|
|
50
50
|
"directory": "packages/tracelane-report"
|
|
51
51
|
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/Cubenest/rrweb-stack/issues"
|
|
54
|
+
},
|
|
52
55
|
"homepage": "https://github.com/Cubenest/rrweb-stack/tree/main/packages/tracelane-report#readme",
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20.18.0"
|
|
58
|
+
},
|
|
53
59
|
"scripts": {
|
|
54
60
|
"build": "tsc -p tsconfig.json",
|
|
55
61
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|