@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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bridge-instruments.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-instruments.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/bridge-instruments.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,132 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2
+ import { WebSocketServer } from 'ws';
3
+ import { BridgeTransport, bridgeSessionId } from '../browser/bridge.js';
4
+ import { CdpClient } from '../browser/cdp.js';
5
+ import { clearConsoleMessages, getConsoleMessages, getPageErrors, setupConsoleCapture, teardownConsoleCapture, } from '../browser/console-log.js';
6
+ import { getCapturedRequests, startRequestCapture, stopRequestCapture, } from '../browser/network.js';
7
+ import { collectVitals } from '../browser/vitals.js';
8
+ /** The Go relay plus the extension behind it, as far as CDP is concerned. */
9
+ class FakeChrome {
10
+ server;
11
+ socket = null;
12
+ /** Canned Runtime.evaluate return values, by the order they are asked for. */
13
+ evalResults = [];
14
+ methods = [];
15
+ constructor() {
16
+ this.server = new WebSocketServer({ host: '127.0.0.1', port: 0 });
17
+ this.server.on('connection', (ws) => {
18
+ this.socket = ws;
19
+ ws.on('message', (raw) => {
20
+ const env = JSON.parse(raw.toString());
21
+ if (env.type !== 'cdp') {
22
+ ws.send(JSON.stringify({ id: env.id, success: true, data: { tabId: env.tabId ?? 5 } }));
23
+ return;
24
+ }
25
+ const { method } = env.params;
26
+ this.methods.push(method);
27
+ const result = method === 'Runtime.evaluate'
28
+ ? { result: { type: 'object', value: this.evalResults.shift() ?? {} } }
29
+ : {};
30
+ ws.send(JSON.stringify({ id: env.id, success: true, data: { result } }));
31
+ });
32
+ });
33
+ }
34
+ get url() {
35
+ return `ws://127.0.0.1:${this.server.address().port}/monoagent/cdp`;
36
+ }
37
+ ready() {
38
+ return new Promise((resolve) => this.server.once('listening', resolve));
39
+ }
40
+ /** What chrome.debugger.onEvent delivers, relayed up the bridge. */
41
+ emit(tabId, method, params) {
42
+ this.socket.send(JSON.stringify({ type: 'cdp_event', data: { tabId, method, params } }));
43
+ }
44
+ close() {
45
+ return new Promise((resolve) => this.server.close(() => resolve()));
46
+ }
47
+ }
48
+ const TAB = 5;
49
+ const SESSION = bridgeSessionId(TAB);
50
+ describe('RIG-07: monobrowse instruments over the extension bridge', () => {
51
+ let chrome;
52
+ let client;
53
+ beforeEach(async () => {
54
+ chrome = new FakeChrome();
55
+ if (chrome.server.address() === null)
56
+ await chrome.ready();
57
+ client = new CdpClient();
58
+ await client.connectTransport(new BridgeTransport({ tabId: TAB, url: chrome.url, token: 'tok' }));
59
+ });
60
+ afterEach(async () => {
61
+ client.close();
62
+ await chrome.close();
63
+ });
64
+ // browser_console: setupConsoleCapture at connect, read the buffers later.
65
+ it('browser_console reads the real tab console', async () => {
66
+ setupConsoleCapture(client, SESSION);
67
+ clearConsoleMessages(SESSION);
68
+ await client.send('Runtime.enable', {}, SESSION);
69
+ await client.send('Log.enable', {}, SESSION);
70
+ chrome.emit(TAB, 'Runtime.consoleAPICalled', {
71
+ type: 'warning',
72
+ args: [{ value: 'cart total mismatch' }],
73
+ });
74
+ chrome.emit(TAB, 'Log.entryAdded', {
75
+ entry: { level: 'error', text: 'Failed to load resource: 402', url: 'https://shop.test/pay' },
76
+ });
77
+ chrome.emit(TAB, 'Runtime.exceptionThrown', {
78
+ exceptionDetails: { exception: { description: 'ReferenceError: checkout is not defined' } },
79
+ });
80
+ await tick();
81
+ expect(getConsoleMessages(SESSION)).toMatchObject([
82
+ { type: 'warn', text: 'cart total mismatch' },
83
+ { type: 'error', text: 'Failed to load resource: 402', url: 'https://shop.test/pay' },
84
+ ]);
85
+ expect(getPageErrors(SESSION)).toMatchObject([
86
+ { text: 'ReferenceError: checkout is not defined' },
87
+ ]);
88
+ teardownConsoleCapture(SESSION);
89
+ });
90
+ // browser_network action:"start" then action:"list".
91
+ it('browser_network records the real tab requests', async () => {
92
+ startRequestCapture(client, SESSION);
93
+ chrome.emit(TAB, 'Network.requestWillBeSent', {
94
+ requestId: 'R1',
95
+ request: { url: 'https://shop.test/api/cart', method: 'GET', headers: {} },
96
+ timestamp: 1,
97
+ });
98
+ chrome.emit(TAB, 'Network.responseReceived', {
99
+ requestId: 'R1',
100
+ response: { status: 402, mimeType: 'application/json', headers: {} },
101
+ timestamp: 2,
102
+ });
103
+ chrome.emit(TAB, 'Network.loadingFinished', {
104
+ requestId: 'R1',
105
+ timestamp: 2,
106
+ encodedDataLength: 1234,
107
+ });
108
+ await tick();
109
+ expect(getCapturedRequests(SESSION)).toMatchObject([
110
+ { url: 'https://shop.test/api/cart', method: 'GET', status: 402 },
111
+ ]);
112
+ stopRequestCapture(SESSION);
113
+ });
114
+ // browser_vitals: one Runtime.evaluate, straight through the bridge.
115
+ it('browser_vitals measures the real tab', async () => {
116
+ chrome.evalResults = [{ lcp: 2400, fcp: 900, cls: 0.03, ttfb: 180 }];
117
+ const vitals = await collectVitals(client, SESSION, 0);
118
+ expect(vitals).toMatchObject({ lcp: 2400, fcp: 900, cls: 0.03, ttfb: 180 });
119
+ expect(chrome.methods).toContain('Runtime.evaluate');
120
+ });
121
+ it('every command reached the tab session, with no CDP sessionId on the wire', async () => {
122
+ await client.send('Page.enable', {}, SESSION);
123
+ // The synthetic session id is monobrowse's bookkeeping; chrome.debugger
124
+ // addresses the page by its debuggee, so it must never travel.
125
+ expect(chrome.methods).toEqual(['Page.enable']);
126
+ });
127
+ });
128
+ /** Let the relayed events drain through the socket and the listeners. */
129
+ function tick() {
130
+ return new Promise((r) => setTimeout(r, 50));
131
+ }
132
+ //# sourceMappingURL=bridge-instruments.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-instruments.test.js","sourceRoot":"","sources":["../../../src/__tests__/bridge-instruments.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bridge-transport.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-transport.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/bridge-transport.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,287 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2
+ import { WebSocketServer } from 'ws';
3
+ import { BRIDGE_TOKEN_HEADER, BridgeTransport, bridgeSessionId, bridgeTargetId, } from '../browser/bridge.js';
4
+ import { CdpClient } from '../browser/cdp.js';
5
+ import { getConsoleMessages, getPageErrors, setupConsoleCapture, teardownConsoleCapture, } from '../browser/console-log.js';
6
+ // --- a scripted inner pipe, for the translation unit tests -----------------
7
+ class ScriptedSocket {
8
+ sent = [];
9
+ closed = false;
10
+ handlers = null;
11
+ /** Answers each outbound envelope as the relay would. */
12
+ autoReply = null;
13
+ async open(handlers) {
14
+ this.handlers = handlers;
15
+ }
16
+ async send(frame) {
17
+ const env = JSON.parse(frame);
18
+ this.sent.push(env);
19
+ const reply = this.autoReply?.(env);
20
+ if (reply !== undefined)
21
+ this.push(reply);
22
+ }
23
+ close() {
24
+ this.closed = true;
25
+ }
26
+ push(msg) {
27
+ this.handlers.message(JSON.stringify(msg));
28
+ }
29
+ drop(err) {
30
+ this.handlers.close(err);
31
+ }
32
+ /** The last envelope of a given type. */
33
+ lastOf(type) {
34
+ return [...this.sent]
35
+ .reverse()
36
+ .find((e) => e.type === type);
37
+ }
38
+ }
39
+ /** A socket whose attach and plain cdp commands always succeed. */
40
+ function okSocket() {
41
+ const s = new ScriptedSocket();
42
+ s.autoReply = (env) => {
43
+ if (env.type === 'cdp_attach' || env.type === 'cdp_detach') {
44
+ return { id: env.id, success: true, data: {} };
45
+ }
46
+ if (env.type === 'cdp') {
47
+ const params = env.params;
48
+ return { id: env.id, success: true, data: { result: { echoed: params.method } } };
49
+ }
50
+ return undefined;
51
+ };
52
+ return s;
53
+ }
54
+ describe('BridgeTransport framing', () => {
55
+ it('attaches the debugger to the tab before reporting itself open', async () => {
56
+ const socket = okSocket();
57
+ const t = new BridgeTransport({ tabId: 42, socket });
58
+ await t.open({ message: () => { }, close: () => { }, error: () => { } });
59
+ const attach = socket.lastOf('cdp_attach');
60
+ expect(attach.tabId).toBe(42);
61
+ });
62
+ it('fails open() when the tab cannot be attached, instead of half-connecting', async () => {
63
+ const socket = new ScriptedSocket();
64
+ socket.autoReply = (env) => ({
65
+ id: env.id,
66
+ success: false,
67
+ error: 'debugger attach: Cannot access a chrome:// URL',
68
+ });
69
+ const t = new BridgeTransport({ tabId: 7, socket });
70
+ await expect(t.open({ message: () => { }, close: () => { }, error: () => { } })).rejects.toThrow(/Cannot access a chrome:\/\/ URL/);
71
+ });
72
+ it('wraps a CDP frame as a bridge command and unwraps the result', async () => {
73
+ const socket = okSocket();
74
+ const client = new CdpClient();
75
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
76
+ const result = await client.send('Page.navigate', { url: 'https://x.test' });
77
+ const cmd = socket.lastOf('cdp');
78
+ expect(cmd.tabId).toBe(42);
79
+ expect(cmd.params).toEqual({ method: 'Page.navigate', params: { url: 'https://x.test' } });
80
+ expect(result).toEqual({ echoed: 'Page.navigate' });
81
+ });
82
+ it('turns a bridge error into a CDP error the caller can read', async () => {
83
+ const socket = new ScriptedSocket();
84
+ socket.autoReply = (env) => env.type === 'cdp_attach'
85
+ ? { id: env.id, success: true, data: {} }
86
+ : { id: env.id, success: false, error: 'Not allowed' };
87
+ const client = new CdpClient();
88
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
89
+ await expect(client.send('HeapProfiler.enable')).rejects.toThrow(/Not allowed/);
90
+ });
91
+ it('strips the synthetic session id from commands on the tab session', async () => {
92
+ const socket = okSocket();
93
+ const client = new CdpClient();
94
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
95
+ await client.send('Runtime.enable', {}, bridgeSessionId(42));
96
+ const cmd = socket.lastOf('cdp');
97
+ // chrome.debugger's tab debuggee IS the page session; a sessionId here
98
+ // would make it look for a child session that does not exist.
99
+ expect(cmd.params).toEqual({ method: 'Runtime.enable', params: {} });
100
+ });
101
+ it('passes a real child session id through for out-of-process frames', async () => {
102
+ const socket = okSocket();
103
+ const client = new CdpClient();
104
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
105
+ await client.send('Runtime.enable', {}, 'OOPIF-SESSION-1');
106
+ const cmd = socket.lastOf('cdp');
107
+ expect(cmd.params).toEqual({
108
+ method: 'Runtime.enable',
109
+ params: {},
110
+ sessionId: 'OOPIF-SESSION-1',
111
+ });
112
+ });
113
+ it('answers Target.attachToTarget for the tab itself without touching the bridge', async () => {
114
+ const socket = okSocket();
115
+ const client = new CdpClient();
116
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
117
+ const before = socket.sent.length;
118
+ const attached = await client.send('Target.attachToTarget', {
119
+ targetId: bridgeTargetId(42),
120
+ flatten: true,
121
+ });
122
+ expect(attached.sessionId).toBe(bridgeSessionId(42));
123
+ expect(socket.sent.length).toBe(before);
124
+ });
125
+ it('forwards Target.attachToTarget for any other target', async () => {
126
+ const socket = okSocket();
127
+ const client = new CdpClient();
128
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
129
+ await client.send('Target.attachToTarget', { targetId: 'SOME-IFRAME', flatten: true });
130
+ expect(socket.lastOf('cdp').params.params).toEqual({
131
+ targetId: 'SOME-IFRAME',
132
+ flatten: true,
133
+ });
134
+ });
135
+ it('labels relayed events with the tab session so per-session listeners match', async () => {
136
+ const socket = okSocket();
137
+ const client = new CdpClient();
138
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
139
+ const seen = [];
140
+ client.on('Network.responseReceived', (_p, sid) => void seen.push(sid));
141
+ socket.push({
142
+ type: 'cdp_event',
143
+ data: { tabId: 42, method: 'Network.responseReceived', params: { requestId: 'R1' } },
144
+ });
145
+ expect(seen).toEqual([bridgeSessionId(42)]);
146
+ });
147
+ it('keeps a child session id on events that carry one', async () => {
148
+ const socket = okSocket();
149
+ const client = new CdpClient();
150
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
151
+ const seen = [];
152
+ client.on('Network.responseReceived', (_p, sid) => void seen.push(sid));
153
+ socket.push({
154
+ type: 'cdp_event',
155
+ data: {
156
+ tabId: 42,
157
+ sessionId: 'OOPIF-SESSION-1',
158
+ method: 'Network.responseReceived',
159
+ params: {},
160
+ },
161
+ });
162
+ expect(seen).toEqual(['OOPIF-SESSION-1']);
163
+ });
164
+ it('ignores events for a tab this transport is not driving', async () => {
165
+ const socket = okSocket();
166
+ const client = new CdpClient();
167
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
168
+ const seen = [];
169
+ client.on('Network.responseReceived', (p) => void seen.push(p));
170
+ socket.push({
171
+ type: 'cdp_event',
172
+ data: { tabId: 99, method: 'Network.responseReceived', params: {} },
173
+ });
174
+ expect(seen).toEqual([]);
175
+ });
176
+ it('fails in-flight commands when the debugger is detached out from under it', async () => {
177
+ const socket = okSocket();
178
+ const client = new CdpClient();
179
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
180
+ socket.autoReply = null; // this one never gets answered
181
+ const pending = client.send('Page.enable', {}, undefined, 0);
182
+ socket.push({
183
+ type: 'cdp_event',
184
+ data: { tabId: 42, method: 'Inspector.detached', params: { reason: 'canceled_by_user' } },
185
+ });
186
+ await expect(pending).rejects.toThrow(/canceled_by_user/);
187
+ expect(client.isConnected()).toBe(false);
188
+ });
189
+ it('detaches the debugger when the client closes, so the banner goes away', async () => {
190
+ const socket = okSocket();
191
+ const client = new CdpClient();
192
+ await client.connectTransport(new BridgeTransport({ tabId: 42, socket }));
193
+ client.close();
194
+ expect(socket.lastOf('cdp_detach')).toMatchObject({ tabId: 42 });
195
+ expect(socket.closed).toBe(true);
196
+ });
197
+ });
198
+ // --- end to end over a real socket -----------------------------------------
199
+ /**
200
+ * Stands in for `/monoagent/cdp` plus the extension behind it: answers the
201
+ * bridge envelopes and can push unsolicited events, exactly as the Go relay
202
+ * fans out `chrome.debugger.onEvent`.
203
+ */
204
+ class FakeBridge {
205
+ server;
206
+ socket = null;
207
+ tokens = [];
208
+ commands = [];
209
+ constructor() {
210
+ this.server = new WebSocketServer({ host: '127.0.0.1', port: 0 });
211
+ this.server.on('connection', (ws, req) => {
212
+ this.socket = ws;
213
+ this.tokens.push(req.headers[BRIDGE_TOKEN_HEADER.toLowerCase()]);
214
+ ws.on('message', (raw) => {
215
+ const env = JSON.parse(raw.toString());
216
+ if (env.type === 'cdp_attach' || env.type === 'cdp_detach') {
217
+ ws.send(JSON.stringify({ id: env.id, success: true, data: {} }));
218
+ return;
219
+ }
220
+ if (env.type === 'cdp') {
221
+ this.commands.push(env.params);
222
+ ws.send(JSON.stringify({ id: env.id, success: true, data: { result: {} } }));
223
+ }
224
+ });
225
+ });
226
+ }
227
+ get url() {
228
+ const { port } = this.server.address();
229
+ return `ws://127.0.0.1:${port}/monoagent/cdp`;
230
+ }
231
+ ready() {
232
+ return new Promise((resolve) => this.server.once('listening', resolve));
233
+ }
234
+ /** Push an event up as the extension's chrome.debugger.onEvent would. */
235
+ emit(tabId, method, params) {
236
+ this.socket.send(JSON.stringify({ type: 'cdp_event', data: { tabId, method, params } }));
237
+ }
238
+ close() {
239
+ return new Promise((resolve) => this.server.close(() => resolve()));
240
+ }
241
+ }
242
+ describe('BridgeTransport end to end over a real socket', () => {
243
+ let bridge;
244
+ beforeEach(async () => {
245
+ bridge = new FakeBridge();
246
+ if (bridge.server.address() === null)
247
+ await bridge.ready();
248
+ });
249
+ afterEach(async () => {
250
+ await bridge.close();
251
+ });
252
+ it('carries console capture — an unmodified instrument — over the bridge', async () => {
253
+ const client = new CdpClient();
254
+ const transport = new BridgeTransport({ tabId: 5, url: bridge.url, token: 'tok-123' });
255
+ await client.connectTransport(transport);
256
+ const sessionId = bridgeSessionId(5);
257
+ setupConsoleCapture(client, sessionId);
258
+ // console-log.ts, untouched: it enables the domains it needs...
259
+ await client.send('Runtime.enable', {}, sessionId);
260
+ await client.send('Log.enable', {}, sessionId);
261
+ // ...and the page's console output arrives as a relayed debugger event.
262
+ bridge.emit(5, 'Runtime.consoleAPICalled', {
263
+ type: 'error',
264
+ args: [{ value: 'checkout failed' }],
265
+ });
266
+ bridge.emit(5, 'Runtime.exceptionThrown', {
267
+ exceptionDetails: { exception: { description: 'TypeError: x is not a function' } },
268
+ });
269
+ await new Promise((r) => setTimeout(r, 50));
270
+ expect(getConsoleMessages(sessionId)).toMatchObject([
271
+ { type: 'error', text: 'checkout failed' },
272
+ ]);
273
+ expect(getPageErrors(sessionId)).toMatchObject([{ text: 'TypeError: x is not a function' }]);
274
+ expect(bridge.commands.map((c) => c.method)).toEqual(['Runtime.enable', 'Log.enable']);
275
+ expect(bridge.tokens).toEqual(['tok-123']);
276
+ teardownConsoleCapture(sessionId);
277
+ client.close();
278
+ });
279
+ it('reports a dropped bridge to in-flight callers', async () => {
280
+ const client = new CdpClient();
281
+ await client.connectTransport(new BridgeTransport({ tabId: 5, url: bridge.url, token: 'tok-123' }));
282
+ const pending = client.send('Page.captureScreenshot', {}, undefined, 0);
283
+ bridge.socket.close();
284
+ await expect(pending).rejects.toThrow(/closed|bridge/i);
285
+ });
286
+ });
287
+ //# sourceMappingURL=bridge-transport.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-transport.test.js","sourceRoot":"","sources":["../../../src/__tests__/bridge-transport.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cdp-transport.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp-transport.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/cdp-transport.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * The transport seam under CdpClient.
3
+ *
4
+ * Two halves: WebSocketTransport must behave exactly as the inlined `ws`
5
+ * handling it replaced (that is what keeps the 474 existing tests honest),
6
+ * and CdpClient must drive *any* transport — the whole point of the seam,
7
+ * since the bridge-backed one is not a socket to a local Chrome at all.
8
+ */
9
+ import { describe, expect, it, vi } from 'vitest';
10
+ // --- fake `ws` -------------------------------------------------------------
11
+ let lastSocket = null;
12
+ class FakeWs {
13
+ url;
14
+ handlers = new Map();
15
+ sent = [];
16
+ closed = false;
17
+ sendError = null;
18
+ constructor(url) {
19
+ this.url = url;
20
+ lastSocket = this;
21
+ }
22
+ on(event, fn) {
23
+ if (!this.handlers.has(event))
24
+ this.handlers.set(event, []);
25
+ this.handlers.get(event).push(fn);
26
+ }
27
+ emit(event, ...args) {
28
+ for (const fn of [...(this.handlers.get(event) ?? [])])
29
+ fn(...args);
30
+ }
31
+ send(data, cb) {
32
+ this.sent.push(data);
33
+ cb?.(this.sendError ?? undefined);
34
+ }
35
+ close() {
36
+ this.closed = true;
37
+ }
38
+ }
39
+ vi.mock('ws', () => ({ WebSocket: FakeWs }));
40
+ const { WebSocketTransport } = await import('../browser/transport.js');
41
+ const { CdpClient } = await import('../browser/cdp.js');
42
+ /** Collects what a transport hands back up to its owner. */
43
+ function recorder() {
44
+ const messages = [];
45
+ const closes = [];
46
+ const errors = [];
47
+ return {
48
+ messages,
49
+ closes,
50
+ message: (d) => void messages.push(d),
51
+ close: (e) => void closes.push(e),
52
+ error: (e) => void errors.push(e),
53
+ };
54
+ }
55
+ describe('WebSocketTransport', () => {
56
+ it('opens on the socket "open" event and reports the url it dialed', async () => {
57
+ const t = new WebSocketTransport('ws://127.0.0.1:9222/devtools/page/ABC');
58
+ const p = t.open(recorder());
59
+ lastSocket.emit('open');
60
+ await p;
61
+ expect(lastSocket.url).toBe('ws://127.0.0.1:9222/devtools/page/ABC');
62
+ });
63
+ it('rejects open() when the socket errors before it ever opened', async () => {
64
+ const t = new WebSocketTransport('ws://127.0.0.1:1/devtools');
65
+ const p = t.open(recorder());
66
+ lastSocket.emit('error', new Error('ECONNREFUSED'));
67
+ await expect(p).rejects.toThrow('ECONNREFUSED');
68
+ });
69
+ it('routes a post-open error to error(), not to a rejected open()', async () => {
70
+ const h = recorder();
71
+ const errors = [];
72
+ h.error = (e) => void errors.push(e);
73
+ const t = new WebSocketTransport('ws://x');
74
+ const p = t.open(h);
75
+ lastSocket.emit('open');
76
+ await p;
77
+ lastSocket.emit('error', new Error('EPIPE'));
78
+ expect(errors.map((e) => e.message)).toEqual(['EPIPE']);
79
+ });
80
+ it('delivers messages as strings and reports close', async () => {
81
+ const h = recorder();
82
+ const t = new WebSocketTransport('ws://x');
83
+ const p = t.open(h);
84
+ lastSocket.emit('open');
85
+ await p;
86
+ lastSocket.emit('message', Buffer.from('{"id":1}'));
87
+ expect(h.messages).toEqual(['{"id":1}']);
88
+ lastSocket.emit('close');
89
+ expect(h.closes).toHaveLength(1);
90
+ });
91
+ it('rejects send() with the socket error and closes the socket on close()', async () => {
92
+ const t = new WebSocketTransport('ws://x');
93
+ const p = t.open(recorder());
94
+ lastSocket.emit('open');
95
+ await p;
96
+ await expect(t.send('{"id":1}')).resolves.toBeUndefined();
97
+ expect(lastSocket.sent).toEqual(['{"id":1}']);
98
+ lastSocket.sendError = new Error('socket gone');
99
+ await expect(t.send('{"id":2}')).rejects.toThrow('socket gone');
100
+ t.close();
101
+ expect(lastSocket.closed).toBe(true);
102
+ });
103
+ });
104
+ // --- CdpClient over an arbitrary transport ---------------------------------
105
+ /** A transport with no socket at all: the test *is* the other end. */
106
+ class ScriptedTransport {
107
+ sent = [];
108
+ closed = false;
109
+ handlers = null;
110
+ async open(handlers) {
111
+ this.handlers = handlers;
112
+ }
113
+ async send(frame) {
114
+ this.sent.push(frame);
115
+ }
116
+ close() {
117
+ this.closed = true;
118
+ }
119
+ /** Push a frame up as if it had arrived from the other side. */
120
+ deliver(msg) {
121
+ this.handlers.message(JSON.stringify(msg));
122
+ }
123
+ drop(err) {
124
+ this.handlers.close(err);
125
+ }
126
+ }
127
+ describe('CdpClient.connectTransport', () => {
128
+ it('round-trips a command through a transport that is not a socket', async () => {
129
+ const t = new ScriptedTransport();
130
+ const client = new CdpClient();
131
+ await client.connectTransport(t);
132
+ expect(client.isConnected()).toBe(true);
133
+ const pending = client.send('Page.navigate', { url: 'https://x.test' });
134
+ const sent = JSON.parse(t.sent[0]);
135
+ expect(sent.method).toBe('Page.navigate');
136
+ expect(sent.params).toEqual({ url: 'https://x.test' });
137
+ t.deliver({ id: sent.id, result: { frameId: 'F1' } });
138
+ expect(await pending).toEqual({ frameId: 'F1' });
139
+ });
140
+ it('dispatches events with their sessionId to listeners', async () => {
141
+ const t = new ScriptedTransport();
142
+ const client = new CdpClient();
143
+ await client.connectTransport(t);
144
+ const seen = [];
145
+ client.on('Network.responseReceived', (params, sid) => void seen.push([params, sid]));
146
+ t.deliver({ method: 'Network.responseReceived', params: { requestId: 'R1' }, sessionId: 'S1' });
147
+ expect(seen).toEqual([[{ requestId: 'R1' }, 'S1']]);
148
+ });
149
+ it('flushes in-flight commands when the transport drops', async () => {
150
+ const t = new ScriptedTransport();
151
+ const client = new CdpClient();
152
+ await client.connectTransport(t);
153
+ const pending = client.send('Page.enable');
154
+ t.drop(new Error('bridge disconnected'));
155
+ await expect(pending).rejects.toThrow('bridge disconnected');
156
+ expect(client.isConnected()).toBe(false);
157
+ });
158
+ it('closes the transport when the client closes', async () => {
159
+ const t = new ScriptedTransport();
160
+ const client = new CdpClient();
161
+ await client.connectTransport(t);
162
+ client.close();
163
+ expect(t.closed).toBe(true);
164
+ await expect(client.send('Page.enable')).rejects.toThrow('CDP not connected');
165
+ });
166
+ });
167
+ //# sourceMappingURL=cdp-transport.test.js.map