@desplega.ai/qa-use 2.2.4 → 2.2.5
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/browser-types.d.ts +18 -1
- package/dist/lib/api/browser-types.d.ts.map +1 -1
- package/dist/lib/api/browser.d.ts +5 -3
- package/dist/lib/api/browser.d.ts.map +1 -1
- package/dist/lib/api/browser.js +21 -3
- package/dist/lib/api/browser.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/cli/commands/browser/create.d.ts.map +1 -1
- package/dist/src/cli/commands/browser/create.js +33 -1
- package/dist/src/cli/commands/browser/create.js.map +1 -1
- package/dist/src/cli/commands/browser/run.d.ts.map +1 -1
- package/dist/src/cli/commands/browser/run.js +61 -9
- package/dist/src/cli/commands/browser/run.js.map +1 -1
- package/dist/src/cli/commands/browser/snapshot.d.ts.map +1 -1
- package/dist/src/cli/commands/browser/snapshot.js +14 -2
- package/dist/src/cli/commands/browser/snapshot.js.map +1 -1
- package/dist/src/cli/commands/test/export.d.ts.map +1 -1
- package/dist/src/cli/commands/test/export.js +47 -30
- package/dist/src/cli/commands/test/export.js.map +1 -1
- package/dist/src/cli/commands/test/sync.d.ts.map +1 -1
- package/dist/src/cli/commands/test/sync.js +54 -28
- package/dist/src/cli/commands/test/sync.js.map +1 -1
- package/dist/src/cli/lib/loader.d.ts +8 -0
- package/dist/src/cli/lib/loader.d.ts.map +1 -1
- package/dist/src/cli/lib/loader.js +38 -7
- package/dist/src/cli/lib/loader.js.map +1 -1
- package/lib/api/browser-types.ts +20 -1
- package/lib/api/browser.test.ts +50 -0
- package/lib/api/browser.ts +23 -3
- package/package.json +1 -1
|
@@ -10,6 +10,10 @@ export const snapshotCommand = new Command('snapshot')
|
|
|
10
10
|
.description('Get the ARIA accessibility tree snapshot')
|
|
11
11
|
.option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
|
|
12
12
|
.option('--json', 'Output raw JSON instead of formatted tree')
|
|
13
|
+
.option('-i, --interactive', 'Only include interactive elements (buttons, inputs, links)')
|
|
14
|
+
.option('-c, --compact', 'Remove empty structural elements')
|
|
15
|
+
.option('-d, --max-depth <n>', 'Limit tree depth (1-20)')
|
|
16
|
+
.option('--scope <selector>', 'CSS selector to scope snapshot (e.g., "#main")')
|
|
13
17
|
.action(async (options) => {
|
|
14
18
|
try {
|
|
15
19
|
// Load configuration
|
|
@@ -26,8 +30,13 @@ export const snapshotCommand = new Command('snapshot')
|
|
|
26
30
|
explicitId: options.sessionId,
|
|
27
31
|
client,
|
|
28
32
|
});
|
|
29
|
-
// Get snapshot
|
|
30
|
-
const snapshot = await client.getSnapshot(resolved.id
|
|
33
|
+
// Get snapshot with filtering options
|
|
34
|
+
const snapshot = await client.getSnapshot(resolved.id, {
|
|
35
|
+
interactive: options.interactive,
|
|
36
|
+
compact: options.compact,
|
|
37
|
+
max_depth: options.maxDepth ? parseInt(options.maxDepth, 10) : undefined,
|
|
38
|
+
scope: options.scope,
|
|
39
|
+
});
|
|
31
40
|
if (options.json) {
|
|
32
41
|
// Output raw JSON
|
|
33
42
|
console.log(JSON.stringify(snapshot, null, 2));
|
|
@@ -37,6 +46,9 @@ export const snapshotCommand = new Command('snapshot')
|
|
|
37
46
|
if (snapshot.url) {
|
|
38
47
|
console.log(`URL: ${snapshot.url}\n`);
|
|
39
48
|
}
|
|
49
|
+
if (snapshot.filter_stats) {
|
|
50
|
+
console.log(`Filtered: ${snapshot.filter_stats.filtered_lines}/${snapshot.filter_stats.original_lines} lines (${snapshot.filter_stats.reduction_percent}% reduction)\n`);
|
|
51
|
+
}
|
|
40
52
|
console.log(formatAriaTree(snapshot.snapshot));
|
|
41
53
|
}
|
|
42
54
|
// Update session timestamp
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/snapshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/test/export.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/test/export.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,aAAa,SAsGtB,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import * as fs from 'fs/promises';
|
|
6
6
|
import * as path from 'path';
|
|
7
|
+
import * as yaml from 'yaml';
|
|
7
8
|
import { loadConfig } from '../../lib/config.js';
|
|
8
9
|
import { error, success, info } from '../../lib/output.js';
|
|
9
10
|
import { ApiClient } from '../../../../lib/api/index.js';
|
|
@@ -31,47 +32,63 @@ export const exportCommand = new Command('export')
|
|
|
31
32
|
// Initialize API client
|
|
32
33
|
const client = new ApiClient(config.api_url);
|
|
33
34
|
client.setApiKey(config.api_key);
|
|
35
|
+
const includeDeps = options.deps !== false;
|
|
34
36
|
if (!options.stdout) {
|
|
35
37
|
console.log(info(`Exporting test ${testId}...`));
|
|
36
38
|
}
|
|
37
39
|
// Export from API
|
|
38
|
-
const content = await client.exportTest(testId, options.format,
|
|
39
|
-
// Output to stdout if requested
|
|
40
|
+
const content = await client.exportTest(testId, options.format, includeDeps);
|
|
41
|
+
// Output to stdout if requested (all tests concatenated)
|
|
40
42
|
if (options.stdout) {
|
|
41
43
|
console.log(content);
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
|
-
|
|
45
|
-
let outputPath = options.output;
|
|
46
|
-
if (!outputPath) {
|
|
47
|
-
// Get test info to use name for filename
|
|
48
|
-
try {
|
|
49
|
-
const testInfo = await client.getTest(testId);
|
|
50
|
-
const safeName = testInfo.name
|
|
51
|
-
.toLowerCase()
|
|
52
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
53
|
-
.replace(/^-|-$/g, '');
|
|
54
|
-
const ext = options.format === 'json' ? '.json' : '.yaml';
|
|
55
|
-
outputPath = path.join(config.test_directory || './qa-tests', safeName + ext);
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// Fall back to using test ID as filename
|
|
59
|
-
const ext = options.format === 'json' ? '.json' : '.yaml';
|
|
60
|
-
outputPath = path.join(config.test_directory || './qa-tests', testId + ext);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
46
|
+
const testDir = config.test_directory || './qa-tests';
|
|
63
47
|
// Ensure directory exists
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
48
|
+
await fs.mkdir(testDir, { recursive: true });
|
|
49
|
+
// Parse tests from content
|
|
50
|
+
let tests;
|
|
51
|
+
if (options.format === 'json') {
|
|
52
|
+
const parsed = JSON.parse(content);
|
|
53
|
+
tests = Array.isArray(parsed) ? parsed : [parsed];
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Parse multi-document YAML
|
|
57
|
+
const docs = yaml.parseAllDocuments(content);
|
|
58
|
+
tests = docs.map((d) => d.toJSON());
|
|
59
|
+
}
|
|
60
|
+
// If explicit output path provided, write single file (backward compat for single test)
|
|
61
|
+
if (options.output) {
|
|
62
|
+
const dir = path.dirname(options.output);
|
|
63
|
+
await fs.mkdir(dir, { recursive: true });
|
|
64
|
+
await fs.writeFile(options.output, content, 'utf-8');
|
|
65
|
+
console.log(success(`Exported to ${options.output}`));
|
|
66
|
+
console.log(` Format: ${options.format}`);
|
|
67
|
+
console.log(` Tests: ${tests.length}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Write each test to its own file
|
|
71
|
+
const ext = options.format === 'json' ? '.json' : '.yaml';
|
|
72
|
+
const written = [];
|
|
73
|
+
for (const test of tests) {
|
|
74
|
+
const safeName = (test.name || test.id || 'unnamed-test')
|
|
75
|
+
.toLowerCase()
|
|
76
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
77
|
+
.replace(/^-|-$/g, '');
|
|
78
|
+
const outputPath = path.join(testDir, safeName + ext);
|
|
79
|
+
// Serialize individual test (depends_on stays as UUID)
|
|
80
|
+
const testContent = options.format === 'json' ? JSON.stringify(test, null, 2) : yaml.stringify(test);
|
|
81
|
+
await fs.writeFile(outputPath, testContent, 'utf-8');
|
|
82
|
+
written.push(outputPath);
|
|
83
|
+
}
|
|
69
84
|
// Show summary
|
|
70
|
-
|
|
85
|
+
console.log(success(`Exported ${written.length} test(s):`));
|
|
86
|
+
for (const file of written) {
|
|
87
|
+
console.log(` - ${file}`);
|
|
88
|
+
}
|
|
71
89
|
console.log(` Format: ${options.format}`);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
console.log(` Dependencies: included`);
|
|
90
|
+
if (includeDeps && tests.length > 1) {
|
|
91
|
+
console.log(` Dependencies: ${tests.length - 1} included`);
|
|
75
92
|
}
|
|
76
93
|
}
|
|
77
94
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../../../src/cli/commands/test/export.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../../../src/cli/commands/test/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/test/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/test/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,WAAW,SAiCpB,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import * as fs from 'fs/promises';
|
|
6
6
|
import * as path from 'path';
|
|
7
|
+
import * as yaml from 'yaml';
|
|
7
8
|
import { loadConfig } from '../../lib/config.js';
|
|
8
9
|
import { discoverTests, loadTestDefinition } from '../../lib/loader.js';
|
|
9
10
|
import { error, success, info, warning } from '../../lib/output.js';
|
|
@@ -57,44 +58,69 @@ async function pullFromCloud(client, testDir, dryRun = false, force = false) {
|
|
|
57
58
|
}
|
|
58
59
|
let pulled = 0;
|
|
59
60
|
let skipped = 0;
|
|
61
|
+
const writtenIds = new Set(); // Track already written tests to avoid duplicates
|
|
60
62
|
for (const test of cloudTests) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
64
|
-
.replace(/^-|-$/g, '');
|
|
65
|
-
const outputPath = path.join(testDir, safeName + '.yaml');
|
|
66
|
-
// Check if file exists
|
|
67
|
-
let exists = false;
|
|
68
|
-
try {
|
|
69
|
-
await fs.access(outputPath);
|
|
70
|
-
exists = true;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// File doesn't exist
|
|
74
|
-
}
|
|
75
|
-
if (exists && !force) {
|
|
76
|
-
console.log(` Skip: ${safeName}.yaml (exists, use --force to overwrite)`);
|
|
77
|
-
skipped++;
|
|
63
|
+
// Skip if this test was already written as a dependency of another test
|
|
64
|
+
if (writtenIds.has(test.id)) {
|
|
78
65
|
continue;
|
|
79
66
|
}
|
|
80
67
|
if (dryRun) {
|
|
81
|
-
|
|
68
|
+
const safeName = test.name
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
71
|
+
.replace(/^-|-$/g, '');
|
|
72
|
+
console.log(` Would pull: ${test.name} -> ${path.join(testDir, safeName + '.yaml')}`);
|
|
73
|
+
continue;
|
|
82
74
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
75
|
+
try {
|
|
76
|
+
// Export with dependencies
|
|
77
|
+
const content = await client.exportTest(test.id, 'yaml', true);
|
|
78
|
+
// Parse multi-document YAML to get all tests (deps + main)
|
|
79
|
+
const docs = yaml.parseAllDocuments(content);
|
|
80
|
+
const tests = docs.map((d) => d.toJSON());
|
|
81
|
+
// Write each test to its own file
|
|
82
|
+
for (const testDef of tests) {
|
|
83
|
+
// Skip if already written
|
|
84
|
+
if (testDef.id && writtenIds.has(testDef.id)) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const safeName = (testDef.name || testDef.id || 'unnamed-test')
|
|
88
|
+
.toLowerCase()
|
|
89
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
90
|
+
.replace(/^-|-$/g, '');
|
|
91
|
+
const outputPath = path.join(testDir, safeName + '.yaml');
|
|
92
|
+
// Check if file exists
|
|
93
|
+
let exists = false;
|
|
94
|
+
try {
|
|
95
|
+
await fs.access(outputPath);
|
|
96
|
+
exists = true;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// File doesn't exist
|
|
100
|
+
}
|
|
101
|
+
if (exists && !force) {
|
|
102
|
+
console.log(` Skip: ${safeName}.yaml (exists, use --force to overwrite)`);
|
|
103
|
+
skipped++;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// Serialize individual test (depends_on stays as UUID)
|
|
107
|
+
const testContent = yaml.stringify(testDef);
|
|
108
|
+
await fs.writeFile(outputPath, testContent, 'utf-8');
|
|
109
|
+
console.log(success(` ${safeName}.yaml`));
|
|
110
|
+
pulled++;
|
|
111
|
+
}
|
|
112
|
+
if (testDef.id) {
|
|
113
|
+
writtenIds.add(testDef.id);
|
|
114
|
+
}
|
|
92
115
|
}
|
|
93
116
|
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
console.log(error(` Failed to export ${test.name}: ${err}`));
|
|
119
|
+
}
|
|
94
120
|
}
|
|
95
121
|
console.log('');
|
|
96
122
|
if (dryRun) {
|
|
97
|
-
console.log(info(`Dry run complete. Would pull ${cloudTests.length
|
|
123
|
+
console.log(info(`Dry run complete. Would pull ${cloudTests.length} test(s).`));
|
|
98
124
|
}
|
|
99
125
|
else {
|
|
100
126
|
console.log(success(`Pulled ${pulled} test(s), skipped ${skipped}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../../../src/cli/commands/test/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../../../src/cli/commands/test/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,14 @@ export declare function loadTestDefinition(filePath: string): Promise<TestDefini
|
|
|
24
24
|
* @returns Full path to test file
|
|
25
25
|
*/
|
|
26
26
|
export declare function resolveTestPath(testNameOrPath: string, directory: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Find a local test file by its ID
|
|
29
|
+
*
|
|
30
|
+
* @param testId - The UUID to search for
|
|
31
|
+
* @param directory - Test directory root
|
|
32
|
+
* @returns File path if found, null otherwise
|
|
33
|
+
*/
|
|
34
|
+
export declare function findLocalTestById(testId: string, directory: string): Promise<string | null>;
|
|
27
35
|
/**
|
|
28
36
|
* Load a test and all its dependencies recursively
|
|
29
37
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,GAAE,MAAqB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGvF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CASlF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAoBjF;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,GAAE,MAAqB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGvF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CASlF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAoBjF;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAejG;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC,CAuC3B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAc/E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,cAAc,EAAE,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,IAAI,CAQN"}
|
|
@@ -53,6 +53,28 @@ export function resolveTestPath(testNameOrPath, directory) {
|
|
|
53
53
|
}
|
|
54
54
|
throw new Error(`Test file not found: ${testNameOrPath}`);
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Find a local test file by its ID
|
|
58
|
+
*
|
|
59
|
+
* @param testId - The UUID to search for
|
|
60
|
+
* @param directory - Test directory root
|
|
61
|
+
* @returns File path if found, null otherwise
|
|
62
|
+
*/
|
|
63
|
+
export async function findLocalTestById(testId, directory) {
|
|
64
|
+
const files = await discoverTests(directory);
|
|
65
|
+
for (const file of files) {
|
|
66
|
+
try {
|
|
67
|
+
const def = await loadTestDefinition(file);
|
|
68
|
+
if (def.id === testId) {
|
|
69
|
+
return file;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Skip files that fail to load
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
56
78
|
/**
|
|
57
79
|
* Load a test and all its dependencies recursively
|
|
58
80
|
*
|
|
@@ -63,22 +85,31 @@ export function resolveTestPath(testNameOrPath, directory) {
|
|
|
63
85
|
export async function loadTestWithDeps(testName, directory) {
|
|
64
86
|
const definitions = [];
|
|
65
87
|
const loaded = new Set();
|
|
66
|
-
async function loadRecursive(
|
|
88
|
+
async function loadRecursive(nameOrPath, isFullPath = false) {
|
|
67
89
|
// Avoid circular dependencies
|
|
68
|
-
if (loaded.has(
|
|
90
|
+
if (loaded.has(nameOrPath))
|
|
69
91
|
return;
|
|
70
|
-
loaded.add(
|
|
71
|
-
|
|
92
|
+
loaded.add(nameOrPath);
|
|
93
|
+
// If isFullPath is true (from findLocalTestById), use directly; otherwise resolve
|
|
94
|
+
const filePath = isFullPath ? nameOrPath : resolveTestPath(nameOrPath, directory);
|
|
72
95
|
const def = await loadTestDefinition(filePath);
|
|
73
|
-
// Load dependency first (if it exists
|
|
96
|
+
// Load dependency first (if it exists)
|
|
74
97
|
if (def.depends_on) {
|
|
75
98
|
// Check if depends_on is a UUID (cloud test) or a file name
|
|
76
99
|
const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(def.depends_on);
|
|
77
|
-
if (
|
|
100
|
+
if (isUuid) {
|
|
101
|
+
// Try to find local file with this ID first
|
|
102
|
+
const localFile = await findLocalTestById(def.depends_on, directory);
|
|
103
|
+
if (localFile) {
|
|
104
|
+
// Load from local file (localFile is already a full path from discoverTests)
|
|
105
|
+
await loadRecursive(localFile, true);
|
|
106
|
+
}
|
|
107
|
+
// If not found locally, API will resolve at runtime
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
78
110
|
// It's a local file reference
|
|
79
111
|
await loadRecursive(def.depends_on);
|
|
80
112
|
}
|
|
81
|
-
// If it's a UUID, the API will resolve it
|
|
82
113
|
}
|
|
83
114
|
definitions.push(def);
|
|
84
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/cli/lib/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,YAAoB,YAAY;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAC7D,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IACvD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAErD,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;IAC/C,CAAC;IAED,aAAa;IACb,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB,EAAE,SAAiB;IACvE,8CAA8C;IAC9C,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACpC,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,qDAAqD;IACrD,IAAI,cAAc,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACjD,CAAC;IAED,2CAA2C;IAC3C,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAE9C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,GAAG,GAAG,CAAC,CAAC;QAC/D,OAAO,QAAQ,CAAC,CAAC,0DAA0D;IAC7E,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,wBAAwB,cAAc,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,SAAiB;IAEjB,MAAM,WAAW,GAAqB,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,KAAK,UAAU,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/cli/lib/loader.ts"],"names":[],"mappings":"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"}
|
package/lib/api/browser-types.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// Session Types
|
|
7
7
|
// ==========================================
|
|
8
8
|
|
|
9
|
-
export type BrowserSessionStatus = 'starting' | 'active' | 'closing' | 'closed';
|
|
9
|
+
export type BrowserSessionStatus = 'starting' | 'active' | 'closing' | 'closed' | 'failed';
|
|
10
10
|
|
|
11
11
|
export type ViewportType = 'desktop' | 'mobile' | 'tablet';
|
|
12
12
|
|
|
@@ -16,6 +16,7 @@ export interface CreateBrowserSessionOptions {
|
|
|
16
16
|
timeout?: number; // Session timeout in seconds (60-3600)
|
|
17
17
|
ws_url?: string; // WebSocket URL for remote/tunneled browser
|
|
18
18
|
record_blocks?: boolean; // Enable block recording for test generation
|
|
19
|
+
after_test_id?: string; // Run a test before session becomes interactive
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface BrowserSession {
|
|
@@ -167,6 +168,17 @@ export interface WaitForLoadAction {
|
|
|
167
168
|
|
|
168
169
|
export interface SnapshotAction {
|
|
169
170
|
type: 'snapshot';
|
|
171
|
+
interactive?: boolean;
|
|
172
|
+
compact?: boolean;
|
|
173
|
+
max_depth?: number;
|
|
174
|
+
scope?: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface SnapshotOptions {
|
|
178
|
+
interactive?: boolean; // Only include interactive elements
|
|
179
|
+
compact?: boolean; // Remove empty structural elements
|
|
180
|
+
max_depth?: number; // Limit tree depth (1-20)
|
|
181
|
+
scope?: string; // CSS selector to scope snapshot
|
|
170
182
|
}
|
|
171
183
|
|
|
172
184
|
export interface ScreenshotAction {
|
|
@@ -209,9 +221,16 @@ export interface ActionResult {
|
|
|
209
221
|
url_after?: string; // URL after action executed
|
|
210
222
|
}
|
|
211
223
|
|
|
224
|
+
export interface SnapshotFilterStats {
|
|
225
|
+
original_lines: number;
|
|
226
|
+
filtered_lines: number;
|
|
227
|
+
reduction_percent: number;
|
|
228
|
+
}
|
|
229
|
+
|
|
212
230
|
export interface SnapshotResult {
|
|
213
231
|
snapshot: string;
|
|
214
232
|
url?: string;
|
|
233
|
+
filter_stats?: SnapshotFilterStats;
|
|
215
234
|
}
|
|
216
235
|
|
|
217
236
|
export interface UrlResult {
|
package/lib/api/browser.test.ts
CHANGED
|
@@ -286,6 +286,56 @@ describe('BrowserApiClient', () => {
|
|
|
286
286
|
expect(snapshot.snapshot).toContain('Example');
|
|
287
287
|
expect(snapshot.url).toBe('https://example.com');
|
|
288
288
|
});
|
|
289
|
+
|
|
290
|
+
it('should get ARIA snapshot with filtering options', async () => {
|
|
291
|
+
const mockSnapshot = {
|
|
292
|
+
snapshot: '- button "Submit" [ref=e1]',
|
|
293
|
+
url: 'https://example.com',
|
|
294
|
+
filter_stats: {
|
|
295
|
+
original_lines: 450,
|
|
296
|
+
filtered_lines: 42,
|
|
297
|
+
reduction_percent: 91,
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
mockAxiosInstance.get.mockResolvedValueOnce({ data: mockSnapshot });
|
|
301
|
+
|
|
302
|
+
const snapshot = await client.getSnapshot('session-123', {
|
|
303
|
+
interactive: true,
|
|
304
|
+
compact: true,
|
|
305
|
+
max_depth: 3,
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
expect(mockAxiosInstance.get).toHaveBeenCalledWith(
|
|
309
|
+
'/sessions/session-123/snapshot?interactive=true&compact=true&max_depth=3'
|
|
310
|
+
);
|
|
311
|
+
expect(snapshot.filter_stats?.reduction_percent).toBe(91);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it('should get ARIA snapshot with scope option', async () => {
|
|
315
|
+
const mockSnapshot = {
|
|
316
|
+
snapshot: '- heading "Main Content" [ref=e1]',
|
|
317
|
+
url: 'https://example.com',
|
|
318
|
+
};
|
|
319
|
+
mockAxiosInstance.get.mockResolvedValueOnce({ data: mockSnapshot });
|
|
320
|
+
|
|
321
|
+
await client.getSnapshot('session-123', { scope: '#main' });
|
|
322
|
+
|
|
323
|
+
expect(mockAxiosInstance.get).toHaveBeenCalledWith(
|
|
324
|
+
'/sessions/session-123/snapshot?scope=%23main'
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('should get ARIA snapshot without options (backward compatible)', async () => {
|
|
329
|
+
const mockSnapshot = {
|
|
330
|
+
snapshot: '- heading "Example" [ref=e1]',
|
|
331
|
+
url: 'https://example.com',
|
|
332
|
+
};
|
|
333
|
+
mockAxiosInstance.get.mockResolvedValueOnce({ data: mockSnapshot });
|
|
334
|
+
|
|
335
|
+
await client.getSnapshot('session-123');
|
|
336
|
+
|
|
337
|
+
expect(mockAxiosInstance.get).toHaveBeenCalledWith('/sessions/session-123/snapshot');
|
|
338
|
+
});
|
|
289
339
|
});
|
|
290
340
|
|
|
291
341
|
describe('getScreenshot', () => {
|
package/lib/api/browser.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
BrowserAction,
|
|
11
11
|
ActionResult,
|
|
12
12
|
SnapshotResult,
|
|
13
|
+
SnapshotOptions,
|
|
13
14
|
UrlResult,
|
|
14
15
|
BlocksResult,
|
|
15
16
|
CreateBrowserSessionOptions,
|
|
@@ -74,6 +75,7 @@ export class BrowserApiClient {
|
|
|
74
75
|
timeout: options.timeout ?? 300,
|
|
75
76
|
...(options.ws_url && { ws_url: options.ws_url }),
|
|
76
77
|
...(options.record_blocks !== undefined && { record_blocks: options.record_blocks }),
|
|
78
|
+
...(options.after_test_id && { after_test_id: options.after_test_id }),
|
|
77
79
|
});
|
|
78
80
|
|
|
79
81
|
return response.data as BrowserSession;
|
|
@@ -140,11 +142,16 @@ export class BrowserApiClient {
|
|
|
140
142
|
return session;
|
|
141
143
|
}
|
|
142
144
|
|
|
143
|
-
// If session is closed
|
|
145
|
+
// If session is closed, throw error
|
|
144
146
|
if (session.status === 'closed') {
|
|
145
147
|
throw new Error(`Session ${sessionId} is closed`);
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
// If session failed (e.g., after_test_id test failed), return session for error handling
|
|
151
|
+
if (session.status === 'failed') {
|
|
152
|
+
return session;
|
|
153
|
+
}
|
|
154
|
+
|
|
148
155
|
// Wait before polling again
|
|
149
156
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
150
157
|
}
|
|
@@ -174,10 +181,21 @@ export class BrowserApiClient {
|
|
|
174
181
|
|
|
175
182
|
/**
|
|
176
183
|
* Get the ARIA accessibility tree snapshot
|
|
184
|
+
* @param sessionId - The session ID
|
|
185
|
+
* @param options - Filtering options (interactive, compact, max_depth, scope)
|
|
177
186
|
*/
|
|
178
|
-
async getSnapshot(sessionId: string): Promise<SnapshotResult> {
|
|
187
|
+
async getSnapshot(sessionId: string, options: SnapshotOptions = {}): Promise<SnapshotResult> {
|
|
179
188
|
try {
|
|
180
|
-
const
|
|
189
|
+
const params = new URLSearchParams();
|
|
190
|
+
if (options.interactive) params.append('interactive', 'true');
|
|
191
|
+
if (options.compact) params.append('compact', 'true');
|
|
192
|
+
if (options.max_depth !== undefined) params.append('max_depth', options.max_depth.toString());
|
|
193
|
+
if (options.scope) params.append('scope', options.scope);
|
|
194
|
+
|
|
195
|
+
const queryString = params.toString();
|
|
196
|
+
const url = `/sessions/${sessionId}/snapshot${queryString ? `?${queryString}` : ''}`;
|
|
197
|
+
|
|
198
|
+
const response = await this.client.get(url);
|
|
181
199
|
return response.data as SnapshotResult;
|
|
182
200
|
} catch (error) {
|
|
183
201
|
throw this.handleError(error, 'get snapshot');
|
|
@@ -354,6 +372,8 @@ export type {
|
|
|
354
372
|
BrowserAction,
|
|
355
373
|
ActionResult,
|
|
356
374
|
SnapshotResult,
|
|
375
|
+
SnapshotOptions,
|
|
376
|
+
SnapshotFilterStats,
|
|
357
377
|
UrlResult,
|
|
358
378
|
CreateBrowserSessionOptions,
|
|
359
379
|
BrowserSessionStatus,
|