@desplega.ai/qa-use 2.2.4 → 2.3.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/browser-types.d.ts +19 -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 +22 -3
- package/dist/lib/api/browser.js.map +1 -1
- package/dist/lib/api/index.d.ts +1 -0
- package/dist/lib/api/index.d.ts.map +1 -1
- package/dist/lib/api/index.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 +44 -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 +67 -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 +21 -1
- package/lib/api/browser.test.ts +50 -0
- package/lib/api/browser.ts +24 -3
- package/lib/api/index.ts +1 -0
- package/package.json +1 -1
|
@@ -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,8 @@ 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
|
|
20
|
+
vars?: Record<string, string>; // Variable overrides for after_test_id test
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export interface BrowserSession {
|
|
@@ -167,6 +169,17 @@ export interface WaitForLoadAction {
|
|
|
167
169
|
|
|
168
170
|
export interface SnapshotAction {
|
|
169
171
|
type: 'snapshot';
|
|
172
|
+
interactive?: boolean;
|
|
173
|
+
compact?: boolean;
|
|
174
|
+
max_depth?: number;
|
|
175
|
+
scope?: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface SnapshotOptions {
|
|
179
|
+
interactive?: boolean; // Only include interactive elements
|
|
180
|
+
compact?: boolean; // Remove empty structural elements
|
|
181
|
+
max_depth?: number; // Limit tree depth (1-20)
|
|
182
|
+
scope?: string; // CSS selector to scope snapshot
|
|
170
183
|
}
|
|
171
184
|
|
|
172
185
|
export interface ScreenshotAction {
|
|
@@ -209,9 +222,16 @@ export interface ActionResult {
|
|
|
209
222
|
url_after?: string; // URL after action executed
|
|
210
223
|
}
|
|
211
224
|
|
|
225
|
+
export interface SnapshotFilterStats {
|
|
226
|
+
original_lines: number;
|
|
227
|
+
filtered_lines: number;
|
|
228
|
+
reduction_percent: number;
|
|
229
|
+
}
|
|
230
|
+
|
|
212
231
|
export interface SnapshotResult {
|
|
213
232
|
snapshot: string;
|
|
214
233
|
url?: string;
|
|
234
|
+
filter_stats?: SnapshotFilterStats;
|
|
215
235
|
}
|
|
216
236
|
|
|
217
237
|
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,8 @@ 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 }),
|
|
79
|
+
...(options.vars && Object.keys(options.vars).length > 0 && { vars: options.vars }),
|
|
77
80
|
});
|
|
78
81
|
|
|
79
82
|
return response.data as BrowserSession;
|
|
@@ -140,11 +143,16 @@ export class BrowserApiClient {
|
|
|
140
143
|
return session;
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
// If session is closed
|
|
146
|
+
// If session is closed, throw error
|
|
144
147
|
if (session.status === 'closed') {
|
|
145
148
|
throw new Error(`Session ${sessionId} is closed`);
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
// If session failed (e.g., after_test_id test failed), return session for error handling
|
|
152
|
+
if (session.status === 'failed') {
|
|
153
|
+
return session;
|
|
154
|
+
}
|
|
155
|
+
|
|
148
156
|
// Wait before polling again
|
|
149
157
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
150
158
|
}
|
|
@@ -174,10 +182,21 @@ export class BrowserApiClient {
|
|
|
174
182
|
|
|
175
183
|
/**
|
|
176
184
|
* Get the ARIA accessibility tree snapshot
|
|
185
|
+
* @param sessionId - The session ID
|
|
186
|
+
* @param options - Filtering options (interactive, compact, max_depth, scope)
|
|
177
187
|
*/
|
|
178
|
-
async getSnapshot(sessionId: string): Promise<SnapshotResult> {
|
|
188
|
+
async getSnapshot(sessionId: string, options: SnapshotOptions = {}): Promise<SnapshotResult> {
|
|
179
189
|
try {
|
|
180
|
-
const
|
|
190
|
+
const params = new URLSearchParams();
|
|
191
|
+
if (options.interactive) params.append('interactive', 'true');
|
|
192
|
+
if (options.compact) params.append('compact', 'true');
|
|
193
|
+
if (options.max_depth !== undefined) params.append('max_depth', options.max_depth.toString());
|
|
194
|
+
if (options.scope) params.append('scope', options.scope);
|
|
195
|
+
|
|
196
|
+
const queryString = params.toString();
|
|
197
|
+
const url = `/sessions/${sessionId}/snapshot${queryString ? `?${queryString}` : ''}`;
|
|
198
|
+
|
|
199
|
+
const response = await this.client.get(url);
|
|
181
200
|
return response.data as SnapshotResult;
|
|
182
201
|
} catch (error) {
|
|
183
202
|
throw this.handleError(error, 'get snapshot');
|
|
@@ -354,6 +373,8 @@ export type {
|
|
|
354
373
|
BrowserAction,
|
|
355
374
|
ActionResult,
|
|
356
375
|
SnapshotResult,
|
|
376
|
+
SnapshotOptions,
|
|
377
|
+
SnapshotFilterStats,
|
|
357
378
|
UrlResult,
|
|
358
379
|
CreateBrowserSessionOptions,
|
|
359
380
|
BrowserSessionStatus,
|
package/lib/api/index.ts
CHANGED
|
@@ -236,6 +236,7 @@ export interface RunCliTestOptions {
|
|
|
236
236
|
store_recording?: boolean;
|
|
237
237
|
store_har?: boolean;
|
|
238
238
|
ws_url?: string;
|
|
239
|
+
vars?: Record<string, string>; // Variable overrides for cloud test (test_id)
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
export type SSECallback = (event: SSEEvent) => void;
|