@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,35 @@
1
+ /**
2
+ * qa-use browser get-blocks - Get recorded blocks (test steps) from the session
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 { error } from '../../lib/output.js';
9
+ export const getBlocksCommand = new Command('get-blocks')
10
+ .description('Get recorded blocks (test steps) from the session')
11
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
12
+ .option('--json', 'Output raw JSON (default)', true)
13
+ .action(async (options) => {
14
+ try {
15
+ const config = await loadConfig();
16
+ if (!config.api_key) {
17
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
18
+ process.exit(1);
19
+ }
20
+ const client = new BrowserApiClient(config.api_url);
21
+ client.setApiKey(config.api_key);
22
+ const resolved = await resolveSessionId({
23
+ explicitId: options.sessionId,
24
+ client,
25
+ });
26
+ const blocks = await client.getBlocks(resolved.id);
27
+ // Output as JSON (default and only mode for now)
28
+ console.log(JSON.stringify(blocks, null, 2));
29
+ }
30
+ catch (err) {
31
+ console.log(error(err instanceof Error ? err.message : 'Failed to get blocks'));
32
+ process.exit(1);
33
+ }
34
+ });
35
+ //# sourceMappingURL=get-blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-blocks.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/get-blocks.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,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAO5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;KACtD,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,uBAAuB,EAAE,gDAAgD,CAAC;KACjF,MAAM,CAAC,QAAQ,EAAE,2BAA2B,EAAE,IAAI,CAAC;KACnD,MAAM,CAAC,KAAK,EAAE,OAAyB,EAAE,EAAE;IAC1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC;YACtC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,MAAM;SACP,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAEnD,iDAAiD;QACjD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser goto - Navigate to URL
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const gotoCommand: Command;
6
+ //# sourceMappingURL=goto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goto.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/goto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,WAAW,SA8CpB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * qa-use browser goto - Navigate to URL
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
+ export const gotoCommand = new Command('goto')
10
+ .description('Navigate to a URL')
11
+ .argument('<url>', 'URL to navigate to')
12
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
13
+ .action(async (url, 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
+ // Validate URL
22
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
23
+ url = 'https://' + url;
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
+ // Execute goto action
34
+ const result = await client.executeAction(resolved.id, {
35
+ type: 'goto',
36
+ url,
37
+ });
38
+ if (result.success) {
39
+ console.log(success(`Navigated to ${url}`));
40
+ // Update session timestamp
41
+ await touchSession(resolved.id);
42
+ }
43
+ else {
44
+ console.log(error(result.error || 'Navigation failed'));
45
+ process.exit(1);
46
+ }
47
+ }
48
+ catch (err) {
49
+ console.log(error(err instanceof Error ? err.message : 'Failed to navigate'));
50
+ process.exit(1);
51
+ }
52
+ });
53
+ //# sourceMappingURL=goto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goto.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/goto.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,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAMrD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,mBAAmB,CAAC;KAChC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;KACvC,MAAM,CAAC,uBAAuB,EAAE,gDAAgD,CAAC;KACjF,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,OAAoB,EAAE,EAAE;IAClD,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,eAAe;QACf,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9D,GAAG,GAAG,UAAU,GAAG,GAAG,CAAC;QACzB,CAAC;QAED,gCAAgC;QAChC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,qBAAqB;QACrB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC;YACtC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,MAAM;SACP,CAAC,CAAC;QAEH,sBAAsB;QACtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE;YACrD,IAAI,EAAE,MAAM;YACZ,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC,CAAC;YAC5C,2BAA2B;YAC3B,MAAM,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,mBAAmB,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser hover - Hover over element by ref or semantic text
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const hoverCommand: Command;
6
+ //# sourceMappingURL=hover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/hover.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,YAAY,SAkDrB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * qa-use browser hover - Hover over element 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 hoverCommand = new Command('hover')
16
+ .description('Hover over an element 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 = { type: 'hover' };
40
+ if (ref) {
41
+ action.ref = normalizeRef(ref);
42
+ }
43
+ else if (options.text) {
44
+ action.text = options.text;
45
+ }
46
+ const result = await client.executeAction(resolved.id, action);
47
+ if (result.success) {
48
+ const target = ref ? `element ${normalizeRef(ref)}` : `"${options.text}"`;
49
+ console.log(success(`Hovering over ${target}`));
50
+ await touchSession(resolved.id);
51
+ }
52
+ else {
53
+ const hint = result.error || 'Hover failed';
54
+ console.log(error(`${hint}. Use 'qa-use browser snapshot' to see available elements.`));
55
+ process.exit(1);
56
+ }
57
+ }
58
+ catch (err) {
59
+ console.log(error(err instanceof Error ? err.message : 'Failed to hover over element'));
60
+ process.exit(1);
61
+ }
62
+ });
63
+ //# sourceMappingURL=hover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/hover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * qa-use browser - Browser control command group
3
+ *
4
+ * Control remote browsers via the desplega.ai Browser API.
5
+ * Uses accessibility-based element targeting with refs.
6
+ */
7
+ import { Command } from 'commander';
8
+ export declare const browserCommand: Command;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqCpC,eAAO,MAAM,cAAc,SAAgE,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * qa-use browser - Browser control command group
3
+ *
4
+ * Control remote browsers via the desplega.ai Browser API.
5
+ * Uses accessibility-based element targeting with refs.
6
+ */
7
+ import { Command } from 'commander';
8
+ // Session management commands
9
+ import { createCommand } from './create.js';
10
+ import { listCommand } from './list.js';
11
+ import { statusCommand } from './status.js';
12
+ import { closeCommand } from './close.js';
13
+ // Navigation & action commands
14
+ import { gotoCommand } from './goto.js';
15
+ import { backCommand } from './back.js';
16
+ import { forwardCommand } from './forward.js';
17
+ import { reloadCommand } from './reload.js';
18
+ import { clickCommand } from './click.js';
19
+ import { fillCommand } from './fill.js';
20
+ import { typeCommand } from './type.js';
21
+ import { pressCommand } from './press.js';
22
+ import { hoverCommand } from './hover.js';
23
+ import { scrollCommand } from './scroll.js';
24
+ import { scrollIntoViewCommand } from './scroll-into-view.js';
25
+ import { selectCommand } from './select.js';
26
+ import { checkCommand } from './check.js';
27
+ import { uncheckCommand } from './uncheck.js';
28
+ import { waitCommand } from './wait.js';
29
+ import { waitForSelectorCommand } from './wait-for-selector.js';
30
+ import { waitForLoadCommand } from './wait-for-load.js';
31
+ // Inspection commands
32
+ import { snapshotCommand } from './snapshot.js';
33
+ import { screenshotCommand } from './screenshot.js';
34
+ import { urlCommand } from './url.js';
35
+ import { getBlocksCommand } from './get-blocks.js';
36
+ // Advanced commands
37
+ import { streamCommand } from './stream.js';
38
+ import { runCommand } from './run.js';
39
+ export const browserCommand = new Command('browser').description('Control remote browsers');
40
+ // Register session management commands
41
+ browserCommand.addCommand(createCommand);
42
+ browserCommand.addCommand(listCommand);
43
+ browserCommand.addCommand(statusCommand);
44
+ browserCommand.addCommand(closeCommand);
45
+ // Register navigation & action commands
46
+ browserCommand.addCommand(gotoCommand);
47
+ browserCommand.addCommand(backCommand);
48
+ browserCommand.addCommand(forwardCommand);
49
+ browserCommand.addCommand(reloadCommand);
50
+ browserCommand.addCommand(clickCommand);
51
+ browserCommand.addCommand(fillCommand);
52
+ browserCommand.addCommand(typeCommand);
53
+ browserCommand.addCommand(pressCommand);
54
+ browserCommand.addCommand(hoverCommand);
55
+ browserCommand.addCommand(scrollCommand);
56
+ browserCommand.addCommand(scrollIntoViewCommand);
57
+ browserCommand.addCommand(selectCommand);
58
+ browserCommand.addCommand(checkCommand);
59
+ browserCommand.addCommand(uncheckCommand);
60
+ browserCommand.addCommand(waitCommand);
61
+ browserCommand.addCommand(waitForSelectorCommand);
62
+ browserCommand.addCommand(waitForLoadCommand);
63
+ // Register inspection commands
64
+ browserCommand.addCommand(snapshotCommand);
65
+ browserCommand.addCommand(screenshotCommand);
66
+ browserCommand.addCommand(urlCommand);
67
+ browserCommand.addCommand(getBlocksCommand);
68
+ // Register advanced commands
69
+ browserCommand.addCommand(streamCommand);
70
+ browserCommand.addCommand(runCommand);
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser list - List browser sessions
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const listCommand: Command;
6
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,WAAW,SA0FpB,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * qa-use browser list - List browser sessions
3
+ */
4
+ import { Command } from 'commander';
5
+ import { BrowserApiClient } from '../../../../lib/api/browser.js';
6
+ import { loadStoredSessions, isSessionStale } from '../../lib/browser-sessions.js';
7
+ import { loadConfig } from '../../lib/config.js';
8
+ import { error, warning } from '../../lib/output.js';
9
+ export const listCommand = new Command('list')
10
+ .description('List browser sessions')
11
+ .option('--json', 'Output as JSON')
12
+ .action(async (options) => {
13
+ try {
14
+ // Load configuration
15
+ const config = await loadConfig();
16
+ if (!config.api_key) {
17
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
18
+ process.exit(1);
19
+ }
20
+ // Create client and set API key
21
+ const client = new BrowserApiClient(config.api_url);
22
+ client.setApiKey(config.api_key);
23
+ // Fetch sessions from API
24
+ const sessions = await client.listSessions();
25
+ // Load locally stored sessions for marking
26
+ const storedSessions = await loadStoredSessions();
27
+ const storedIds = new Set(storedSessions.map((s) => s.id));
28
+ if (options.json) {
29
+ // JSON output
30
+ const output = sessions.map((s) => ({
31
+ id: s.id,
32
+ status: s.status,
33
+ created_at: s.created_at,
34
+ url: s.current_url,
35
+ local: storedIds.has(s.id),
36
+ }));
37
+ console.log(JSON.stringify(output, null, 2));
38
+ return;
39
+ }
40
+ // Human-readable output
41
+ if (sessions.length === 0) {
42
+ console.log(warning('No browser sessions found.'));
43
+ return;
44
+ }
45
+ console.log(`Found ${sessions.length} session(s):\n`);
46
+ // Table header
47
+ console.log('ID Status Created URL');
48
+ console.log('─'.repeat(90));
49
+ for (const session of sessions) {
50
+ const isLocal = storedIds.has(session.id);
51
+ const localMarker = isLocal ? ' *' : ' ';
52
+ // Format created time
53
+ const createdAt = new Date(session.created_at);
54
+ const createdStr = createdAt.toISOString().replace('T', ' ').slice(0, 19);
55
+ // Format URL (truncate if too long)
56
+ const url = session.current_url || '-';
57
+ const truncatedUrl = url.length > 30 ? url.slice(0, 27) + '...' : url;
58
+ // Status with color indicator
59
+ let statusStr = session.status.padEnd(8);
60
+ if (session.status === 'active') {
61
+ statusStr = `\x1b[32m${statusStr}\x1b[0m`; // Green
62
+ }
63
+ else if (session.status === 'starting') {
64
+ statusStr = `\x1b[33m${statusStr}\x1b[0m`; // Yellow
65
+ }
66
+ else if (session.status === 'closed' || session.status === 'closing') {
67
+ statusStr = `\x1b[90m${statusStr}\x1b[0m`; // Gray
68
+ }
69
+ console.log(`${session.id}${localMarker}${statusStr} ${createdStr} ${truncatedUrl}`);
70
+ }
71
+ console.log('');
72
+ console.log('* = tracked locally (auto-resolved with -s flag)');
73
+ // Check for stale local sessions
74
+ const staleSessions = storedSessions.filter(isSessionStale);
75
+ if (staleSessions.length > 0) {
76
+ console.log('');
77
+ console.log(warning(`${staleSessions.length} stale local session(s) will be cleaned up automatically.`));
78
+ }
79
+ }
80
+ catch (err) {
81
+ console.log(error(err instanceof Error ? err.message : 'Failed to list sessions'));
82
+ process.exit(1);
83
+ }
84
+ });
85
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser press - Press keyboard key
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const pressCommand: Command;
6
+ //# sourceMappingURL=press.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"press.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/press.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,eAAO,MAAM,YAAY,SA0CrB,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * qa-use browser press - Press keyboard key
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
+ // Common key names for reference
10
+ const COMMON_KEYS = [
11
+ 'Enter',
12
+ 'Tab',
13
+ 'Escape',
14
+ 'Backspace',
15
+ 'Delete',
16
+ 'ArrowUp',
17
+ 'ArrowDown',
18
+ 'ArrowLeft',
19
+ 'ArrowRight',
20
+ 'Home',
21
+ 'End',
22
+ 'PageUp',
23
+ 'PageDown',
24
+ 'Space',
25
+ ];
26
+ export const pressCommand = new Command('press')
27
+ .description('Press a keyboard key')
28
+ .argument('<key>', `Key to press (e.g., "Enter", "Tab", "Escape")`)
29
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
30
+ .action(async (key, options) => {
31
+ try {
32
+ // Load configuration
33
+ const config = await loadConfig();
34
+ if (!config.api_key) {
35
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
36
+ process.exit(1);
37
+ }
38
+ // Create client and set API key
39
+ const client = new BrowserApiClient(config.api_url);
40
+ client.setApiKey(config.api_key);
41
+ // Resolve session ID
42
+ const resolved = await resolveSessionId({
43
+ explicitId: options.sessionId,
44
+ client,
45
+ });
46
+ // Execute press action
47
+ const result = await client.executeAction(resolved.id, {
48
+ type: 'press',
49
+ key,
50
+ });
51
+ if (result.success) {
52
+ console.log(success(`Pressed key: ${key}`));
53
+ await touchSession(resolved.id);
54
+ }
55
+ else {
56
+ const hint = result.error || 'Key press failed';
57
+ console.log(error(hint));
58
+ console.log(`Common keys: ${COMMON_KEYS.join(', ')}`);
59
+ process.exit(1);
60
+ }
61
+ }
62
+ catch (err) {
63
+ console.log(error(err instanceof Error ? err.message : 'Failed to press key'));
64
+ process.exit(1);
65
+ }
66
+ });
67
+ //# sourceMappingURL=press.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"press.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/press.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,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAMrD,iCAAiC;AACjC,MAAM,WAAW,GAAG;IAClB,OAAO;IACP,KAAK;IACL,QAAQ;IACR,WAAW;IACX,QAAQ;IACR,SAAS;IACT,WAAW;IACX,WAAW;IACX,YAAY;IACZ,MAAM;IACN,KAAK;IACL,QAAQ;IACR,UAAU;IACV,OAAO;CACR,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,sBAAsB,CAAC;KACnC,QAAQ,CAAC,OAAO,EAAE,+CAA+C,CAAC;KAClE,MAAM,CAAC,uBAAuB,EAAE,gDAAgD,CAAC;KACjF,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,OAAqB,EAAE,EAAE;IACnD,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,gCAAgC;QAChC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,qBAAqB;QACrB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC;YACtC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,MAAM;SACP,CAAC,CAAC;QAEH,uBAAuB;QACvB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE;YACrD,IAAI,EAAE,OAAO;YACb,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC,CAAC;YAC5C,MAAM,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,kBAAkB,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,gBAAgB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser reload - Reload current page
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const reloadCommand: Command;
6
+ //# sourceMappingURL=reload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reload.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/reload.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,aAAa,SAkCtB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * qa-use browser reload - Reload current 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
+ export const reloadCommand = new Command('reload')
10
+ .description('Reload current page')
11
+ .option('-s, --session-id <id>', 'Session ID (auto-resolved if only one session)')
12
+ .action(async (options) => {
13
+ try {
14
+ const config = await loadConfig();
15
+ if (!config.api_key) {
16
+ console.log(error('API key not configured. Run `qa-use setup` first.'));
17
+ process.exit(1);
18
+ }
19
+ const client = new BrowserApiClient(config.api_url);
20
+ client.setApiKey(config.api_key);
21
+ const resolved = await resolveSessionId({
22
+ explicitId: options.sessionId,
23
+ client,
24
+ });
25
+ const result = await client.executeAction(resolved.id, {
26
+ type: 'reload',
27
+ });
28
+ if (result.success) {
29
+ console.log(success('Page reloaded'));
30
+ await touchSession(resolved.id);
31
+ }
32
+ else {
33
+ console.log(error(result.error || 'Reload failed'));
34
+ process.exit(1);
35
+ }
36
+ }
37
+ catch (err) {
38
+ console.log(error(err instanceof Error ? err.message : 'Failed to reload page'));
39
+ process.exit(1);
40
+ }
41
+ });
42
+ //# sourceMappingURL=reload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reload.js","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/reload.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,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAMrD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,uBAAuB,EAAE,gDAAgD,CAAC;KACjF,MAAM,CAAC,KAAK,EAAE,OAAsB,EAAE,EAAE;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjC,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC;YACtC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,MAAM;SACP,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE;YACrD,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;YACtC,MAAM,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * qa-use browser run - Interactive REPL mode
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const runCommand: Command;
6
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/browser/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,eAAO,MAAM,UAAU,SAwbnB,CAAC"}