@mechris3/glassbox 0.1.0

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 (162) hide show
  1. package/README.md +213 -0
  2. package/dist/bin/glassbox.d.ts +14 -0
  3. package/dist/bin/glassbox.d.ts.map +1 -0
  4. package/dist/bin/glassbox.js +140 -0
  5. package/dist/bin/glassbox.js.map +1 -0
  6. package/dist/src/adapters/base-adapter.d.ts +70 -0
  7. package/dist/src/adapters/base-adapter.d.ts.map +1 -0
  8. package/dist/src/adapters/base-adapter.js +155 -0
  9. package/dist/src/adapters/base-adapter.js.map +1 -0
  10. package/dist/src/adapters/browser-adapter.interface.d.ts +41 -0
  11. package/dist/src/adapters/browser-adapter.interface.d.ts.map +1 -0
  12. package/dist/src/adapters/browser-adapter.interface.js +7 -0
  13. package/dist/src/adapters/browser-adapter.interface.js.map +1 -0
  14. package/dist/src/adapters/cdp-adapter.d.ts +63 -0
  15. package/dist/src/adapters/cdp-adapter.d.ts.map +1 -0
  16. package/dist/src/adapters/cdp-adapter.js +231 -0
  17. package/dist/src/adapters/cdp-adapter.js.map +1 -0
  18. package/dist/src/ai/collectors.d.ts +35 -0
  19. package/dist/src/ai/collectors.d.ts.map +1 -0
  20. package/dist/src/ai/collectors.js +170 -0
  21. package/dist/src/ai/collectors.js.map +1 -0
  22. package/dist/src/ai/queries.d.ts +21 -0
  23. package/dist/src/ai/queries.d.ts.map +1 -0
  24. package/dist/src/ai/queries.js +59 -0
  25. package/dist/src/ai/queries.js.map +1 -0
  26. package/dist/src/ai/types.d.ts +55 -0
  27. package/dist/src/ai/types.d.ts.map +1 -0
  28. package/dist/src/ai/types.js +6 -0
  29. package/dist/src/ai/types.js.map +1 -0
  30. package/dist/src/cdp/connection.d.ts +37 -0
  31. package/dist/src/cdp/connection.d.ts.map +1 -0
  32. package/dist/src/cdp/connection.js +86 -0
  33. package/dist/src/cdp/connection.js.map +1 -0
  34. package/dist/src/cdp/connection.test.d.ts +6 -0
  35. package/dist/src/cdp/connection.test.d.ts.map +1 -0
  36. package/dist/src/cdp/connection.test.js +93 -0
  37. package/dist/src/cdp/connection.test.js.map +1 -0
  38. package/dist/src/cdp/domains.d.ts +116 -0
  39. package/dist/src/cdp/domains.d.ts.map +1 -0
  40. package/dist/src/cdp/domains.js +153 -0
  41. package/dist/src/cdp/domains.js.map +1 -0
  42. package/dist/src/cdp/launcher.d.ts +26 -0
  43. package/dist/src/cdp/launcher.d.ts.map +1 -0
  44. package/dist/src/cdp/launcher.js +175 -0
  45. package/dist/src/cdp/launcher.js.map +1 -0
  46. package/dist/src/config.d.ts +28 -0
  47. package/dist/src/config.d.ts.map +1 -0
  48. package/dist/src/config.js +72 -0
  49. package/dist/src/config.js.map +1 -0
  50. package/dist/src/config.test.d.ts +5 -0
  51. package/dist/src/config.test.d.ts.map +1 -0
  52. package/dist/src/config.test.js +46 -0
  53. package/dist/src/config.test.js.map +1 -0
  54. package/dist/src/errors.d.ts +26 -0
  55. package/dist/src/errors.d.ts.map +1 -0
  56. package/dist/src/errors.js +27 -0
  57. package/dist/src/errors.js.map +1 -0
  58. package/dist/src/index.d.ts +18 -0
  59. package/dist/src/index.d.ts.map +1 -0
  60. package/dist/src/index.js +28 -0
  61. package/dist/src/index.js.map +1 -0
  62. package/dist/src/journey.d.ts +35 -0
  63. package/dist/src/journey.d.ts.map +1 -0
  64. package/dist/src/journey.js +39 -0
  65. package/dist/src/journey.js.map +1 -0
  66. package/dist/src/mcp/server.d.ts +22 -0
  67. package/dist/src/mcp/server.d.ts.map +1 -0
  68. package/dist/src/mcp/server.js +229 -0
  69. package/dist/src/mcp/server.js.map +1 -0
  70. package/dist/src/page-objects/base.page.d.ts +28 -0
  71. package/dist/src/page-objects/base.page.d.ts.map +1 -0
  72. package/dist/src/page-objects/base.page.js +51 -0
  73. package/dist/src/page-objects/base.page.js.map +1 -0
  74. package/dist/src/page-objects/browser-context.page.d.ts +14 -0
  75. package/dist/src/page-objects/browser-context.page.d.ts.map +1 -0
  76. package/dist/src/page-objects/browser-context.page.js +28 -0
  77. package/dist/src/page-objects/browser-context.page.js.map +1 -0
  78. package/dist/src/runner/lifecycle-hooks.d.ts +43 -0
  79. package/dist/src/runner/lifecycle-hooks.d.ts.map +1 -0
  80. package/dist/src/runner/lifecycle-hooks.js +70 -0
  81. package/dist/src/runner/lifecycle-hooks.js.map +1 -0
  82. package/dist/src/runner/run-all-journeys.d.ts +35 -0
  83. package/dist/src/runner/run-all-journeys.d.ts.map +1 -0
  84. package/dist/src/runner/run-all-journeys.js +167 -0
  85. package/dist/src/runner/run-all-journeys.js.map +1 -0
  86. package/dist/src/runner/run-journey.d.ts +17 -0
  87. package/dist/src/runner/run-journey.d.ts.map +1 -0
  88. package/dist/src/runner/run-journey.js +179 -0
  89. package/dist/src/runner/run-journey.js.map +1 -0
  90. package/dist/src/runner/spawn-journey.d.ts +36 -0
  91. package/dist/src/runner/spawn-journey.d.ts.map +1 -0
  92. package/dist/src/runner/spawn-journey.js +40 -0
  93. package/dist/src/runner/spawn-journey.js.map +1 -0
  94. package/dist/src/server/diagnostic-service.d.ts +69 -0
  95. package/dist/src/server/diagnostic-service.d.ts.map +1 -0
  96. package/dist/src/server/diagnostic-service.js +165 -0
  97. package/dist/src/server/diagnostic-service.js.map +1 -0
  98. package/dist/src/server/diagnostic-service.test.d.ts +5 -0
  99. package/dist/src/server/diagnostic-service.test.d.ts.map +1 -0
  100. package/dist/src/server/diagnostic-service.test.js +82 -0
  101. package/dist/src/server/diagnostic-service.test.js.map +1 -0
  102. package/dist/src/server/index.d.ts +11 -0
  103. package/dist/src/server/index.d.ts.map +1 -0
  104. package/dist/src/server/index.js +167 -0
  105. package/dist/src/server/index.js.map +1 -0
  106. package/dist/src/server/journey-discovery.d.ts +16 -0
  107. package/dist/src/server/journey-discovery.d.ts.map +1 -0
  108. package/dist/src/server/journey-discovery.js +38 -0
  109. package/dist/src/server/journey-discovery.js.map +1 -0
  110. package/dist/src/server/settings-storage.d.ts +27 -0
  111. package/dist/src/server/settings-storage.d.ts.map +1 -0
  112. package/dist/src/server/settings-storage.js +27 -0
  113. package/dist/src/server/settings-storage.js.map +1 -0
  114. package/dist/src/server/test-executor.d.ts +64 -0
  115. package/dist/src/server/test-executor.d.ts.map +1 -0
  116. package/dist/src/server/test-executor.js +279 -0
  117. package/dist/src/server/test-executor.js.map +1 -0
  118. package/dist/src/server/websocket.d.ts +51 -0
  119. package/dist/src/server/websocket.d.ts.map +1 -0
  120. package/dist/src/server/websocket.js +28 -0
  121. package/dist/src/server/websocket.js.map +1 -0
  122. package/dist/src/utils/browser-discovery.d.ts +11 -0
  123. package/dist/src/utils/browser-discovery.d.ts.map +1 -0
  124. package/dist/src/utils/browser-discovery.js +102 -0
  125. package/dist/src/utils/browser-discovery.js.map +1 -0
  126. package/dist/src/utils/error-formatter.d.ts +13 -0
  127. package/dist/src/utils/error-formatter.d.ts.map +1 -0
  128. package/dist/src/utils/error-formatter.js +29 -0
  129. package/dist/src/utils/error-formatter.js.map +1 -0
  130. package/dist/src/utils/escape.d.ts +10 -0
  131. package/dist/src/utils/escape.d.ts.map +1 -0
  132. package/dist/src/utils/escape.js +22 -0
  133. package/dist/src/utils/escape.js.map +1 -0
  134. package/dist/src/utils/escape.test.d.ts +5 -0
  135. package/dist/src/utils/escape.test.d.ts.map +1 -0
  136. package/dist/src/utils/escape.test.js +49 -0
  137. package/dist/src/utils/escape.test.js.map +1 -0
  138. package/dist/src/utils/page-object-error.d.ts +5 -0
  139. package/dist/src/utils/page-object-error.d.ts.map +1 -0
  140. package/dist/src/utils/page-object-error.js +22 -0
  141. package/dist/src/utils/page-object-error.js.map +1 -0
  142. package/dist/src/utils/profile-discovery.d.ts +20 -0
  143. package/dist/src/utils/profile-discovery.d.ts.map +1 -0
  144. package/dist/src/utils/profile-discovery.js +68 -0
  145. package/dist/src/utils/profile-discovery.js.map +1 -0
  146. package/dist/src/utils/wait-utils.d.ts +10 -0
  147. package/dist/src/utils/wait-utils.d.ts.map +1 -0
  148. package/dist/src/utils/wait-utils.js +20 -0
  149. package/dist/src/utils/wait-utils.js.map +1 -0
  150. package/dist/src/utils/wait-utils.test.d.ts +5 -0
  151. package/dist/src/utils/wait-utils.test.d.ts.map +1 -0
  152. package/dist/src/utils/wait-utils.test.js +30 -0
  153. package/dist/src/utils/wait-utils.test.js.map +1 -0
  154. package/package.json +60 -0
  155. package/src/server/static/index.html +541 -0
  156. package/ui/dist/3rdpartylicenses.txt +419 -0
  157. package/ui/dist/browser/assets/logo.svg +29 -0
  158. package/ui/dist/browser/index.html +13 -0
  159. package/ui/dist/browser/main-7OJWN7GZ.js +16 -0
  160. package/ui/dist/browser/polyfills-5CFQRCPP.js +2 -0
  161. package/ui/dist/browser/styles-HMZYQRBV.css +1 -0
  162. package/ui/dist/prerendered-routes.json +3 -0
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ /**
3
+ * DiagnosticService — server-side diagnostic data store.
4
+ *
5
+ * Accumulates diagnostic data streamed from runner child processes
6
+ * and exposes it via REST API endpoints for the AI bridge to consume.
7
+ *
8
+ * Data flow:
9
+ * 1. Runner collects diagnostics via CDP during journey execution
10
+ * 2. At journey end, runner outputs the data as JSON to stdout
11
+ * 3. TestExecutor catches it and calls ingestRunnerData()
12
+ * 4. REST API serves the accumulated data on demand
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DiagnosticService = void 0;
16
+ const connection_js_1 = require("../cdp/connection.js");
17
+ /** Maximum entries per diagnostic category to prevent unbounded memory growth. */
18
+ const MAX_ENTRIES = 5000;
19
+ class DiagnosticService {
20
+ collectedData = {
21
+ consoleErrors: [],
22
+ exceptions: [],
23
+ networkLog: [],
24
+ networkFailures: [],
25
+ metrics: [],
26
+ timeline: [],
27
+ };
28
+ liveSession = null;
29
+ /**
30
+ * Ingest diagnostic data streamed from a runner child process.
31
+ * Caps each category at MAX_ENTRIES to prevent memory issues on chatty apps.
32
+ */
33
+ ingestRunnerData(data) {
34
+ if (data.consoleErrors)
35
+ this.cappedPush(this.collectedData.consoleErrors, data.consoleErrors);
36
+ if (data.exceptions)
37
+ this.cappedPush(this.collectedData.exceptions, data.exceptions);
38
+ if (data.networkLog)
39
+ this.cappedPush(this.collectedData.networkLog, data.networkLog);
40
+ if (data.networkFailures)
41
+ this.cappedPush(this.collectedData.networkFailures, data.networkFailures);
42
+ if (data.metrics)
43
+ this.cappedPush(this.collectedData.metrics, data.metrics);
44
+ if (data.timeline)
45
+ this.cappedPush(this.collectedData.timeline, data.timeline);
46
+ }
47
+ /** Push items into an array, keeping only the most recent MAX_ENTRIES. */
48
+ cappedPush(target, items) {
49
+ target.push(...items);
50
+ if (target.length > MAX_ENTRIES) {
51
+ target.splice(0, target.length - MAX_ENTRIES);
52
+ }
53
+ }
54
+ /** Reset all collected data. */
55
+ reset() {
56
+ this.collectedData = {
57
+ consoleErrors: [],
58
+ exceptions: [],
59
+ networkLog: [],
60
+ networkFailures: [],
61
+ metrics: [],
62
+ timeline: [],
63
+ };
64
+ }
65
+ // --- Getters (data exposure for REST API — returns copies to prevent external mutation) ---
66
+ getConsoleErrors() {
67
+ return [...this.collectedData.consoleErrors];
68
+ }
69
+ getExceptions() {
70
+ return [...this.collectedData.exceptions];
71
+ }
72
+ getNetworkLog() {
73
+ return [...this.collectedData.networkLog];
74
+ }
75
+ getNetworkFailures() {
76
+ return [...this.collectedData.networkFailures];
77
+ }
78
+ getMetrics() {
79
+ return [...this.collectedData.metrics];
80
+ }
81
+ getTimeline(lastN) {
82
+ if (lastN)
83
+ return this.collectedData.timeline.slice(-lastN);
84
+ return [...this.collectedData.timeline];
85
+ }
86
+ /**
87
+ * Summary of collected data — minimal response for the AI to decide
88
+ * which detailed endpoints to query next.
89
+ */
90
+ getSummary() {
91
+ return {
92
+ consoleErrors: this.collectedData.consoleErrors.length,
93
+ exceptions: this.collectedData.exceptions.length,
94
+ networkFailures: this.collectedData.networkFailures.length,
95
+ totalRequests: this.collectedData.networkLog.length,
96
+ timelineEvents: this.collectedData.timeline.length,
97
+ liveSessionAvailable: this.liveSession?.connection !== null,
98
+ };
99
+ }
100
+ // --- Live session management (for post-failure inspection) ---
101
+ /**
102
+ * Store a live browser session for post-failure queries.
103
+ * Called by TestExecutor when a journey fails and the browser stays alive.
104
+ */
105
+ async setLiveSession(wsEndpoint) {
106
+ this.closeLiveSession();
107
+ try {
108
+ const connection = await connection_js_1.CDPConnection.connect(wsEndpoint);
109
+ // Find the first page target and attach
110
+ const targets = await connection.send('Target.getTargets');
111
+ const pageTarget = targets.targetInfos.find((t) => t.type === 'page');
112
+ let sessionId = null;
113
+ if (pageTarget) {
114
+ const result = await connection.send('Target.attachToTarget', { targetId: pageTarget.targetId, flatten: true });
115
+ sessionId = result.sessionId;
116
+ }
117
+ this.liveSession = { wsEndpoint, connection, sessionId };
118
+ }
119
+ catch {
120
+ this.liveSession = null;
121
+ }
122
+ }
123
+ /** Close the live session (called before a new run or on reset). */
124
+ closeLiveSession() {
125
+ if (this.liveSession?.connection) {
126
+ this.liveSession.connection.close();
127
+ }
128
+ this.liveSession = null;
129
+ }
130
+ /** Whether a live session is available for DOM/screenshot queries. */
131
+ get hasLiveSession() {
132
+ return this.liveSession?.connection !== null && this.liveSession?.sessionId !== null;
133
+ }
134
+ /** Get the DOM snapshot (outerHTML) of an element or the full page. */
135
+ async getDomSnapshot(selector) {
136
+ if (!this.liveSession?.connection || !this.liveSession.sessionId) {
137
+ return 'No live browser session available. Run a journey first (browser stays open on failure).';
138
+ }
139
+ const expression = selector
140
+ ? `document.querySelector('${selector}')?.outerHTML ?? 'Element not found: ${selector}'`
141
+ : `document.documentElement.outerHTML`;
142
+ const result = await this.liveSession.connection.send('Runtime.evaluate', {
143
+ expression,
144
+ returnByValue: true,
145
+ }, this.liveSession.sessionId);
146
+ return result.result.value;
147
+ }
148
+ /** Capture a screenshot of the current page state (base64 PNG). */
149
+ async getScreenshot() {
150
+ if (!this.liveSession?.connection || !this.liveSession.sessionId) {
151
+ return '';
152
+ }
153
+ const result = await this.liveSession.connection.send('Page.captureScreenshot', undefined, this.liveSession.sessionId);
154
+ return result.data;
155
+ }
156
+ /** Get the accessibility tree of the current page. */
157
+ async getAccessibilityTree() {
158
+ if (!this.liveSession?.connection || !this.liveSession.sessionId) {
159
+ return { error: 'No live browser session available.' };
160
+ }
161
+ return this.liveSession.connection.send('Accessibility.getFullAXTree', undefined, this.liveSession.sessionId);
162
+ }
163
+ }
164
+ exports.DiagnosticService = DiagnosticService;
165
+ //# sourceMappingURL=diagnostic-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-service.js","sourceRoot":"","sources":["../../../src/server/diagnostic-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Unit tests for DiagnosticService.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=diagnostic-service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-service.test.d.ts","sourceRoot":"","sources":["../../../src/server/diagnostic-service.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * Unit tests for DiagnosticService.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const diagnostic_service_js_1 = require("./diagnostic-service.js");
8
+ (0, vitest_1.describe)('DiagnosticService', () => {
9
+ let service;
10
+ (0, vitest_1.beforeEach)(() => {
11
+ service = new diagnostic_service_js_1.DiagnosticService();
12
+ });
13
+ (0, vitest_1.it)('starts with empty data', () => {
14
+ const summary = service.getSummary();
15
+ (0, vitest_1.expect)(summary.consoleErrors).toBe(0);
16
+ (0, vitest_1.expect)(summary.exceptions).toBe(0);
17
+ (0, vitest_1.expect)(summary.networkFailures).toBe(0);
18
+ (0, vitest_1.expect)(summary.totalRequests).toBe(0);
19
+ (0, vitest_1.expect)(summary.timelineEvents).toBe(0);
20
+ });
21
+ (0, vitest_1.it)('ingests runner data and reflects in getters', () => {
22
+ service.ingestRunnerData({
23
+ consoleErrors: [{ level: 'error', text: 'test error', args: [], timestamp: 1, stackTrace: [] }],
24
+ networkLog: [
25
+ { requestId: '1', url: 'http://test.com', method: 'GET', timestamp: 1, type: 'XHR' },
26
+ { requestId: '2', url: 'http://test.com/api', method: 'POST', timestamp: 2, type: 'Fetch' },
27
+ ],
28
+ });
29
+ (0, vitest_1.expect)(service.getConsoleErrors()).toHaveLength(1);
30
+ (0, vitest_1.expect)(service.getNetworkLog()).toHaveLength(2);
31
+ (0, vitest_1.expect)(service.getSummary().consoleErrors).toBe(1);
32
+ (0, vitest_1.expect)(service.getSummary().totalRequests).toBe(2);
33
+ });
34
+ (0, vitest_1.it)('reset clears all data', () => {
35
+ service.ingestRunnerData({
36
+ exceptions: [{ text: 'err', description: 'desc', stackTrace: [], timestamp: 1 }],
37
+ });
38
+ (0, vitest_1.expect)(service.getExceptions()).toHaveLength(1);
39
+ service.reset();
40
+ (0, vitest_1.expect)(service.getExceptions()).toHaveLength(0);
41
+ (0, vitest_1.expect)(service.getSummary().exceptions).toBe(0);
42
+ });
43
+ (0, vitest_1.it)('returns copies not references', () => {
44
+ service.ingestRunnerData({
45
+ consoleErrors: [{ level: 'error', text: 'test', args: [], timestamp: 1, stackTrace: [] }],
46
+ });
47
+ const errors = service.getConsoleErrors();
48
+ errors.push({ level: 'warning', text: 'injected', args: [], timestamp: 2, stackTrace: [] });
49
+ // Original should not be affected
50
+ (0, vitest_1.expect)(service.getConsoleErrors()).toHaveLength(1);
51
+ });
52
+ (0, vitest_1.it)('getTimeline returns last N entries', () => {
53
+ service.ingestRunnerData({
54
+ timeline: [
55
+ { type: 'console', timestamp: 1, data: {} },
56
+ { type: 'network-request', timestamp: 2, data: {} },
57
+ { type: 'exception', timestamp: 3, data: {} },
58
+ { type: 'network-response', timestamp: 4, data: {} },
59
+ { type: 'console', timestamp: 5, data: {} },
60
+ ],
61
+ });
62
+ (0, vitest_1.expect)(service.getTimeline(2)).toHaveLength(2);
63
+ (0, vitest_1.expect)(service.getTimeline(2)[0].timestamp).toBe(4);
64
+ (0, vitest_1.expect)(service.getTimeline()).toHaveLength(5);
65
+ });
66
+ (0, vitest_1.it)('caps entries at maximum', () => {
67
+ // Create more than MAX_ENTRIES (5000) items
68
+ const largeArray = Array.from({ length: 6000 }, (_, i) => ({
69
+ requestId: String(i),
70
+ url: `http://test.com/${i}`,
71
+ method: 'GET',
72
+ timestamp: i,
73
+ type: 'XHR',
74
+ }));
75
+ service.ingestRunnerData({ networkLog: largeArray });
76
+ // Should be capped at 5000
77
+ (0, vitest_1.expect)(service.getNetworkLog()).toHaveLength(5000);
78
+ // Should keep the most recent entries
79
+ (0, vitest_1.expect)(service.getNetworkLog()[0].url).toBe('http://test.com/1000');
80
+ });
81
+ });
82
+ //# sourceMappingURL=diagnostic-service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-service.test.js","sourceRoot":"","sources":["../../../src/server/diagnostic-service.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Express server — REST API, WebSocket, static UI serving.
3
+ */
4
+ import { WebSocketManager } from './websocket.js';
5
+ import type { GlassboxConfig } from '../config.js';
6
+ export declare function createGlassboxServer(config: GlassboxConfig): {
7
+ app: import("express-serve-static-core").Express;
8
+ server: import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
9
+ wsManager: WebSocketManager;
10
+ };
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAOlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc;;;;EAkL1D"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * Express server — REST API, WebSocket, static UI serving.
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createGlassboxServer = createGlassboxServer;
10
+ const express_1 = __importDefault(require("express"));
11
+ const cors_1 = __importDefault(require("cors"));
12
+ const http_1 = require("http");
13
+ const path_1 = require("path");
14
+ const fs_1 = require("fs");
15
+ const websocket_js_1 = require("./websocket.js");
16
+ const test_executor_js_1 = require("./test-executor.js");
17
+ const journey_discovery_js_1 = require("./journey-discovery.js");
18
+ const settings_storage_js_1 = require("./settings-storage.js");
19
+ const diagnostic_service_js_1 = require("./diagnostic-service.js");
20
+ const browser_discovery_js_1 = require("../utils/browser-discovery.js");
21
+ const profile_discovery_js_1 = require("../utils/profile-discovery.js");
22
+ function createGlassboxServer(config) {
23
+ const app = (0, express_1.default)();
24
+ const server = (0, http_1.createServer)(app);
25
+ app.use((0, cors_1.default)());
26
+ app.use(express_1.default.json());
27
+ // Serve dashboard UI.
28
+ // Prefers Angular build output (ui/dist/) if it exists, otherwise falls back to
29
+ // the static HTML dashboard in src/server/static/.
30
+ // Resolve from CWD to find the package root reliably regardless of
31
+ // whether we're running from source (tsx) or compiled output (dist/).
32
+ const packageRoot = (0, path_1.resolve)(__dirname.includes('dist') ? (0, path_1.resolve)(__dirname, '../../..') : (0, path_1.resolve)(__dirname, '../..'));
33
+ const angularPath = (0, path_1.resolve)(packageRoot, 'ui/dist/browser');
34
+ const fallbackPath = (0, path_1.resolve)(packageRoot, 'src/server/static');
35
+ const uiPath = (0, fs_1.existsSync)((0, path_1.resolve)(angularPath, 'index.html')) ? angularPath : fallbackPath;
36
+ app.use(express_1.default.static(uiPath));
37
+ // Services
38
+ const wsManager = new websocket_js_1.WebSocketManager(server);
39
+ const discovery = new journey_discovery_js_1.JourneyDiscovery(config.journeys);
40
+ const settings = new settings_storage_js_1.SettingsStorage();
41
+ const diagnostics = new diagnostic_service_js_1.DiagnosticService();
42
+ const executor = new test_executor_js_1.TestExecutor(config, wsManager, diagnostics);
43
+ // --- REST API ---
44
+ app.get('/api/journeys', async (_req, res) => {
45
+ const journeys = await discovery.discover();
46
+ res.json(journeys);
47
+ });
48
+ app.post('/api/tests/run', (req, res) => {
49
+ const { journeys, config: runConfig } = req.body;
50
+ if (!Array.isArray(journeys)) {
51
+ res.status(400).json({ error: 'journeys must be an array of file paths' });
52
+ return;
53
+ }
54
+ // Fire and forget — results stream via WebSocket
55
+ executor.run(journeys, runConfig).catch((err) => {
56
+ wsManager.broadcast({ type: 'error', message: String(err) });
57
+ });
58
+ res.json({ status: 'started' });
59
+ });
60
+ app.post('/api/tests/stop', (_req, res) => {
61
+ executor.stop();
62
+ res.json({ status: 'stopped' });
63
+ });
64
+ app.post('/api/tests/pause', (_req, res) => {
65
+ executor.pause();
66
+ res.json({ status: 'paused' });
67
+ });
68
+ app.post('/api/tests/resume', (_req, res) => {
69
+ executor.resume();
70
+ res.json({ status: 'resumed' });
71
+ });
72
+ app.post('/api/tests/step', (req, res) => {
73
+ const { count } = req.body;
74
+ executor.step(count ?? 1);
75
+ res.json({ status: 'stepping' });
76
+ });
77
+ app.post('/api/breakpoints', (req, res) => {
78
+ const { journey, breakpoints } = req.body;
79
+ executor.setBreakpoints(journey, breakpoints);
80
+ res.json({ status: 'set' });
81
+ });
82
+ app.get('/api/breakpoints/:journey', (req, res) => {
83
+ const breakpoints = executor.getBreakpoints(req.params.journey);
84
+ res.json({ breakpoints });
85
+ });
86
+ app.delete('/api/breakpoints/:journey', (req, res) => {
87
+ executor.clearBreakpoints(req.params.journey);
88
+ res.json({ status: 'cleared' });
89
+ });
90
+ app.patch('/api/config', (req, res) => {
91
+ executor.updateConfig(req.body);
92
+ res.json({ status: 'updated' });
93
+ });
94
+ app.get('/api/tests/status', (_req, res) => {
95
+ res.json({ status: executor.isRunning ? 'running' : 'idle' });
96
+ });
97
+ app.get('/api/config/browsers', (_req, res) => {
98
+ res.json((0, browser_discovery_js_1.discoverBrowsers)());
99
+ });
100
+ app.get('/api/config/profiles', (req, res) => {
101
+ const userDataDir = req.query.userDataDir;
102
+ if (!userDataDir) {
103
+ res.json([]);
104
+ return;
105
+ }
106
+ res.json((0, profile_discovery_js_1.discoverProfiles)(userDataDir));
107
+ });
108
+ app.get('/api/settings', async (_req, res) => {
109
+ const data = await settings.read();
110
+ res.json(data);
111
+ });
112
+ app.put('/api/settings', async (req, res) => {
113
+ await settings.write(req.body);
114
+ const saved = await settings.read();
115
+ res.json(saved);
116
+ });
117
+ // --- Diagnostic API (for AI bridge and debugging) ---
118
+ app.get('/api/diagnostics/summary', (_req, res) => {
119
+ res.json(diagnostics.getSummary());
120
+ });
121
+ app.get('/api/diagnostics/console-errors', (_req, res) => {
122
+ res.json(diagnostics.getConsoleErrors());
123
+ });
124
+ app.get('/api/diagnostics/exceptions', (_req, res) => {
125
+ res.json(diagnostics.getExceptions());
126
+ });
127
+ app.get('/api/diagnostics/network-log', (_req, res) => {
128
+ res.json(diagnostics.getNetworkLog());
129
+ });
130
+ app.get('/api/diagnostics/network-failures', (_req, res) => {
131
+ res.json(diagnostics.getNetworkFailures());
132
+ });
133
+ app.get('/api/diagnostics/metrics', (_req, res) => {
134
+ res.json(diagnostics.getMetrics());
135
+ });
136
+ app.get('/api/diagnostics/timeline', (req, res) => {
137
+ const lastN = req.query.lastN ? parseInt(req.query.lastN, 10) : undefined;
138
+ res.json(diagnostics.getTimeline(lastN));
139
+ });
140
+ app.get('/api/diagnostics/storage', async (_req, res) => {
141
+ res.json({ localStorage: {}, cookies: [] });
142
+ });
143
+ app.get('/api/diagnostics/dom', async (req, res) => {
144
+ const selector = req.query.selector;
145
+ const html = await diagnostics.getDomSnapshot(selector);
146
+ res.json({ html });
147
+ });
148
+ app.get('/api/diagnostics/screenshot', async (_req, res) => {
149
+ const data = await diagnostics.getScreenshot();
150
+ res.json({ data });
151
+ });
152
+ app.get('/api/diagnostics/accessibility-tree', async (_req, res) => {
153
+ const tree = await diagnostics.getAccessibilityTree();
154
+ res.json(tree);
155
+ });
156
+ app.post('/api/diagnostics/reset', (_req, res) => {
157
+ diagnostics.closeLiveSession();
158
+ diagnostics.reset();
159
+ res.json({ status: 'reset' });
160
+ });
161
+ // SPA fallback
162
+ app.get('*', (_req, res) => {
163
+ res.sendFile((0, path_1.resolve)(uiPath, 'index.html'));
164
+ });
165
+ return { app, server, wsManager };
166
+ }
167
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * JourneyDiscovery — scans for journey files matching a glob pattern.
3
+ * Glob is resolved relative to the current working directory (consumer's project).
4
+ */
5
+ export interface DiscoveredJourney {
6
+ id: string;
7
+ name: string;
8
+ path: string;
9
+ }
10
+ export declare class JourneyDiscovery {
11
+ private pattern;
12
+ constructor(pattern: string);
13
+ /** Discover journey files matching the configured glob, resolved from CWD. */
14
+ discover(): Promise<DiscoveredJourney[]>;
15
+ }
16
+ //# sourceMappingURL=journey-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journey-discovery.d.ts","sourceRoot":"","sources":["../../../src/server/journey-discovery.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAI3B,8EAA8E;IACxE,QAAQ,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAc/C"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * JourneyDiscovery — scans for journey files matching a glob pattern.
4
+ * Glob is resolved relative to the current working directory (consumer's project).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.JourneyDiscovery = void 0;
8
+ const glob_1 = require("glob");
9
+ const path_1 = require("path");
10
+ class JourneyDiscovery {
11
+ pattern;
12
+ constructor(pattern) {
13
+ this.pattern = pattern;
14
+ }
15
+ /** Discover journey files matching the configured glob, resolved from CWD. */
16
+ async discover() {
17
+ const files = await (0, glob_1.glob)(this.pattern, { cwd: process.cwd(), absolute: true });
18
+ return files
19
+ .map((filePath) => {
20
+ const filename = (0, path_1.basename)(filePath, '.journey.ts');
21
+ return {
22
+ id: filename,
23
+ name: kebabToTitle(filename),
24
+ path: filePath,
25
+ };
26
+ })
27
+ .sort((a, b) => a.name.localeCompare(b.name));
28
+ }
29
+ }
30
+ exports.JourneyDiscovery = JourneyDiscovery;
31
+ /** Convert kebab-case filename to Title Case display name. */
32
+ function kebabToTitle(kebab) {
33
+ return kebab
34
+ .split('-')
35
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
36
+ .join(' ');
37
+ }
38
+ //# sourceMappingURL=journey-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journey-discovery.js","sourceRoot":"","sources":["../../../src/server/journey-discovery.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAA4B;AAC5B,+BAAgC;AAQhC,MAAa,gBAAgB;IACnB,OAAO,CAAS;IAExB,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/E,OAAO,KAAK;aACT,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YAChB,MAAM,QAAQ,GAAG,IAAA,eAAQ,EAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;YACnD,OAAO;gBACL,EAAE,EAAE,QAAQ;gBACZ,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;gBAC5B,IAAI,EAAE,QAAQ;aACf,CAAC;QACJ,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAClD,CAAC;CACF;AAtBD,4CAsBC;AAED,8DAA8D;AAC9D,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * SettingsStorage — persists UI settings to .glassbox/settings.json
3
+ */
4
+ export interface PersistedSettings {
5
+ targetUrl?: string;
6
+ browserPath?: string;
7
+ userDataDir?: string;
8
+ actionDelay?: number;
9
+ viewportWidth?: number;
10
+ viewportHeight?: number;
11
+ devtools?: boolean;
12
+ keepBrowserOpen?: boolean;
13
+ settingsPanelOpen?: boolean;
14
+ activeTab?: string;
15
+ selectedJourneyIds?: string[];
16
+ breakpoints?: Record<string, number[]>;
17
+ sidebarWidth?: number;
18
+ targetUrlHistory?: string[];
19
+ theme?: string;
20
+ }
21
+ export declare class SettingsStorage {
22
+ private dir;
23
+ private filePath;
24
+ read(): Promise<PersistedSettings>;
25
+ write(settings: PersistedSettings): Promise<void>;
26
+ }
27
+ //# sourceMappingURL=settings-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-storage.d.ts","sourceRoot":"","sources":["../../../src/server/settings-storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAuC;IAClD,OAAO,CAAC,QAAQ,CAAsC;IAEhD,IAAI,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAOlC,KAAK,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAMxD"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * SettingsStorage — persists UI settings to .glassbox/settings.json
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SettingsStorage = void 0;
7
+ const promises_1 = require("fs/promises");
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ class SettingsStorage {
11
+ dir = (0, path_1.resolve)(process.cwd(), '.glassbox');
12
+ filePath = (0, path_1.resolve)(this.dir, 'settings.json');
13
+ async read() {
14
+ if (!(0, fs_1.existsSync)(this.filePath))
15
+ return {};
16
+ const raw = await (0, promises_1.readFile)(this.filePath, 'utf-8');
17
+ return JSON.parse(raw);
18
+ }
19
+ async write(settings) {
20
+ if (!(0, fs_1.existsSync)(this.dir)) {
21
+ await (0, promises_1.mkdir)(this.dir, { recursive: true });
22
+ }
23
+ await (0, promises_1.writeFile)(this.filePath, JSON.stringify(settings, null, 2));
24
+ }
25
+ }
26
+ exports.SettingsStorage = SettingsStorage;
27
+ //# sourceMappingURL=settings-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-storage.js","sourceRoot":"","sources":["../../../src/server/settings-storage.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,0CAAyD;AACzD,2BAAgC;AAChC,+BAA+B;AAoB/B,MAAa,eAAe;IAClB,GAAG,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAC1C,QAAQ,GAAG,IAAA,cAAO,EAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEtD,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QAE1C,MAAM,GAAG,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAA2B;QACrC,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAA,gBAAK,EAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,IAAA,oBAAS,EAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;CACF;AAjBD,0CAiBC"}