@desplega.ai/qa-use 2.0.1 → 2.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.
- package/dist/lib/api/sse.d.ts.map +1 -1
- package/dist/lib/api/sse.js +31 -7
- package/dist/lib/api/sse.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/cli/commands/test/export.d.ts +6 -0
- package/dist/src/cli/commands/test/export.d.ts.map +1 -0
- package/dist/src/cli/commands/test/export.js +82 -0
- package/dist/src/cli/commands/test/export.js.map +1 -0
- package/dist/src/cli/commands/test/index.d.ts.map +1 -1
- package/dist/src/cli/commands/test/index.js +4 -0
- package/dist/src/cli/commands/test/index.js.map +1 -1
- package/dist/src/cli/commands/test/run.d.ts.map +1 -1
- package/dist/src/cli/commands/test/run.js +17 -6
- package/dist/src/cli/commands/test/run.js.map +1 -1
- package/dist/src/cli/commands/test/sync.d.ts +6 -0
- package/dist/src/cli/commands/test/sync.d.ts.map +1 -0
- package/dist/src/cli/commands/test/sync.js +157 -0
- package/dist/src/cli/commands/test/sync.js.map +1 -0
- package/dist/src/cli/lib/browser.d.ts +50 -0
- package/dist/src/cli/lib/browser.d.ts.map +1 -0
- package/dist/src/cli/lib/browser.js +111 -0
- package/dist/src/cli/lib/browser.js.map +1 -0
- package/dist/src/cli/lib/id-injector.d.ts +59 -0
- package/dist/src/cli/lib/id-injector.d.ts.map +1 -0
- package/dist/src/cli/lib/id-injector.js +143 -0
- package/dist/src/cli/lib/id-injector.js.map +1 -0
- package/dist/src/cli/lib/output.d.ts +13 -1
- package/dist/src/cli/lib/output.d.ts.map +1 -1
- package/dist/src/cli/lib/output.js +145 -8
- package/dist/src/cli/lib/output.js.map +1 -1
- package/dist/src/cli/lib/runner.d.ts +9 -1
- package/dist/src/cli/lib/runner.d.ts.map +1 -1
- package/dist/src/cli/lib/runner.js +6 -2
- package/dist/src/cli/lib/runner.js.map +1 -1
- package/dist/src/types/test-definition.d.ts +5 -3
- package/dist/src/types/test-definition.d.ts.map +1 -1
- package/dist/src/types/test-definition.js +3 -3
- package/lib/api/sse.ts +36 -7
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser and tunnel management for CLI test execution
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic localhost tunneling when tests target localhost URLs,
|
|
5
|
+
* and browser WebSocket connection for remote test execution.
|
|
6
|
+
*/
|
|
7
|
+
import { TunnelManager } from '../../../lib/tunnel/index.js';
|
|
8
|
+
import { BrowserManager } from '../../../lib/browser/index.js';
|
|
9
|
+
import { URL } from 'url';
|
|
10
|
+
/**
|
|
11
|
+
* Check if a URL points to localhost
|
|
12
|
+
*/
|
|
13
|
+
export function isLocalhostUrl(url) {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = new URL(url);
|
|
16
|
+
return (parsed.hostname === 'localhost' ||
|
|
17
|
+
parsed.hostname === '127.0.0.1' ||
|
|
18
|
+
parsed.hostname === '::1' ||
|
|
19
|
+
parsed.hostname.endsWith('.localhost'));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the port from a URL
|
|
27
|
+
*/
|
|
28
|
+
export function getPortFromUrl(url) {
|
|
29
|
+
try {
|
|
30
|
+
const parsed = new URL(url);
|
|
31
|
+
if (parsed.port) {
|
|
32
|
+
return parseInt(parsed.port, 10);
|
|
33
|
+
}
|
|
34
|
+
// Default ports
|
|
35
|
+
return parsed.protocol === 'https:' ? 443 : 80;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return 80;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Start browser and tunnel (if needed for localhost testing)
|
|
43
|
+
*
|
|
44
|
+
* @param testUrl - The URL being tested (to detect localhost)
|
|
45
|
+
* @param options - Browser and tunnel options
|
|
46
|
+
* @returns BrowserTunnelSession with connection details
|
|
47
|
+
*/
|
|
48
|
+
export async function startBrowserWithTunnel(testUrl, options = {}) {
|
|
49
|
+
const browser = new BrowserManager();
|
|
50
|
+
let tunnel = null;
|
|
51
|
+
let publicWsUrl = null;
|
|
52
|
+
// Start browser
|
|
53
|
+
console.error('Starting browser...');
|
|
54
|
+
const browserSession = await browser.startBrowser({
|
|
55
|
+
headless: options.headless ?? true,
|
|
56
|
+
});
|
|
57
|
+
const wsUrl = browserSession.wsEndpoint;
|
|
58
|
+
const isLocalhost = testUrl ? isLocalhostUrl(testUrl) : false;
|
|
59
|
+
// If testing localhost, set up tunnel for browser WebSocket
|
|
60
|
+
if (isLocalhost || !testUrl) {
|
|
61
|
+
console.error('Localhost URL detected - starting tunnel for browser connection...');
|
|
62
|
+
tunnel = new TunnelManager();
|
|
63
|
+
// Extract port from WebSocket URL
|
|
64
|
+
const wsPort = getPortFromUrl(wsUrl);
|
|
65
|
+
const tunnelSession = await tunnel.startTunnel(wsPort, {
|
|
66
|
+
apiKey: options.apiKey,
|
|
67
|
+
sessionIndex: options.sessionIndex,
|
|
68
|
+
});
|
|
69
|
+
publicWsUrl = tunnel.getWebSocketUrl(wsUrl);
|
|
70
|
+
console.error(`Tunnel established: ${tunnelSession.publicUrl}`);
|
|
71
|
+
console.error(`Public WebSocket URL: ${publicWsUrl}`);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
browser,
|
|
75
|
+
tunnel,
|
|
76
|
+
wsUrl,
|
|
77
|
+
publicWsUrl,
|
|
78
|
+
isLocalhost,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Stop browser and tunnel
|
|
83
|
+
*/
|
|
84
|
+
export async function stopBrowserWithTunnel(session) {
|
|
85
|
+
if (session.tunnel) {
|
|
86
|
+
await session.tunnel.stopTunnel();
|
|
87
|
+
}
|
|
88
|
+
await session.browser.stopBrowser();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get the appropriate WebSocket URL for API calls
|
|
92
|
+
* Returns public URL if tunnel is active, otherwise local URL
|
|
93
|
+
*/
|
|
94
|
+
export function getEffectiveWsUrl(session) {
|
|
95
|
+
return session.publicWsUrl || session.wsUrl;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if browser and tunnel are healthy
|
|
99
|
+
*/
|
|
100
|
+
export async function checkSessionHealth(session) {
|
|
101
|
+
const browserHealthy = await session.browser.checkHealth();
|
|
102
|
+
if (!browserHealthy) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (session.tunnel) {
|
|
106
|
+
const tunnelHealthy = await session.tunnel.checkHealth();
|
|
107
|
+
return tunnelHealthy;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../../src/cli/lib/browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID injection utility for YAML test definition files
|
|
3
|
+
*
|
|
4
|
+
* After a test is persisted to the cloud, this utility injects the
|
|
5
|
+
* assigned test ID back into the original YAML file, enabling
|
|
6
|
+
* round-trip synchronization between local files and cloud tests.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Inject a test ID into a YAML file
|
|
10
|
+
*
|
|
11
|
+
* This function preserves comments and formatting by:
|
|
12
|
+
* 1. Parsing with yaml library that preserves structure
|
|
13
|
+
* 2. Adding/updating the 'id' field at the document root
|
|
14
|
+
* 3. Writing back with preserved formatting
|
|
15
|
+
*
|
|
16
|
+
* @param filePath - Path to the YAML test definition file
|
|
17
|
+
* @param testId - UUID to inject
|
|
18
|
+
* @returns True if file was modified, false if ID already present
|
|
19
|
+
*/
|
|
20
|
+
export declare function injectTestId(filePath: string, testId: string): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Inject multiple test IDs into their corresponding files
|
|
23
|
+
*
|
|
24
|
+
* @param mappings - Array of { filePath, testId } pairs
|
|
25
|
+
* @returns Summary of injections performed
|
|
26
|
+
*/
|
|
27
|
+
export declare function injectTestIds(mappings: Array<{
|
|
28
|
+
filePath: string;
|
|
29
|
+
testId: string;
|
|
30
|
+
}>): Promise<{
|
|
31
|
+
injected: string[];
|
|
32
|
+
skipped: string[];
|
|
33
|
+
errors: Array<{
|
|
34
|
+
filePath: string;
|
|
35
|
+
error: string;
|
|
36
|
+
}>;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Extract ID from a test definition file
|
|
40
|
+
*
|
|
41
|
+
* @param filePath - Path to test definition file
|
|
42
|
+
* @returns Test ID if present, null otherwise
|
|
43
|
+
*/
|
|
44
|
+
export declare function extractTestId(filePath: string): Promise<string | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a test definition file has a cloud ID
|
|
47
|
+
*
|
|
48
|
+
* @param filePath - Path to test definition file
|
|
49
|
+
* @returns True if file has an ID field
|
|
50
|
+
*/
|
|
51
|
+
export declare function hasTestId(filePath: string): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Remove ID from a test definition file (for creating new tests)
|
|
54
|
+
*
|
|
55
|
+
* @param filePath - Path to YAML test definition file
|
|
56
|
+
* @returns True if ID was removed, false if no ID present
|
|
57
|
+
*/
|
|
58
|
+
export declare function removeTestId(filePath: string): Promise<boolean>;
|
|
59
|
+
//# sourceMappingURL=id-injector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-injector.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/id-injector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCrF;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,OAAO,CAAC;IACT,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC,CA+BD;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe5E;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBrE"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID injection utility for YAML test definition files
|
|
3
|
+
*
|
|
4
|
+
* After a test is persisted to the cloud, this utility injects the
|
|
5
|
+
* assigned test ID back into the original YAML file, enabling
|
|
6
|
+
* round-trip synchronization between local files and cloud tests.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'fs/promises';
|
|
9
|
+
import * as yaml from 'yaml';
|
|
10
|
+
/**
|
|
11
|
+
* Inject a test ID into a YAML file
|
|
12
|
+
*
|
|
13
|
+
* This function preserves comments and formatting by:
|
|
14
|
+
* 1. Parsing with yaml library that preserves structure
|
|
15
|
+
* 2. Adding/updating the 'id' field at the document root
|
|
16
|
+
* 3. Writing back with preserved formatting
|
|
17
|
+
*
|
|
18
|
+
* @param filePath - Path to the YAML test definition file
|
|
19
|
+
* @param testId - UUID to inject
|
|
20
|
+
* @returns True if file was modified, false if ID already present
|
|
21
|
+
*/
|
|
22
|
+
export async function injectTestId(filePath, testId) {
|
|
23
|
+
// Read file content
|
|
24
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
25
|
+
// Parse as YAML document to preserve comments/formatting
|
|
26
|
+
const doc = yaml.parseDocument(content);
|
|
27
|
+
// Check if ID already exists and matches
|
|
28
|
+
const existingId = doc.get('id');
|
|
29
|
+
if (existingId === testId) {
|
|
30
|
+
return false; // No change needed
|
|
31
|
+
}
|
|
32
|
+
// Add or update the id field
|
|
33
|
+
// For simplicity, we use set() which adds to end if not present
|
|
34
|
+
// Then we re-order the keys by reconstructing the content
|
|
35
|
+
doc.set('id', testId);
|
|
36
|
+
// If we want id first, we need to reorder the map
|
|
37
|
+
const contents = doc.contents;
|
|
38
|
+
if (yaml.isMap(contents) && !existingId) {
|
|
39
|
+
// Find the id item and move it to front
|
|
40
|
+
const items = contents.items;
|
|
41
|
+
const idIndex = items.findIndex((item) => {
|
|
42
|
+
const key = yaml.isScalar(item.key) ? item.key.value : item.key;
|
|
43
|
+
return key === 'id';
|
|
44
|
+
});
|
|
45
|
+
if (idIndex > 0) {
|
|
46
|
+
const idItem = items.splice(idIndex, 1)[0];
|
|
47
|
+
items.unshift(idItem);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Write back to file
|
|
51
|
+
const output = doc.toString();
|
|
52
|
+
await fs.writeFile(filePath, output, 'utf-8');
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Inject multiple test IDs into their corresponding files
|
|
57
|
+
*
|
|
58
|
+
* @param mappings - Array of { filePath, testId } pairs
|
|
59
|
+
* @returns Summary of injections performed
|
|
60
|
+
*/
|
|
61
|
+
export async function injectTestIds(mappings) {
|
|
62
|
+
const result = {
|
|
63
|
+
injected: [],
|
|
64
|
+
skipped: [],
|
|
65
|
+
errors: [],
|
|
66
|
+
};
|
|
67
|
+
for (const { filePath, testId } of mappings) {
|
|
68
|
+
try {
|
|
69
|
+
// Only process YAML files
|
|
70
|
+
if (!filePath.match(/\.(yaml|yml)$/)) {
|
|
71
|
+
result.skipped.push(filePath);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const modified = await injectTestId(filePath, testId);
|
|
75
|
+
if (modified) {
|
|
76
|
+
result.injected.push(filePath);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
result.skipped.push(filePath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
result.errors.push({
|
|
84
|
+
filePath,
|
|
85
|
+
error: error instanceof Error ? error.message : String(error),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Extract ID from a test definition file
|
|
93
|
+
*
|
|
94
|
+
* @param filePath - Path to test definition file
|
|
95
|
+
* @returns Test ID if present, null otherwise
|
|
96
|
+
*/
|
|
97
|
+
export async function extractTestId(filePath) {
|
|
98
|
+
try {
|
|
99
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
100
|
+
if (filePath.endsWith('.json')) {
|
|
101
|
+
const parsed = JSON.parse(content);
|
|
102
|
+
return parsed.id || null;
|
|
103
|
+
}
|
|
104
|
+
// Parse YAML
|
|
105
|
+
const parsed = yaml.parse(content);
|
|
106
|
+
return parsed.id || null;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if a test definition file has a cloud ID
|
|
114
|
+
*
|
|
115
|
+
* @param filePath - Path to test definition file
|
|
116
|
+
* @returns True if file has an ID field
|
|
117
|
+
*/
|
|
118
|
+
export async function hasTestId(filePath) {
|
|
119
|
+
const id = await extractTestId(filePath);
|
|
120
|
+
return id !== null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Remove ID from a test definition file (for creating new tests)
|
|
124
|
+
*
|
|
125
|
+
* @param filePath - Path to YAML test definition file
|
|
126
|
+
* @returns True if ID was removed, false if no ID present
|
|
127
|
+
*/
|
|
128
|
+
export async function removeTestId(filePath) {
|
|
129
|
+
// Only process YAML files
|
|
130
|
+
if (!filePath.match(/\.(yaml|yml)$/)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
134
|
+
const doc = yaml.parseDocument(content);
|
|
135
|
+
if (!doc.has('id')) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
doc.delete('id');
|
|
139
|
+
const output = doc.toString();
|
|
140
|
+
await fs.writeFile(filePath, output, 'utf-8');
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=id-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-injector.js","sourceRoot":"","sources":["../../../../src/cli/lib/id-injector.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
* Console output formatting utilities
|
|
3
3
|
*/
|
|
4
4
|
import type { SSEEvent } from '../../../lib/api/sse.js';
|
|
5
|
+
/**
|
|
6
|
+
* Context for SSE progress output, used for features like --update-local
|
|
7
|
+
*/
|
|
8
|
+
export interface SSEProgressContext {
|
|
9
|
+
/** Whether to update local file on test_fixed event */
|
|
10
|
+
updateLocal?: boolean;
|
|
11
|
+
/** Path to the source test definition file */
|
|
12
|
+
sourceFile?: string;
|
|
13
|
+
}
|
|
5
14
|
/**
|
|
6
15
|
* Format success message
|
|
7
16
|
*/
|
|
@@ -32,8 +41,11 @@ export declare function duration(seconds: number): string;
|
|
|
32
41
|
export declare function progressBar(completed: number, total: number, width?: number): string;
|
|
33
42
|
/**
|
|
34
43
|
* Print SSE event progress in real-time
|
|
44
|
+
* @param event - SSE event to print
|
|
45
|
+
* @param verbose - If true, also print raw event data
|
|
46
|
+
* @param context - Optional context for features like --update-local
|
|
35
47
|
*/
|
|
36
|
-
export declare function printSSEProgress(event: SSEEvent): void;
|
|
48
|
+
export declare function printSSEProgress(event: SSEEvent, verbose?: boolean, context?: SSEProgressContext): void;
|
|
37
49
|
/**
|
|
38
50
|
* Print test list table
|
|
39
51
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/output.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuBD;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAOxF;AAoED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,QAAQ,EACf,OAAO,GAAE,OAAe,EACxB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,IAAI,CAsHN;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAajG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GACjE,IAAI,CAUN"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Console output formatting utilities
|
|
3
3
|
*/
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as yaml from 'yaml';
|
|
4
6
|
// ANSI color codes
|
|
5
7
|
const colors = {
|
|
6
8
|
reset: '\x1b[0m',
|
|
@@ -11,6 +13,14 @@ const colors = {
|
|
|
11
13
|
gray: '\x1b[90m',
|
|
12
14
|
cyan: '\x1b[36m',
|
|
13
15
|
};
|
|
16
|
+
// Track printed logs per step to avoid duplicates when logs are sent incrementally
|
|
17
|
+
const printedLogs = new Map();
|
|
18
|
+
/**
|
|
19
|
+
* Reset printed logs tracker (call on new test run)
|
|
20
|
+
*/
|
|
21
|
+
function resetPrintedLogs() {
|
|
22
|
+
printedLogs.clear();
|
|
23
|
+
}
|
|
14
24
|
/**
|
|
15
25
|
* Format success message
|
|
16
26
|
*/
|
|
@@ -60,22 +70,129 @@ export function progressBar(completed, total, width = 30) {
|
|
|
60
70
|
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
61
71
|
return `${colors.cyan}${bar}${colors.reset} ${percentage}%`;
|
|
62
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Format a single log line with appropriate icon based on prefix
|
|
75
|
+
*/
|
|
76
|
+
function formatLogLine(log) {
|
|
77
|
+
// Known prefixes and their icons/colors
|
|
78
|
+
const prefixMap = [
|
|
79
|
+
{ prefix: '[Failed]', icon: '✗', color: colors.red },
|
|
80
|
+
{ prefix: '[Retry]', icon: '↻', color: colors.yellow },
|
|
81
|
+
{ prefix: '[Screenshot]', icon: '📷', color: colors.gray },
|
|
82
|
+
{ prefix: '[Info]', icon: 'ℹ', color: colors.blue },
|
|
83
|
+
{ prefix: '[Warning]', icon: '⚠', color: colors.yellow },
|
|
84
|
+
{ prefix: '[Error]', icon: '✗', color: colors.red },
|
|
85
|
+
];
|
|
86
|
+
for (const { prefix, icon, color } of prefixMap) {
|
|
87
|
+
if (log.startsWith(prefix)) {
|
|
88
|
+
const message = log.slice(prefix.length).trim();
|
|
89
|
+
return ` ${color}${icon}${colors.reset} ${colors.gray}${message}${colors.reset}`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// AI-based logs (don't have bracket prefix)
|
|
93
|
+
if (log.startsWith('AI-based') || log.startsWith('Using AI')) {
|
|
94
|
+
return ` ${colors.blue}🤖${colors.reset} ${colors.gray}${log}${colors.reset}`;
|
|
95
|
+
}
|
|
96
|
+
// Free-form logs without known prefix
|
|
97
|
+
return ` ${colors.gray}· ${log}${colors.reset}`;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Print a single log entry with multiline support
|
|
101
|
+
*/
|
|
102
|
+
function printLogEntry(log) {
|
|
103
|
+
// Handle multiline logs (e.g., [Failed] with stack traces)
|
|
104
|
+
const lines = log.split('\n');
|
|
105
|
+
console.log(formatLogLine(lines[0]));
|
|
106
|
+
// Indent continuation lines
|
|
107
|
+
for (let i = 1; i < lines.length; i++) {
|
|
108
|
+
if (lines[i].trim()) {
|
|
109
|
+
console.log(` ${colors.gray}${lines[i]}${colors.reset}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Print logs incrementally, avoiding duplicates for a given step
|
|
115
|
+
* Logs are tracked per step_index to handle cumulative logs from backend
|
|
116
|
+
*/
|
|
117
|
+
function printLogsIncremental(stepIndex, logs) {
|
|
118
|
+
if (!logs?.length)
|
|
119
|
+
return;
|
|
120
|
+
let seen = printedLogs.get(stepIndex);
|
|
121
|
+
if (!seen) {
|
|
122
|
+
seen = new Set();
|
|
123
|
+
printedLogs.set(stepIndex, seen);
|
|
124
|
+
}
|
|
125
|
+
for (const log of logs) {
|
|
126
|
+
if (!seen.has(log)) {
|
|
127
|
+
seen.add(log);
|
|
128
|
+
printLogEntry(log);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
63
132
|
/**
|
|
64
133
|
* Print SSE event progress in real-time
|
|
134
|
+
* @param event - SSE event to print
|
|
135
|
+
* @param verbose - If true, also print raw event data
|
|
136
|
+
* @param context - Optional context for features like --update-local
|
|
65
137
|
*/
|
|
66
|
-
export function printSSEProgress(event) {
|
|
138
|
+
export function printSSEProgress(event, verbose = false, context) {
|
|
139
|
+
// In verbose mode, print raw event data first
|
|
140
|
+
if (verbose) {
|
|
141
|
+
console.log(`${colors.gray}[${event.event}] ${JSON.stringify(event.data)}${colors.reset}`);
|
|
142
|
+
}
|
|
67
143
|
switch (event.event) {
|
|
68
144
|
case 'start':
|
|
145
|
+
resetPrintedLogs();
|
|
69
146
|
console.log(success(`Test started (run_id: ${event.data.run_id})`));
|
|
70
|
-
console.log(`
|
|
147
|
+
console.log(`Total steps: ${event.data.total_steps}\n`);
|
|
71
148
|
break;
|
|
72
149
|
case 'step_start':
|
|
73
|
-
|
|
150
|
+
console.log(`${colors.gray}[${event.data.step_index}]${colors.reset} ${event.data.name}...`);
|
|
151
|
+
printLogsIncremental(event.data.step_index, event.data.logs);
|
|
74
152
|
break;
|
|
153
|
+
case 'step_retry': {
|
|
154
|
+
const attempt = event.data.retry_attempt;
|
|
155
|
+
const maxRetries = event.data.max_retries;
|
|
156
|
+
const waitInfo = event.data.retry_wait_seconds
|
|
157
|
+
? ` (waited ${event.data.retry_wait_seconds}s)`
|
|
158
|
+
: '';
|
|
159
|
+
const phase = event.data.retry_phase;
|
|
160
|
+
// Use different icons and colors based on retry phase
|
|
161
|
+
// Only show tag for 'fixing' phase (AI self-healing)
|
|
162
|
+
const isFixing = phase === 'fixing';
|
|
163
|
+
const icon = isFixing
|
|
164
|
+
? `${colors.blue}🔧${colors.reset}`
|
|
165
|
+
: `${colors.yellow}↻${colors.reset}`;
|
|
166
|
+
const phaseTag = isFixing ? ` ${colors.blue}[fixing]${colors.reset}` : '';
|
|
167
|
+
console.log(` ${icon} Retry ${attempt}/${maxRetries}${waitInfo}${phaseTag}`);
|
|
168
|
+
printLogsIncremental(event.data.step_index, event.data.logs);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
75
171
|
case 'step_complete': {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
172
|
+
// Skip spurious 0ms step_complete events (backend sends these during retries)
|
|
173
|
+
// But allow skipped steps through since they legitimately have 0 duration
|
|
174
|
+
if (event.data.duration === 0 && event.data.status !== 'skipped') {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
let status;
|
|
178
|
+
let timeStr;
|
|
179
|
+
if (event.data.status === 'passed') {
|
|
180
|
+
status = colors.green + '✓';
|
|
181
|
+
timeStr = ` ${colors.gray}${duration(event.data.duration)}${colors.reset}`;
|
|
182
|
+
}
|
|
183
|
+
else if (event.data.status === 'skipped') {
|
|
184
|
+
status = colors.yellow + '⊘';
|
|
185
|
+
// For skipped steps, print the step name since step_start wasn't shown
|
|
186
|
+
console.log(`${colors.gray}[${event.data.step_index}]${colors.reset} ${event.data.name}...`);
|
|
187
|
+
timeStr = ` ${colors.gray}skipped${colors.reset}`;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
status = colors.red + '✗';
|
|
191
|
+
timeStr = ` ${colors.gray}${duration(event.data.duration)}${colors.reset}`;
|
|
192
|
+
}
|
|
193
|
+
console.log(`${status}${colors.reset}${timeStr}`);
|
|
194
|
+
// Print any remaining logs not yet printed
|
|
195
|
+
printLogsIncremental(event.data.step_index, event.data.logs);
|
|
79
196
|
break;
|
|
80
197
|
}
|
|
81
198
|
case 'complete':
|
|
@@ -91,15 +208,35 @@ export function printSSEProgress(event) {
|
|
|
91
208
|
console.log('');
|
|
92
209
|
console.log(error(`Test error: ${event.data.error}`));
|
|
93
210
|
if (event.data.step_index !== undefined) {
|
|
94
|
-
console.log(`
|
|
211
|
+
console.log(`At step ${event.data.step_index}`);
|
|
95
212
|
}
|
|
96
213
|
break;
|
|
97
214
|
case 'persisted':
|
|
98
215
|
console.log(success(`Test saved to cloud (ID: ${event.data.test_id})`));
|
|
99
216
|
break;
|
|
217
|
+
case 'test_fixed': {
|
|
218
|
+
console.log('');
|
|
219
|
+
console.log(`${colors.blue}🔧${colors.reset} Test auto-fixed: "${event.data.name}"`);
|
|
220
|
+
if (context?.updateLocal && context?.sourceFile) {
|
|
221
|
+
// event.data contains the fixed TestDefinition
|
|
222
|
+
// Serialize based on source file extension
|
|
223
|
+
const isYaml = context.sourceFile.match(/\.ya?ml$/i);
|
|
224
|
+
const content = isYaml ? yaml.stringify(event.data) : JSON.stringify(event.data, null, 2);
|
|
225
|
+
fs.writeFileSync(context.sourceFile, content);
|
|
226
|
+
console.log(`${colors.green}✓${colors.reset} Updated ${context.sourceFile}`);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
console.log(`${colors.gray}Use --update-local to save fixed version to local file.${colors.reset}`);
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
case 'step_log':
|
|
234
|
+
// Individual log line streamed from the backend
|
|
235
|
+
printLogsIncremental(event.data.step_index, [event.data.log_line]);
|
|
236
|
+
break;
|
|
100
237
|
default:
|
|
101
238
|
// Log unknown events in gray
|
|
102
|
-
console.log(
|
|
239
|
+
console.log(`${colors.gray}[${event.event}]${colors.reset}`);
|
|
103
240
|
}
|
|
104
241
|
}
|
|
105
242
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../../../src/cli/lib/output.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../../../src/cli/lib/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,15 +3,23 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { ApiClient, type RunCliTestOptions, type RunCliTestResult } from '../../../lib/api/index.js';
|
|
5
5
|
import type { SSEEvent } from '../../../lib/api/sse.js';
|
|
6
|
+
export interface RunTestOptions {
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
/** Whether to update local file on test_fixed event */
|
|
9
|
+
updateLocal?: boolean;
|
|
10
|
+
/** Path to the source test definition file */
|
|
11
|
+
sourceFile?: string;
|
|
12
|
+
}
|
|
6
13
|
/**
|
|
7
14
|
* Run a test with real-time progress output
|
|
8
15
|
*
|
|
9
16
|
* @param client - ApiClient instance
|
|
10
17
|
* @param options - Test run options
|
|
18
|
+
* @param runOptions - Runner options (verbose, etc.)
|
|
11
19
|
* @param onEvent - Optional additional event callback
|
|
12
20
|
* @returns Test result
|
|
13
21
|
*/
|
|
14
|
-
export declare function runTest(client: ApiClient, options: RunCliTestOptions, onEvent?: (event: SSEEvent) => void): Promise<RunCliTestResult>;
|
|
22
|
+
export declare function runTest(client: ApiClient, options: RunCliTestOptions, runOptions?: RunTestOptions, onEvent?: (event: SSEEvent) => void): Promise<RunCliTestResult>;
|
|
15
23
|
/**
|
|
16
24
|
* Run multiple tests sequentially
|
|
17
25
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,SAAS,EACT,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGxD
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,SAAS,EACT,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGxD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,EAC1B,UAAU,GAAE,cAAmB,EAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,iBAAiB,EAAE,GACzB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAU7B"}
|
|
@@ -8,13 +8,17 @@ import { printSSEProgress } from './output.js';
|
|
|
8
8
|
*
|
|
9
9
|
* @param client - ApiClient instance
|
|
10
10
|
* @param options - Test run options
|
|
11
|
+
* @param runOptions - Runner options (verbose, etc.)
|
|
11
12
|
* @param onEvent - Optional additional event callback
|
|
12
13
|
* @returns Test result
|
|
13
14
|
*/
|
|
14
|
-
export async function runTest(client, options, onEvent) {
|
|
15
|
+
export async function runTest(client, options, runOptions = {}, onEvent) {
|
|
16
|
+
const { verbose = false, updateLocal, sourceFile } = runOptions;
|
|
17
|
+
// Build context for SSE progress handler
|
|
18
|
+
const context = updateLocal || sourceFile ? { updateLocal, sourceFile } : undefined;
|
|
15
19
|
return await client.runCliTest(options, (event) => {
|
|
16
20
|
// Print progress to console
|
|
17
|
-
printSSEProgress(event);
|
|
21
|
+
printSSEProgress(event, verbose, context);
|
|
18
22
|
// Call additional callback if provided
|
|
19
23
|
if (onEvent) {
|
|
20
24
|
onEvent(event);
|