@desplega.ai/qa-use 2.10.1 → 2.11.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/README.md CHANGED
@@ -170,18 +170,28 @@ QA_USE_REGION=us # Optional: "us" or "auto" (default)
170
170
 
171
171
  ### Config File
172
172
 
173
- Alternatively, use `~/.qa-use.json`:
173
+ Alternatively, create a `.qa-use.json` in your project root or `~/.qa-use.json` in your home directory:
174
174
 
175
175
  ```json
176
176
  {
177
- "env": {
178
- "QA_USE_API_KEY": "your-api-key-here",
179
- "QA_USE_REGION": "us"
180
- }
177
+ "$schema": "https://qa-use.dev/cli-schema.json",
178
+ "api_key": "your-api-key-here",
179
+ "region": "us"
181
180
  }
182
181
  ```
183
182
 
184
- Environment variables take precedence over the config file.
183
+ **Precedence** (first wins):
184
+ 1. Environment variables
185
+ 2. `.qa-use.json` in current directory
186
+ 3. `~/.qa-use.json` in home directory
187
+
188
+ | Variable | Description | Default |
189
+ |----------|-------------|---------|
190
+ | `QA_USE_API_KEY` | API key for authentication | (required) |
191
+ | `QA_USE_API_URL` | API endpoint | `https://api.desplega.ai` |
192
+ | `QA_USE_APP_URL` | App URL | `https://app.desplega.ai` |
193
+ | `QA_USE_REGION` | Region (`us` or `auto`) | `auto` |
194
+ | `QA_USE_DEFAULT_APP_CONFIG_ID` | Default app config | (from API key) |
185
195
 
186
196
  ## CI/CD Integration
187
197
 
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Priority order:
5
5
  * 1. Environment variables (process.env)
6
- * 2. Config file (~/.qa-use.json) with structure: { "env": { "VAR_NAME": "value" } }
6
+ * 2. Config file (~/.qa-use.json) top-level fields (api_key, api_url, etc.)
7
+ * 3. Config file (~/.qa-use.json) env block ({ "env": { "VAR_NAME": "value" } })
7
8
  */
8
9
  export type EnvSource = 'env' | 'config' | 'none';
9
10
  export interface EnvResult {
@@ -12,7 +13,9 @@ export interface EnvResult {
12
13
  }
13
14
  /**
14
15
  * Get an environment variable value with fallback to config file,
15
- * along with the source of the value
16
+ * along with the source of the value.
17
+ *
18
+ * Priority: process.env → config top-level field → config env block
16
19
  *
17
20
  * @param name - The environment variable name (e.g., 'QA_USE_API_KEY')
18
21
  * @returns Object containing the value and its source
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/env/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+CH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAcxD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAgBD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CA6BvC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/env/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA8DH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAwBxD;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAgBD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CA6BvC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtD"}
@@ -3,11 +3,22 @@
3
3
  *
4
4
  * Priority order:
5
5
  * 1. Environment variables (process.env)
6
- * 2. Config file (~/.qa-use.json) with structure: { "env": { "VAR_NAME": "value" } }
6
+ * 2. Config file (~/.qa-use.json) top-level fields (api_key, api_url, etc.)
7
+ * 3. Config file (~/.qa-use.json) env block ({ "env": { "VAR_NAME": "value" } })
7
8
  */
8
9
  import { existsSync, readFileSync } from 'node:fs';
9
10
  import { homedir } from 'node:os';
10
11
  import { join } from 'node:path';
12
+ /**
13
+ * Mapping from env var names to top-level config field names.
14
+ * Allows getEnvWithSource to check direct fields before the env block.
15
+ */
16
+ const ENV_TO_FIELD = {
17
+ QA_USE_API_KEY: 'api_key',
18
+ QA_USE_API_URL: 'api_url',
19
+ QA_USE_APP_URL: 'app_url',
20
+ QA_USE_REGION: 'region',
21
+ };
11
22
  let cachedConfig = null;
12
23
  let configLoadAttempted = false;
13
24
  /**
@@ -41,7 +52,9 @@ function loadConfig() {
41
52
  }
42
53
  /**
43
54
  * Get an environment variable value with fallback to config file,
44
- * along with the source of the value
55
+ * along with the source of the value.
56
+ *
57
+ * Priority: process.env → config top-level field → config env block
45
58
  *
46
59
  * @param name - The environment variable name (e.g., 'QA_USE_API_KEY')
47
60
  * @returns Object containing the value and its source
@@ -52,10 +65,19 @@ export function getEnvWithSource(name) {
52
65
  if (envValue !== undefined && envValue !== '') {
53
66
  return { value: envValue, source: 'env' };
54
67
  }
55
- // Fallback to config file
68
+ // Fallback to config file — check top-level field first, then env block
56
69
  const config = loadConfig();
57
- if (config?.env?.[name]) {
58
- return { value: config.env[name], source: 'config' };
70
+ if (config) {
71
+ const fieldName = ENV_TO_FIELD[name];
72
+ if (fieldName) {
73
+ const fieldValue = config[fieldName];
74
+ if (typeof fieldValue === 'string' && fieldValue) {
75
+ return { value: fieldValue, source: 'config' };
76
+ }
77
+ }
78
+ if (config.env?.[name]) {
79
+ return { value: config.env[name], source: 'config' };
80
+ }
59
81
  }
60
82
  return { value: undefined, source: 'none' };
61
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/env/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/env/index.ts"],"names":[],"mappings":"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"}
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desplega.ai/qa-use",
3
- "version": "2.10.1",
3
+ "version": "2.11.0",
4
4
  "packageManager": "bun@^1.3.4",
5
5
  "description": "QA automation tool for browser testing with MCP server support",
6
6
  "type": "module",
@@ -36,6 +36,7 @@
36
36
  "test": "bun test --preload ./test-setup.ts",
37
37
  "test:unit": "node scripts/test-unit.js",
38
38
  "test:integration": "node scripts/test-integration.js",
39
+ "test:e2e": "tsx scripts/e2e.ts",
39
40
  "test:coverage": "bun test --coverage --preload ./test-setup.ts",
40
41
  "generate:docs": "tsx scripts/generate-docs.ts",
41
42
  "generate:readme": "node scripts/generate-readme-tools.js",
@@ -1 +1 @@
1
- {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,eAAO,MAAM,WAAW,SAmLpB,CAAC"}
1
+ {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/info.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,eAAO,MAAM,WAAW,SAmLpB,CAAC"}
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * qa-use info - Show current configuration and app config details
3
3
  */
4
+ import { homedir } from 'node:os';
4
5
  import { Command } from 'commander';
5
6
  import { ApiClient } from '../../../lib/api/index.js';
6
7
  import { BrowserManager } from '../../../lib/browser/index.js';
7
- import { homedir } from 'node:os';
8
8
  import { getEnvWithSource } from '../../../lib/env/index.js';
9
9
  import { configExists, findConfigFile, loadConfig } from '../lib/config.js';
10
10
  import { error, success, warning } from '../lib/output.js';
@@ -33,18 +33,18 @@ export const infoCommand = new Command('info')
33
33
  console.log('QA-Use Configuration\n');
34
34
  const hasLocalConfig = await configExists();
35
35
  const config = await loadConfig();
36
- // Determine API key source
36
+ // Determine API key source — env vars have highest precedence
37
37
  const apiKeyEnvResult = getEnvWithSource('QA_USE_API_KEY');
38
38
  const apiKey = config.api_key || apiKeyEnvResult.value;
39
39
  const configPath = await findConfigFile();
40
40
  let apiKeySource = '';
41
41
  if (apiKey) {
42
- if (config.api_key && configPath) {
43
- apiKeySource = ` (from ${configPath.replace(homedir(), '~')})`;
44
- }
45
- else if (apiKeyEnvResult.value && apiKeyEnvResult.source === 'env') {
42
+ if (apiKeyEnvResult.value && apiKeyEnvResult.source === 'env') {
46
43
  apiKeySource = ' (from environment variable)';
47
44
  }
45
+ else if (config.api_key && configPath) {
46
+ apiKeySource = ` (from ${configPath.replace(homedir(), '~')})`;
47
+ }
48
48
  else if (apiKeyEnvResult.source === 'config') {
49
49
  apiKeySource = ' (from ~/.qa-use.json)';
50
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"info.js","sourceRoot":"","sources":["../../../../src/cli/commands/info.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../../../src/cli/commands/info.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,7 @@ export const setupCommand = new Command('setup')
24
24
  options.yes);
25
25
  // No-op: already configured and no options provided
26
26
  if (hasExistingConfig && config.api_key && !hasAnyOption) {
27
- console.log(success('Already configured (.qa-use-tests.json)'));
27
+ console.log(success('Already configured (.qa-use.json)'));
28
28
  console.log(` API key: ${config.api_key.slice(0, 8)}...`);
29
29
  console.log(` Test dir: ${config.test_directory || './qa-tests'}`);
30
30
  if (config.default_app_config_id) {
@@ -106,7 +106,7 @@ export const setupCommand = new Command('setup')
106
106
  }
107
107
  // Save configuration
108
108
  await saveConfig(config);
109
- console.log(`\n${success('Configuration saved to .qa-use-tests.json')}`);
109
+ console.log(`\n${success('Configuration saved to .qa-use.json')}`);
110
110
  }
111
111
  catch (err) {
112
112
  console.log(error(`Setup failed: ${formatError(err)}`));
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/cli/commands/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/cli/commands/setup.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  * DO NOT EDIT MANUALLY — Generated from plugins/qa-use/skills/qa-use/
4
4
  * Run 'bun run generate:docs' to regenerate.
5
5
  */
6
- export declare const MAIN_DOC = "---\nname: qa-use\ndescription: E2E testing and browser automation with qa-use CLI. Use when the user needs to run tests, verify features, automate browser interactions, or debug test failures.\nallowed-tools: Bash(qa-use *)\n---\n\n# qa-use\n\nE2E testing and browser automation for AI-driven development workflows.\n\n## Critical Insight: Plugin Commands as Shortcuts\n\n**For AI Harnesses (codex, opencode, etc.):**\n\nPlugin commands (slash commands like `/qa-use:verify`) are **convenience shortcuts** that wrap CLI workflows. Harnesses with only the Bash tool can access ALL functionality via CLI commands documented below.\n\n**Pattern throughout this document:**\n- **CLI Workflow**: Step-by-step CLI commands (works for ALL harnesses)\n- **Plugin Shortcut**: Optional slash command (convenience)\n\n## Setup & Configuration\n\nBefore using any qa-use commands, verify configuration is in place:\n\n```bash\n# Check current configuration (no-op if already configured)\nqa-use setup\n\n# Configure with API key (validates against server)\nqa-use setup --api-key <key>\n\n# View full configuration details\nqa-use info\n```\n\n**Environment Variables (alternative to config file):**\n\n| Variable | Description |\n|----------|-------------|\n| `QA_USE_API_KEY` | API key for authentication |\n| `QA_USE_REGION` | Region: `us` (default) or `auto` |\n| `QA_USE_API_URL` | Override API base URL |\n\n**Config file:** `.qa-use-tests.json` in the project directory or `~/.qa-use.json` in the home directory. Environment variables take precedence.\n\n**If you encounter \"API key not configured\", 401, or auth errors:** Run `qa-use setup` to check config state. NEVER fabricate or guess API keys.\n\n## Core Workflow\n\n### 1. Browser Control & Session Lifecycle\n\n**CLI Workflow:**\n```bash\n# Create browser session\nqa-use browser create --viewport desktop\n\n# For localhost testing\nqa-use browser create --tunnel --no-headless\n\n# Navigate\nqa-use browser goto https://example.com\n\n# Snapshot to get element refs (ALWAYS do this before interacting)\nqa-use browser snapshot\n\n# Interact by ref\nqa-use browser click e3\nqa-use browser fill e5 \"text\"\n\n# Close\nqa-use browser close\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:explore https://example.com\n```\n(Wraps create + goto + snapshot with autonomous exploration)\n\n**Critical:** Always run `snapshot` before your **first** interaction on a page. Never guess element refs.\n\n**Snapshot Diff Feature (use it to avoid unnecessary snapshots):**\nAfter each action (goto, click, fill, etc.), the browser automatically shows DOM changes:\n- **Summary**: \"5 elements added, 1 element modified\"\n- **Added elements**: `+ [e54] generic \"Thanks for agreeing!\"` (green)\n- **Modified elements**: `~ [e18] checkbox \"I agree...\"` with `+attrs: checked, active` (yellow)\n- **Removed elements**: `- [e99] button \"Submit\"` (red)\n\n**When you can skip a full `snapshot`:** If the diff output from your last action already shows the element ref you need to interact with next, use it directly \u2014 no need for an intermediate `snapshot`. For example, if clicking a button shows `+ [e54] button \"Submit\"` in the diff, you can `click e54` immediately.\n\n**When you still need a full `snapshot`:** Run `snapshot` when you need to find elements that weren't in the diff (e.g., pre-existing elements you haven't interacted with yet), or when the diff was truncated (shows \"... and N more changes\").\n\n### 2. Understanding Blocks\n\n**What are blocks?**\n\nBlocks are atomic recorded interactions from a browser session. They are:\n- Automatically captured during any browser interaction (click, fill, goto, scroll, etc.)\n- Stored server-side with the session\n- Retrieved via `qa-use browser get-blocks`\n- The foundation for test generation\n\n**Why blocks matter:**\n- **Record-once, replay-many**: Interactive recording becomes automated test\n- **AI-friendly**: Agents can analyze blocks to understand user intent\n- **Version control**: Blocks stored with session enable test iteration\n- **Bridge CLI \u2192 Tests**: Natural workflow from exploration to automation\n\n**How blocks work:**\n\n```bash\n# 1. Create session and interact\nqa-use browser create --tunnel --no-headless\nqa-use browser goto https://example.com\nqa-use browser snapshot # Returns: [ref=e1] button\nqa-use browser click e1 # Records as block\nqa-use browser fill e5 \"text\" # Records as block\n\n# 2. Retrieve blocks (JSON array)\nqa-use browser get-blocks\n# Returns:\n# [\n# {\"type\": \"goto\", \"url\": \"...\", \"timestamp\": \"...\"},\n# {\"type\": \"click\", \"ref\": \"e1\", \"timestamp\": \"...\"},\n# {\"type\": \"fill\", \"ref\": \"e5\", \"value\": \"text\", \"timestamp\": \"...\"}\n# ]\n\n# 3. Generate test YAML from blocks\nqa-use browser generate-test -n \"my_test\" -o qa-tests/my_test.yaml\n\n# 4. Run generated test\nqa-use test run my_test\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:record start my_test\n# ... perform interactions ...\n/qa-use:record stop\n```\n(Wraps the interactive workflow with AI-powered test generation)\n\n### 3. Test Management\n\n**CLI Workflow:**\n```bash\n# Run test by name\nqa-use test run login\n\n# Run with autofix (AI self-healing)\nqa-use test run login --autofix\n\n# Validate syntax\nqa-use test validate login\n\n# Show test details\nqa-use test info login\n\n# List test runs\nqa-use test runs --status failed\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:test-run login --autofix\n```\n(Convenience shortcut for common test execution)\n\n### 4. Test Sync Lifecycle\n\n**CLI Workflow:**\n```bash\n# Pull tests from cloud\nqa-use test sync pull\n\n# Push all local tests to cloud\nqa-use test sync push --all\n\n# Push specific test\nqa-use test sync push --id <uuid>\n\n# Force push (overwrite conflicts)\nqa-use test sync push --force\n\n# Compare local vs cloud\nqa-use test diff login.yaml\n```\n\n**No Plugin Shortcut** - Use CLI commands directly\n\n## Essential Commands\n\n### Browser Session Management\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser create` | Create remote browser session |\n| `qa-use browser create <url>` | Create session and navigate to URL |\n| `qa-use browser create --tunnel` | Create local browser with API tunnel |\n| `qa-use browser create --no-headless` | Show browser window (tunnel mode only) |\n| `qa-use browser create --viewport <size>` | Set viewport: `desktop`, `tablet`, `mobile` |\n| `qa-use browser create --ws-url <url>` | Connect to existing WebSocket browser |\n| `qa-use browser create --after-test-id <uuid>` | Run a test first, then become interactive |\n| `qa-use browser create --var <key=value>` | Override app config variables (repeatable) |\n| `qa-use browser list` | List active sessions |\n| `qa-use browser status` | Show current session details (app_url, recording_url, etc.) |\n| `qa-use browser close` | Close active session |\n\nSessions auto-persist in `~/.qa-use.json`. One active session = no `-s` flag needed.\n\n### Navigation\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser goto <url>` | Navigate to URL |\n| `qa-use browser back` | Go back |\n| `qa-use browser forward` | Go forward |\n| `qa-use browser reload` | Reload page |\n\n### Element Interaction\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser click <ref>` | Click element by ref |\n| `qa-use browser click --text \"Button\"` | Click by semantic description |\n| `qa-use browser fill <ref> \"value\"` | Fill input field |\n| `qa-use browser type <ref> \"text\"` | Type with delays (for autocomplete) |\n| `qa-use browser press <key>` | Press key (e.g., `Enter`, `Tab`) |\n| `qa-use browser check <ref>` | Check checkbox |\n| `qa-use browser uncheck <ref>` | Uncheck checkbox |\n| `qa-use browser select <ref> \"option\"` | Select dropdown option |\n| `qa-use browser hover <ref>` | Hover over element |\n| `qa-use browser scroll down 500` | Scroll by pixels |\n| `qa-use browser scroll-into-view <ref>` | Scroll element into view |\n| `qa-use browser drag <ref> --target <ref>` | Drag element to target |\n| `qa-use browser mfa-totp [ref] <secret>` | Generate TOTP code (optionally fill) |\n| `qa-use browser upload <ref> <file>...` | Upload file(s) to input (base64-encoded, works remote & tunnel) |\n\n### Inspection & Snapshot Diff\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser snapshot` | Get full ARIA tree with element refs (use only when diff output is insufficient) |\n| `qa-use browser url` | Get current URL |\n| `qa-use browser screenshot` | Save screenshot.png |\n| `qa-use browser screenshot file.png` | Save to custom path |\n| `qa-use browser screenshot --base64` | Output base64 to stdout |\n| `qa-use browser evaluate <expression>` | Execute JavaScript in browser context |\n\nThe snapshot-diff feature automatically displays DOM changes after each browser action:\n- **Added elements**: Shown with `+` prefix and green color \u2014 these refs are immediately usable\n- **Modified elements**: Shown with `~` prefix and yellow color, including attribute changes (`+attrs: checked`)\n- **Removed elements**: Shown with `-` prefix and red color \u2014 do NOT use these refs\n\n**Downloads:** When an action triggers a file download (e.g., clicking a download link), the response includes download info: filename, size, and a presigned URL. Use `qa-use browser downloads` to list all downloads or `--save <dir>` to save them locally.\n\nUse diff output to interact with newly appeared elements directly, without running a full `snapshot` first.\n\n### Test Operations\n\n| Command | Description |\n|---------|-------------|\n| `qa-use test run <name>` | Run test by name |\n| `qa-use test run --all` | Run all tests |\n| `qa-use test run <name> --tunnel` | Run with local browser tunnel |\n| `qa-use test run <name> --autofix` | Enable AI self-healing |\n| `qa-use test run <name> --update-local` | Persist AI fixes to file |\n| `qa-use test run <name> --download` | Download assets to `/tmp/qa-use/downloads/` |\n| `qa-use test run <name> --var key=value` | Override variable |\n| `qa-use test validate <name>` | Validate test syntax |\n| `qa-use test list` | List available tests |\n| `qa-use test info <name>` | Show test details (steps, tags, description) |\n| `qa-use test info --id <uuid>` | Show cloud test details by ID |\n| `qa-use test runs [name]` | List test run history |\n| `qa-use test runs --id <uuid>` | Filter runs by test ID |\n| `qa-use test runs --status failed` | Filter runs by status |\n| `qa-use test init` | Initialize test directory |\n| `qa-use test sync pull` | Pull tests from cloud |\n| `qa-use test sync push --all` | Push all local tests to cloud |\n| `qa-use test sync push --id <uuid>` | Push specific test |\n| `qa-use test sync push --force` | Push tests, overwriting conflicts |\n| `qa-use test diff <file>` | Compare local vs cloud test |\n| `qa-use test schema [path]` | View test definition schema |\n\n### API Operations (Dynamic OpenAPI)\n\n`qa-use api` dynamically discovers operations from `/api/v1/openapi.json` and caches metadata locally for offline fallback.\n\n| Command | Description |\n|---------|-------------|\n| `qa-use api ls` | List available `/api/v1/*` routes from OpenAPI |\n| `qa-use api ls --refresh` | Force refresh OpenAPI cache |\n| `qa-use api ls --offline` | Use cached OpenAPI metadata only |\n| `qa-use api /api/v1/tests` | Call endpoint (method inferred when possible) |\n| `qa-use api -X GET /api/v1/test-runs -f limit=5` | GET with query fields |\n| `qa-use api -X POST /api/v1/tests-actions/run --input body.json` | POST with JSON body file |\n| `qa-use api -X GET /api/v1/test-runs/<id>` | Fetch detail endpoint by ID |\n\n**No Plugin Shortcut** - Use CLI commands directly.\n\n### Logs & Debugging\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser logs console` | View console logs from session |\n| `qa-use browser logs console -s <id>` | View logs from specific/closed session |\n| `qa-use browser logs network` | View network request logs |\n| `qa-use browser logs network -s <id>` | View network logs from specific session |\n| `qa-use browser downloads` | List downloaded files from session |\n| `qa-use browser downloads --save <dir>` | Save downloaded files to local directory |\n| `qa-use browser downloads --json` | Output download info as JSON |\n\n### Test Generation\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser generate-test` | Generate test YAML from recorded session |\n| `qa-use browser generate-test -s <id>` | Generate from specific session |\n| `qa-use browser generate-test -n <name>` | Specify test name |\n| `qa-use browser generate-test -o <path>` | Specify output path |\n| `qa-use browser get-blocks` | Get recorded interaction blocks (JSON) |\n\n### Waiting\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser wait <ms>` | Fixed wait |\n| `qa-use browser wait-for-selector \".class\"` | Wait for selector |\n| `qa-use browser wait-for-load` | Wait for page load |\n\n### Variable Overrides\n\nUse `--var` to override app config variables at runtime. Common variables:\n\n| Variable | Description |\n|----------|-------------|\n| `base_url` | Base URL for the app (e.g., preview deployment URL) |\n| `login_url` | Login page URL |\n| `login_username` | Username/email for authentication |\n| `login_password` | Password for authentication |\n\nExample with ephemeral preview URL:\n```bash\nqa-use browser create --after-test-id <login-test-uuid> \\\n --var base_url=https://preview-123.example.com \\\n --var login_url=https://preview-123.example.com/auth/login\n```\n\n## Common Patterns\n\n### Pattern 1: Feature Verification\n\n**CLI Workflow:**\n```bash\n# 1. Search for existing test\nqa-use test list | grep \"login\"\n\n# 2. Run test with autofix\nqa-use test run login --autofix\n\n# 3. Debug failures\nqa-use browser logs console\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:verify \"login works with valid credentials\"\n```\n(Wraps the above CLI workflow with AI-powered test discovery and analysis)\n\n### Pattern 2: Record & Generate Test\n\n**CLI Workflow:**\n```bash\n# 1. Create session\nqa-use browser create --tunnel --no-headless\n\n# 2. Navigate and interact\nqa-use browser goto https://example.com\nqa-use browser snapshot\nqa-use browser click e1\nqa-use browser fill e5 \"test\"\n\n# 3. Generate test from blocks\nqa-use browser get-blocks\nqa-use browser generate-test -n \"my_test\"\n\n# 4. Run test\nqa-use test run my_test\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:record start my_test\n# ... perform interactions ...\n/qa-use:record stop\n```\n\n### Pattern 3: Authenticated Exploration\n\n**CLI Workflow:**\n```bash\n# Create session that runs login test first\nqa-use browser create --after-test-id <login-test-uuid>\n\n# Session now authenticated, explore\nqa-use browser goto /dashboard\nqa-use browser snapshot\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:explore /dashboard\n```\n(Automatically handles auth detection and session creation)\n\n### Pattern 4: Edit Existing Test\n\n**CLI Workflow:**\n```bash\n# 1. Open test file in editor\nvim qa-tests/login.yaml\n\n# 2. Validate syntax\nqa-use test validate login\n\n# 3. Run to verify\nqa-use test run login\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:record edit login\n```\n(AI-assisted editing with validation)\n\n### Pattern 5: Using Snapshot Diff to Avoid Unnecessary Snapshots\n\n**CLI Workflow:**\n```bash\n# Create session and navigate\nqa-use browser create --tunnel --no-headless\nqa-use browser goto https://evals.desplega.ai/checkboxes\n\n# goto shows diff \u2014 initial page load shows all elements:\n# Changes: 45 elements added\n# + [e18] checkbox \"I agree to the terms and conditions\"\n# + [e19] generic \"I agree to the terms and conditions\"\n\n# \u2705 Use ref from diff directly \u2014 no snapshot needed!\nqa-use browser click e18\n\n# Diff shows what changed:\n# Changes: 5 elements added, 1 element modified\n# + [e54] generic \"Thanks for agreeing!\"\n# + [e55] link \"Terms and Conditions\"\n# ~ [e18] checkbox \"I agree to the terms and conditions\"\n# +attrs: active, checked\n\n# \u2705 Can click e55 directly from diff output \u2014 no snapshot needed!\nqa-use browser click e55\n\n# \u274C Need to find an element NOT in the diff? Now run snapshot:\nqa-use browser snapshot\n```\n\n**Key principle:** Use diff output as your primary source of element refs after actions. Only fall back to `snapshot` when you need to find elements that weren't in the diff.\n\n**Benefits:**\n- Fewer API calls = faster automation\n- Diff refs are always fresh (just returned from the server)\n- Instantly see what changed (new elements, attribute changes, removals)\n\n**No Plugin Shortcut** - Automatic feature in all browser commands\n\n## CI/CD Integration\n\n### Running Tests in CI\n\n**Environment Variables:**\n```bash\nexport QA_USE_API_KEY=\"your-api-key\"\nexport QA_USE_REGION=\"us\" # Optional: \"us\" or \"auto\"\n```\n\n**Basic Test Execution:**\n```bash\n# Run all tests\nqa-use test run --all\n\n# Run specific tag\nqa-use test run --tag smoke\n\n# Exit codes: 0 = pass, 1 = fail\n```\n\n### GitHub Actions Example\n\n```yaml\nname: QA Tests\non: [push, pull_request]\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v3\n - uses: actions/setup-node@v3\n with:\n node-version: '20'\n - name: Install qa-use\n run: npm install -g @desplega.ai/qa-use\n - name: Run tests\n run: qa-use test run --all\n env:\n QA_USE_API_KEY: ${{ secrets.QA_USE_API_KEY }}\n```\n\n### Test Artifacts\n\n**Screenshots:**\n- Automatically saved on failure\n- Location: `/tmp/qa-use/downloads/` (local) or cloud (remote)\n\n**Logs:**\n- Console logs: `qa-use browser logs console -s <session-id>`\n- Network logs: `qa-use browser logs network -s <session-id>`\n\n## Advanced Topics\n\n### Localhost Testing (Tunnel Mode)\n\n**When to use tunnel mode:**\n\n```\nTesting localhost (http://localhost:3000)?\n \u251C\u2500 YES \u2192 Use --tunnel\n \u2502 \u2514\u2500 qa-use browser create --tunnel [--no-headless]\n \u2502 (Starts local Playwright, creates localtunnel, keeps running)\n \u2502\n \u2514\u2500 NO (Public URL) \u2192 Use remote browser (default)\n \u2514\u2500 qa-use browser create\n (Uses desplega.ai cloud browser via WebSocket)\n```\n\n**The `--tunnel` flag is a binary choice:**\n- **Local tunnel mode**: Playwright on your machine + localtunnel\n- **Remote mode**: WebSocket URL to cloud-hosted browser\n\n**For test execution:**\n```bash\n# Local app\nqa-use test run my_test --tunnel [--headful]\n\n# Public app\nqa-use test run my_test\n```\n\n**Plugin shortcuts handle tunnel detection automatically:**\n```\n/qa-use:explore http://localhost:3000\n/qa-use:record start local_test\n```\n\nSee [references/localhost-testing.md](references/localhost-testing.md) for troubleshooting.\n\n### Session Persistence\n\nSessions are stored in `~/.qa-use.json` and have:\n- **TTL**: 30 minutes (default)\n- **Auto-resolve**: One active session = no `-s` flag needed\n- **Cleanup**: Automatic on timeout or explicit `browser close`\n\n### Block Limitations\n\n**What's captured:**\n- goto, click, fill, type, check, uncheck, select, hover\n- scroll, scroll-into-view, drag, upload, press\n\n**What's NOT captured:**\n- Assertions (must be added manually)\n- Waits (inferred from timing, may need adjustment)\n- Complex interactions (multi-drag, hover sequences)\n\n**Manual editing:** Edit generated YAML to add assertions and refine selectors.\n\n### WebSocket Sessions\n\n**Sharing sessions across processes:**\n```bash\n# Process 1: Create session\nqa-use browser create --tunnel\n# Output: ws://localhost:12345/browser/abc123\n\n# Process 2: Connect to session\nqa-use browser goto https://example.com --ws-url ws://localhost:12345/browser/abc123\n```\n\n## Deep-Dive References\n\nAccess any reference at runtime via the CLI: `qa-use docs <topic>`\n\n| Topic | CLI Command | Description |\n|-------|-------------|-------------|\n| [browser-commands.md](references/browser-commands.md) | `qa-use docs browser-commands` | Complete browser CLI reference with all flags |\n| [test-format.md](references/test-format.md) | `qa-use docs test-format` | Full test YAML specification |\n| [localhost-testing.md](references/localhost-testing.md) | `qa-use docs localhost-testing` | Tunnel setup for local development |\n| [failure-debugging.md](references/failure-debugging.md) | `qa-use docs failure-debugging` | Failure classification and diagnostics |\n| [ci.md](references/ci.md) | `qa-use docs ci` | CI/CD integration patterns and examples |\n\nUse `qa-use docs --list` to discover all available topics and templates.\n\n## Templates\n\n| Template | Description |\n|----------|-------------|\n| [basic-test.yaml](templates/basic-test.yaml) | Simple navigation and assertion |\n| [auth-flow.yaml](templates/auth-flow.yaml) | Login flow with credentials |\n| [form-test.yaml](templates/form-test.yaml) | Form submission with validation |\n\n## Test Format Overview\n\n```yaml\nname: Login Test\ndescription: Validates login functionality with valid credentials\ntags:\n - smoke\n - auth\napp_config: <app-config-id>\nvariables:\n email: test@example.com\n password: secret123\ndepends_on: setup-test # Optional\nsteps:\n - action: goto\n url: /login\n - action: fill\n target: email input\n value: $email\n - action: click\n target: login button\n - action: to_be_visible\n target: dashboard\n```\n\nSee [references/test-format.md](references/test-format.md) for complete specification.\n\n## Common Mistakes\n\n| \u274C Wrong | \u2705 Correct |\n|---------|-----------|\n| `browser navigate <url>` | `browser goto <url>` |\n| `browser destroy` | `browser close` |\n| `browser close <session-id>` | `browser close` |\n| Guessing element refs | Use refs from diff output or `snapshot` |\n| Running `snapshot` after every action | Use diff output; only `snapshot` when needed |\n| Testing localhost without `--tunnel` | Use `--tunnel` flag |\n| `test sync --pull` | `test sync pull` (subcommand, not flag) |\n| `test sync --push` | `test sync push` (subcommand, not flag) |\n\n## Troubleshooting\n\nWhen stuck or encountering unexpected errors, use the built-in documentation:\n\n```bash\n# Check configuration state\nqa-use setup\n\n# Browse main documentation\nqa-use docs\n\n# List all available topics\nqa-use docs --list\n\n# Access specific topic\nqa-use docs <topic>\n```\n\n| Situation | Command |\n|-----------|---------|\n| Auth / API key errors | `qa-use setup` then `qa-use docs` |\n| Unknown browser command | `qa-use docs browser-commands` |\n| Test failures | `qa-use docs failure-debugging` |\n| Localhost / tunnel issues | `qa-use docs localhost-testing` |\n| Test YAML syntax | `qa-use docs test-format` |\n| CI/CD setup | `qa-use docs ci` |\n\n**Key rules:**\n- ALWAYS consult `qa-use docs` before improvising workarounds\n- NEVER fabricate API keys, tokens, URLs, or credentials\n- If `qa-use setup` shows no config, report it \u2014 don't guess\n\n## npx Alternative\n\nAll commands use `qa-use` assuming global install. For one-off use:\n```bash\nnpx @desplega.ai/qa-use browser <command>\n```\n";
6
+ export declare const MAIN_DOC = "---\nname: qa-use\ndescription: E2E testing and browser automation with qa-use CLI. Use when the user needs to run tests, verify features, automate browser interactions, or debug test failures.\nallowed-tools: Bash(qa-use *)\n---\n\n# qa-use\n\nE2E testing and browser automation for AI-driven development workflows.\n\n## Critical Insight: Plugin Commands as Shortcuts\n\n**For AI Harnesses (codex, opencode, etc.):**\n\nPlugin commands (slash commands like `/qa-use:verify`) are **convenience shortcuts** that wrap CLI workflows. Harnesses with only the Bash tool can access ALL functionality via CLI commands documented below.\n\n**Pattern throughout this document:**\n- **CLI Workflow**: Step-by-step CLI commands (works for ALL harnesses)\n- **Plugin Shortcut**: Optional slash command (convenience)\n\n## Setup & Configuration\n\nBefore using any qa-use commands, verify configuration is in place:\n\n```bash\n# Check current configuration (no-op if already configured)\nqa-use setup\n\n# Configure with API key (validates against server)\nqa-use setup --api-key <key>\n\n# View full configuration details\nqa-use info\n```\n\n**Environment Variables (alternative to config file):**\n\n| Variable | Description |\n|----------|-------------|\n| `QA_USE_API_KEY` | API key for authentication |\n| `QA_USE_REGION` | Region: `us` (default) or `auto` |\n| `QA_USE_API_URL` | Override API base URL |\n\n**Config file:** `.qa-use.json` in the project directory or `~/.qa-use.json` in the home directory. Precedence: env vars > project `.qa-use.json` > `~/.qa-use.json`.\n\n**If you encounter \"API key not configured\", 401, or auth errors:** Run `qa-use setup` to check config state. NEVER fabricate or guess API keys.\n\n## Core Workflow\n\n### 1. Browser Control & Session Lifecycle\n\n**CLI Workflow:**\n```bash\n# Create browser session\nqa-use browser create --viewport desktop\n\n# For localhost testing\nqa-use browser create --tunnel --no-headless\n\n# Navigate\nqa-use browser goto https://example.com\n\n# Snapshot to get element refs (ALWAYS do this before interacting)\nqa-use browser snapshot\n\n# Interact by ref\nqa-use browser click e3\nqa-use browser fill e5 \"text\"\n\n# Close\nqa-use browser close\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:explore https://example.com\n```\n(Wraps create + goto + snapshot with autonomous exploration)\n\n**Critical:** Always run `snapshot` before your **first** interaction on a page. Never guess element refs.\n\n**Snapshot Diff Feature (use it to avoid unnecessary snapshots):**\nAfter each action (goto, click, fill, etc.), the browser automatically shows DOM changes:\n- **Summary**: \"5 elements added, 1 element modified\"\n- **Added elements**: `+ [e54] generic \"Thanks for agreeing!\"` (green)\n- **Modified elements**: `~ [e18] checkbox \"I agree...\"` with `+attrs: checked, active` (yellow)\n- **Removed elements**: `- [e99] button \"Submit\"` (red)\n\n**When you can skip a full `snapshot`:** If the diff output from your last action already shows the element ref you need to interact with next, use it directly \u2014 no need for an intermediate `snapshot`. For example, if clicking a button shows `+ [e54] button \"Submit\"` in the diff, you can `click e54` immediately.\n\n**When you still need a full `snapshot`:** Run `snapshot` when you need to find elements that weren't in the diff (e.g., pre-existing elements you haven't interacted with yet), or when the diff was truncated (shows \"... and N more changes\").\n\n### 2. Understanding Blocks\n\n**What are blocks?**\n\nBlocks are atomic recorded interactions from a browser session. They are:\n- Automatically captured during any browser interaction (click, fill, goto, scroll, etc.)\n- Stored server-side with the session\n- Retrieved via `qa-use browser get-blocks`\n- The foundation for test generation\n\n**Why blocks matter:**\n- **Record-once, replay-many**: Interactive recording becomes automated test\n- **AI-friendly**: Agents can analyze blocks to understand user intent\n- **Version control**: Blocks stored with session enable test iteration\n- **Bridge CLI \u2192 Tests**: Natural workflow from exploration to automation\n\n**How blocks work:**\n\n```bash\n# 1. Create session and interact\nqa-use browser create --tunnel --no-headless\nqa-use browser goto https://example.com\nqa-use browser snapshot # Returns: [ref=e1] button\nqa-use browser click e1 # Records as block\nqa-use browser fill e5 \"text\" # Records as block\n\n# 2. Retrieve blocks (JSON array)\nqa-use browser get-blocks\n# Returns:\n# [\n# {\"type\": \"goto\", \"url\": \"...\", \"timestamp\": \"...\"},\n# {\"type\": \"click\", \"ref\": \"e1\", \"timestamp\": \"...\"},\n# {\"type\": \"fill\", \"ref\": \"e5\", \"value\": \"text\", \"timestamp\": \"...\"}\n# ]\n\n# 3. Generate test YAML from blocks\nqa-use browser generate-test -n \"my_test\" -o qa-tests/my_test.yaml\n\n# 4. Run generated test\nqa-use test run my_test\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:record start my_test\n# ... perform interactions ...\n/qa-use:record stop\n```\n(Wraps the interactive workflow with AI-powered test generation)\n\n### 3. Test Management\n\n**CLI Workflow:**\n```bash\n# Run test by name\nqa-use test run login\n\n# Run with autofix (AI self-healing)\nqa-use test run login --autofix\n\n# Validate syntax\nqa-use test validate login\n\n# Show test details\nqa-use test info login\n\n# List test runs\nqa-use test runs --status failed\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:test-run login --autofix\n```\n(Convenience shortcut for common test execution)\n\n### 4. Test Sync Lifecycle\n\n**CLI Workflow:**\n```bash\n# Pull tests from cloud\nqa-use test sync pull\n\n# Push all local tests to cloud\nqa-use test sync push --all\n\n# Push specific test\nqa-use test sync push --id <uuid>\n\n# Force push (overwrite conflicts)\nqa-use test sync push --force\n\n# Compare local vs cloud\nqa-use test diff login.yaml\n```\n\n**No Plugin Shortcut** - Use CLI commands directly\n\n## Essential Commands\n\n### Browser Session Management\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser create` | Create remote browser session |\n| `qa-use browser create <url>` | Create session and navigate to URL |\n| `qa-use browser create --tunnel` | Create local browser with API tunnel |\n| `qa-use browser create --no-headless` | Show browser window (tunnel mode only) |\n| `qa-use browser create --viewport <size>` | Set viewport: `desktop`, `tablet`, `mobile` |\n| `qa-use browser create --ws-url <url>` | Connect to existing WebSocket browser |\n| `qa-use browser create --after-test-id <uuid>` | Run a test first, then become interactive |\n| `qa-use browser create --var <key=value>` | Override app config variables (repeatable) |\n| `qa-use browser list` | List active sessions |\n| `qa-use browser status` | Show current session details (app_url, recording_url, etc.) |\n| `qa-use browser close` | Close active session |\n\nSessions auto-persist in `~/.qa-use.json`. One active session = no `-s` flag needed.\n\n### Navigation\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser goto <url>` | Navigate to URL |\n| `qa-use browser back` | Go back |\n| `qa-use browser forward` | Go forward |\n| `qa-use browser reload` | Reload page |\n\n### Element Interaction\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser click <ref>` | Click element by ref |\n| `qa-use browser click --text \"Button\"` | Click by semantic description |\n| `qa-use browser fill <ref> \"value\"` | Fill input field |\n| `qa-use browser type <ref> \"text\"` | Type with delays (for autocomplete) |\n| `qa-use browser press <key>` | Press key (e.g., `Enter`, `Tab`) |\n| `qa-use browser check <ref>` | Check checkbox |\n| `qa-use browser uncheck <ref>` | Uncheck checkbox |\n| `qa-use browser select <ref> \"option\"` | Select dropdown option |\n| `qa-use browser hover <ref>` | Hover over element |\n| `qa-use browser scroll down 500` | Scroll by pixels |\n| `qa-use browser scroll-into-view <ref>` | Scroll element into view |\n| `qa-use browser drag <ref> --target <ref>` | Drag element to target |\n| `qa-use browser mfa-totp [ref] <secret>` | Generate TOTP code (optionally fill) |\n| `qa-use browser upload <ref> <file>...` | Upload file(s) to input (base64-encoded, works remote & tunnel) |\n\n### Inspection & Snapshot Diff\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser snapshot` | Get full ARIA tree with element refs (use only when diff output is insufficient) |\n| `qa-use browser url` | Get current URL |\n| `qa-use browser screenshot` | Save screenshot.png |\n| `qa-use browser screenshot file.png` | Save to custom path |\n| `qa-use browser screenshot --base64` | Output base64 to stdout |\n| `qa-use browser evaluate <expression>` | Execute JavaScript in browser context |\n\nThe snapshot-diff feature automatically displays DOM changes after each browser action:\n- **Added elements**: Shown with `+` prefix and green color \u2014 these refs are immediately usable\n- **Modified elements**: Shown with `~` prefix and yellow color, including attribute changes (`+attrs: checked`)\n- **Removed elements**: Shown with `-` prefix and red color \u2014 do NOT use these refs\n\n**Downloads:** When an action triggers a file download (e.g., clicking a download link), the response includes download info: filename, size, and a presigned URL. Use `qa-use browser downloads` to list all downloads or `--save <dir>` to save them locally.\n\nUse diff output to interact with newly appeared elements directly, without running a full `snapshot` first.\n\n### Test Operations\n\n| Command | Description |\n|---------|-------------|\n| `qa-use test run <name>` | Run test by name |\n| `qa-use test run --all` | Run all tests |\n| `qa-use test run <name> --tunnel` | Run with local browser tunnel |\n| `qa-use test run <name> --autofix` | Enable AI self-healing |\n| `qa-use test run <name> --update-local` | Persist AI fixes to file |\n| `qa-use test run <name> --download` | Download assets to `/tmp/qa-use/downloads/` |\n| `qa-use test run <name> --var key=value` | Override variable |\n| `qa-use test validate <name>` | Validate test syntax |\n| `qa-use test list` | List available tests |\n| `qa-use test info <name>` | Show test details (steps, tags, description) |\n| `qa-use test info --id <uuid>` | Show cloud test details by ID |\n| `qa-use test runs [name]` | List test run history |\n| `qa-use test runs --id <uuid>` | Filter runs by test ID |\n| `qa-use test runs --status failed` | Filter runs by status |\n| `qa-use test init` | Initialize test directory |\n| `qa-use test sync pull` | Pull tests from cloud |\n| `qa-use test sync push --all` | Push all local tests to cloud |\n| `qa-use test sync push --id <uuid>` | Push specific test |\n| `qa-use test sync push --force` | Push tests, overwriting conflicts |\n| `qa-use test diff <file>` | Compare local vs cloud test |\n| `qa-use test schema [path]` | View test definition schema |\n\n### API Operations (Dynamic OpenAPI)\n\n`qa-use api` dynamically discovers operations from `/api/v1/openapi.json` and caches metadata locally for offline fallback.\n\n| Command | Description |\n|---------|-------------|\n| `qa-use api ls` | List available `/api/v1/*` routes from OpenAPI |\n| `qa-use api ls --refresh` | Force refresh OpenAPI cache |\n| `qa-use api ls --offline` | Use cached OpenAPI metadata only |\n| `qa-use api /api/v1/tests` | Call endpoint (method inferred when possible) |\n| `qa-use api -X GET /api/v1/test-runs -f limit=5` | GET with query fields |\n| `qa-use api -X POST /api/v1/tests-actions/run --input body.json` | POST with JSON body file |\n| `qa-use api -X GET /api/v1/test-runs/<id>` | Fetch detail endpoint by ID |\n\n**No Plugin Shortcut** - Use CLI commands directly.\n\n### Logs & Debugging\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser logs console` | View console logs from session |\n| `qa-use browser logs console -s <id>` | View logs from specific/closed session |\n| `qa-use browser logs network` | View network request logs |\n| `qa-use browser logs network -s <id>` | View network logs from specific session |\n| `qa-use browser downloads` | List downloaded files from session |\n| `qa-use browser downloads --save <dir>` | Save downloaded files to local directory |\n| `qa-use browser downloads --json` | Output download info as JSON |\n\n### Test Generation\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser generate-test` | Generate test YAML from recorded session |\n| `qa-use browser generate-test -s <id>` | Generate from specific session |\n| `qa-use browser generate-test -n <name>` | Specify test name |\n| `qa-use browser generate-test -o <path>` | Specify output path |\n| `qa-use browser get-blocks` | Get recorded interaction blocks (JSON) |\n\n### Waiting\n\n| Command | Description |\n|---------|-------------|\n| `qa-use browser wait <ms>` | Fixed wait |\n| `qa-use browser wait-for-selector \".class\"` | Wait for selector |\n| `qa-use browser wait-for-load` | Wait for page load |\n\n### Variable Overrides\n\nUse `--var` to override app config variables at runtime. Common variables:\n\n| Variable | Description |\n|----------|-------------|\n| `base_url` | Base URL for the app (e.g., preview deployment URL) |\n| `login_url` | Login page URL |\n| `login_username` | Username/email for authentication |\n| `login_password` | Password for authentication |\n\nExample with ephemeral preview URL:\n```bash\nqa-use browser create --after-test-id <login-test-uuid> \\\n --var base_url=https://preview-123.example.com \\\n --var login_url=https://preview-123.example.com/auth/login\n```\n\n## Common Patterns\n\n### Pattern 1: Feature Verification\n\n**CLI Workflow:**\n```bash\n# 1. Search for existing test\nqa-use test list | grep \"login\"\n\n# 2. Run test with autofix\nqa-use test run login --autofix\n\n# 3. Debug failures\nqa-use browser logs console\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:verify \"login works with valid credentials\"\n```\n(Wraps the above CLI workflow with AI-powered test discovery and analysis)\n\n### Pattern 2: Record & Generate Test\n\n**CLI Workflow:**\n```bash\n# 1. Create session\nqa-use browser create --tunnel --no-headless\n\n# 2. Navigate and interact\nqa-use browser goto https://example.com\nqa-use browser snapshot\nqa-use browser click e1\nqa-use browser fill e5 \"test\"\n\n# 3. Generate test from blocks\nqa-use browser get-blocks\nqa-use browser generate-test -n \"my_test\"\n\n# 4. Run test\nqa-use test run my_test\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:record start my_test\n# ... perform interactions ...\n/qa-use:record stop\n```\n\n### Pattern 3: Authenticated Exploration\n\n**CLI Workflow:**\n```bash\n# Create session that runs login test first\nqa-use browser create --after-test-id <login-test-uuid>\n\n# Session now authenticated, explore\nqa-use browser goto /dashboard\nqa-use browser snapshot\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:explore /dashboard\n```\n(Automatically handles auth detection and session creation)\n\n### Pattern 4: Edit Existing Test\n\n**CLI Workflow:**\n```bash\n# 1. Open test file in editor\nvim qa-tests/login.yaml\n\n# 2. Validate syntax\nqa-use test validate login\n\n# 3. Run to verify\nqa-use test run login\n```\n\n**Plugin Shortcut:**\n```\n/qa-use:record edit login\n```\n(AI-assisted editing with validation)\n\n### Pattern 5: Using Snapshot Diff to Avoid Unnecessary Snapshots\n\n**CLI Workflow:**\n```bash\n# Create session and navigate\nqa-use browser create --tunnel --no-headless\nqa-use browser goto https://evals.desplega.ai/checkboxes\n\n# goto shows diff \u2014 initial page load shows all elements:\n# Changes: 45 elements added\n# + [e18] checkbox \"I agree to the terms and conditions\"\n# + [e19] generic \"I agree to the terms and conditions\"\n\n# \u2705 Use ref from diff directly \u2014 no snapshot needed!\nqa-use browser click e18\n\n# Diff shows what changed:\n# Changes: 5 elements added, 1 element modified\n# + [e54] generic \"Thanks for agreeing!\"\n# + [e55] link \"Terms and Conditions\"\n# ~ [e18] checkbox \"I agree to the terms and conditions\"\n# +attrs: active, checked\n\n# \u2705 Can click e55 directly from diff output \u2014 no snapshot needed!\nqa-use browser click e55\n\n# \u274C Need to find an element NOT in the diff? Now run snapshot:\nqa-use browser snapshot\n```\n\n**Key principle:** Use diff output as your primary source of element refs after actions. Only fall back to `snapshot` when you need to find elements that weren't in the diff.\n\n**Benefits:**\n- Fewer API calls = faster automation\n- Diff refs are always fresh (just returned from the server)\n- Instantly see what changed (new elements, attribute changes, removals)\n\n**No Plugin Shortcut** - Automatic feature in all browser commands\n\n## CI/CD Integration\n\n### Running Tests in CI\n\n**Environment Variables:**\n```bash\nexport QA_USE_API_KEY=\"your-api-key\"\nexport QA_USE_REGION=\"us\" # Optional: \"us\" or \"auto\"\n```\n\n**Basic Test Execution:**\n```bash\n# Run all tests\nqa-use test run --all\n\n# Run specific tag\nqa-use test run --tag smoke\n\n# Exit codes: 0 = pass, 1 = fail\n```\n\n### GitHub Actions Example\n\n```yaml\nname: QA Tests\non: [push, pull_request]\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v3\n - uses: actions/setup-node@v3\n with:\n node-version: '20'\n - name: Install qa-use\n run: npm install -g @desplega.ai/qa-use\n - name: Run tests\n run: qa-use test run --all\n env:\n QA_USE_API_KEY: ${{ secrets.QA_USE_API_KEY }}\n```\n\n### Test Artifacts\n\n**Screenshots:**\n- Automatically saved on failure\n- Location: `/tmp/qa-use/downloads/` (local) or cloud (remote)\n\n**Logs:**\n- Console logs: `qa-use browser logs console -s <session-id>`\n- Network logs: `qa-use browser logs network -s <session-id>`\n\n## Advanced Topics\n\n### Localhost Testing (Tunnel Mode)\n\n**When to use tunnel mode:**\n\n```\nTesting localhost (http://localhost:3000)?\n \u251C\u2500 YES \u2192 Use --tunnel\n \u2502 \u2514\u2500 qa-use browser create --tunnel [--no-headless]\n \u2502 (Starts local Playwright, creates localtunnel, keeps running)\n \u2502\n \u2514\u2500 NO (Public URL) \u2192 Use remote browser (default)\n \u2514\u2500 qa-use browser create\n (Uses desplega.ai cloud browser via WebSocket)\n```\n\n**The `--tunnel` flag is a binary choice:**\n- **Local tunnel mode**: Playwright on your machine + localtunnel\n- **Remote mode**: WebSocket URL to cloud-hosted browser\n\n**For test execution:**\n```bash\n# Local app\nqa-use test run my_test --tunnel [--headful]\n\n# Public app\nqa-use test run my_test\n```\n\n**Plugin shortcuts handle tunnel detection automatically:**\n```\n/qa-use:explore http://localhost:3000\n/qa-use:record start local_test\n```\n\nSee [references/localhost-testing.md](references/localhost-testing.md) for troubleshooting.\n\n### Session Persistence\n\nSessions are stored in `~/.qa-use.json` and have:\n- **TTL**: 30 minutes (default)\n- **Auto-resolve**: One active session = no `-s` flag needed\n- **Cleanup**: Automatic on timeout or explicit `browser close`\n\n### Block Limitations\n\n**What's captured:**\n- goto, click, fill, type, check, uncheck, select, hover\n- scroll, scroll-into-view, drag, upload, press\n\n**What's NOT captured:**\n- Assertions (must be added manually)\n- Waits (inferred from timing, may need adjustment)\n- Complex interactions (multi-drag, hover sequences)\n\n**Manual editing:** Edit generated YAML to add assertions and refine selectors.\n\n### WebSocket Sessions\n\n**Sharing sessions across processes:**\n```bash\n# Process 1: Create session\nqa-use browser create --tunnel\n# Output: ws://localhost:12345/browser/abc123\n\n# Process 2: Connect to session\nqa-use browser goto https://example.com --ws-url ws://localhost:12345/browser/abc123\n```\n\n## Deep-Dive References\n\nAccess any reference at runtime via the CLI: `qa-use docs <topic>`\n\n| Topic | CLI Command | Description |\n|-------|-------------|-------------|\n| [browser-commands.md](references/browser-commands.md) | `qa-use docs browser-commands` | Complete browser CLI reference with all flags |\n| [test-format.md](references/test-format.md) | `qa-use docs test-format` | Full test YAML specification |\n| [localhost-testing.md](references/localhost-testing.md) | `qa-use docs localhost-testing` | Tunnel setup for local development |\n| [failure-debugging.md](references/failure-debugging.md) | `qa-use docs failure-debugging` | Failure classification and diagnostics |\n| [ci.md](references/ci.md) | `qa-use docs ci` | CI/CD integration patterns and examples |\n\nUse `qa-use docs --list` to discover all available topics and templates.\n\n## Templates\n\n| Template | Description |\n|----------|-------------|\n| [basic-test.yaml](templates/basic-test.yaml) | Simple navigation and assertion |\n| [auth-flow.yaml](templates/auth-flow.yaml) | Login flow with credentials |\n| [form-test.yaml](templates/form-test.yaml) | Form submission with validation |\n\n## Test Format Overview\n\n```yaml\nname: Login Test\ndescription: Validates login functionality with valid credentials\ntags:\n - smoke\n - auth\napp_config: <app-config-id>\nvariables:\n email: test@example.com\n password: secret123\ndepends_on: setup-test # Optional\nsteps:\n - action: goto\n url: /login\n - action: fill\n target: email input\n value: $email\n - action: click\n target: login button\n - action: to_be_visible\n target: dashboard\n```\n\nSee [references/test-format.md](references/test-format.md) for complete specification.\n\n## Common Mistakes\n\n| \u274C Wrong | \u2705 Correct |\n|---------|-----------|\n| `browser navigate <url>` | `browser goto <url>` |\n| `browser destroy` | `browser close` |\n| `browser close <session-id>` | `browser close` |\n| Guessing element refs | Use refs from diff output or `snapshot` |\n| Running `snapshot` after every action | Use diff output; only `snapshot` when needed |\n| Testing localhost without `--tunnel` | Use `--tunnel` flag |\n| `test sync --pull` | `test sync pull` (subcommand, not flag) |\n| `test sync --push` | `test sync push` (subcommand, not flag) |\n\n## Troubleshooting\n\nWhen stuck or encountering unexpected errors, use the built-in documentation:\n\n```bash\n# Check configuration state\nqa-use setup\n\n# Browse main documentation\nqa-use docs\n\n# List all available topics\nqa-use docs --list\n\n# Access specific topic\nqa-use docs <topic>\n```\n\n| Situation | Command |\n|-----------|---------|\n| Auth / API key errors | `qa-use setup` then `qa-use docs` |\n| Unknown browser command | `qa-use docs browser-commands` |\n| Test failures | `qa-use docs failure-debugging` |\n| Localhost / tunnel issues | `qa-use docs localhost-testing` |\n| Test YAML syntax | `qa-use docs test-format` |\n| CI/CD setup | `qa-use docs ci` |\n\n**Key rules:**\n- ALWAYS consult `qa-use docs` before improvising workarounds\n- NEVER fabricate API keys, tokens, URLs, or credentials\n- If `qa-use setup` shows no config, report it \u2014 don't guess\n\n## npx Alternative\n\nAll commands use `qa-use` assuming global install. For one-off use:\n```bash\nnpx @desplega.ai/qa-use browser <command>\n```\n";
7
7
  export declare const REFERENCE_DOCS: Record<string, {
8
8
  title: string;
9
9
  content: string;
@@ -1 +1 @@
1
- {"version":3,"file":"docs-content.d.ts","sourceRoot":"","sources":["../../../../src/cli/generated/docs-content.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,QAAQ,i5tBA0rBpB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAuoD7E,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAiIxE,CAAC"}
1
+ {"version":3,"file":"docs-content.d.ts","sourceRoot":"","sources":["../../../../src/cli/generated/docs-content.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,QAAQ,s6tBA0rBpB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAuoD7E,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAiIxE,CAAC"}
@@ -46,7 +46,7 @@ qa-use info
46
46
  | \`QA_USE_REGION\` | Region: \`us\` (default) or \`auto\` |
47
47
  | \`QA_USE_API_URL\` | Override API base URL |
48
48
 
49
- **Config file:** \`.qa-use-tests.json\` in the project directory or \`~/.qa-use.json\` in the home directory. Environment variables take precedence.
49
+ **Config file:** \`.qa-use.json\` in the project directory or \`~/.qa-use.json\` in the home directory. Precedence: env vars > project \`.qa-use.json\` > \`~/.qa-use.json\`.
50
50
 
51
51
  **If you encounter "API key not configured", 401, or auth errors:** Run \`qa-use setup\` to check config state. NEVER fabricate or guess API keys.
52
52
 
@@ -1702,7 +1702,7 @@ curl https://your-app.com/health
1702
1702
  qa-use browser logs network -s <session-id>
1703
1703
 
1704
1704
  # 3. Verify credentials haven't expired
1705
- # Check .qa-use-tests.json or environment variables
1705
+ # Check .qa-use.json or environment variables
1706
1706
  \`\`\`
1707
1707
 
1708
1708
  ### Suggested Actions
@@ -2022,7 +2022,7 @@ steps:
2022
2022
  | Field | Description |
2023
2023
  |-------|-------------|
2024
2024
  | \`name\` | Human-readable test name |
2025
- | \`app_config\` | App configuration ID from desplega.ai (or use default from \`.qa-use-tests.json\`) |
2025
+ | \`app_config\` | App configuration ID from desplega.ai (or use default from \`.qa-use.json\`) |
2026
2026
  | \`steps\` | Array of test steps |
2027
2027
 
2028
2028
  ## Optional Fields
@@ -2360,7 +2360,7 @@ qa-tests/
2360
2360
  └── seed-data.yaml
2361
2361
  \`\`\`
2362
2362
 
2363
- Configure the test directory in \`.qa-use-tests.json\`:
2363
+ Configure the test directory in \`.qa-use.json\`:
2364
2364
 
2365
2365
  \`\`\`json
2366
2366
  {
@@ -2432,7 +2432,7 @@ name: Basic Test
2432
2432
  description: Navigate to a page and verify an element is visible
2433
2433
 
2434
2434
  # Replace with your app config ID from desplega.ai
2435
- # Or set default_app_config_id in .qa-use-tests.json
2435
+ # Or set default_app_config_id in .qa-use.json
2436
2436
  app_config: $APP_CONFIG_ID
2437
2437
 
2438
2438
  steps:
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Configuration file management for .qa-use-tests.json
2
+ * Configuration file management for .qa-use.json
3
3
  */
4
4
  export interface CliConfig {
5
5
  env?: Record<string, string>;
@@ -15,20 +15,22 @@ export interface CliConfig {
15
15
  };
16
16
  }
17
17
  /**
18
- * Search for config file in current directory and home directory
18
+ * Search for config file in current directory and home directory.
19
+ * Checks .qa-use.json first, falls back to .qa-use-tests.json (deprecated).
19
20
  */
20
21
  export declare function findConfigFile(): Promise<string | null>;
21
22
  /**
22
- * Load CLI configuration from .qa-use-tests.json
23
+ * Load CLI configuration from .qa-use.json
23
24
  *
24
25
  * Priority order (highest to lowest):
25
- * 1. Project config file (.qa-use-tests.json in cwd or home)
26
- * 2. Environment variables (QA_USE_API_KEY, QA_USE_API_URL, etc.)
27
- * 3. Built-in defaults
26
+ * 1. Environment variables (QA_USE_API_KEY, QA_USE_API_URL, etc.)
27
+ * 2. Project config file (.qa-use.json in cwd)
28
+ * 3. User config file (~/.qa-use.json in home)
29
+ * 4. Built-in defaults
28
30
  */
29
31
  export declare function loadConfig(): Promise<CliConfig>;
30
32
  /**
31
- * Save configuration to .qa-use-tests.json in current directory
33
+ * Save configuration to .qa-use.json in current directory
32
34
  */
33
35
  export declare function saveConfig(config: CliConfig): Promise<void>;
34
36
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAID;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsB7D;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAgDrD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAErD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAqCD;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAU7D;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CA+CrD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAErD"}
@@ -1,42 +1,61 @@
1
1
  /**
2
- * Configuration file management for .qa-use-tests.json
2
+ * Configuration file management for .qa-use.json
3
3
  */
4
4
  import * as fs from 'node:fs/promises';
5
5
  import { homedir } from 'node:os';
6
6
  import * as path from 'node:path';
7
- const CONFIG_FILENAME = '.qa-use-tests.json';
7
+ const CONFIG_FILENAME = '.qa-use.json';
8
+ const LEGACY_CONFIG_FILENAME = '.qa-use-tests.json';
9
+ const legacyWarningShown = new Set();
8
10
  /**
9
- * Search for config file in current directory and home directory
11
+ * Try to access a config file, checking the primary name first then the legacy name.
12
+ * Returns the resolved path or null. Logs a deprecation warning (once per dir) for legacy files.
10
13
  */
11
- export async function findConfigFile() {
12
- // Check current directory
13
- const cwd = process.cwd();
14
- const localConfig = path.join(cwd, CONFIG_FILENAME);
14
+ async function resolveConfigInDir(dir) {
15
+ const primary = path.join(dir, CONFIG_FILENAME);
15
16
  try {
16
- await fs.access(localConfig);
17
- return localConfig;
17
+ await fs.access(primary);
18
+ return primary;
18
19
  }
19
20
  catch {
20
- // Not in current directory
21
+ // Primary not found, try legacy
21
22
  }
22
- // Check home directory
23
- const homeConfig = path.join(homedir(), CONFIG_FILENAME);
23
+ const legacy = path.join(dir, LEGACY_CONFIG_FILENAME);
24
24
  try {
25
- await fs.access(homeConfig);
26
- return homeConfig;
25
+ await fs.access(legacy);
26
+ if (!legacyWarningShown.has(dir)) {
27
+ legacyWarningShown.add(dir);
28
+ console.error(`Warning: ${legacy} is deprecated. Rename to ${CONFIG_FILENAME} — legacy support will be removed in a future version.`);
29
+ }
30
+ return legacy;
27
31
  }
28
32
  catch {
29
- // Not in home directory
33
+ // Neither found
30
34
  }
31
35
  return null;
32
36
  }
33
37
  /**
34
- * Load CLI configuration from .qa-use-tests.json
38
+ * Search for config file in current directory and home directory.
39
+ * Checks .qa-use.json first, falls back to .qa-use-tests.json (deprecated).
40
+ */
41
+ export async function findConfigFile() {
42
+ const cwd = process.cwd();
43
+ const localConfig = await resolveConfigInDir(cwd);
44
+ if (localConfig)
45
+ return localConfig;
46
+ const homeConfig = await resolveConfigInDir(homedir());
47
+ if (homeConfig)
48
+ return homeConfig;
49
+ return null;
50
+ }
51
+ /**
52
+ * Load CLI configuration from .qa-use.json
35
53
  *
36
54
  * Priority order (highest to lowest):
37
- * 1. Project config file (.qa-use-tests.json in cwd or home)
38
- * 2. Environment variables (QA_USE_API_KEY, QA_USE_API_URL, etc.)
39
- * 3. Built-in defaults
55
+ * 1. Environment variables (QA_USE_API_KEY, QA_USE_API_URL, etc.)
56
+ * 2. Project config file (.qa-use.json in cwd)
57
+ * 3. User config file (~/.qa-use.json in home)
58
+ * 4. Built-in defaults
40
59
  */
41
60
  export async function loadConfig() {
42
61
  const configPath = await findConfigFile();
@@ -60,29 +79,28 @@ export async function loadConfig() {
60
79
  console.error(error);
61
80
  }
62
81
  }
63
- // Apply env block from config (after file merge, before env fallback)
82
+ // Apply env block from config (only if shell env doesn't already set them)
64
83
  if (config.env) {
65
84
  for (const [key, value] of Object.entries(config.env)) {
66
85
  if (!process.env[key]) {
67
- // Don't override existing shell env vars
68
86
  process.env[key] = value;
69
87
  }
70
88
  }
71
89
  }
72
- // Environment variables are fallbacks only used when config file doesn't set the value
73
- if (!config.api_key && process.env.QA_USE_API_KEY) {
90
+ // Environment variables take precedence over config file values
91
+ if (process.env.QA_USE_API_KEY) {
74
92
  config.api_key = process.env.QA_USE_API_KEY;
75
93
  }
76
- if (!config.api_url && process.env.QA_USE_API_URL) {
94
+ if (process.env.QA_USE_API_URL) {
77
95
  config.api_url = process.env.QA_USE_API_URL;
78
96
  }
79
- if (!config.default_app_config_id && process.env.QA_USE_DEFAULT_APP_CONFIG_ID) {
97
+ if (process.env.QA_USE_DEFAULT_APP_CONFIG_ID) {
80
98
  config.default_app_config_id = process.env.QA_USE_DEFAULT_APP_CONFIG_ID;
81
99
  }
82
100
  return config;
83
101
  }
84
102
  /**
85
- * Save configuration to .qa-use-tests.json in current directory
103
+ * Save configuration to .qa-use.json in current directory
86
104
  */
87
105
  export async function saveConfig(config) {
88
106
  const configPath = path.join(process.cwd(), CONFIG_FILENAME);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"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"}
package/lib/env/index.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Priority order:
5
5
  * 1. Environment variables (process.env)
6
- * 2. Config file (~/.qa-use.json) with structure: { "env": { "VAR_NAME": "value" } }
6
+ * 2. Config file (~/.qa-use.json) top-level fields (api_key, api_url, etc.)
7
+ * 3. Config file (~/.qa-use.json) env block ({ "env": { "VAR_NAME": "value" } })
7
8
  */
8
9
 
9
10
  import { existsSync, readFileSync } from 'node:fs';
@@ -11,9 +12,24 @@ import { homedir } from 'node:os';
11
12
  import { join } from 'node:path';
12
13
 
13
14
  interface QaUseConfig {
15
+ api_key?: string;
16
+ api_url?: string;
17
+ app_url?: string;
18
+ region?: string;
14
19
  env?: Record<string, string>;
15
20
  }
16
21
 
22
+ /**
23
+ * Mapping from env var names to top-level config field names.
24
+ * Allows getEnvWithSource to check direct fields before the env block.
25
+ */
26
+ const ENV_TO_FIELD: Record<string, keyof QaUseConfig> = {
27
+ QA_USE_API_KEY: 'api_key',
28
+ QA_USE_API_URL: 'api_url',
29
+ QA_USE_APP_URL: 'app_url',
30
+ QA_USE_REGION: 'region',
31
+ };
32
+
17
33
  let cachedConfig: QaUseConfig | null = null;
18
34
  let configLoadAttempted = false;
19
35
 
@@ -60,7 +76,9 @@ export interface EnvResult {
60
76
 
61
77
  /**
62
78
  * Get an environment variable value with fallback to config file,
63
- * along with the source of the value
79
+ * along with the source of the value.
80
+ *
81
+ * Priority: process.env → config top-level field → config env block
64
82
  *
65
83
  * @param name - The environment variable name (e.g., 'QA_USE_API_KEY')
66
84
  * @returns Object containing the value and its source
@@ -72,10 +90,20 @@ export function getEnvWithSource(name: string): EnvResult {
72
90
  return { value: envValue, source: 'env' };
73
91
  }
74
92
 
75
- // Fallback to config file
93
+ // Fallback to config file — check top-level field first, then env block
76
94
  const config = loadConfig();
77
- if (config?.env?.[name]) {
78
- return { value: config.env[name], source: 'config' };
95
+ if (config) {
96
+ const fieldName = ENV_TO_FIELD[name];
97
+ if (fieldName) {
98
+ const fieldValue = config[fieldName];
99
+ if (typeof fieldValue === 'string' && fieldValue) {
100
+ return { value: fieldValue, source: 'config' };
101
+ }
102
+ }
103
+
104
+ if (config.env?.[name]) {
105
+ return { value: config.env[name], source: 'config' };
106
+ }
79
107
  }
80
108
 
81
109
  return { value: undefined, source: 'none' };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desplega.ai/qa-use",
3
- "version": "2.10.1",
3
+ "version": "2.11.0",
4
4
  "packageManager": "bun@^1.3.4",
5
5
  "description": "QA automation tool for browser testing with MCP server support",
6
6
  "type": "module",
@@ -36,6 +36,7 @@
36
36
  "test": "bun test --preload ./test-setup.ts",
37
37
  "test:unit": "node scripts/test-unit.js",
38
38
  "test:integration": "node scripts/test-integration.js",
39
+ "test:e2e": "tsx scripts/e2e.ts",
39
40
  "test:coverage": "bun test --coverage --preload ./test-setup.ts",
40
41
  "generate:docs": "tsx scripts/generate-docs.ts",
41
42
  "generate:readme": "node scripts/generate-readme-tools.js",