@testivai/witness-cdp 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/cdp/binding.d.ts +56 -0
- package/dist/cdp/binding.d.ts.map +1 -0
- package/dist/cdp/binding.js +364 -0
- package/dist/cdp/binding.js.map +1 -0
- package/dist/cdp/capture.d.ts +61 -0
- package/dist/cdp/capture.d.ts.map +1 -0
- package/dist/cdp/capture.js +422 -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/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 +438 -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,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.witnessCommand = 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.witnessCommand = new commander_1.Command('witness')
|
|
48
|
+
.description('Witness 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/witnesses')
|
|
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(`Witnessing 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
|
+
// Witness 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;AAgGpC,eAAO,MAAM,WAAW,SA4IpB,CAAC"}
|
|
@@ -0,0 +1,255 @@
|
|
|
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 inquirer_1 = __importDefault(require("inquirer"));
|
|
45
|
+
const framework_detect_1 = require("../utils/framework-detect");
|
|
46
|
+
const logger_1 = require("../utils/logger");
|
|
47
|
+
const template_generator_1 = require("../utils/template-generator");
|
|
48
|
+
const LANGUAGE_CHOICES = [
|
|
49
|
+
{ name: 'JavaScript / TypeScript', value: 'javascript' },
|
|
50
|
+
{ name: 'Python', value: 'python' },
|
|
51
|
+
{ name: 'Java', value: 'java' },
|
|
52
|
+
{ name: 'Ruby', value: 'ruby' },
|
|
53
|
+
];
|
|
54
|
+
const FRAMEWORK_CHOICES = {
|
|
55
|
+
javascript: [
|
|
56
|
+
{ name: 'Cypress', value: 'cypress' },
|
|
57
|
+
{ name: 'Selenium', value: 'selenium-js' },
|
|
58
|
+
{ name: 'WebdriverIO', value: 'webdriverio' },
|
|
59
|
+
{ name: 'Puppeteer', value: 'puppeteer' },
|
|
60
|
+
],
|
|
61
|
+
python: [
|
|
62
|
+
{ name: 'Selenium (pytest)', value: 'selenium-pytest' },
|
|
63
|
+
{ name: 'Selenium (unittest)', value: 'selenium-unittest' },
|
|
64
|
+
{ name: 'Robot Framework', value: 'robot-framework' },
|
|
65
|
+
],
|
|
66
|
+
java: [
|
|
67
|
+
{ name: 'Selenium (JUnit 5)', value: 'selenium-junit' },
|
|
68
|
+
{ name: 'Selenium (TestNG)', value: 'selenium-testng' },
|
|
69
|
+
],
|
|
70
|
+
ruby: [
|
|
71
|
+
{ name: 'RSpec + Capybara', value: 'rspec-capybara' },
|
|
72
|
+
{ name: 'Cucumber + Capybara', value: 'cucumber-capybara' },
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
const TEST_DIR_DEFAULTS = {
|
|
76
|
+
'cypress': 'cypress/e2e',
|
|
77
|
+
'selenium-js': 'tests',
|
|
78
|
+
'webdriverio': 'test/specs',
|
|
79
|
+
'puppeteer': 'tests',
|
|
80
|
+
'selenium-pytest': 'tests',
|
|
81
|
+
'selenium-unittest': 'tests',
|
|
82
|
+
'robot-framework': 'tests',
|
|
83
|
+
'selenium-junit': 'src/test/java',
|
|
84
|
+
'selenium-testng': 'src/test/java',
|
|
85
|
+
'rspec-capybara': 'spec/features',
|
|
86
|
+
'cucumber-capybara': 'features',
|
|
87
|
+
};
|
|
88
|
+
const NEXT_STEPS = {
|
|
89
|
+
'cypress': ['1. npx testivai auth <your-api-key>', "2. Add cy.witness('name') to your tests", '3. npx testivai run "cypress run --browser chrome"'],
|
|
90
|
+
'selenium-js': ['1. npx testivai auth <your-api-key>', "2. Use witness(driver, 'name') in your tests", '3. npx testivai run "npx jest tests/"'],
|
|
91
|
+
'webdriverio': ['1. npx testivai auth <your-api-key>', "2. Add browser.witness('name') to your tests", '3. npx testivai run "npx wdio run wdio.conf.js"'],
|
|
92
|
+
'puppeteer': ['1. npx testivai auth <your-api-key>', "2. Use witness(page, 'name') in your tests", '3. npx testivai run "npx jest tests/"'],
|
|
93
|
+
'selenium-pytest': ['1. npx testivai auth <your-api-key>', "2. Use witness(driver, 'name') in your tests", '3. npx testivai run "pytest tests/ -v"'],
|
|
94
|
+
'selenium-unittest': ['1. npx testivai auth <your-api-key>', "2. Use witness(self.driver, 'name') in tests", '3. npx testivai run "python -m unittest discover tests/"'],
|
|
95
|
+
'robot-framework': ['1. npx testivai auth <your-api-key>', '2. Use the Witness keyword in your robot tests', '3. npx testivai run "robot tests/"'],
|
|
96
|
+
'selenium-junit': ['1. npx testivai auth <your-api-key>', '2. Use TestivAIWitness.witness(driver, "name")', '3. npx testivai run "mvn test"'],
|
|
97
|
+
'selenium-testng': ['1. npx testivai auth <your-api-key>', '2. Use TestivAIWitness.witness(driver, "name")', '3. npx testivai run "mvn test"'],
|
|
98
|
+
'rspec-capybara': ['1. npx testivai auth <your-api-key>', "2. Include TestivaiWitness and call witness('name')", '3. npx testivai run "bundle exec rspec"'],
|
|
99
|
+
'cucumber-capybara': ['1. npx testivai auth <your-api-key>', '2. Use the "page looks correct" step in features', '3. npx testivai run "bundle exec cucumber"'],
|
|
100
|
+
};
|
|
101
|
+
function isPlaywrightProject(cwd) {
|
|
102
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
103
|
+
if (!fs.existsSync(pkgPath))
|
|
104
|
+
return false;
|
|
105
|
+
try {
|
|
106
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
107
|
+
return !!(pkg.dependencies?.['@playwright/test'] ||
|
|
108
|
+
pkg.devDependencies?.['@playwright/test'] ||
|
|
109
|
+
pkg.dependencies?.playwright ||
|
|
110
|
+
pkg.devDependencies?.playwright);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function printBox(lines) {
|
|
117
|
+
const width = Math.max(...lines.map((l) => l.length)) + 4;
|
|
118
|
+
console.log(chalk_1.default.cyan(' ┌' + '─'.repeat(width) + '┐'));
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
const pad = ' '.repeat(width - line.length - 2);
|
|
121
|
+
console.log(chalk_1.default.cyan(' │') + ' ' + line + pad + chalk_1.default.cyan('│'));
|
|
122
|
+
}
|
|
123
|
+
console.log(chalk_1.default.cyan(' └' + '─'.repeat(width) + '┘'));
|
|
124
|
+
}
|
|
125
|
+
exports.initCommand = new commander_1.Command('init')
|
|
126
|
+
.description('Initialize TestivAI CDP SDK in your project')
|
|
127
|
+
.option('-f, --force', 'Overwrite existing configuration files')
|
|
128
|
+
.option('-y, --yes', 'Skip prompts and use auto-detected framework')
|
|
129
|
+
.action(async (options) => {
|
|
130
|
+
try {
|
|
131
|
+
const cwd = process.cwd();
|
|
132
|
+
// ── Auto-detect mode (--yes flag) ─────────────────────────────────────
|
|
133
|
+
if (options.yes) {
|
|
134
|
+
logger_1.logger.info('Initializing TestivAI CDP SDK...');
|
|
135
|
+
const detection = framework_detect_1.FrameworkDetector.detect();
|
|
136
|
+
logger_1.logger.info(`Detected framework: ${detection.framework}`);
|
|
137
|
+
if (detection.confidence < 0.5) {
|
|
138
|
+
logger_1.logger.warn('Low confidence in framework detection');
|
|
139
|
+
}
|
|
140
|
+
(0, template_generator_1.generateConfig)(options.force ?? false, cwd);
|
|
141
|
+
console.log(chalk_1.default.cyan('\n=== Framework Setup Instructions ==='));
|
|
142
|
+
detection.instructions.forEach((line) => console.log(line));
|
|
143
|
+
console.log(chalk_1.default.cyan('\n=== General Setup ==='));
|
|
144
|
+
console.log(`
|
|
145
|
+
1. Authenticate with your API key:
|
|
146
|
+
${chalk_1.default.yellow('testivai auth <your-api-key>')}
|
|
147
|
+
|
|
148
|
+
2. Run your tests:
|
|
149
|
+
${chalk_1.default.yellow('testivai run "your-test-command"')}
|
|
150
|
+
|
|
151
|
+
${chalk_1.default.gray('For more information, see: https://docs.testiv.ai/cdp')}
|
|
152
|
+
`);
|
|
153
|
+
logger_1.logger.success('Initialization complete!');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// ── Playwright early-exit ──────────────────────────────────────────────
|
|
157
|
+
if (isPlaywrightProject(cwd)) {
|
|
158
|
+
console.log();
|
|
159
|
+
console.log(chalk_1.default.yellow('⚠ Playwright detected in this project.'));
|
|
160
|
+
console.log();
|
|
161
|
+
console.log('For Playwright, use the dedicated SDK instead:');
|
|
162
|
+
console.log(chalk_1.default.cyan(' npm install @testivai/witness-playwright'));
|
|
163
|
+
console.log(chalk_1.default.gray(' Docs: https://testiv.ai/docs#playwright'));
|
|
164
|
+
console.log();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
// ── Interactive wizard ─────────────────────────────────────────────────
|
|
168
|
+
console.log();
|
|
169
|
+
console.log(chalk_1.default.cyan.bold(' ╔══════════════════════════════════════╗'));
|
|
170
|
+
console.log(chalk_1.default.cyan.bold(' ║ TestivAI Visual Regression Setup ║'));
|
|
171
|
+
console.log(chalk_1.default.cyan.bold(' ╚══════════════════════════════════════╝'));
|
|
172
|
+
console.log();
|
|
173
|
+
const { language } = await inquirer_1.default.prompt([
|
|
174
|
+
{
|
|
175
|
+
type: 'list',
|
|
176
|
+
name: 'language',
|
|
177
|
+
message: 'Select your language:',
|
|
178
|
+
choices: LANGUAGE_CHOICES,
|
|
179
|
+
},
|
|
180
|
+
]);
|
|
181
|
+
const { frameworkKey } = await inquirer_1.default.prompt([
|
|
182
|
+
{
|
|
183
|
+
type: 'list',
|
|
184
|
+
name: 'frameworkKey',
|
|
185
|
+
message: 'Select your test framework:',
|
|
186
|
+
choices: FRAMEWORK_CHOICES[language],
|
|
187
|
+
},
|
|
188
|
+
]);
|
|
189
|
+
const defaultTestDir = TEST_DIR_DEFAULTS[frameworkKey] ?? 'tests';
|
|
190
|
+
const { testDir } = await inquirer_1.default.prompt([
|
|
191
|
+
{
|
|
192
|
+
type: 'input',
|
|
193
|
+
name: 'testDir',
|
|
194
|
+
message: 'Where are your test files?',
|
|
195
|
+
default: defaultTestDir,
|
|
196
|
+
},
|
|
197
|
+
]);
|
|
198
|
+
console.log();
|
|
199
|
+
// ── Generate template files ────────────────────────────────────────────
|
|
200
|
+
const { created, skipped } = (0, template_generator_1.generateTemplates)({
|
|
201
|
+
frameworkKey: frameworkKey,
|
|
202
|
+
testDir: testDir,
|
|
203
|
+
force: options.force ?? false,
|
|
204
|
+
cwd,
|
|
205
|
+
});
|
|
206
|
+
const configResult = (0, template_generator_1.generateConfig)(options.force ?? false, cwd);
|
|
207
|
+
if (configResult.created)
|
|
208
|
+
created.push('testivai.config.ts');
|
|
209
|
+
// Cypress: handle cypress.config.js
|
|
210
|
+
if (frameworkKey === 'cypress') {
|
|
211
|
+
const cypressResult = (0, template_generator_1.generateCypressConfig)(options.force ?? false, cwd);
|
|
212
|
+
if (cypressResult.generated) {
|
|
213
|
+
created.push('cypress.config.js');
|
|
214
|
+
}
|
|
215
|
+
else if (cypressResult.exists && cypressResult.existingFile) {
|
|
216
|
+
console.log(chalk_1.default.yellow(`\n⚠ Existing ${cypressResult.existingFile} detected.`));
|
|
217
|
+
console.log(' Add the TestivAI plugin to your setupNodeEvents:\n');
|
|
218
|
+
console.log(chalk_1.default.gray(" const testivaiPlugin = require('./cypress/support/testivai-plugin');"));
|
|
219
|
+
console.log(chalk_1.default.gray(' setupNodeEvents(on, config) {'));
|
|
220
|
+
console.log(chalk_1.default.gray(' return testivaiPlugin(on, config);'));
|
|
221
|
+
console.log(chalk_1.default.gray(' }\n'));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
for (const f of created) {
|
|
225
|
+
console.log(chalk_1.default.green(' ✓ Created: ') + f);
|
|
226
|
+
}
|
|
227
|
+
for (const f of skipped) {
|
|
228
|
+
console.log(chalk_1.default.yellow(' ⚠ Skipped (exists): ') + f);
|
|
229
|
+
}
|
|
230
|
+
// ── Completion box ─────────────────────────────────────────────────────
|
|
231
|
+
const steps = NEXT_STEPS[frameworkKey] ?? [
|
|
232
|
+
'1. npx testivai auth <your-api-key>',
|
|
233
|
+
'2. Add witness calls to your tests',
|
|
234
|
+
'3. npx testivai run "<your-test-command>"',
|
|
235
|
+
];
|
|
236
|
+
console.log();
|
|
237
|
+
printBox([
|
|
238
|
+
'Setup complete! Next steps:',
|
|
239
|
+
'',
|
|
240
|
+
...steps,
|
|
241
|
+
'',
|
|
242
|
+
`Docs: https://testiv.ai/docs#${frameworkKey.split('-')[0]}`,
|
|
243
|
+
]);
|
|
244
|
+
console.log();
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
if (error?.name === 'ExitPromptError') {
|
|
248
|
+
console.log(chalk_1.default.gray('\n Setup cancelled.'));
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
logger_1.logger.error('Initialization failed:', error);
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;AAYpC,eAAO,MAAM,UAAU,SAkKnB,CAAC"}
|