@testivai/witness 1.0.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.
- package/LICENSE +21 -0
- package/README.md +405 -0
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +24 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/bin/testivai.d.ts +3 -0
- package/dist/bin/testivai.d.ts.map +1 -0
- package/dist/bin/testivai.js +48 -0
- package/dist/bin/testivai.js.map +1 -0
- package/dist/browser/binding.d.ts +56 -0
- package/dist/browser/binding.d.ts.map +1 -0
- package/dist/browser/binding.js +364 -0
- package/dist/browser/binding.js.map +1 -0
- package/dist/browser/capture.d.ts +61 -0
- package/dist/browser/capture.d.ts.map +1 -0
- package/dist/browser/capture.js +422 -0
- package/dist/browser/capture.js.map +1 -0
- package/dist/browser/client.d.ts +63 -0
- package/dist/browser/client.d.ts.map +1 -0
- package/dist/browser/client.js +279 -0
- package/dist/browser/client.js.map +1 -0
- package/dist/browser/discovery.d.ts +33 -0
- package/dist/browser/discovery.d.ts.map +1 -0
- package/dist/browser/discovery.js +157 -0
- package/dist/browser/discovery.js.map +1 -0
- package/dist/ci.d.ts +31 -0
- package/dist/ci.d.ts.map +1 -0
- package/dist/ci.js +118 -0
- package/dist/ci.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +122 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/capture.d.ts +3 -0
- package/dist/commands/capture.d.ts.map +1 -0
- package/dist/commands/capture.js +143 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +255 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +439 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +329 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file-naming.d.ts +31 -0
- package/dist/utils/file-naming.d.ts.map +1 -0
- package/dist/utils/file-naming.js +137 -0
- package/dist/utils/file-naming.js.map +1 -0
- package/dist/utils/framework-detect.d.ts +31 -0
- package/dist/utils/framework-detect.d.ts.map +1 -0
- package/dist/utils/framework-detect.js +379 -0
- package/dist/utils/framework-detect.js.map +1 -0
- package/dist/utils/logger.d.ts +29 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +114 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/process.d.ts +61 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +208 -0
- package/dist/utils/process.js.map +1 -0
- package/dist/utils/template-generator.d.ts +36 -0
- package/dist/utils/template-generator.d.ts.map +1 -0
- package/dist/utils/template-generator.js +255 -0
- package/dist/utils/template-generator.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.BrowserClient = void 0;
|
|
40
|
+
const chrome_remote_interface_1 = __importDefault(require("chrome-remote-interface"));
|
|
41
|
+
const events_1 = require("events");
|
|
42
|
+
const logger_1 = require("../utils/logger");
|
|
43
|
+
/**
|
|
44
|
+
* Browser protocol client wrapper
|
|
45
|
+
*/
|
|
46
|
+
class BrowserClient extends events_1.EventEmitter {
|
|
47
|
+
constructor() {
|
|
48
|
+
super(...arguments);
|
|
49
|
+
this.client = null;
|
|
50
|
+
this.connectionInfo = null;
|
|
51
|
+
this.isConnected = false;
|
|
52
|
+
this.reconnectAttempts = 0;
|
|
53
|
+
this.maxReconnectAttempts = 3;
|
|
54
|
+
this.reconnectDelay = 500;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Connect to browser via remote debugging
|
|
58
|
+
*/
|
|
59
|
+
async connect(port) {
|
|
60
|
+
try {
|
|
61
|
+
// Import here to avoid issues if chrome-remote-interface is not available
|
|
62
|
+
const { BrowserDiscovery } = await Promise.resolve().then(() => __importStar(require('./discovery')));
|
|
63
|
+
// Discover browser endpoint
|
|
64
|
+
this.connectionInfo = await BrowserDiscovery.discover(port);
|
|
65
|
+
// Connect to the WebSocket
|
|
66
|
+
this.client = await (0, chrome_remote_interface_1.default)({
|
|
67
|
+
target: this.connectionInfo.webSocketDebuggerUrl,
|
|
68
|
+
});
|
|
69
|
+
// Set up event handlers
|
|
70
|
+
if (this.client) {
|
|
71
|
+
this.client.on('disconnect', () => {
|
|
72
|
+
this.isConnected = false;
|
|
73
|
+
this.emit('disconnect');
|
|
74
|
+
logger_1.logger.debug('Browser client disconnected');
|
|
75
|
+
});
|
|
76
|
+
this.client.on('event', (method, params) => {
|
|
77
|
+
this.emit('event', method, params);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
this.isConnected = true;
|
|
81
|
+
this.reconnectAttempts = 0;
|
|
82
|
+
logger_1.logger.connected(port || 9222);
|
|
83
|
+
this.emit('connect', this.client);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger_1.logger.error(`Failed to connect to browser: ${error}`);
|
|
87
|
+
// Try to reconnect if we haven't exceeded max attempts
|
|
88
|
+
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
89
|
+
this.reconnectAttempts++;
|
|
90
|
+
logger_1.logger.debug(`Reconnecting attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}...`);
|
|
91
|
+
await new Promise(resolve => setTimeout(resolve, this.reconnectDelay));
|
|
92
|
+
return this.connect(port);
|
|
93
|
+
}
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Disconnect from browser
|
|
99
|
+
*/
|
|
100
|
+
async disconnect() {
|
|
101
|
+
if (this.client) {
|
|
102
|
+
try {
|
|
103
|
+
await this.client.close();
|
|
104
|
+
this.client = null;
|
|
105
|
+
this.isConnected = false;
|
|
106
|
+
this.connectionInfo = null;
|
|
107
|
+
logger_1.logger.disconnected();
|
|
108
|
+
this.emit('disconnect');
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger_1.logger.error(`Error disconnecting from browser: ${error}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check if connected
|
|
117
|
+
*/
|
|
118
|
+
isClientConnected() {
|
|
119
|
+
return this.isConnected && this.client !== null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the raw protocol client
|
|
123
|
+
*/
|
|
124
|
+
getClient() {
|
|
125
|
+
return this.client;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get connection info
|
|
129
|
+
*/
|
|
130
|
+
getConnectionInfo() {
|
|
131
|
+
return this.connectionInfo;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Enable a domain
|
|
135
|
+
*/
|
|
136
|
+
async enableDomain(domain) {
|
|
137
|
+
if (!this.client) {
|
|
138
|
+
throw new Error('Not connected to browser');
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
await this.client.send(`${domain}.enable`);
|
|
142
|
+
logger_1.logger.debug(`Enabled domain: ${domain}`);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
logger_1.logger.error(`Failed to enable domain ${domain}: ${error}`);
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Send a command to browser
|
|
151
|
+
*/
|
|
152
|
+
async send(method, params) {
|
|
153
|
+
if (!this.client) {
|
|
154
|
+
throw new Error('Not connected to browser');
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const result = await this.client.send(method, params);
|
|
158
|
+
logger_1.logger.debug(`Browser command: ${method}`, params);
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
logger_1.logger.error(`Browser command failed: ${method}`, error);
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get available targets (tabs/pages)
|
|
168
|
+
*/
|
|
169
|
+
async getTargets() {
|
|
170
|
+
if (!this.client) {
|
|
171
|
+
throw new Error('Not connected to browser');
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const { Target } = this.client;
|
|
175
|
+
const targets = await Target.getTargets();
|
|
176
|
+
return targets.targetInfos;
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
logger_1.logger.error('Failed to get targets:', error);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Attach to a specific target
|
|
185
|
+
*/
|
|
186
|
+
async attachToTarget(targetId) {
|
|
187
|
+
if (!this.client) {
|
|
188
|
+
throw new Error('Not connected to browser');
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
const { Target } = this.client;
|
|
192
|
+
await Target.attachToTarget({ targetId, flatten: true });
|
|
193
|
+
logger_1.logger.debug(`Attached to target: ${targetId}`);
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
logger_1.logger.error(`Failed to attach to target ${targetId}:`, error);
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Create a new tab
|
|
202
|
+
*/
|
|
203
|
+
async createTarget(url = 'about:blank') {
|
|
204
|
+
if (!this.client) {
|
|
205
|
+
throw new Error('Not connected to browser');
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const { Target } = this.client;
|
|
209
|
+
const result = await Target.createTarget({ url });
|
|
210
|
+
logger_1.logger.debug(`Created new target: ${result.targetId}`);
|
|
211
|
+
return result.targetId;
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
logger_1.logger.error('Failed to create target:', error);
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Close a target
|
|
220
|
+
*/
|
|
221
|
+
async closeTarget(targetId) {
|
|
222
|
+
if (!this.client) {
|
|
223
|
+
throw new Error('Not connected to browser');
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const { Target } = this.client;
|
|
227
|
+
await Target.closeTarget({ targetId });
|
|
228
|
+
logger_1.logger.debug(`Closed target: ${targetId}`);
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
logger_1.logger.error(`Failed to close target ${targetId}:`, error);
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Set up event listeners for specific domains
|
|
237
|
+
*/
|
|
238
|
+
setupEventListeners() {
|
|
239
|
+
if (!this.client) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
// Page events
|
|
243
|
+
if (this.client.Page) {
|
|
244
|
+
this.client.Page.frameNavigated((params) => {
|
|
245
|
+
this.emit('frameNavigated', params);
|
|
246
|
+
logger_1.logger.debug('Frame navigated:', params.frame.id);
|
|
247
|
+
});
|
|
248
|
+
this.client.Page.loadEventFired(() => {
|
|
249
|
+
this.emit('loadEventFired');
|
|
250
|
+
logger_1.logger.debug('Load event fired');
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
// Runtime events
|
|
254
|
+
if (this.client.Runtime) {
|
|
255
|
+
this.client.Runtime.bindingCalled((params) => {
|
|
256
|
+
this.emit('bindingCalled', params);
|
|
257
|
+
logger_1.logger.bindingCalled(params.name, params.payload);
|
|
258
|
+
});
|
|
259
|
+
this.client.Runtime.consoleAPICalled((params) => {
|
|
260
|
+
this.emit('consoleAPICalled', params);
|
|
261
|
+
});
|
|
262
|
+
this.client.Runtime.exceptionThrown((params) => {
|
|
263
|
+
this.emit('exceptionThrown', params);
|
|
264
|
+
logger_1.logger.error('Runtime exception:', params.exceptionDetails);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
// Network events
|
|
268
|
+
if (this.client.Network) {
|
|
269
|
+
this.client.Network.requestWillBeSent((params) => {
|
|
270
|
+
this.emit('requestWillBeSent', params);
|
|
271
|
+
});
|
|
272
|
+
this.client.Network.responseReceived((params) => {
|
|
273
|
+
this.emit('responseReceived', params);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
exports.BrowserClient = BrowserClient;
|
|
279
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/browser/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BrowserConnectionInfo } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Auto-discover browser debugging endpoint
|
|
4
|
+
*/
|
|
5
|
+
export declare class BrowserDiscovery {
|
|
6
|
+
/**
|
|
7
|
+
* Discover browser endpoint on available ports
|
|
8
|
+
*/
|
|
9
|
+
static discover(port?: number): Promise<BrowserConnectionInfo>;
|
|
10
|
+
/**
|
|
11
|
+
* Try to connect to a specific port
|
|
12
|
+
*/
|
|
13
|
+
private static tryPort;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a port is available
|
|
16
|
+
*/
|
|
17
|
+
static isPortAvailable(port: number): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Get launch instructions for Chrome
|
|
20
|
+
*/
|
|
21
|
+
static getLaunchInstructions(port?: number): string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Custom error for browser discovery failures
|
|
25
|
+
*/
|
|
26
|
+
export declare class BrowserDiscoveryError extends Error {
|
|
27
|
+
constructor();
|
|
28
|
+
/**
|
|
29
|
+
* Get user-friendly error message with instructions
|
|
30
|
+
*/
|
|
31
|
+
getInstructions(): string[];
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/browser/discovery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAQjD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;OAEG;WACU,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAqCpE;;OAEG;mBACkB,OAAO;IA6C5B;;OAEG;WACU,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS5D;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,IAAI,GAAE,MAAa,GAAG,MAAM,EAAE;CAgC5D;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;;IAM9C;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;CAG5B"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BrowserDiscoveryError = exports.BrowserDiscovery = void 0;
|
|
7
|
+
const logger_1 = require("../utils/logger");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
/**
|
|
10
|
+
* Default browser debugging ports to try
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_PORTS = [9222, 9223, 9224, 9229];
|
|
13
|
+
/**
|
|
14
|
+
* Auto-discover browser debugging endpoint
|
|
15
|
+
*/
|
|
16
|
+
class BrowserDiscovery {
|
|
17
|
+
/**
|
|
18
|
+
* Discover browser endpoint on available ports
|
|
19
|
+
*/
|
|
20
|
+
static async discover(port) {
|
|
21
|
+
// If port is specified, try only that port
|
|
22
|
+
if (port) {
|
|
23
|
+
logger_1.logger.debug(`Trying specified port: ${port}`);
|
|
24
|
+
const info = await this.tryPort(port);
|
|
25
|
+
if (info) {
|
|
26
|
+
return info;
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Browser debugging endpoint not found on port ${port}`);
|
|
29
|
+
}
|
|
30
|
+
// Check environment variable first
|
|
31
|
+
const envPort = process.env.TESTIVAI_BROWSER_PORT || process.env.TESTIVAI_CDP_PORT;
|
|
32
|
+
if (envPort) {
|
|
33
|
+
const portNum = parseInt(envPort, 10);
|
|
34
|
+
if (!isNaN(portNum)) {
|
|
35
|
+
logger_1.logger.debug(`Trying port from environment: ${portNum}`);
|
|
36
|
+
const info = await this.tryPort(portNum);
|
|
37
|
+
if (info) {
|
|
38
|
+
return info;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Try default ports
|
|
43
|
+
for (const defaultPort of DEFAULT_PORTS) {
|
|
44
|
+
logger_1.logger.debug(`Trying default port: ${defaultPort}`);
|
|
45
|
+
const info = await this.tryPort(defaultPort);
|
|
46
|
+
if (info) {
|
|
47
|
+
return info;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// No port found
|
|
51
|
+
throw new BrowserDiscoveryError();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Try to connect to a specific port
|
|
55
|
+
*/
|
|
56
|
+
static async tryPort(port) {
|
|
57
|
+
try {
|
|
58
|
+
// First, try the HTTP endpoint to get connection info
|
|
59
|
+
const response = await fetch(`http://localhost:${port}/json/version`);
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const versionInfo = await response.json();
|
|
64
|
+
// Then get the list of tabs/pages
|
|
65
|
+
const tabsResponse = await fetch(`http://localhost:${port}/json`);
|
|
66
|
+
if (!tabsResponse.ok) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const tabs = await tabsResponse.json();
|
|
70
|
+
// Find a suitable page (not an extension or background page)
|
|
71
|
+
const suitableTab = tabs.find((tab) => tab.type === 'page' &&
|
|
72
|
+
!tab.url.startsWith('chrome-extension://') &&
|
|
73
|
+
!tab.url.startsWith('chrome://'));
|
|
74
|
+
const versionInfoAny = versionInfo;
|
|
75
|
+
return {
|
|
76
|
+
webSocketDebuggerUrl: suitableTab?.webSocketDebuggerUrl || versionInfoAny.webSocketDebuggerUrl,
|
|
77
|
+
devtoolsFrontendUrl: suitableTab?.devtoolsFrontendUrl || versionInfoAny.devtoolsFrontendUrl,
|
|
78
|
+
id: suitableTab?.id || versionInfoAny.id,
|
|
79
|
+
title: suitableTab?.title,
|
|
80
|
+
url: suitableTab?.url,
|
|
81
|
+
browserVersion: versionInfoAny['Browser'],
|
|
82
|
+
protocolVersion: versionInfoAny['Protocol-Version'],
|
|
83
|
+
userAgent: versionInfoAny['User-Agent'],
|
|
84
|
+
v8Version: versionInfoAny['V8-Version'],
|
|
85
|
+
webKitVersion: versionInfoAny['WebKit-Version'],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
logger_1.logger.debug(`Port ${port} not available: ${error}`);
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if a port is available
|
|
95
|
+
*/
|
|
96
|
+
static async isPortAvailable(port) {
|
|
97
|
+
try {
|
|
98
|
+
const response = await fetch(`http://localhost:${port}/json/version`);
|
|
99
|
+
return response.ok;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get launch instructions for Chrome
|
|
107
|
+
*/
|
|
108
|
+
static getLaunchInstructions(port = 9222) {
|
|
109
|
+
const instructions = [
|
|
110
|
+
'',
|
|
111
|
+
chalk_1.default.yellow('Chrome not found with remote debugging enabled.'),
|
|
112
|
+
chalk_1.default.yellow('Launch Chrome with the following flag:'),
|
|
113
|
+
'',
|
|
114
|
+
chalk_1.default.cyan(` --remote-debugging-port=${port}`),
|
|
115
|
+
'',
|
|
116
|
+
chalk_1.default.yellow('Examples:'),
|
|
117
|
+
'',
|
|
118
|
+
// macOS
|
|
119
|
+
chalk_1.default.gray('# macOS (Chrome):'),
|
|
120
|
+
chalk_1.default.cyan(` /Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=${port}`),
|
|
121
|
+
'',
|
|
122
|
+
// Windows
|
|
123
|
+
chalk_1.default.gray('# Windows (Chrome):'),
|
|
124
|
+
chalk_1.default.cyan(` "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" --remote-debugging-port=${port}`),
|
|
125
|
+
'',
|
|
126
|
+
// Linux
|
|
127
|
+
chalk_1.default.gray('# Linux (Chrome):'),
|
|
128
|
+
chalk_1.default.cyan(` google-chrome --remote-debugging-port=${port}`),
|
|
129
|
+
'',
|
|
130
|
+
// Chrome Canary/Dev
|
|
131
|
+
chalk_1.default.gray('# Or with Chrome Canary/Dev:'),
|
|
132
|
+
chalk_1.default.cyan(` google-chrome-unstable --remote-debugging-port=${port}`),
|
|
133
|
+
'',
|
|
134
|
+
chalk_1.default.yellow('Then run your test command again.'),
|
|
135
|
+
'',
|
|
136
|
+
];
|
|
137
|
+
return instructions;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.BrowserDiscovery = BrowserDiscovery;
|
|
141
|
+
/**
|
|
142
|
+
* Custom error for browser discovery failures
|
|
143
|
+
*/
|
|
144
|
+
class BrowserDiscoveryError extends Error {
|
|
145
|
+
constructor() {
|
|
146
|
+
super('Browser debugging endpoint not found');
|
|
147
|
+
this.name = 'BrowserDiscoveryError';
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get user-friendly error message with instructions
|
|
151
|
+
*/
|
|
152
|
+
getInstructions() {
|
|
153
|
+
return BrowserDiscovery.getLaunchInstructions();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.BrowserDiscoveryError = BrowserDiscoveryError;
|
|
157
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/browser/discovery.ts"],"names":[],"mappings":"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"}
|
package/dist/ci.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for detecting CI/CD environments and extracting a unique run identifier.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* CI environment information for integration feedback (e.g., GitHub commit statuses, PR comments).
|
|
6
|
+
*/
|
|
7
|
+
export interface CiInfo {
|
|
8
|
+
/** CI provider name */
|
|
9
|
+
provider: string;
|
|
10
|
+
/** Pull/Merge request number (if available) */
|
|
11
|
+
prNumber?: number;
|
|
12
|
+
/** URL to the CI run (if available) */
|
|
13
|
+
runUrl?: string;
|
|
14
|
+
/** CI build/run identifier */
|
|
15
|
+
buildId?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Gets a unique identifier for the current CI run.
|
|
19
|
+
* This ID is used to group snapshots from parallel shards into a single batch.
|
|
20
|
+
*
|
|
21
|
+
* @returns A unique string identifier for the CI run, or null if not in a known CI environment.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getCiRunId(): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Gets detailed CI environment information including PR number and run URL.
|
|
26
|
+
* Used for integration feedback (GitHub commit statuses, PR comments, etc.).
|
|
27
|
+
*
|
|
28
|
+
* @returns CiInfo object if in a known CI environment, or null otherwise.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getCiInfo(): CiInfo | null;
|
|
31
|
+
//# sourceMappingURL=ci.d.ts.map
|
package/dist/ci.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../src/ci.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAuB1C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAoFzC"}
|
package/dist/ci.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utilities for detecting CI/CD environments and extracting a unique run identifier.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getCiRunId = getCiRunId;
|
|
7
|
+
exports.getCiInfo = getCiInfo;
|
|
8
|
+
/**
|
|
9
|
+
* Gets a unique identifier for the current CI run.
|
|
10
|
+
* This ID is used to group snapshots from parallel shards into a single batch.
|
|
11
|
+
*
|
|
12
|
+
* @returns A unique string identifier for the CI run, or null if not in a known CI environment.
|
|
13
|
+
*/
|
|
14
|
+
function getCiRunId() {
|
|
15
|
+
// GitHub Actions
|
|
16
|
+
if (process.env.GITHUB_RUN_ID) {
|
|
17
|
+
return `github-${process.env.GITHUB_RUN_ID}`;
|
|
18
|
+
}
|
|
19
|
+
// GitLab CI
|
|
20
|
+
if (process.env.GITLAB_CI) {
|
|
21
|
+
return `gitlab-${process.env.CI_PIPELINE_ID}`;
|
|
22
|
+
}
|
|
23
|
+
// Jenkins
|
|
24
|
+
if (process.env.JENKINS_URL) {
|
|
25
|
+
return `jenkins-${process.env.BUILD_ID}`;
|
|
26
|
+
}
|
|
27
|
+
// CircleCI
|
|
28
|
+
if (process.env.CIRCLECI) {
|
|
29
|
+
return `circleci-${process.env.CIRCLE_WORKFLOW_ID}`;
|
|
30
|
+
}
|
|
31
|
+
// Travis CI
|
|
32
|
+
if (process.env.TRAVIS) {
|
|
33
|
+
return `travis-${process.env.TRAVIS_BUILD_ID}`;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets detailed CI environment information including PR number and run URL.
|
|
39
|
+
* Used for integration feedback (GitHub commit statuses, PR comments, etc.).
|
|
40
|
+
*
|
|
41
|
+
* @returns CiInfo object if in a known CI environment, or null otherwise.
|
|
42
|
+
*/
|
|
43
|
+
function getCiInfo() {
|
|
44
|
+
// GitHub Actions
|
|
45
|
+
if (process.env.GITHUB_ACTIONS) {
|
|
46
|
+
const serverUrl = process.env.GITHUB_SERVER_URL || 'https://github.com';
|
|
47
|
+
const repo = process.env.GITHUB_REPOSITORY;
|
|
48
|
+
const runId = process.env.GITHUB_RUN_ID;
|
|
49
|
+
// PR number: available via GITHUB_EVENT_NUMBER in pull_request events,
|
|
50
|
+
// or from GITHUB_REF (refs/pull/<number>/merge)
|
|
51
|
+
let prNumber;
|
|
52
|
+
if (process.env.GITHUB_EVENT_NUMBER) {
|
|
53
|
+
prNumber = parseInt(process.env.GITHUB_EVENT_NUMBER, 10) || undefined;
|
|
54
|
+
}
|
|
55
|
+
else if (process.env.GITHUB_REF?.startsWith('refs/pull/')) {
|
|
56
|
+
const match = process.env.GITHUB_REF.match(/^refs\/pull\/(\d+)\//);
|
|
57
|
+
if (match) {
|
|
58
|
+
prNumber = parseInt(match[1], 10);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
provider: 'github_actions',
|
|
63
|
+
prNumber,
|
|
64
|
+
runUrl: repo && runId ? `${serverUrl}/${repo}/actions/runs/${runId}` : undefined,
|
|
65
|
+
buildId: runId,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// GitLab CI
|
|
69
|
+
if (process.env.GITLAB_CI) {
|
|
70
|
+
const prNumber = process.env.CI_MERGE_REQUEST_IID
|
|
71
|
+
? parseInt(process.env.CI_MERGE_REQUEST_IID, 10) || undefined
|
|
72
|
+
: undefined;
|
|
73
|
+
return {
|
|
74
|
+
provider: 'gitlab_ci',
|
|
75
|
+
prNumber,
|
|
76
|
+
runUrl: process.env.CI_PIPELINE_URL || undefined,
|
|
77
|
+
buildId: process.env.CI_PIPELINE_ID,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// CircleCI
|
|
81
|
+
if (process.env.CIRCLECI) {
|
|
82
|
+
const prNumber = process.env.CIRCLE_PULL_REQUEST
|
|
83
|
+
? parseInt(process.env.CIRCLE_PULL_REQUEST.split('/').pop() || '', 10) || undefined
|
|
84
|
+
: undefined;
|
|
85
|
+
return {
|
|
86
|
+
provider: 'circleci',
|
|
87
|
+
prNumber,
|
|
88
|
+
runUrl: process.env.CIRCLE_BUILD_URL || undefined,
|
|
89
|
+
buildId: process.env.CIRCLE_WORKFLOW_ID,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Jenkins
|
|
93
|
+
if (process.env.JENKINS_URL) {
|
|
94
|
+
const prNumber = process.env.CHANGE_ID
|
|
95
|
+
? parseInt(process.env.CHANGE_ID, 10) || undefined
|
|
96
|
+
: undefined;
|
|
97
|
+
return {
|
|
98
|
+
provider: 'jenkins',
|
|
99
|
+
prNumber,
|
|
100
|
+
runUrl: process.env.BUILD_URL || undefined,
|
|
101
|
+
buildId: process.env.BUILD_ID,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Travis CI
|
|
105
|
+
if (process.env.TRAVIS) {
|
|
106
|
+
const prNumber = process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false'
|
|
107
|
+
? parseInt(process.env.TRAVIS_PULL_REQUEST, 10) || undefined
|
|
108
|
+
: undefined;
|
|
109
|
+
return {
|
|
110
|
+
provider: 'travis_ci',
|
|
111
|
+
prNumber,
|
|
112
|
+
runUrl: process.env.TRAVIS_BUILD_WEB_URL || undefined,
|
|
113
|
+
buildId: process.env.TRAVIS_BUILD_ID,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=ci.js.map
|
package/dist/ci.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci.js","sourceRoot":"","sources":["../src/ci.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,WAAW,SA+GpB,CAAC"}
|