@testivai/witness-cdp 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.
Potentially problematic release.
This version of @testivai/witness-cdp might be problematic. Click here for more details.
- 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/cdp/binding.d.ts +44 -0
- package/dist/cdp/binding.d.ts.map +1 -0
- package/dist/cdp/binding.js +183 -0
- package/dist/cdp/binding.js.map +1 -0
- package/dist/cdp/capture.d.ts +42 -0
- package/dist/cdp/capture.d.ts.map +1 -0
- package/dist/cdp/capture.js +235 -0
- package/dist/cdp/capture.js.map +1 -0
- package/dist/cdp/client.d.ts +63 -0
- package/dist/cdp/client.d.ts.map +1 -0
- package/dist/cdp/client.js +279 -0
- package/dist/cdp/client.js.map +1 -0
- package/dist/cdp/discovery.d.ts +33 -0
- package/dist/cdp/discovery.d.ts.map +1 -0
- package/dist/cdp/discovery.js +157 -0
- package/dist/cdp/discovery.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 +140 -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 +307 -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 +244 -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/package.json +64 -0
|
@@ -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.CdpDiscoveryError = exports.CdpDiscovery = void 0;
|
|
7
|
+
const logger_1 = require("../utils/logger");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
/**
|
|
10
|
+
* Default CDP ports to try
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_PORTS = [9222, 9223, 9224, 9229];
|
|
13
|
+
/**
|
|
14
|
+
* Auto-discover Chrome DevTools Protocol endpoint
|
|
15
|
+
*/
|
|
16
|
+
class CdpDiscovery {
|
|
17
|
+
/**
|
|
18
|
+
* Discover CDP 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(`Chrome DevTools Protocol not found on port ${port}`);
|
|
29
|
+
}
|
|
30
|
+
// Check environment variable first
|
|
31
|
+
const envPort = 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 TESTIVAI_CDP_PORT: ${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 CdpDiscoveryError();
|
|
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.CdpDiscovery = CdpDiscovery;
|
|
141
|
+
/**
|
|
142
|
+
* Custom error for CDP discovery failures
|
|
143
|
+
*/
|
|
144
|
+
class CdpDiscoveryError extends Error {
|
|
145
|
+
constructor() {
|
|
146
|
+
super('Chrome DevTools Protocol not found');
|
|
147
|
+
this.name = 'CdpDiscoveryError';
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get user-friendly error message with instructions
|
|
151
|
+
*/
|
|
152
|
+
getInstructions() {
|
|
153
|
+
return CdpDiscovery.getLaunchInstructions();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.CdpDiscoveryError = CdpDiscoveryError;
|
|
157
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/cdp/discovery.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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.authCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const common_1 = require("@testivai/common");
|
|
6
|
+
const logger_1 = require("../utils/logger");
|
|
7
|
+
exports.authCommand = new commander_1.Command('auth')
|
|
8
|
+
.description('Authenticate with your TestivAI API key')
|
|
9
|
+
.argument('[api-key]', 'Your TestivAI API key (optional if TESTIVAI_API_KEY env var is set)')
|
|
10
|
+
.option('--check', 'Check if you are authenticated')
|
|
11
|
+
.option('--show', 'Show current API key')
|
|
12
|
+
.option('--delete', 'Delete stored credentials')
|
|
13
|
+
.action(async (apiKey, options) => {
|
|
14
|
+
try {
|
|
15
|
+
// Check authentication status
|
|
16
|
+
if (options.check) {
|
|
17
|
+
const key = (0, common_1.getApiKey)();
|
|
18
|
+
if (key) {
|
|
19
|
+
logger_1.logger.success(`Authenticated with API key: ${maskApiKey(key)}`);
|
|
20
|
+
// Validate the key with the server
|
|
21
|
+
const client = new common_1.CoreApiClient(key);
|
|
22
|
+
const validation = await client.validateApiKey();
|
|
23
|
+
if (validation.valid) {
|
|
24
|
+
logger_1.logger.success(`API key is valid for project: ${validation.projectName}`);
|
|
25
|
+
if (validation.organizationName) {
|
|
26
|
+
logger_1.logger.info(`Organization: ${validation.organizationName}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
logger_1.logger.error(`API key validation failed: ${validation.error}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
logger_1.logger.error('Not authenticated. Run "testivai auth <api-key>" to authenticate.');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Show current API key
|
|
41
|
+
if (options.show) {
|
|
42
|
+
const key = (0, common_1.getApiKey)();
|
|
43
|
+
if (key) {
|
|
44
|
+
logger_1.logger.info(`Current API key: ${maskApiKey(key)}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
logger_1.logger.warn('No API key is stored. Set TESTIVAI_API_KEY environment variable or run "testivai auth <api-key>"');
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Delete stored credentials
|
|
52
|
+
if (options.delete) {
|
|
53
|
+
const credentials = (0, common_1.loadCredentials)();
|
|
54
|
+
if (credentials) {
|
|
55
|
+
(0, common_1.deleteCredentials)();
|
|
56
|
+
logger_1.logger.success('Deleted stored credentials');
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
logger_1.logger.warn('No stored credentials to delete');
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Authenticate with API key
|
|
64
|
+
const envKey = process.env.TESTIVAI_API_KEY;
|
|
65
|
+
const keyToUse = apiKey || envKey;
|
|
66
|
+
if (!keyToUse) {
|
|
67
|
+
logger_1.logger.error('No API key provided.');
|
|
68
|
+
logger_1.logger.info('Usage:');
|
|
69
|
+
logger_1.logger.info(' testivai auth <api-key>');
|
|
70
|
+
logger_1.logger.info(' TESTIVAI_API_KEY=<api-key> testivai auth');
|
|
71
|
+
logger_1.logger.info('');
|
|
72
|
+
logger_1.logger.info('Get your API key from: https://dashboard.testiv.ai');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
// Validate API key format
|
|
76
|
+
if (!keyToUse.startsWith('tstvai-')) {
|
|
77
|
+
logger_1.logger.warn('Warning: API key should start with "tstvai-"');
|
|
78
|
+
}
|
|
79
|
+
// Test the API key
|
|
80
|
+
logger_1.logger.info('Validating API key...');
|
|
81
|
+
const client = new common_1.CoreApiClient(keyToUse);
|
|
82
|
+
const validation = await client.validateApiKey();
|
|
83
|
+
if (!validation.valid) {
|
|
84
|
+
logger_1.logger.error(`Invalid API key: ${validation.error}`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
// Save credentials if not from environment
|
|
88
|
+
if (!envKey) {
|
|
89
|
+
(0, common_1.saveCredentials)({
|
|
90
|
+
apiKey: keyToUse,
|
|
91
|
+
validatedAt: new Date().toISOString(),
|
|
92
|
+
projectId: validation.projectId,
|
|
93
|
+
projectName: validation.projectName,
|
|
94
|
+
});
|
|
95
|
+
logger_1.logger.success('API key saved locally');
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
logger_1.logger.success('Using API key from environment variable');
|
|
99
|
+
}
|
|
100
|
+
// Show success message
|
|
101
|
+
logger_1.logger.success(`Authenticated successfully!`);
|
|
102
|
+
logger_1.logger.info(`Project: ${validation.projectName}`);
|
|
103
|
+
if (validation.organizationName) {
|
|
104
|
+
logger_1.logger.info(`Organization: ${validation.organizationName}`);
|
|
105
|
+
}
|
|
106
|
+
logger_1.logger.info(`API key: ${maskApiKey(keyToUse)}`);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
logger_1.logger.error('Authentication failed:', error);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Mask API key for display
|
|
115
|
+
*/
|
|
116
|
+
function maskApiKey(apiKey) {
|
|
117
|
+
if (!apiKey || apiKey.length < 12) {
|
|
118
|
+
return '[invalid]';
|
|
119
|
+
}
|
|
120
|
+
return `${apiKey.substring(0, 8)}...${apiKey.substring(apiKey.length - 4)}`;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,cAAc,SAiDvB,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
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.captureCommand = void 0;
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const client_1 = require("../cdp/client");
|
|
43
|
+
const capture_1 = require("../cdp/capture");
|
|
44
|
+
const discovery_1 = require("../cdp/discovery");
|
|
45
|
+
const logger_1 = require("../utils/logger");
|
|
46
|
+
const file_naming_1 = require("../utils/file-naming");
|
|
47
|
+
exports.captureCommand = new commander_1.Command('capture')
|
|
48
|
+
.description('Capture a single visual snapshot')
|
|
49
|
+
.argument('<name>', 'Snapshot name')
|
|
50
|
+
.option('-p, --port <number>', 'Chrome DevTools Protocol port')
|
|
51
|
+
.option('-o, --output <path>', 'Output directory for captured files', '.testivai/captures')
|
|
52
|
+
.option('-f, --format <format>', 'Output format (json|png)', 'json')
|
|
53
|
+
.action(async (name, options) => {
|
|
54
|
+
let client = null;
|
|
55
|
+
try {
|
|
56
|
+
logger_1.logger.info(`Capturing snapshot: ${name}`);
|
|
57
|
+
// Connect to CDP
|
|
58
|
+
logger_1.logger.info('Connecting to Chrome...');
|
|
59
|
+
client = new client_1.CdpClient();
|
|
60
|
+
await client.connect(parseInt(options.port, 10) || undefined);
|
|
61
|
+
// Setup capture
|
|
62
|
+
const capture = new capture_1.CdpCapture(client);
|
|
63
|
+
// Capture snapshot
|
|
64
|
+
const snapshot = await capture.captureSnapshot(name);
|
|
65
|
+
// Save based on format
|
|
66
|
+
if (options.format === 'json') {
|
|
67
|
+
await saveAsJson(snapshot, options.output, name);
|
|
68
|
+
}
|
|
69
|
+
else if (options.format === 'png') {
|
|
70
|
+
await saveAsPng(snapshot, options.output, name);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new Error(`Unknown format: ${options.format}`);
|
|
74
|
+
}
|
|
75
|
+
logger_1.logger.success(`Snapshot captured successfully!`);
|
|
76
|
+
console.log(chalk_1.default.gray(`Saved to: ${options.output}`));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error instanceof discovery_1.CdpDiscoveryError) {
|
|
80
|
+
console.log(chalk_1.default.red(error.message));
|
|
81
|
+
console.log(...error.getInstructions());
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
logger_1.logger.error('Capture failed:', error);
|
|
85
|
+
}
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
// Clean up
|
|
90
|
+
if (client) {
|
|
91
|
+
await client.disconnect();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
/**
|
|
96
|
+
* Save snapshot as JSON
|
|
97
|
+
*/
|
|
98
|
+
async function saveAsJson(snapshot, outputDir, name) {
|
|
99
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
100
|
+
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
101
|
+
// Create output directory
|
|
102
|
+
if (!fs.existsSync(outputDir)) {
|
|
103
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
// Prepare data
|
|
106
|
+
const data = {
|
|
107
|
+
...snapshot,
|
|
108
|
+
capturedAt: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
// Write JSON file
|
|
111
|
+
const filename = `${(0, file_naming_1.toSafeFilename)(name)}.json`;
|
|
112
|
+
const filepath = path.join(outputDir, filename);
|
|
113
|
+
fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf-8');
|
|
114
|
+
// Also save PNG separately if screenshot data exists
|
|
115
|
+
if (snapshot.screenshotData) {
|
|
116
|
+
const pngFilename = `${(0, file_naming_1.toSafeFilename)(name)}.png`;
|
|
117
|
+
const pngFilepath = path.join(outputDir, pngFilename);
|
|
118
|
+
const pngBuffer = Buffer.from(snapshot.screenshotData, 'base64');
|
|
119
|
+
fs.writeFileSync(pngFilepath, pngBuffer);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Save snapshot as PNG only
|
|
124
|
+
*/
|
|
125
|
+
async function saveAsPng(snapshot, outputDir, name) {
|
|
126
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
127
|
+
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
128
|
+
// Create output directory
|
|
129
|
+
if (!fs.existsSync(outputDir)) {
|
|
130
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
131
|
+
}
|
|
132
|
+
// Save PNG
|
|
133
|
+
if (snapshot.screenshotData) {
|
|
134
|
+
const filename = `${(0, file_naming_1.toSafeFilename)(name)}.png`;
|
|
135
|
+
const filepath = path.join(outputDir, filename);
|
|
136
|
+
const pngBuffer = Buffer.from(snapshot.screenshotData, 'base64');
|
|
137
|
+
fs.writeFileSync(filepath, pngBuffer);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw new Error('No screenshot data in snapshot');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,WAAW,SAiDpB,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
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.initCommand = void 0;
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const framework_detect_1 = require("../utils/framework-detect");
|
|
45
|
+
const logger_1 = require("../utils/logger");
|
|
46
|
+
exports.initCommand = new commander_1.Command('init')
|
|
47
|
+
.description('Initialize TestivAI CDP SDK in your project')
|
|
48
|
+
.option('-f, --force', 'Overwrite existing configuration')
|
|
49
|
+
.action(async (options) => {
|
|
50
|
+
try {
|
|
51
|
+
logger_1.logger.info('Initializing TestivAI CDP SDK...');
|
|
52
|
+
// Detect framework
|
|
53
|
+
const detection = framework_detect_1.FrameworkDetector.detect();
|
|
54
|
+
logger_1.logger.info(`Detected framework: ${detection.framework}`);
|
|
55
|
+
if (detection.confidence < 0.5) {
|
|
56
|
+
logger_1.logger.warn('Low confidence in framework detection');
|
|
57
|
+
}
|
|
58
|
+
// Print evidence
|
|
59
|
+
if (detection.evidence.length > 0) {
|
|
60
|
+
logger_1.logger.verbose('Detection evidence:');
|
|
61
|
+
detection.evidence.forEach(e => logger_1.logger.verbose(` - ${e}`));
|
|
62
|
+
}
|
|
63
|
+
// Create config file
|
|
64
|
+
await createConfigFile(options.force);
|
|
65
|
+
// Print framework-specific instructions
|
|
66
|
+
console.log(chalk_1.default.cyan('\n=== Framework Setup Instructions ==='));
|
|
67
|
+
detection.instructions.forEach(line => console.log(line));
|
|
68
|
+
// Print general instructions
|
|
69
|
+
console.log(chalk_1.default.cyan('\n=== General Setup ==='));
|
|
70
|
+
console.log(`
|
|
71
|
+
1. Make sure Chrome is running with remote debugging:
|
|
72
|
+
${chalk_1.default.yellow('chrome --remote-debugging-port=9222')}
|
|
73
|
+
|
|
74
|
+
2. Authenticate with your API key:
|
|
75
|
+
${chalk_1.default.yellow('testivai auth <your-api-key>')}
|
|
76
|
+
|
|
77
|
+
3. Run your tests:
|
|
78
|
+
${chalk_1.default.yellow('testivai run "your-test-command"')}
|
|
79
|
+
|
|
80
|
+
${chalk_1.default.gray('For more information, see: https://docs.testiv.ai/cdp')}
|
|
81
|
+
`);
|
|
82
|
+
logger_1.logger.success('Initialization complete!');
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
logger_1.logger.error('Initialization failed:', error);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* Create the configuration file
|
|
91
|
+
*/
|
|
92
|
+
async function createConfigFile(force) {
|
|
93
|
+
const configPath = path.join(process.cwd(), 'testivai.config.ts');
|
|
94
|
+
// Check if config already exists
|
|
95
|
+
if (fs.existsSync(configPath) && !force) {
|
|
96
|
+
logger_1.logger.warn('Configuration file already exists. Use --force to overwrite.');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Create default config
|
|
100
|
+
const configContent = `/**
|
|
101
|
+
* TestivAI Configuration
|
|
102
|
+
* Generated by @testivai/witness-cdp
|
|
103
|
+
*/
|
|
104
|
+
import type { CdpConfig } from '@testivai/witness-cdp';
|
|
105
|
+
|
|
106
|
+
const config: CdpConfig = {
|
|
107
|
+
// API key (set via TESTIVAI_API_KEY environment variable)
|
|
108
|
+
// apiKey: 'your-api-key-here',
|
|
109
|
+
|
|
110
|
+
// Project ID from TestivAI dashboard
|
|
111
|
+
// projectId: 'your-project-id-here',
|
|
112
|
+
|
|
113
|
+
// Chrome DevTools Protocol port
|
|
114
|
+
cdpPort: 9222,
|
|
115
|
+
|
|
116
|
+
// Auto-launch Chrome if not running (experimental)
|
|
117
|
+
autoLaunch: false,
|
|
118
|
+
|
|
119
|
+
// Chrome executable path (for auto-launch)
|
|
120
|
+
// chromePath: '/path/to/chrome',
|
|
121
|
+
|
|
122
|
+
// Additional Chrome arguments
|
|
123
|
+
chromeArgs: [
|
|
124
|
+
'--no-sandbox',
|
|
125
|
+
'--disable-dev-shm-usage',
|
|
126
|
+
'--disable-gpu',
|
|
127
|
+
],
|
|
128
|
+
|
|
129
|
+
// Connection settings
|
|
130
|
+
connectionTimeout: 5000,
|
|
131
|
+
connectionRetries: 3,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export default config;
|
|
135
|
+
`;
|
|
136
|
+
// Write config file
|
|
137
|
+
fs.writeFileSync(configPath, configContent, 'utf-8');
|
|
138
|
+
logger_1.logger.success(`Created configuration file: ${configPath}`);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAoC;AACpC,kDAA0B;AAC1B,uCAAyB;AACzB,2CAA6B;AAC7B,gEAA8D;AAC9D,4CAAyC;AAE5B,QAAA,WAAW,GAAG,IAAI,mBAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,aAAa,EAAE,kCAAkC,CAAC;KACzD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,eAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAEhD,mBAAmB;QACnB,MAAM,SAAS,GAAG,oCAAiB,CAAC,MAAM,EAAE,CAAC;QAE7C,eAAM,CAAC,IAAI,CAAC,uBAAuB,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1D,IAAI,SAAS,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;YAC/B,eAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACvD,CAAC;QAED,iBAAiB;QACjB,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,eAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;YACtC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,eAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC;QAED,qBAAqB;QACrB,MAAM,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEtC,wCAAwC;QACxC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;QAClE,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1D,6BAA6B;QAC7B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;KAEb,eAAK,CAAC,MAAM,CAAC,qCAAqC,CAAC;;;KAGnD,eAAK,CAAC,MAAM,CAAC,8BAA8B,CAAC;;;KAG5C,eAAK,CAAC,MAAM,CAAC,kCAAkC,CAAC;;EAEnD,eAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC;OAC9D,CAAC,CAAC;QAEH,eAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAE7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,KAAc;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAElE,iCAAiC;IACjC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACxC,eAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCvB,CAAC;IAEA,oBAAoB;IACpB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IACrD,eAAM,CAAC,OAAO,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,UAAU,SA8GnB,CAAC"}
|