@monoes/monobrowse 1.0.12 → 1.0.14

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.
Files changed (271) hide show
  1. package/dist/src/__tests__/bridge-instruments.test.d.ts +2 -0
  2. package/dist/src/__tests__/bridge-instruments.test.d.ts.map +1 -0
  3. package/dist/src/__tests__/bridge-instruments.test.js +132 -0
  4. package/dist/src/__tests__/bridge-instruments.test.js.map +1 -0
  5. package/dist/src/__tests__/bridge-transport.test.d.ts +2 -0
  6. package/dist/src/__tests__/bridge-transport.test.d.ts.map +1 -0
  7. package/dist/src/__tests__/bridge-transport.test.js +287 -0
  8. package/dist/src/__tests__/bridge-transport.test.js.map +1 -0
  9. package/dist/src/__tests__/cdp-transport.test.d.ts +2 -0
  10. package/dist/src/__tests__/cdp-transport.test.d.ts.map +1 -0
  11. package/dist/src/__tests__/cdp-transport.test.js +167 -0
  12. package/dist/src/__tests__/cdp-transport.test.js.map +1 -0
  13. package/dist/src/__tests__/profiler-heap.test.d.ts +2 -0
  14. package/dist/src/__tests__/profiler-heap.test.d.ts.map +1 -0
  15. package/dist/src/__tests__/profiler-heap.test.js +154 -0
  16. package/dist/src/__tests__/profiler-heap.test.js.map +1 -0
  17. package/dist/src/__tests__/report-a11y.test.d.ts +2 -0
  18. package/dist/src/__tests__/report-a11y.test.d.ts.map +1 -0
  19. package/dist/src/__tests__/report-a11y.test.js +147 -0
  20. package/dist/src/__tests__/report-a11y.test.js.map +1 -0
  21. package/dist/src/__tests__/report-analyze.test.d.ts +2 -0
  22. package/dist/src/__tests__/report-analyze.test.d.ts.map +1 -0
  23. package/dist/src/__tests__/report-analyze.test.js +157 -0
  24. package/dist/src/__tests__/report-analyze.test.js.map +1 -0
  25. package/dist/src/__tests__/report-budget.test.d.ts +2 -0
  26. package/dist/src/__tests__/report-budget.test.d.ts.map +1 -0
  27. package/dist/src/__tests__/report-budget.test.js +80 -0
  28. package/dist/src/__tests__/report-budget.test.js.map +1 -0
  29. package/dist/src/__tests__/report-diff.test.d.ts +2 -0
  30. package/dist/src/__tests__/report-diff.test.d.ts.map +1 -0
  31. package/dist/src/__tests__/report-diff.test.js +231 -0
  32. package/dist/src/__tests__/report-diff.test.js.map +1 -0
  33. package/dist/src/__tests__/report-evidence.test.d.ts +2 -0
  34. package/dist/src/__tests__/report-evidence.test.d.ts.map +1 -0
  35. package/dist/src/__tests__/report-evidence.test.js +214 -0
  36. package/dist/src/__tests__/report-evidence.test.js.map +1 -0
  37. package/dist/src/__tests__/report-flake.test.d.ts +2 -0
  38. package/dist/src/__tests__/report-flake.test.d.ts.map +1 -0
  39. package/dist/src/__tests__/report-flake.test.js +182 -0
  40. package/dist/src/__tests__/report-flake.test.js.map +1 -0
  41. package/dist/src/__tests__/report-history.test.d.ts +2 -0
  42. package/dist/src/__tests__/report-history.test.d.ts.map +1 -0
  43. package/dist/src/__tests__/report-history.test.js +229 -0
  44. package/dist/src/__tests__/report-history.test.js.map +1 -0
  45. package/dist/src/__tests__/report-output.test.d.ts +2 -0
  46. package/dist/src/__tests__/report-output.test.d.ts.map +1 -0
  47. package/dist/src/__tests__/report-output.test.js +169 -0
  48. package/dist/src/__tests__/report-output.test.js.map +1 -0
  49. package/dist/src/__tests__/report-png.test.d.ts +2 -0
  50. package/dist/src/__tests__/report-png.test.d.ts.map +1 -0
  51. package/dist/src/__tests__/report-png.test.js +84 -0
  52. package/dist/src/__tests__/report-png.test.js.map +1 -0
  53. package/dist/src/__tests__/report-render-extras.test.d.ts +2 -0
  54. package/dist/src/__tests__/report-render-extras.test.d.ts.map +1 -0
  55. package/dist/src/__tests__/report-render-extras.test.js +285 -0
  56. package/dist/src/__tests__/report-render-extras.test.js.map +1 -0
  57. package/dist/src/__tests__/report-render.test.d.ts +2 -0
  58. package/dist/src/__tests__/report-render.test.d.ts.map +1 -0
  59. package/dist/src/__tests__/report-render.test.js +143 -0
  60. package/dist/src/__tests__/report-render.test.js.map +1 -0
  61. package/dist/src/__tests__/report-run.test.d.ts +2 -0
  62. package/dist/src/__tests__/report-run.test.d.ts.map +1 -0
  63. package/dist/src/__tests__/report-run.test.js +234 -0
  64. package/dist/src/__tests__/report-run.test.js.map +1 -0
  65. package/dist/src/browser/bridge.d.ts +119 -0
  66. package/dist/src/browser/bridge.d.ts.map +1 -0
  67. package/dist/src/browser/bridge.js +264 -0
  68. package/dist/src/browser/bridge.js.map +1 -0
  69. package/dist/src/browser/cdp.d.ts +11 -1
  70. package/dist/src/browser/cdp.d.ts.map +1 -1
  71. package/dist/src/browser/cdp.js +60 -56
  72. package/dist/src/browser/cdp.js.map +1 -1
  73. package/dist/src/browser/index.d.ts +3 -0
  74. package/dist/src/browser/index.d.ts.map +1 -1
  75. package/dist/src/browser/index.js +3 -0
  76. package/dist/src/browser/index.js.map +1 -1
  77. package/dist/src/browser/profiler.d.ts.map +1 -1
  78. package/dist/src/browser/profiler.js +19 -22
  79. package/dist/src/browser/profiler.js.map +1 -1
  80. package/dist/src/browser/transport.d.ts +62 -0
  81. package/dist/src/browser/transport.d.ts.map +1 -0
  82. package/dist/src/browser/transport.js +65 -0
  83. package/dist/src/browser/transport.js.map +1 -0
  84. package/dist/src/cli/commander-adapter.d.ts +16 -0
  85. package/dist/src/cli/commander-adapter.d.ts.map +1 -0
  86. package/dist/src/cli/commander-adapter.js +68 -0
  87. package/dist/src/cli/commander-adapter.js.map +1 -0
  88. package/dist/src/cli/commands-context.d.ts +14 -0
  89. package/dist/src/cli/commands-context.d.ts.map +1 -0
  90. package/dist/src/cli/commands-context.js +351 -0
  91. package/dist/src/cli/commands-context.js.map +1 -0
  92. package/dist/src/cli/commands-data.d.ts +12 -0
  93. package/dist/src/cli/commands-data.d.ts.map +1 -0
  94. package/dist/src/cli/commands-data.js +246 -0
  95. package/dist/src/cli/commands-data.js.map +1 -0
  96. package/dist/src/cli/commands-element.d.ts +15 -0
  97. package/dist/src/cli/commands-element.d.ts.map +1 -0
  98. package/dist/src/cli/commands-element.js +262 -0
  99. package/dist/src/cli/commands-element.js.map +1 -0
  100. package/dist/src/cli/commands-files.d.ts +9 -0
  101. package/dist/src/cli/commands-files.d.ts.map +1 -0
  102. package/dist/src/cli/commands-files.js +207 -0
  103. package/dist/src/cli/commands-files.js.map +1 -0
  104. package/dist/src/cli/commands-input.d.ts +26 -0
  105. package/dist/src/cli/commands-input.d.ts.map +1 -0
  106. package/dist/src/cli/commands-input.js +399 -0
  107. package/dist/src/cli/commands-input.js.map +1 -0
  108. package/dist/src/cli/commands-navigate.d.ts +12 -0
  109. package/dist/src/cli/commands-navigate.d.ts.map +1 -0
  110. package/dist/src/cli/commands-navigate.js +389 -0
  111. package/dist/src/cli/commands-navigate.js.map +1 -0
  112. package/dist/src/cli/commands-page.d.ts +25 -0
  113. package/dist/src/cli/commands-page.d.ts.map +1 -0
  114. package/dist/src/cli/commands-page.js +377 -0
  115. package/dist/src/cli/commands-page.js.map +1 -0
  116. package/dist/src/cli/commands-report.d.ts +8 -0
  117. package/dist/src/cli/commands-report.d.ts.map +1 -0
  118. package/dist/src/cli/commands-report.js +256 -0
  119. package/dist/src/cli/commands-report.js.map +1 -0
  120. package/dist/src/cli/commands-script.d.ts +43 -0
  121. package/dist/src/cli/commands-script.d.ts.map +1 -0
  122. package/dist/src/cli/commands-script.js +168 -0
  123. package/dist/src/cli/commands-script.js.map +1 -0
  124. package/dist/src/cli/commands-session.d.ts +15 -0
  125. package/dist/src/cli/commands-session.d.ts.map +1 -0
  126. package/dist/src/cli/commands-session.js +357 -0
  127. package/dist/src/cli/commands-session.js.map +1 -0
  128. package/dist/src/cli/commands-trace.d.ts +12 -0
  129. package/dist/src/cli/commands-trace.d.ts.map +1 -0
  130. package/dist/src/cli/commands-trace.js +347 -0
  131. package/dist/src/cli/commands-trace.js.map +1 -0
  132. package/dist/src/cli/commands.d.ts +22 -42
  133. package/dist/src/cli/commands.d.ts.map +1 -1
  134. package/dist/src/cli/commands.js +48 -3400
  135. package/dist/src/cli/commands.js.map +1 -1
  136. package/dist/src/cli/session.d.ts +47 -0
  137. package/dist/src/cli/session.d.ts.map +1 -0
  138. package/dist/src/cli/session.js +343 -0
  139. package/dist/src/cli/session.js.map +1 -0
  140. package/dist/src/report/a11y.d.ts +52 -0
  141. package/dist/src/report/a11y.d.ts.map +1 -0
  142. package/dist/src/report/a11y.js +231 -0
  143. package/dist/src/report/a11y.js.map +1 -0
  144. package/dist/src/report/analyze.d.ts +20 -0
  145. package/dist/src/report/analyze.d.ts.map +1 -0
  146. package/dist/src/report/analyze.js +136 -0
  147. package/dist/src/report/analyze.js.map +1 -0
  148. package/dist/src/report/budget.d.ts +27 -0
  149. package/dist/src/report/budget.d.ts.map +1 -0
  150. package/dist/src/report/budget.js +143 -0
  151. package/dist/src/report/budget.js.map +1 -0
  152. package/dist/src/report/collect-a11y.d.ts +25 -0
  153. package/dist/src/report/collect-a11y.d.ts.map +1 -0
  154. package/dist/src/report/collect-a11y.js +154 -0
  155. package/dist/src/report/collect-a11y.js.map +1 -0
  156. package/dist/src/report/collect.d.ts +45 -0
  157. package/dist/src/report/collect.d.ts.map +1 -0
  158. package/dist/src/report/collect.js +275 -0
  159. package/dist/src/report/collect.js.map +1 -0
  160. package/dist/src/report/evidence.d.ts +80 -0
  161. package/dist/src/report/evidence.d.ts.map +1 -0
  162. package/dist/src/report/evidence.js +279 -0
  163. package/dist/src/report/evidence.js.map +1 -0
  164. package/dist/src/report/flake.d.ts +88 -0
  165. package/dist/src/report/flake.d.ts.map +1 -0
  166. package/dist/src/report/flake.js +232 -0
  167. package/dist/src/report/flake.js.map +1 -0
  168. package/dist/src/report/history.d.ts +85 -0
  169. package/dist/src/report/history.d.ts.map +1 -0
  170. package/dist/src/report/history.js +176 -0
  171. package/dist/src/report/history.js.map +1 -0
  172. package/dist/src/report/index.d.ts +102 -0
  173. package/dist/src/report/index.d.ts.map +1 -0
  174. package/dist/src/report/index.js +216 -0
  175. package/dist/src/report/index.js.map +1 -0
  176. package/dist/src/report/pixel-diff.d.ts +30 -0
  177. package/dist/src/report/pixel-diff.d.ts.map +1 -0
  178. package/dist/src/report/pixel-diff.js +175 -0
  179. package/dist/src/report/pixel-diff.js.map +1 -0
  180. package/dist/src/report/png.d.ts +28 -0
  181. package/dist/src/report/png.d.ts.map +1 -0
  182. package/dist/src/report/png.js +259 -0
  183. package/dist/src/report/png.js.map +1 -0
  184. package/dist/src/report/render-evidence.d.ts +16 -0
  185. package/dist/src/report/render-evidence.d.ts.map +1 -0
  186. package/dist/src/report/render-evidence.js +174 -0
  187. package/dist/src/report/render-evidence.js.map +1 -0
  188. package/dist/src/report/render-trend.d.ts +16 -0
  189. package/dist/src/report/render-trend.d.ts.map +1 -0
  190. package/dist/src/report/render-trend.js +194 -0
  191. package/dist/src/report/render-trend.js.map +1 -0
  192. package/dist/src/report/render.d.ts +21 -0
  193. package/dist/src/report/render.d.ts.map +1 -0
  194. package/dist/src/report/render.js +286 -0
  195. package/dist/src/report/render.js.map +1 -0
  196. package/dist/src/report/run-diff.d.ts +18 -0
  197. package/dist/src/report/run-diff.d.ts.map +1 -0
  198. package/dist/src/report/run-diff.js +51 -0
  199. package/dist/src/report/run-diff.js.map +1 -0
  200. package/dist/src/report/structure.d.ts +41 -0
  201. package/dist/src/report/structure.d.ts.map +1 -0
  202. package/dist/src/report/structure.js +210 -0
  203. package/dist/src/report/structure.js.map +1 -0
  204. package/dist/src/report/trend.d.ts +26 -0
  205. package/dist/src/report/trend.d.ts.map +1 -0
  206. package/dist/src/report/trend.js +164 -0
  207. package/dist/src/report/trend.js.map +1 -0
  208. package/dist/src/report/types.d.ts +320 -0
  209. package/dist/src/report/types.d.ts.map +1 -0
  210. package/dist/src/report/types.js +11 -0
  211. package/dist/src/report/types.js.map +1 -0
  212. package/dist/src/report/util.d.ts +17 -0
  213. package/dist/src/report/util.d.ts.map +1 -0
  214. package/dist/src/report/util.js +45 -0
  215. package/dist/src/report/util.js.map +1 -0
  216. package/dist/tsconfig.tsbuildinfo +1 -1
  217. package/package.json +1 -1
  218. package/src/__tests__/bridge-instruments.test.ts +180 -0
  219. package/src/__tests__/bridge-transport.test.ts +365 -0
  220. package/src/__tests__/cdp-transport.test.ts +198 -0
  221. package/src/__tests__/profiler-heap.test.ts +191 -0
  222. package/src/__tests__/report-a11y.test.ts +180 -0
  223. package/src/__tests__/report-analyze.test.ts +202 -0
  224. package/src/__tests__/report-budget.test.ts +92 -0
  225. package/src/__tests__/report-diff.test.ts +272 -0
  226. package/src/__tests__/report-evidence.test.ts +276 -0
  227. package/src/__tests__/report-flake.test.ts +214 -0
  228. package/src/__tests__/report-history.test.ts +293 -0
  229. package/src/__tests__/report-output.test.ts +210 -0
  230. package/src/__tests__/report-png.test.ts +95 -0
  231. package/src/__tests__/report-render-extras.test.ts +315 -0
  232. package/src/__tests__/report-render.test.ts +175 -0
  233. package/src/__tests__/report-run.test.ts +264 -0
  234. package/src/browser/bridge.ts +354 -0
  235. package/src/browser/cdp.ts +57 -52
  236. package/src/browser/index.ts +3 -0
  237. package/src/browser/profiler.ts +28 -21
  238. package/src/browser/transport.ts +111 -0
  239. package/src/cli/commander-adapter.ts +65 -0
  240. package/src/cli/commands-context.ts +367 -0
  241. package/src/cli/commands-data.ts +248 -0
  242. package/src/cli/commands-element.ts +305 -0
  243. package/src/cli/commands-files.ts +248 -0
  244. package/src/cli/commands-input.ts +434 -0
  245. package/src/cli/commands-navigate.ts +442 -0
  246. package/src/cli/commands-page.ts +420 -0
  247. package/src/cli/commands-report.ts +275 -0
  248. package/src/cli/commands-script.ts +183 -0
  249. package/src/cli/commands-session.ts +376 -0
  250. package/src/cli/commands-trace.ts +349 -0
  251. package/src/cli/commands.ts +101 -3677
  252. package/src/cli/session.ts +412 -0
  253. package/src/report/a11y.ts +242 -0
  254. package/src/report/analyze.ts +181 -0
  255. package/src/report/budget.ts +155 -0
  256. package/src/report/collect-a11y.ts +200 -0
  257. package/src/report/collect.ts +408 -0
  258. package/src/report/evidence.ts +379 -0
  259. package/src/report/flake.ts +303 -0
  260. package/src/report/history.ts +219 -0
  261. package/src/report/index.ts +307 -0
  262. package/src/report/pixel-diff.ts +197 -0
  263. package/src/report/png.ts +290 -0
  264. package/src/report/render-evidence.ts +194 -0
  265. package/src/report/render-trend.ts +225 -0
  266. package/src/report/render.ts +314 -0
  267. package/src/report/run-diff.ts +63 -0
  268. package/src/report/structure.ts +212 -0
  269. package/src/report/trend.ts +189 -0
  270. package/src/report/types.ts +356 -0
  271. package/src/report/util.ts +48 -0
@@ -0,0 +1,259 @@
1
+ /**
2
+ * A minimal PNG decoder and encoder built on node's own `zlib`.
3
+ *
4
+ * This exists so the pixel diff (RIG-10) can compare two screenshots without
5
+ * adding an image dependency to a package whose whole point is to be a small
6
+ * self-contained CDP client. PNG is simple enough to justify it: the format
7
+ * is a chunk list wrapping one zlib stream, and node ships the zlib.
8
+ *
9
+ * Scope is deliberately narrow — what `Page.captureScreenshot` actually
10
+ * emits. Non-interlaced, bit depth 8 (16 is accepted by taking the high
11
+ * byte), colour types 0/2/3/4/6. Anything else throws a message that names
12
+ * what it saw, so the caller can degrade to "pixel diff unavailable" instead
13
+ * of rendering a wrong picture.
14
+ */
15
+ import { deflateSync, inflateSync } from 'node:zlib';
16
+ const SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
17
+ // ---------------------------------------------------------------------------
18
+ // CRC32 — PNG chunks carry their own checksum, and zlib does not expose one.
19
+ // ---------------------------------------------------------------------------
20
+ const CRC_TABLE = (() => {
21
+ const table = new Uint32Array(256);
22
+ for (let n = 0; n < 256; n++) {
23
+ let c = n;
24
+ for (let k = 0; k < 8; k++)
25
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
26
+ table[n] = c >>> 0;
27
+ }
28
+ return table;
29
+ })();
30
+ export function crc32(buf) {
31
+ let c = 0xffffffff;
32
+ for (let i = 0; i < buf.length; i++)
33
+ c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
34
+ return (c ^ 0xffffffff) >>> 0;
35
+ }
36
+ // ---------------------------------------------------------------------------
37
+ // Decode
38
+ // ---------------------------------------------------------------------------
39
+ const CHANNELS = { 0: 1, 2: 3, 3: 1, 4: 2, 6: 4 };
40
+ function paeth(a, b, c) {
41
+ const p = a + b - c;
42
+ const pa = Math.abs(p - a);
43
+ const pb = Math.abs(p - b);
44
+ const pc = Math.abs(p - c);
45
+ if (pa <= pb && pa <= pc)
46
+ return a;
47
+ return pb <= pc ? b : c;
48
+ }
49
+ /** Undo the per-scanline filters in place, returning the raw sample bytes. */
50
+ function unfilter(raw, width, height, bpp, stride) {
51
+ const out = Buffer.alloc(height * stride);
52
+ let pos = 0;
53
+ for (let y = 0; y < height; y++) {
54
+ const filter = raw[pos++];
55
+ const line = raw.subarray(pos, pos + stride);
56
+ pos += stride;
57
+ const cur = out.subarray(y * stride, (y + 1) * stride);
58
+ const prev = y > 0 ? out.subarray((y - 1) * stride, y * stride) : null;
59
+ for (let x = 0; x < stride; x++) {
60
+ const a = x >= bpp ? cur[x - bpp] : 0;
61
+ const b = prev ? prev[x] : 0;
62
+ const c = prev && x >= bpp ? prev[x - bpp] : 0;
63
+ const v = line[x];
64
+ switch (filter) {
65
+ case 0:
66
+ cur[x] = v;
67
+ break;
68
+ case 1:
69
+ cur[x] = (v + a) & 0xff;
70
+ break;
71
+ case 2:
72
+ cur[x] = (v + b) & 0xff;
73
+ break;
74
+ case 3:
75
+ cur[x] = (v + ((a + b) >> 1)) & 0xff;
76
+ break;
77
+ case 4:
78
+ cur[x] = (v + paeth(a, b, c)) & 0xff;
79
+ break;
80
+ default:
81
+ throw new Error(`PNG: unknown scanline filter ${filter} on row ${y}`);
82
+ }
83
+ }
84
+ }
85
+ void width;
86
+ return out;
87
+ }
88
+ function readHeader(buf, offset) {
89
+ return {
90
+ width: buf.readUInt32BE(offset),
91
+ height: buf.readUInt32BE(offset + 4),
92
+ bitDepth: buf[offset + 8],
93
+ colorType: buf[offset + 9],
94
+ interlace: buf[offset + 12],
95
+ };
96
+ }
97
+ /**
98
+ * Expand one row of decoded samples into RGBA. `step` is the byte stride of
99
+ * one sample (1 for bit depth 8, 2 for 16 — where we keep the high byte).
100
+ */
101
+ function toRgba(samples, header, palette, transparency) {
102
+ const { width, height, bitDepth, colorType } = header;
103
+ const channels = CHANNELS[colorType];
104
+ const step = bitDepth === 16 ? 2 : 1;
105
+ const stride = width * channels * step;
106
+ const out = new Uint8Array(width * height * 4);
107
+ for (let y = 0; y < height; y++) {
108
+ for (let x = 0; x < width; x++) {
109
+ const s = y * stride + x * channels * step;
110
+ const d = (y * width + x) * 4;
111
+ if (colorType === 3) {
112
+ const index = samples[s];
113
+ if (!palette || index * 3 + 2 >= palette.length) {
114
+ throw new Error(`PNG: palette index ${index} out of range`);
115
+ }
116
+ out[d] = palette[index * 3];
117
+ out[d + 1] = palette[index * 3 + 1];
118
+ out[d + 2] = palette[index * 3 + 2];
119
+ out[d + 3] = transparency && index < transparency.length ? transparency[index] : 255;
120
+ }
121
+ else if (colorType === 0) {
122
+ const g = samples[s];
123
+ out[d] = g;
124
+ out[d + 1] = g;
125
+ out[d + 2] = g;
126
+ out[d + 3] = 255;
127
+ }
128
+ else if (colorType === 4) {
129
+ const g = samples[s];
130
+ out[d] = g;
131
+ out[d + 1] = g;
132
+ out[d + 2] = g;
133
+ out[d + 3] = samples[s + step];
134
+ }
135
+ else if (colorType === 2) {
136
+ out[d] = samples[s];
137
+ out[d + 1] = samples[s + step];
138
+ out[d + 2] = samples[s + 2 * step];
139
+ out[d + 3] = 255;
140
+ }
141
+ else {
142
+ out[d] = samples[s];
143
+ out[d + 1] = samples[s + step];
144
+ out[d + 2] = samples[s + 2 * step];
145
+ out[d + 3] = samples[s + 3 * step];
146
+ }
147
+ }
148
+ }
149
+ return out;
150
+ }
151
+ export function decodePng(input) {
152
+ const buf = Buffer.from(input.buffer, input.byteOffset, input.byteLength);
153
+ if (buf.length < 8 || !buf.subarray(0, 8).equals(SIGNATURE)) {
154
+ throw new Error('PNG: not a PNG (bad signature)');
155
+ }
156
+ let header = null;
157
+ let palette = null;
158
+ let transparency = null;
159
+ const idat = [];
160
+ let pos = 8;
161
+ while (pos + 8 <= buf.length) {
162
+ const length = buf.readUInt32BE(pos);
163
+ const type = buf.toString('ascii', pos + 4, pos + 8);
164
+ const dataStart = pos + 8;
165
+ if (dataStart + length > buf.length)
166
+ throw new Error(`PNG: truncated ${type} chunk`);
167
+ if (type === 'IHDR')
168
+ header = readHeader(buf, dataStart);
169
+ else if (type === 'PLTE')
170
+ palette = buf.subarray(dataStart, dataStart + length);
171
+ else if (type === 'tRNS')
172
+ transparency = buf.subarray(dataStart, dataStart + length);
173
+ else if (type === 'IDAT')
174
+ idat.push(buf.subarray(dataStart, dataStart + length));
175
+ else if (type === 'IEND')
176
+ break;
177
+ pos = dataStart + length + 4;
178
+ }
179
+ if (!header)
180
+ throw new Error('PNG: no IHDR chunk');
181
+ if (header.interlace !== 0) {
182
+ throw new Error('PNG: interlaced (Adam7) images are not supported');
183
+ }
184
+ if (header.bitDepth !== 8 && header.bitDepth !== 16) {
185
+ throw new Error(`PNG: unsupported bit depth ${header.bitDepth} (need 8 or 16)`);
186
+ }
187
+ const channels = CHANNELS[header.colorType];
188
+ if (channels === undefined) {
189
+ throw new Error(`PNG: unsupported colour type ${header.colorType}`);
190
+ }
191
+ if (header.colorType === 3 && header.bitDepth !== 8) {
192
+ throw new Error(`PNG: palette images below bit depth 8 are not supported`);
193
+ }
194
+ if (!idat.length)
195
+ throw new Error('PNG: no IDAT data');
196
+ const sampleBytes = header.bitDepth === 16 ? 2 : 1;
197
+ const stride = header.width * channels * sampleBytes;
198
+ const bpp = Math.max(1, channels * sampleBytes);
199
+ const inflated = inflateSync(Buffer.concat(idat));
200
+ const expected = header.height * (stride + 1);
201
+ if (inflated.length < expected) {
202
+ throw new Error(`PNG: pixel data short by ${expected - inflated.length} bytes`);
203
+ }
204
+ const samples = unfilter(inflated, header.width, header.height, bpp, stride);
205
+ return {
206
+ width: header.width,
207
+ height: header.height,
208
+ data: toRgba(samples, header, palette, transparency),
209
+ };
210
+ }
211
+ // ---------------------------------------------------------------------------
212
+ // Encode
213
+ // ---------------------------------------------------------------------------
214
+ function chunk(type, data) {
215
+ const head = Buffer.alloc(8);
216
+ head.writeUInt32BE(data.length, 0);
217
+ head.write(type, 4, 'ascii');
218
+ const body = Buffer.concat([head.subarray(4), Buffer.from(data)]);
219
+ const crc = Buffer.alloc(4);
220
+ crc.writeUInt32BE(crc32(body), 0);
221
+ return Buffer.concat([head.subarray(0, 4), body, crc]);
222
+ }
223
+ /** Encode RGBA bytes as a non-interlaced, 8-bit truecolour-with-alpha PNG. */
224
+ export function encodePng(image) {
225
+ const { width, height, data } = image;
226
+ if (data.length !== width * height * 4) {
227
+ throw new Error(`PNG: encode expected ${width * height * 4} bytes for ${width}x${height}, got ${data.length}`);
228
+ }
229
+ const stride = width * 4;
230
+ const raw = Buffer.alloc(height * (stride + 1));
231
+ for (let y = 0; y < height; y++) {
232
+ raw[y * (stride + 1)] = 0; // filter: None. Simplest, and deflate still wins.
233
+ Buffer.from(data.buffer, data.byteOffset + y * stride, stride).copy(raw, y * (stride + 1) + 1);
234
+ }
235
+ const ihdr = Buffer.alloc(13);
236
+ ihdr.writeUInt32BE(width, 0);
237
+ ihdr.writeUInt32BE(height, 4);
238
+ ihdr[8] = 8; // bit depth
239
+ ihdr[9] = 6; // colour type: RGBA
240
+ ihdr[10] = 0; // compression
241
+ ihdr[11] = 0; // filter
242
+ ihdr[12] = 0; // interlace
243
+ return Buffer.concat([
244
+ SIGNATURE,
245
+ chunk('IHDR', ihdr),
246
+ chunk('IDAT', deflateSync(raw, { level: 6 })),
247
+ chunk('IEND', new Uint8Array(0)),
248
+ ]);
249
+ }
250
+ /** `data:image/png;base64,...` -> bytes. Accepts a bare base64 payload too. */
251
+ export function pngFromDataUrl(dataUrl) {
252
+ const comma = dataUrl.indexOf(',');
253
+ const payload = dataUrl.startsWith('data:') && comma >= 0 ? dataUrl.slice(comma + 1) : dataUrl;
254
+ return new Uint8Array(Buffer.from(payload, 'base64'));
255
+ }
256
+ export function pngToDataUrl(png) {
257
+ return `data:image/png;base64,${Buffer.from(png).toString('base64')}`;
258
+ }
259
+ //# sourceMappingURL=png.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"png.js","sourceRoot":"","sources":["../../../src/report/png.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Report sections for the recorded evidence timeline (RIG-11) and the flake
3
+ * analysis (RIG-14).
4
+ *
5
+ * The evidence section is written to be read the way someone triages a bug:
6
+ * a filmstrip of what the page looked like either side of the failure, then
7
+ * one time-ordered list mixing frames, console output and network failures,
8
+ * so "the error fired, then the screen went blank" is visible rather than
9
+ * inferred.
10
+ */
11
+ import type { FlakeReport } from './flake.js';
12
+ import type { Evidence } from './types.js';
13
+ export declare const EVIDENCE_STYLES: string;
14
+ export declare function renderEvidence(evidence: Evidence | undefined): string;
15
+ export declare function renderFlake(flake: FlakeReport | undefined): string;
16
+ //# sourceMappingURL=render-evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-evidence.d.ts","sourceRoot":"","sources":["../../../src/report/render-evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,YAAY,CAAC;AAG1D,eAAO,MAAM,eAAe,QAqBpB,CAAC;AAsDT,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAmBrE;AAwED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAYlE"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Report sections for the recorded evidence timeline (RIG-11) and the flake
3
+ * analysis (RIG-14).
4
+ *
5
+ * The evidence section is written to be read the way someone triages a bug:
6
+ * a filmstrip of what the page looked like either side of the failure, then
7
+ * one time-ordered list mixing frames, console output and network failures,
8
+ * so "the error fired, then the screen went blank" is visible rather than
9
+ * inferred.
10
+ */
11
+ import { escapeHtml } from './util.js';
12
+ export const EVIDENCE_STYLES = `
13
+ .filmstrip{display:flex;gap:10px;overflow-x:auto;padding:4px 0 10px;margin:0 0 8px}
14
+ .filmstrip figure{flex:0 0 auto;width:180px;margin:0}
15
+ .filmstrip img{width:180px;height:auto;border-radius:6px}
16
+ .filmstrip figcaption{font-variant-numeric:tabular-nums}
17
+ .filmstrip figure.focus img{border-color:var(--fail);border-width:2px}
18
+ .timeline{list-style:none;margin:0;padding:0;border-left:2px solid var(--line);
19
+ margin-left:8px}
20
+ .timeline li{position:relative;padding:6px 0 6px 18px;font-size:13px}
21
+ .timeline li::before{content:"";position:absolute;left:-5px;top:12px;width:8px;height:8px;
22
+ border-radius:50%;background:var(--muted)}
23
+ .timeline li.error::before{background:var(--fail)}
24
+ .timeline li.warning::before{background:var(--warn)}
25
+ .timeline li.marker{font-weight:600;color:var(--fail)}
26
+ .timeline .at{display:inline-block;min-width:66px;color:var(--muted);
27
+ font-variant-numeric:tabular-nums;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
28
+ .verdict.flaky{background:var(--warn-bg);border-color:var(--warn);color:var(--warn)}
29
+ .rate{display:inline-block;min-width:72px}
30
+ .bar{display:inline-block;width:80px;height:8px;border-radius:4px;background:var(--pass);
31
+ overflow:hidden;vertical-align:middle}
32
+ .bar i{display:block;height:100%;background:var(--fail)}
33
+ `.trim();
34
+ function at(offsetMs) {
35
+ const sign = offsetMs < 0 ? '−' : '+';
36
+ const abs = Math.abs(offsetMs);
37
+ return abs >= 1000 ? `${sign}${(abs / 1000).toFixed(2)}s` : `${sign}${Math.round(abs)}ms`;
38
+ }
39
+ // ---------------------------------------------------------------------------
40
+ // Evidence
41
+ // ---------------------------------------------------------------------------
42
+ function renderFilmstrip(evidence) {
43
+ if (!evidence.frames.length)
44
+ return '';
45
+ // Mark the frame closest to the failure so the eye lands on it first.
46
+ let focusIndex = -1;
47
+ if (evidence.focusOffsetMs !== null) {
48
+ let best = Infinity;
49
+ evidence.frames.forEach((f, i) => {
50
+ const d = Math.abs(f.offsetMs - evidence.focusOffsetMs);
51
+ if (d < best) {
52
+ best = d;
53
+ focusIndex = i;
54
+ }
55
+ });
56
+ }
57
+ const figures = evidence.frames
58
+ .map((f, i) => `<figure class="${i === focusIndex ? 'focus' : ''}">
59
+ <figcaption>${escapeHtml(at(f.offsetMs))}${i === focusIndex ? ' · at failure' : ''}</figcaption>
60
+ <img alt="${escapeHtml(`Frame at ${at(f.offsetMs)}`)}" src="${escapeHtml(f.dataUrl)}">
61
+ </figure>`)
62
+ .join('');
63
+ return `<div class="filmstrip">${figures}</div>`;
64
+ }
65
+ function renderTimelineRows(timeline) {
66
+ if (!timeline.length)
67
+ return '<p class="empty">Nothing was recorded for this run.</p>';
68
+ const rows = timeline
69
+ .map((e) => {
70
+ const detail = e.detail ? ` — ${escapeHtml(e.detail)}` : '';
71
+ const frame = e.kind === 'frame' && e.frameIndex !== undefined
72
+ ? ` <span style="color:var(--muted)">#${e.frameIndex + 1}</span>`
73
+ : '';
74
+ return `<li class="${e.severity}${e.kind === 'marker' ? ' marker' : ''}">
75
+ <span class="at">${escapeHtml(at(e.offsetMs))}</span>${escapeHtml(e.label)}${frame}${detail}
76
+ </li>`;
77
+ })
78
+ .join('');
79
+ return `<ul class="timeline">${rows}</ul>`;
80
+ }
81
+ export function renderEvidence(evidence) {
82
+ if (!evidence)
83
+ return '';
84
+ const why = evidence.reason === 'budget-failure'
85
+ ? 'Recorded because this run breached its budget.'
86
+ : 'Recorded because --record was passed.';
87
+ const focus = evidence.focusOffsetMs !== null
88
+ ? ` The timeline is centred on the first failure, at ${at(evidence.focusOffsetMs)} into the run.`
89
+ : '';
90
+ const notes = evidence.notes.length
91
+ ? `<p class="note">${evidence.notes.map((n) => escapeHtml(n)).join(' ')}</p>`
92
+ : '';
93
+ return `<h2>Evidence</h2>
94
+ <p class="note">${escapeHtml(why)}${escapeHtml(focus)} Offsets are measured from the start of the run.</p>
95
+ ${renderFilmstrip(evidence)}
96
+ ${renderTimelineRows(evidence.timeline)}
97
+ ${notes}`;
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Flake
101
+ // ---------------------------------------------------------------------------
102
+ function rateBar(check) {
103
+ const pct = Math.round(check.flakeRate * 100);
104
+ return `<span class="bar" role="img" aria-label="${escapeHtml(`failed ${pct}% of runs`)}"><i style="width:${pct}%"></i></span>`;
105
+ }
106
+ function renderChecks(flake) {
107
+ const rows = flake.checks
108
+ // Unstable checks first: they are the reason this section exists.
109
+ .sort((a, b) => Number(a.stable) - Number(b.stable) || b.flakeRate - a.flakeRate)
110
+ .map((c) => `<tr>
111
+ <td>${escapeHtml(c.label)}</td>
112
+ <td class="num mono"><span class="rate">${c.passed} of ${c.runs} passed</span></td>
113
+ <td>${rateBar(c)}</td>
114
+ <td>${c.stable ? (c.failed ? '<span class="pill error">always fails</span>' : '<span class="pill good">stable</span>') : '<span class="pill warning">flaky</span>'}</td>
115
+ <td class="wrap mono">${escapeHtml(c.actuals.join(', '))}</td>
116
+ </tr>`)
117
+ .join('');
118
+ return `<table><thead><tr><th>Check</th><th>Outcome</th><th>Failure rate</th><th></th><th>Measured each run</th></tr></thead>
119
+ <tbody>${rows}</tbody></table>`;
120
+ }
121
+ function renderSignals(flake) {
122
+ if (!flake.signals.length) {
123
+ return '<p class="empty">No error or failed request came and went between runs.</p>';
124
+ }
125
+ const rows = flake.signals
126
+ .slice(0, 30)
127
+ .map((s) => `<tr>
128
+ <td>${escapeHtml(s.kind)}</td>
129
+ <td class="wrap">${escapeHtml(s.signature)}</td>
130
+ <td class="num mono">${s.runs} of ${s.total}</td>
131
+ </tr>`)
132
+ .join('');
133
+ return `<table><thead><tr><th>Kind</th><th>Signal</th><th>Appeared in</th></tr></thead><tbody>${rows}</tbody></table>
134
+ <p class="note">Ids, hashes and long numbers are normalised before grouping, so one intermittent error is one row rather than N.</p>`;
135
+ }
136
+ function renderMetricSpread(flake) {
137
+ if (!flake.metrics.length)
138
+ return '';
139
+ const rows = flake.metrics
140
+ .map((m) => {
141
+ const fmt = (v) => m.unit === 'score'
142
+ ? v.toFixed(3)
143
+ : v >= 1000
144
+ ? `${(v / 1000).toFixed(2)}s`
145
+ : `${Math.round(v)}ms`;
146
+ return `<tr>
147
+ <td><b>${escapeHtml(m.label)}</b></td>
148
+ <td class="num mono">${escapeHtml(fmt(m.min))} – ${escapeHtml(fmt(m.max))}</td>
149
+ <td class="num mono">${escapeHtml(fmt(m.median))}</td>
150
+ <td class="num mono">${escapeHtml(fmt(m.spread))}</td>
151
+ <td>${m.unstable ? '<span class="pill warning">varies widely</span>' : '<span class="pill good">consistent</span>'}</td>
152
+ <td class="num mono">${m.measured} of ${m.total}</td>
153
+ </tr>`;
154
+ })
155
+ .join('');
156
+ return `<h3 style="font-size:13px;color:var(--muted);margin:24px 0 8px">Metric spread</h3>
157
+ <table><thead><tr><th>Metric</th><th>Range</th><th>Median</th><th>Spread</th><th></th><th>Measured</th></tr></thead>
158
+ <tbody>${rows}</tbody></table>`;
159
+ }
160
+ export function renderFlake(flake) {
161
+ if (!flake)
162
+ return '';
163
+ return `<h2>Repeatability — ${flake.runs} runs</h2>
164
+ <section class="verdict ${flake.verdict === 'pass' ? 'pass' : flake.verdict === 'fail' ? 'fail' : 'flaky'}">
165
+ <div class="tag">${flake.verdict.toUpperCase()}</div>
166
+ <div class="line">${escapeHtml(flake.headline)}</div>
167
+ </section>
168
+ <p class="note"><b>Confidence: ${escapeHtml(flake.confidence)}.</b> ${escapeHtml(flake.confidenceNote)}</p>
169
+ ${renderChecks(flake)}
170
+ <h3 style="font-size:13px;color:var(--muted);margin:24px 0 8px">Intermittent errors and requests</h3>
171
+ ${renderSignals(flake)}
172
+ ${renderMetricSpread(flake)}`;
173
+ }
174
+ //# sourceMappingURL=render-evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-evidence.js","sourceRoot":"","sources":["../../../src/report/render-evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Report sections for the trend (RIG-13) and the run-to-run diff (RIG-10).
3
+ *
4
+ * Kept separate from render.ts purely for size. Same rules apply: no external
5
+ * resources, so the sparklines are hand-written inline SVG rather than a
6
+ * charting library, and the diff image is a `data:` URI.
7
+ *
8
+ * The design goal for the trend is legibility at a glance — the point of the
9
+ * feature is catching decay nobody noticed, which only works if the reader
10
+ * sees it without going looking.
11
+ */
12
+ import type { RunDiff, TrendReport } from './types.js';
13
+ export declare const TREND_STYLES: string;
14
+ export declare function renderTrend(trend: TrendReport | undefined): string;
15
+ export declare function renderDiff(diff: RunDiff | undefined): string;
16
+ //# sourceMappingURL=render-trend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-trend.d.ts","sourceRoot":"","sources":["../../../src/report/render-trend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAgC,WAAW,EAAe,MAAM,YAAY,CAAC;AAMlG,eAAO,MAAM,YAAY,QAkBjB,CAAC;AAyCT,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAyClE;AAsFD,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAmB5D"}