@tracelane/report 0.1.0-alpha.11 → 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 +60 -23
- 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;
|
|
@@ -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)));
|
|
@@ -715,23 +738,34 @@ const BOOTSTRAP = `
|
|
|
715
738
|
}
|
|
716
739
|
tickPanels(0);
|
|
717
740
|
|
|
718
|
-
// ---- 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).
|
|
719
744
|
if (rrPlayer && typeof rrPlayer.goto === 'function') {
|
|
720
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
|
+
};
|
|
721
758
|
for (var sc = 0; sc < seekContainers.length; sc++) {
|
|
722
759
|
(function (containerId) {
|
|
723
760
|
var ctr = document.getElementById(containerId);
|
|
724
761
|
if (!ctr) return;
|
|
725
762
|
ctr.addEventListener('click', function (ev) {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
var t = parseInt(target.getAttribute('data-time') || '0', 10);
|
|
733
|
-
if (isFinite(t) && t >= 0) {
|
|
734
|
-
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);
|
|
735
769
|
}
|
|
736
770
|
});
|
|
737
771
|
})(seekContainers[sc]);
|
|
@@ -745,7 +779,10 @@ const BOOTSTRAP = `
|
|
|
745
779
|
(function (tab) {
|
|
746
780
|
tab.addEventListener('click', function () {
|
|
747
781
|
var targetId = tab.getAttribute('data-pane');
|
|
748
|
-
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
|
+
}
|
|
749
786
|
for (var j = 0; j < panes.length; j++) {
|
|
750
787
|
panes[j].classList.toggle('active', panes[j].id === targetId);
|
|
751
788
|
}
|
|
@@ -857,7 +894,7 @@ function formatRelativeMs(ms) {
|
|
|
857
894
|
}
|
|
858
895
|
/** Compose the full self-contained HTML document. */
|
|
859
896
|
export function renderReportHtml(data) {
|
|
860
|
-
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;
|
|
861
898
|
const title = `tracelane — ${meta.spec ?? '(no spec)'} :: ${meta.title} (${meta.status})`;
|
|
862
899
|
// Banner only when the events were pruned to fit the size cap (ADR-0005).
|
|
863
900
|
const banner = pruned
|
|
@@ -898,21 +935,21 @@ ${banner}
|
|
|
898
935
|
</section>
|
|
899
936
|
<aside class="panels" aria-label="Investigation panels">
|
|
900
937
|
<div class="tabs" role="tablist">
|
|
901
|
-
<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">
|
|
902
939
|
Console <span class="count">0</span><span class="count-total">/ ${consoleCount}</span>
|
|
903
940
|
</button>
|
|
904
|
-
<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">
|
|
905
942
|
Network <span class="count">0</span><span class="count-total">/ ${networkCount}</span>
|
|
906
943
|
</button>
|
|
907
|
-
<button class="tab" type="button" role="tab" data-pane="pane-actions">
|
|
908
|
-
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>
|
|
909
946
|
</button>
|
|
910
|
-
<button class="tab" type="button" role="tab" data-pane="pane-timeline">
|
|
911
|
-
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>
|
|
912
949
|
</button>
|
|
913
950
|
</div>
|
|
914
951
|
|
|
915
|
-
<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">
|
|
916
953
|
<div class="panel-toolbar">
|
|
917
954
|
<input type="text" class="panel-filter" placeholder="Filter console…" aria-label="Filter console messages" />
|
|
918
955
|
<button class="filter-chip" type="button" data-level="error">errors</button>
|
|
@@ -922,7 +959,7 @@ ${banner}
|
|
|
922
959
|
<div class="panel-pending" id="console-pending" role="status" aria-live="polite">Console output will appear during playback.</div>
|
|
923
960
|
</div>
|
|
924
961
|
|
|
925
|
-
<div class="panel-pane" id="pane-network" role="tabpanel">
|
|
962
|
+
<div class="panel-pane" id="pane-network" role="tabpanel" aria-labelledby="tab-network">
|
|
926
963
|
<div class="panel-toolbar">
|
|
927
964
|
<input type="text" class="panel-filter" placeholder="Filter URLs…" aria-label="Filter network requests" />
|
|
928
965
|
</div>
|
|
@@ -930,7 +967,7 @@ ${banner}
|
|
|
930
967
|
<div class="panel-pending" id="network-pending" role="status" aria-live="polite">Network errors will appear during playback.</div>
|
|
931
968
|
</div>
|
|
932
969
|
|
|
933
|
-
<div class="panel-pane" id="pane-actions" role="tabpanel">
|
|
970
|
+
<div class="panel-pane" id="pane-actions" role="tabpanel" aria-labelledby="tab-actions">
|
|
934
971
|
<div class="coming-soon">
|
|
935
972
|
<strong>Actions panel — coming soon</strong>
|
|
936
973
|
<span>User-input event extraction lands in a follow-up changeset.</span>
|
|
@@ -938,7 +975,7 @@ ${banner}
|
|
|
938
975
|
</div>
|
|
939
976
|
</div>
|
|
940
977
|
|
|
941
|
-
<div class="panel-pane" id="pane-timeline" role="tabpanel">
|
|
978
|
+
<div class="panel-pane" id="pane-timeline" role="tabpanel" aria-labelledby="tab-timeline">
|
|
942
979
|
<div class="coming-soon">
|
|
943
980
|
<strong>Timeline panel — coming soon</strong>
|
|
944
981
|
<span>Use the rrweb-player scrubber above to navigate the recording today.</span>
|
|
@@ -957,7 +994,7 @@ ${banner}
|
|
|
957
994
|
<script>${loadPlayerUmd()}</script>
|
|
958
995
|
<script>${dataScript}</script>
|
|
959
996
|
<script>${BOOTSTRAP}</script>
|
|
960
|
-
${FOOTER_HTML}
|
|
997
|
+
${footer ? FOOTER_HTML : ''}
|
|
961
998
|
</body>
|
|
962
999
|
</html>`;
|
|
963
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",
|