@desplega.ai/qa-use 2.1.7 → 2.2.2

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.
Files changed (138) hide show
  1. package/dist/lib/api/browser-types.d.ts +175 -0
  2. package/dist/lib/api/browser-types.d.ts.map +1 -0
  3. package/dist/lib/api/browser-types.js +5 -0
  4. package/dist/lib/api/browser-types.js.map +1 -0
  5. package/dist/lib/api/browser.d.ts +66 -0
  6. package/dist/lib/api/browser.d.ts.map +1 -0
  7. package/dist/lib/api/browser.js +223 -0
  8. package/dist/lib/api/browser.js.map +1 -0
  9. package/dist/package.json +2 -1
  10. package/dist/src/cli/commands/browser/back.d.ts +6 -0
  11. package/dist/src/cli/commands/browser/back.d.ts.map +1 -0
  12. package/dist/src/cli/commands/browser/back.js +42 -0
  13. package/dist/src/cli/commands/browser/back.js.map +1 -0
  14. package/dist/src/cli/commands/browser/check.d.ts +6 -0
  15. package/dist/src/cli/commands/browser/check.d.ts.map +1 -0
  16. package/dist/src/cli/commands/browser/check.js +62 -0
  17. package/dist/src/cli/commands/browser/check.js.map +1 -0
  18. package/dist/src/cli/commands/browser/click.d.ts +6 -0
  19. package/dist/src/cli/commands/browser/click.d.ts.map +1 -0
  20. package/dist/src/cli/commands/browser/click.js +63 -0
  21. package/dist/src/cli/commands/browser/click.js.map +1 -0
  22. package/dist/src/cli/commands/browser/close.d.ts +6 -0
  23. package/dist/src/cli/commands/browser/close.d.ts.map +1 -0
  24. package/dist/src/cli/commands/browser/close.js +44 -0
  25. package/dist/src/cli/commands/browser/close.js.map +1 -0
  26. package/dist/src/cli/commands/browser/create.d.ts +6 -0
  27. package/dist/src/cli/commands/browser/create.d.ts.map +1 -0
  28. package/dist/src/cli/commands/browser/create.js +281 -0
  29. package/dist/src/cli/commands/browser/create.js.map +1 -0
  30. package/dist/src/cli/commands/browser/fill.d.ts +6 -0
  31. package/dist/src/cli/commands/browser/fill.d.ts.map +1 -0
  32. package/dist/src/cli/commands/browser/fill.js +83 -0
  33. package/dist/src/cli/commands/browser/fill.js.map +1 -0
  34. package/dist/src/cli/commands/browser/forward.d.ts +6 -0
  35. package/dist/src/cli/commands/browser/forward.d.ts.map +1 -0
  36. package/dist/src/cli/commands/browser/forward.js +42 -0
  37. package/dist/src/cli/commands/browser/forward.js.map +1 -0
  38. package/dist/src/cli/commands/browser/get-blocks.d.ts +6 -0
  39. package/dist/src/cli/commands/browser/get-blocks.d.ts.map +1 -0
  40. package/dist/src/cli/commands/browser/get-blocks.js +35 -0
  41. package/dist/src/cli/commands/browser/get-blocks.js.map +1 -0
  42. package/dist/src/cli/commands/browser/goto.d.ts +6 -0
  43. package/dist/src/cli/commands/browser/goto.d.ts.map +1 -0
  44. package/dist/src/cli/commands/browser/goto.js +53 -0
  45. package/dist/src/cli/commands/browser/goto.js.map +1 -0
  46. package/dist/src/cli/commands/browser/hover.d.ts +6 -0
  47. package/dist/src/cli/commands/browser/hover.d.ts.map +1 -0
  48. package/dist/src/cli/commands/browser/hover.js +63 -0
  49. package/dist/src/cli/commands/browser/hover.js.map +1 -0
  50. package/dist/src/cli/commands/browser/index.d.ts +9 -0
  51. package/dist/src/cli/commands/browser/index.d.ts.map +1 -0
  52. package/dist/src/cli/commands/browser/index.js +71 -0
  53. package/dist/src/cli/commands/browser/index.js.map +1 -0
  54. package/dist/src/cli/commands/browser/list.d.ts +6 -0
  55. package/dist/src/cli/commands/browser/list.d.ts.map +1 -0
  56. package/dist/src/cli/commands/browser/list.js +85 -0
  57. package/dist/src/cli/commands/browser/list.js.map +1 -0
  58. package/dist/src/cli/commands/browser/press.d.ts +6 -0
  59. package/dist/src/cli/commands/browser/press.d.ts.map +1 -0
  60. package/dist/src/cli/commands/browser/press.js +67 -0
  61. package/dist/src/cli/commands/browser/press.js.map +1 -0
  62. package/dist/src/cli/commands/browser/reload.d.ts +6 -0
  63. package/dist/src/cli/commands/browser/reload.d.ts.map +1 -0
  64. package/dist/src/cli/commands/browser/reload.js +42 -0
  65. package/dist/src/cli/commands/browser/reload.js.map +1 -0
  66. package/dist/src/cli/commands/browser/run.d.ts +6 -0
  67. package/dist/src/cli/commands/browser/run.d.ts.map +1 -0
  68. package/dist/src/cli/commands/browser/run.js +618 -0
  69. package/dist/src/cli/commands/browser/run.js.map +1 -0
  70. package/dist/src/cli/commands/browser/screenshot.d.ts +6 -0
  71. package/dist/src/cli/commands/browser/screenshot.d.ts.map +1 -0
  72. package/dist/src/cli/commands/browser/screenshot.js +72 -0
  73. package/dist/src/cli/commands/browser/screenshot.js.map +1 -0
  74. package/dist/src/cli/commands/browser/scroll-into-view.d.ts +6 -0
  75. package/dist/src/cli/commands/browser/scroll-into-view.d.ts.map +1 -0
  76. package/dist/src/cli/commands/browser/scroll-into-view.js +64 -0
  77. package/dist/src/cli/commands/browser/scroll-into-view.js.map +1 -0
  78. package/dist/src/cli/commands/browser/scroll.d.ts +6 -0
  79. package/dist/src/cli/commands/browser/scroll.d.ts.map +1 -0
  80. package/dist/src/cli/commands/browser/scroll.js +63 -0
  81. package/dist/src/cli/commands/browser/scroll.js.map +1 -0
  82. package/dist/src/cli/commands/browser/select.d.ts +6 -0
  83. package/dist/src/cli/commands/browser/select.d.ts.map +1 -0
  84. package/dist/src/cli/commands/browser/select.js +83 -0
  85. package/dist/src/cli/commands/browser/select.js.map +1 -0
  86. package/dist/src/cli/commands/browser/snapshot.d.ts +6 -0
  87. package/dist/src/cli/commands/browser/snapshot.d.ts.map +1 -0
  88. package/dist/src/cli/commands/browser/snapshot.js +72 -0
  89. package/dist/src/cli/commands/browser/snapshot.js.map +1 -0
  90. package/dist/src/cli/commands/browser/status.d.ts +6 -0
  91. package/dist/src/cli/commands/browser/status.d.ts.map +1 -0
  92. package/dist/src/cli/commands/browser/status.js +91 -0
  93. package/dist/src/cli/commands/browser/status.js.map +1 -0
  94. package/dist/src/cli/commands/browser/stream.d.ts +6 -0
  95. package/dist/src/cli/commands/browser/stream.d.ts.map +1 -0
  96. package/dist/src/cli/commands/browser/stream.js +135 -0
  97. package/dist/src/cli/commands/browser/stream.js.map +1 -0
  98. package/dist/src/cli/commands/browser/tunnel.d.ts +13 -0
  99. package/dist/src/cli/commands/browser/tunnel.d.ts.map +1 -0
  100. package/dist/src/cli/commands/browser/tunnel.js +225 -0
  101. package/dist/src/cli/commands/browser/tunnel.js.map +1 -0
  102. package/dist/src/cli/commands/browser/type.d.ts +6 -0
  103. package/dist/src/cli/commands/browser/type.d.ts.map +1 -0
  104. package/dist/src/cli/commands/browser/type.js +61 -0
  105. package/dist/src/cli/commands/browser/type.js.map +1 -0
  106. package/dist/src/cli/commands/browser/uncheck.d.ts +6 -0
  107. package/dist/src/cli/commands/browser/uncheck.d.ts.map +1 -0
  108. package/dist/src/cli/commands/browser/uncheck.js +62 -0
  109. package/dist/src/cli/commands/browser/uncheck.js.map +1 -0
  110. package/dist/src/cli/commands/browser/url.d.ts +6 -0
  111. package/dist/src/cli/commands/browser/url.d.ts.map +1 -0
  112. package/dist/src/cli/commands/browser/url.js +40 -0
  113. package/dist/src/cli/commands/browser/url.js.map +1 -0
  114. package/dist/src/cli/commands/browser/wait-for-load.d.ts +6 -0
  115. package/dist/src/cli/commands/browser/wait-for-load.d.ts.map +1 -0
  116. package/dist/src/cli/commands/browser/wait-for-load.js +50 -0
  117. package/dist/src/cli/commands/browser/wait-for-load.js.map +1 -0
  118. package/dist/src/cli/commands/browser/wait-for-selector.d.ts +6 -0
  119. package/dist/src/cli/commands/browser/wait-for-selector.d.ts.map +1 -0
  120. package/dist/src/cli/commands/browser/wait-for-selector.js +52 -0
  121. package/dist/src/cli/commands/browser/wait-for-selector.js.map +1 -0
  122. package/dist/src/cli/commands/browser/wait.d.ts +6 -0
  123. package/dist/src/cli/commands/browser/wait.d.ts.map +1 -0
  124. package/dist/src/cli/commands/browser/wait.js +60 -0
  125. package/dist/src/cli/commands/browser/wait.js.map +1 -0
  126. package/dist/src/cli/commands/test/run.d.ts.map +1 -1
  127. package/dist/src/cli/commands/test/run.js +38 -7
  128. package/dist/src/cli/commands/test/run.js.map +1 -1
  129. package/dist/src/cli/index.js +2 -0
  130. package/dist/src/cli/index.js.map +1 -1
  131. package/dist/src/cli/lib/browser-sessions.d.ts +72 -0
  132. package/dist/src/cli/lib/browser-sessions.d.ts.map +1 -0
  133. package/dist/src/cli/lib/browser-sessions.js +184 -0
  134. package/dist/src/cli/lib/browser-sessions.js.map +1 -0
  135. package/lib/api/browser-types.ts +278 -0
  136. package/lib/api/browser.test.ts +378 -0
  137. package/lib/api/browser.ts +279 -0
  138. package/package.json +2 -1
@@ -0,0 +1,72 @@
1
+ /**
2
+ * qa-use browser screenshot - Capture screenshot
3
+ */
4
+ import { Command } from 'commander';
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
8
+ import { resolveSessionId, touchSession } from '../../lib/browser-sessions.js';
9
+ import { loadConfig } from '../../lib/config.js';
10
+ import { success, error } from '../../lib/output.js';
11
+ export const screenshotCommand = new Command('screenshot')
12
+ .description('Capture a screenshot of the current page')
13
+ .argument('[file]', 'Output file path (default: screenshot-{timestamp}.png)')
14
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
15
+ .option('--base64', 'Output as base64 to stdout')
16
+ .option('--stdout', 'Output raw PNG bytes to stdout (for piping)')
17
+ .action(async (file, options) => {
18
+ try {
19
+ // Load configuration
20
+ const config = await loadConfig();
21
+ if (!config.api_key) {
22
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
23
+ process.exit(1);
24
+ }
25
+ // Create client and set API key
26
+ const client = new BrowserApiClient(config.api_url);
27
+ client.setApiKey(config.api_key);
28
+ // Resolve session ID
29
+ const resolved = await resolveSessionId({
30
+ explicitId: options.sessionId,
31
+ client,
32
+ });
33
+ // Get screenshot
34
+ const imageBuffer = await client.getScreenshot(resolved.id);
35
+ // Update session timestamp
36
+ await touchSession(resolved.id);
37
+ // Handle output based on options
38
+ if (options.stdout) {
39
+ // Output raw PNG bytes to stdout
40
+ process.stdout.write(imageBuffer);
41
+ return;
42
+ }
43
+ if (options.base64) {
44
+ // Output base64 to stdout
45
+ const base64 = imageBuffer.toString('base64');
46
+ console.log(base64);
47
+ return;
48
+ }
49
+ // Write to file
50
+ const outputPath = file || generateFilename();
51
+ const absolutePath = path.resolve(outputPath);
52
+ // Ensure directory exists
53
+ const dir = path.dirname(absolutePath);
54
+ if (!fs.existsSync(dir)) {
55
+ fs.mkdirSync(dir, { recursive: true });
56
+ }
57
+ fs.writeFileSync(absolutePath, imageBuffer);
58
+ console.log(success(`Screenshot saved to ${absolutePath}`));
59
+ }
60
+ catch (err) {
61
+ console.log(error(err instanceof Error ? err.message : 'Failed to capture screenshot'));
62
+ process.exit(1);
63
+ }
64
+ });
65
+ /**
66
+ * Generate a default filename with timestamp
67
+ */
68
+ function generateFilename() {
69
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
70
+ return `screenshot-${timestamp}.png`;
71
+ }
72
+ //# sourceMappingURL=screenshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/screenshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser scroll-into-view - Scroll element into view by ref or semantic text
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const scrollIntoViewCommand: Command;
6
+ //# sourceMappingURL=scroll-into-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-into-view.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/scroll-into-view.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,qBAAqB,SAmD9B,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * qa-use browser scroll-into-view - Scroll element into view by ref or semantic text
3
+ */
4
+ import { Command } from 'commander';
5
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
6
+ import { resolveSessionId, touchSession } from '../../lib/browser-sessions.js';
7
+ import { loadConfig } from '../../lib/config.js';
8
+ import { success, error } from '../../lib/output.js';
9
+ /**
10
+ * Normalize ref by stripping leading @ if present
11
+ */
12
+ function normalizeRef(ref) {
13
+ return ref.startsWith('@') ? ref.slice(1) : ref;
14
+ }
15
+ export const scrollIntoViewCommand = new Command('scroll-into-view')
16
+ .description('Scroll an element into view by ref or semantic description')
17
+ .argument('[ref]', 'Element ref from snapshot (e.g., "e3" or "@e3")')
18
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
19
+ .option('-t, --text <description>', 'Semantic element description (AI-based, slower)')
20
+ .action(async (ref, options) => {
21
+ try {
22
+ // Validate that either ref or --text is provided
23
+ if (!ref && !options.text) {
24
+ console.log(error('Either <ref> argument or --text option is required'));
25
+ process.exit(1);
26
+ }
27
+ const config = await loadConfig();
28
+ if (!config.api_key) {
29
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
30
+ process.exit(1);
31
+ }
32
+ const client = new BrowserApiClient(config.api_url);
33
+ client.setApiKey(config.api_key);
34
+ const resolved = await resolveSessionId({
35
+ explicitId: options.sessionId,
36
+ client,
37
+ });
38
+ // Build action with either ref or text
39
+ const action = {
40
+ type: 'scroll_into_view',
41
+ };
42
+ if (ref) {
43
+ action.ref = normalizeRef(ref);
44
+ }
45
+ else if (options.text) {
46
+ action.text = options.text;
47
+ }
48
+ const result = await client.executeAction(resolved.id, action);
49
+ if (result.success) {
50
+ const target = ref ? `element ${normalizeRef(ref)}` : `"${options.text}"`;
51
+ console.log(success(`Scrolled ${target} into view`));
52
+ await touchSession(resolved.id);
53
+ }
54
+ else {
55
+ console.log(error(result.error || 'Scroll into view failed'));
56
+ process.exit(1);
57
+ }
58
+ }
59
+ catch (err) {
60
+ console.log(error(err instanceof Error ? err.message : 'Failed to scroll into view'));
61
+ process.exit(1);
62
+ }
63
+ });
64
+ //# sourceMappingURL=scroll-into-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-into-view.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/scroll-into-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser scroll - Scroll page
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const scrollCommand: Command;
6
+ //# sourceMappingURL=scroll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/scroll.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,aAAa,SA0DtB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * qa-use browser scroll - Scroll page
3
+ */
4
+ import { Command } from 'commander';
5
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
6
+ import { resolveSessionId, touchSession } from '../../lib/browser-sessions.js';
7
+ import { loadConfig } from '../../lib/config.js';
8
+ import { success, error } from '../../lib/output.js';
9
+ const VALID_DIRECTIONS = ['up', 'down', 'left', 'right'];
10
+ export const scrollCommand = new Command('scroll')
11
+ .description('Scroll the page')
12
+ .argument('<direction>', 'Scroll direction: up, down, left, or right')
13
+ .argument('[amount]', 'Scroll amount in pixels (default: 500)', '500')
14
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
15
+ .action(async (direction, amountStr, options) => {
16
+ try {
17
+ // Load configuration
18
+ const config = await loadConfig();
19
+ if (!config.api_key) {
20
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
21
+ process.exit(1);
22
+ }
23
+ // Validate direction
24
+ const normalizedDirection = direction.toLowerCase();
25
+ if (!VALID_DIRECTIONS.includes(normalizedDirection)) {
26
+ console.log(error(`Invalid direction: ${direction}. Must be one of: ${VALID_DIRECTIONS.join(', ')}`));
27
+ process.exit(1);
28
+ }
29
+ // Parse amount
30
+ const amount = parseInt(amountStr, 10);
31
+ if (isNaN(amount) || amount <= 0) {
32
+ console.log(error('Amount must be a positive number'));
33
+ process.exit(1);
34
+ }
35
+ // Create client and set API key
36
+ const client = new BrowserApiClient(config.api_url);
37
+ client.setApiKey(config.api_key);
38
+ // Resolve session ID
39
+ const resolved = await resolveSessionId({
40
+ explicitId: options.sessionId,
41
+ client,
42
+ });
43
+ // Execute scroll action
44
+ const result = await client.executeAction(resolved.id, {
45
+ type: 'scroll',
46
+ direction: normalizedDirection,
47
+ amount,
48
+ });
49
+ if (result.success) {
50
+ console.log(success(`Scrolled ${normalizedDirection} ${amount}px`));
51
+ await touchSession(resolved.id);
52
+ }
53
+ else {
54
+ console.log(error(result.error || 'Scroll failed'));
55
+ process.exit(1);
56
+ }
57
+ }
58
+ catch (err) {
59
+ console.log(error(err instanceof Error ? err.message : 'Failed to scroll'));
60
+ process.exit(1);
61
+ }
62
+ });
63
+ //# sourceMappingURL=scroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/scroll.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser select - Select dropdown option by ref or semantic text
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const selectCommand: Command;
6
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/select.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,aAAa,SA0EvB,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * qa-use browser select - Select dropdown option by ref or semantic text
3
+ */
4
+ import { Command } from 'commander';
5
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
6
+ import { resolveSessionId, touchSession } from '../../lib/browser-sessions.js';
7
+ import { loadConfig } from '../../lib/config.js';
8
+ import { success, error } from '../../lib/output.js';
9
+ /**
10
+ * Normalize ref by stripping leading @ if present
11
+ */
12
+ function normalizeRef(ref) {
13
+ return ref.startsWith('@') ? ref.slice(1) : ref;
14
+ }
15
+ export const selectCommand = new Command('select')
16
+ .description('Select a dropdown option by ref or semantic description')
17
+ .argument('[ref]', 'Element ref from snapshot (e.g., "e5" or "@e5")')
18
+ .argument('<value>', 'Option value to select')
19
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
20
+ .option('-t, --text <description>', 'Semantic element description (AI-based, slower)')
21
+ .action(async (refOrValue, valueOrUndefined, options) => {
22
+ try {
23
+ // Handle argument parsing: if --text is used, first arg is value; otherwise first is ref, second is value
24
+ let ref;
25
+ let value;
26
+ if (options.text) {
27
+ // When using --text, the first argument is the value
28
+ value = refOrValue;
29
+ if (!value) {
30
+ console.log(error('Value argument is required'));
31
+ process.exit(1);
32
+ }
33
+ }
34
+ else {
35
+ // Normal mode: first arg is ref, second is value
36
+ ref = refOrValue;
37
+ value = valueOrUndefined;
38
+ if (!ref || !value) {
39
+ console.log(error('Both <ref> and <value> arguments are required (or use --text with <value>)'));
40
+ process.exit(1);
41
+ }
42
+ }
43
+ const config = await loadConfig();
44
+ if (!config.api_key) {
45
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
46
+ process.exit(1);
47
+ }
48
+ const client = new BrowserApiClient(config.api_url);
49
+ client.setApiKey(config.api_key);
50
+ const resolved = await resolveSessionId({
51
+ explicitId: options.sessionId,
52
+ client,
53
+ });
54
+ // Build action with either ref or text
55
+ const action = {
56
+ type: 'select',
57
+ value,
58
+ };
59
+ if (ref) {
60
+ action.ref = normalizeRef(ref);
61
+ }
62
+ else if (options.text) {
63
+ action.text = options.text;
64
+ }
65
+ const result = await client.executeAction(resolved.id, action);
66
+ if (result.success) {
67
+ const displayValue = value.length > 50 ? value.slice(0, 47) + '...' : value;
68
+ const target = ref ? normalizeRef(ref) : `"${options.text}"`;
69
+ console.log(success(`Selected "${displayValue}" in ${target}`));
70
+ await touchSession(resolved.id);
71
+ }
72
+ else {
73
+ const hint = result.error || 'Select failed';
74
+ console.log(error(`${hint}. Use 'qa-use browser snapshot' to see available elements.`));
75
+ process.exit(1);
76
+ }
77
+ }
78
+ catch (err) {
79
+ console.log(error(err instanceof Error ? err.message : 'Failed to select option'));
80
+ process.exit(1);
81
+ }
82
+ });
83
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/select.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser snapshot - Get ARIA accessibility tree
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const snapshotCommand: Command;
6
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/snapshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,eAAe,SA2CxB,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * qa-use browser snapshot - Get ARIA accessibility tree
3
+ */
4
+ import { Command } from 'commander';
5
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
6
+ import { resolveSessionId, touchSession } from '../../lib/browser-sessions.js';
7
+ import { loadConfig } from '../../lib/config.js';
8
+ import { error } from '../../lib/output.js';
9
+ export const snapshotCommand = new Command('snapshot')
10
+ .description('Get the ARIA accessibility tree snapshot')
11
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
12
+ .option('--json', 'Output raw JSON instead of formatted tree')
13
+ .action(async (options) => {
14
+ try {
15
+ // Load configuration
16
+ const config = await loadConfig();
17
+ if (!config.api_key) {
18
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
19
+ process.exit(1);
20
+ }
21
+ // Create client and set API key
22
+ const client = new BrowserApiClient(config.api_url);
23
+ client.setApiKey(config.api_key);
24
+ // Resolve session ID
25
+ const resolved = await resolveSessionId({
26
+ explicitId: options.sessionId,
27
+ client,
28
+ });
29
+ // Get snapshot
30
+ const snapshot = await client.getSnapshot(resolved.id);
31
+ if (options.json) {
32
+ // Output raw JSON
33
+ console.log(JSON.stringify(snapshot, null, 2));
34
+ }
35
+ else {
36
+ // Output formatted ARIA tree
37
+ if (snapshot.url) {
38
+ console.log(`URL: ${snapshot.url}\n`);
39
+ }
40
+ console.log(formatAriaTree(snapshot.snapshot));
41
+ }
42
+ // Update session timestamp
43
+ await touchSession(resolved.id);
44
+ }
45
+ catch (err) {
46
+ console.log(error(err instanceof Error ? err.message : 'Failed to get snapshot'));
47
+ process.exit(1);
48
+ }
49
+ });
50
+ /**
51
+ * Format ARIA tree with highlighted refs
52
+ */
53
+ function formatAriaTree(tree) {
54
+ // ANSI color codes
55
+ const colors = {
56
+ reset: '\x1b[0m',
57
+ green: '\x1b[32m',
58
+ cyan: '\x1b[36m',
59
+ gray: '\x1b[90m',
60
+ yellow: '\x1b[33m',
61
+ };
62
+ // Highlight refs like [ref=e3]
63
+ const highlighted = tree.replace(/\[ref=(\w+)\]/g, (match, ref) => {
64
+ return `${colors.cyan}[ref=${colors.yellow}${ref}${colors.cyan}]${colors.reset}`;
65
+ });
66
+ // Highlight element types (heading, button, link, textbox, etc.)
67
+ const withElements = highlighted.replace(/^(\s*-\s+)(heading|button|link|textbox|combobox|listbox|checkbox|radio|menu|menuitem|dialog|img|paragraph|list|listitem|table|row|cell|tab|tablist|tabpanel)/gm, (match, prefix, element) => {
68
+ return `${prefix}${colors.green}${element}${colors.reset}`;
69
+ });
70
+ return withElements;
71
+ }
72
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser status - Get session status
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const statusCommand: Command;
6
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,aAAa,SA8FtB,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * qa-use browser status - Get session status
3
+ */
4
+ import { Command } from 'commander';
5
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
6
+ import { resolveSessionId } from '../../lib/browser-sessions.js';
7
+ import { loadConfig } from '../../lib/config.js';
8
+ import { success, error, info } from '../../lib/output.js';
9
+ export const statusCommand = new Command('status')
10
+ .description('Get session status and details')
11
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
12
+ .option('--json', 'Output as JSON')
13
+ .action(async (options) => {
14
+ try {
15
+ // Load configuration
16
+ const config = await loadConfig();
17
+ if (!config.api_key) {
18
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
19
+ process.exit(1);
20
+ }
21
+ // Create client and set API key
22
+ const client = new BrowserApiClient(config.api_url);
23
+ client.setApiKey(config.api_key);
24
+ // Resolve session ID
25
+ const resolved = await resolveSessionId({
26
+ explicitId: options.sessionId,
27
+ client,
28
+ verify: false, // We'll get the session anyway
29
+ });
30
+ // Get session details
31
+ const session = await client.getSession(resolved.id);
32
+ if (options.json) {
33
+ console.log(JSON.stringify(session, null, 2));
34
+ return;
35
+ }
36
+ // Human-readable output
37
+ console.log('');
38
+ console.log(`Session ID: ${session.id}`);
39
+ // Status with color
40
+ let statusDisplay;
41
+ switch (session.status) {
42
+ case 'active':
43
+ statusDisplay = `\x1b[32m${session.status}\x1b[0m`; // Green
44
+ break;
45
+ case 'starting':
46
+ statusDisplay = `\x1b[33m${session.status}\x1b[0m`; // Yellow
47
+ break;
48
+ case 'closed':
49
+ case 'closing':
50
+ statusDisplay = `\x1b[90m${session.status}\x1b[0m`; // Gray
51
+ break;
52
+ default:
53
+ statusDisplay = session.status;
54
+ }
55
+ console.log(`Status: ${statusDisplay}`);
56
+ // Created time
57
+ const createdAt = new Date(session.created_at);
58
+ console.log(`Created: ${createdAt.toISOString()}`);
59
+ // Updated time if available
60
+ if (session.updated_at) {
61
+ const updatedAt = new Date(session.updated_at);
62
+ console.log(`Updated: ${updatedAt.toISOString()}`);
63
+ }
64
+ // Current URL
65
+ if (session.current_url) {
66
+ console.log(`URL: ${session.current_url}`);
67
+ }
68
+ // Viewport
69
+ if (session.viewport) {
70
+ console.log(`Viewport: ${session.viewport}`);
71
+ }
72
+ // Headless mode
73
+ if (session.headless !== undefined) {
74
+ console.log(`Headless: ${session.headless}`);
75
+ }
76
+ // Timeout
77
+ if (session.timeout) {
78
+ console.log(`Timeout: ${session.timeout}s`);
79
+ }
80
+ console.log('');
81
+ // Show source if auto-resolved
82
+ if (resolved.source === 'stored') {
83
+ console.log(info('(Session auto-resolved from local storage)'));
84
+ }
85
+ }
86
+ catch (err) {
87
+ console.log(error(err instanceof Error ? err.message : 'Failed to get session status'));
88
+ process.exit(1);
89
+ }
90
+ });
91
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser stream - Real-time WebSocket event streaming
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const streamCommand: Command;
6
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/stream.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,eAAO,MAAM,aAAa,SAiFtB,CAAC"}