@desplega.ai/qa-use 2.0.1

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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1003 -0
  3. package/bin/qa-use.js +7 -0
  4. package/dist/lib/api/index.d.ts +296 -0
  5. package/dist/lib/api/index.d.ts.map +1 -0
  6. package/dist/lib/api/index.js +564 -0
  7. package/dist/lib/api/index.js.map +1 -0
  8. package/dist/lib/api/sse.d.ts +33 -0
  9. package/dist/lib/api/sse.d.ts.map +1 -0
  10. package/dist/lib/api/sse.js +97 -0
  11. package/dist/lib/api/sse.js.map +1 -0
  12. package/dist/lib/browser/index.d.ts +28 -0
  13. package/dist/lib/browser/index.d.ts.map +1 -0
  14. package/dist/lib/browser/index.js +145 -0
  15. package/dist/lib/browser/index.js.map +1 -0
  16. package/dist/lib/env/index.d.ts +41 -0
  17. package/dist/lib/env/index.d.ts.map +1 -0
  18. package/dist/lib/env/index.js +125 -0
  19. package/dist/lib/env/index.js.map +1 -0
  20. package/dist/lib/tunnel/index.d.ts +38 -0
  21. package/dist/lib/tunnel/index.d.ts.map +1 -0
  22. package/dist/lib/tunnel/index.js +154 -0
  23. package/dist/lib/tunnel/index.js.map +1 -0
  24. package/dist/package.json +100 -0
  25. package/dist/src/cli/commands/info.d.ts +6 -0
  26. package/dist/src/cli/commands/info.d.ts.map +1 -0
  27. package/dist/src/cli/commands/info.js +32 -0
  28. package/dist/src/cli/commands/info.js.map +1 -0
  29. package/dist/src/cli/commands/mcp.d.ts +6 -0
  30. package/dist/src/cli/commands/mcp.d.ts.map +1 -0
  31. package/dist/src/cli/commands/mcp.js +45 -0
  32. package/dist/src/cli/commands/mcp.js.map +1 -0
  33. package/dist/src/cli/commands/setup.d.ts +6 -0
  34. package/dist/src/cli/commands/setup.d.ts.map +1 -0
  35. package/dist/src/cli/commands/setup.js +59 -0
  36. package/dist/src/cli/commands/setup.js.map +1 -0
  37. package/dist/src/cli/commands/test/index.d.ts +6 -0
  38. package/dist/src/cli/commands/test/index.d.ts.map +1 -0
  39. package/dist/src/cli/commands/test/index.js +15 -0
  40. package/dist/src/cli/commands/test/index.js.map +1 -0
  41. package/dist/src/cli/commands/test/init.d.ts +6 -0
  42. package/dist/src/cli/commands/test/init.d.ts.map +1 -0
  43. package/dist/src/cli/commands/test/init.js +64 -0
  44. package/dist/src/cli/commands/test/init.js.map +1 -0
  45. package/dist/src/cli/commands/test/list.d.ts +6 -0
  46. package/dist/src/cli/commands/test/list.d.ts.map +1 -0
  47. package/dist/src/cli/commands/test/list.js +70 -0
  48. package/dist/src/cli/commands/test/list.js.map +1 -0
  49. package/dist/src/cli/commands/test/run.d.ts +6 -0
  50. package/dist/src/cli/commands/test/run.d.ts.map +1 -0
  51. package/dist/src/cli/commands/test/run.js +95 -0
  52. package/dist/src/cli/commands/test/run.js.map +1 -0
  53. package/dist/src/cli/commands/test/validate.d.ts +6 -0
  54. package/dist/src/cli/commands/test/validate.d.ts.map +1 -0
  55. package/dist/src/cli/commands/test/validate.js +70 -0
  56. package/dist/src/cli/commands/test/validate.js.map +1 -0
  57. package/dist/src/cli/index.d.ts +6 -0
  58. package/dist/src/cli/index.d.ts.map +1 -0
  59. package/dist/src/cli/index.js +21 -0
  60. package/dist/src/cli/index.js.map +1 -0
  61. package/dist/src/cli/lib/config.d.ts +36 -0
  62. package/dist/src/cli/lib/config.d.ts.map +1 -0
  63. package/dist/src/cli/lib/config.js +89 -0
  64. package/dist/src/cli/lib/config.js.map +1 -0
  65. package/dist/src/cli/lib/loader.d.ts +49 -0
  66. package/dist/src/cli/lib/loader.d.ts.map +1 -0
  67. package/dist/src/cli/lib/loader.js +122 -0
  68. package/dist/src/cli/lib/loader.js.map +1 -0
  69. package/dist/src/cli/lib/output.d.ts +53 -0
  70. package/dist/src/cli/lib/output.d.ts.map +1 -0
  71. package/dist/src/cli/lib/output.js +133 -0
  72. package/dist/src/cli/lib/output.js.map +1 -0
  73. package/dist/src/cli/lib/runner.d.ts +23 -0
  74. package/dist/src/cli/lib/runner.d.ts.map +1 -0
  75. package/dist/src/cli/lib/runner.js +40 -0
  76. package/dist/src/cli/lib/runner.js.map +1 -0
  77. package/dist/src/http-server.d.ts +14 -0
  78. package/dist/src/http-server.d.ts.map +1 -0
  79. package/dist/src/http-server.js +145 -0
  80. package/dist/src/http-server.js.map +1 -0
  81. package/dist/src/index.d.ts +9 -0
  82. package/dist/src/index.d.ts.map +1 -0
  83. package/dist/src/index.js +21 -0
  84. package/dist/src/index.js.map +1 -0
  85. package/dist/src/server.d.ts +58 -0
  86. package/dist/src/server.d.ts.map +1 -0
  87. package/dist/src/server.js +2376 -0
  88. package/dist/src/server.js.map +1 -0
  89. package/dist/src/tunnel-mode.d.ts +13 -0
  90. package/dist/src/tunnel-mode.d.ts.map +1 -0
  91. package/dist/src/tunnel-mode.js +159 -0
  92. package/dist/src/tunnel-mode.js.map +1 -0
  93. package/dist/src/types/test-definition.d.ts +320 -0
  94. package/dist/src/types/test-definition.d.ts.map +1 -0
  95. package/dist/src/types/test-definition.js +11 -0
  96. package/dist/src/types/test-definition.js.map +1 -0
  97. package/dist/src/types.d.ts +209 -0
  98. package/dist/src/types.d.ts.map +1 -0
  99. package/dist/src/types.js +34 -0
  100. package/dist/src/types.js.map +1 -0
  101. package/dist/src/utils/package.d.ts +12 -0
  102. package/dist/src/utils/package.d.ts.map +1 -0
  103. package/dist/src/utils/package.js +36 -0
  104. package/dist/src/utils/package.js.map +1 -0
  105. package/dist/src/utils/summary.d.ts +45 -0
  106. package/dist/src/utils/summary.d.ts.map +1 -0
  107. package/dist/src/utils/summary.js +198 -0
  108. package/dist/src/utils/summary.js.map +1 -0
  109. package/lib/api/index.ts +977 -0
  110. package/lib/api/sse.ts +112 -0
  111. package/lib/browser/index.ts +181 -0
  112. package/lib/env/index.ts +156 -0
  113. package/lib/tunnel/index.test.ts +344 -0
  114. package/lib/tunnel/index.ts +197 -0
  115. package/lib/tunnel/integration.test.ts +98 -0
  116. package/package.json +100 -0
  117. package/server.json +16 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * qa-use test validate - Validate test definitions
3
+ */
4
+ import { Command } from 'commander';
5
+ import { loadConfig } from '../../lib/config.js';
6
+ import { loadTestWithDeps } from '../../lib/loader.js';
7
+ import { error, success, printValidationErrors } from '../../lib/output.js';
8
+ import { ApiClient } from '../../../../lib/api/index.js';
9
+ export const validateCommand = new Command('validate')
10
+ .description('Validate test definition without running')
11
+ .argument('<test>', 'Test name or path')
12
+ .option('--strict', 'Treat warnings as errors')
13
+ .action(async (test, options) => {
14
+ try {
15
+ const config = await loadConfig();
16
+ // Check API key
17
+ if (!config.api_key) {
18
+ console.log(error('API key not configured'));
19
+ console.log(' Run `qa-use setup` to configure');
20
+ process.exit(1);
21
+ }
22
+ // Initialize API client
23
+ const client = new ApiClient(config.api_url);
24
+ client.setApiKey(config.api_key);
25
+ // Load test definitions
26
+ console.log(`Loading test: ${test}...`);
27
+ const definitions = await loadTestWithDeps(test, config.test_directory || './qa-tests');
28
+ console.log(success(`Loaded ${definitions.length} test(s)\n`));
29
+ // Validate
30
+ console.log('Validating...');
31
+ const validation = await client.validateTestDefinition(definitions);
32
+ if (validation.valid) {
33
+ console.log(success('Validation passed\n'));
34
+ if (validation.resolved) {
35
+ console.log('Resolved:');
36
+ if (validation.resolved.app_config_id) {
37
+ console.log(` App Config: ${validation.resolved.app_config_id}`);
38
+ }
39
+ if (validation.resolved.total_steps !== undefined) {
40
+ console.log(` Total Steps: ${validation.resolved.total_steps}`);
41
+ }
42
+ if (validation.resolved.dependencies && validation.resolved.dependencies.length > 0) {
43
+ console.log(` Dependencies: ${validation.resolved.dependencies.join(', ')}`);
44
+ }
45
+ }
46
+ if (validation.warnings.length > 0) {
47
+ console.log(`\n⚠️ ${validation.warnings.length} warnings:`);
48
+ printValidationErrors(validation.warnings);
49
+ if (options.strict) {
50
+ process.exit(1);
51
+ }
52
+ }
53
+ }
54
+ else {
55
+ console.log(error('Validation failed\n'));
56
+ console.log(`Errors (${validation.errors.length}):`);
57
+ printValidationErrors(validation.errors);
58
+ if (validation.warnings.length > 0) {
59
+ console.log(`\nWarnings (${validation.warnings.length}):`);
60
+ printValidationErrors(validation.warnings);
61
+ }
62
+ process.exit(1);
63
+ }
64
+ }
65
+ catch (err) {
66
+ console.log(error(`Validation failed: ${err}`));
67
+ process.exit(1);
68
+ }
69
+ });
70
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/cli/commands/test/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * QA-Use CLI - Command line interface for test automation
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;GAEG"}
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * QA-Use CLI - Command line interface for test automation
4
+ */
5
+ import { Command } from 'commander';
6
+ import { setupCommand } from './commands/setup.js';
7
+ import { infoCommand } from './commands/info.js';
8
+ import { testCommand } from './commands/test/index.js';
9
+ import { mcpCommand } from './commands/mcp.js';
10
+ // Get version from package.json
11
+ const version = '2.0.0';
12
+ const program = new Command();
13
+ program.name('qa-use').description('QA automation tool for desplega.ai').version(version);
14
+ // Register commands
15
+ program.addCommand(setupCommand);
16
+ program.addCommand(infoCommand);
17
+ program.addCommand(testCommand);
18
+ program.addCommand(mcpCommand);
19
+ // Parse command line arguments
20
+ program.parse();
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,gCAAgC;AAChC,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1F,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAE/B,+BAA+B;AAC/B,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Configuration file management for .qa-use-tests.json
3
+ */
4
+ export interface CliConfig {
5
+ api_key?: string;
6
+ api_url?: string;
7
+ default_app_config_id?: string;
8
+ test_directory?: string;
9
+ defaults?: {
10
+ headless?: boolean;
11
+ persist?: boolean;
12
+ timeout?: number;
13
+ allow_fix?: boolean;
14
+ };
15
+ }
16
+ /**
17
+ * Load CLI configuration from .qa-use-tests.json
18
+ *
19
+ * Searches for config file in:
20
+ * 1. Current directory
21
+ * 2. Home directory
22
+ *
23
+ * Environment variables override config file values:
24
+ * - QA_USE_API_KEY
25
+ * - QA_USE_API_URL
26
+ */
27
+ export declare function loadConfig(): Promise<CliConfig>;
28
+ /**
29
+ * Save configuration to .qa-use-tests.json in current directory
30
+ */
31
+ export declare function saveConfig(config: CliConfig): Promise<void>;
32
+ /**
33
+ * Check if config file exists
34
+ */
35
+ export declare function configExists(): Promise<boolean>;
36
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,SAAS;IACxB,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;AA+BD;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAkCrD;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"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Configuration file management for .qa-use-tests.json
3
+ */
4
+ import * as fs from 'fs/promises';
5
+ import * as path from 'path';
6
+ import { homedir } from 'os';
7
+ const CONFIG_FILENAME = '.qa-use-tests.json';
8
+ /**
9
+ * Search for config file in current directory and home directory
10
+ */
11
+ async function findConfigFile() {
12
+ // Check current directory
13
+ const cwd = process.cwd();
14
+ const localConfig = path.join(cwd, CONFIG_FILENAME);
15
+ try {
16
+ await fs.access(localConfig);
17
+ return localConfig;
18
+ }
19
+ catch {
20
+ // Not in current directory
21
+ }
22
+ // Check home directory
23
+ const homeConfig = path.join(homedir(), CONFIG_FILENAME);
24
+ try {
25
+ await fs.access(homeConfig);
26
+ return homeConfig;
27
+ }
28
+ catch {
29
+ // Not in home directory
30
+ }
31
+ return null;
32
+ }
33
+ /**
34
+ * Load CLI configuration from .qa-use-tests.json
35
+ *
36
+ * Searches for config file in:
37
+ * 1. Current directory
38
+ * 2. Home directory
39
+ *
40
+ * Environment variables override config file values:
41
+ * - QA_USE_API_KEY
42
+ * - QA_USE_API_URL
43
+ */
44
+ export async function loadConfig() {
45
+ const configPath = await findConfigFile();
46
+ let config = {
47
+ test_directory: './qa-tests',
48
+ defaults: {
49
+ headless: true,
50
+ persist: false,
51
+ timeout: 300,
52
+ allow_fix: true,
53
+ },
54
+ };
55
+ if (configPath) {
56
+ try {
57
+ const content = await fs.readFile(configPath, 'utf-8');
58
+ const fileConfig = JSON.parse(content);
59
+ config = { ...config, ...fileConfig };
60
+ }
61
+ catch (error) {
62
+ console.error(`Warning: Failed to parse config file at ${configPath}`);
63
+ console.error(error);
64
+ }
65
+ }
66
+ // Environment variables override config file
67
+ if (process.env.QA_USE_API_KEY) {
68
+ config.api_key = process.env.QA_USE_API_KEY;
69
+ }
70
+ if (process.env.QA_USE_API_URL) {
71
+ config.api_url = process.env.QA_USE_API_URL;
72
+ }
73
+ return config;
74
+ }
75
+ /**
76
+ * Save configuration to .qa-use-tests.json in current directory
77
+ */
78
+ export async function saveConfig(config) {
79
+ const configPath = path.join(process.cwd(), CONFIG_FILENAME);
80
+ const content = JSON.stringify(config, null, 2);
81
+ await fs.writeFile(configPath, content, 'utf-8');
82
+ }
83
+ /**
84
+ * Check if config file exists
85
+ */
86
+ export async function configExists() {
87
+ return (await findConfigFile()) !== null;
88
+ }
89
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAe7B,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAE7C;;GAEG;AACH,KAAK,UAAU,cAAc;IAC3B,0BAA0B;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC7B,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;IAED,uBAAuB;IACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5B,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;IAE1C,IAAI,MAAM,GAAc;QACtB,cAAc,EAAE,YAAY;QAC5B,QAAQ,EAAE;YACR,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,IAAI;SAChB;KACF,CAAC;IAEF,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACvD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAc,CAAC;YACpD,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2CAA2C,UAAU,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC9C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAiB;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,CAAC,MAAM,cAAc,EAAE,CAAC,KAAK,IAAI,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Test definition file discovery and loading
3
+ */
4
+ import type { TestDefinition } from '../../../src/types/test-definition.js';
5
+ /**
6
+ * Discover test definition files in a directory
7
+ *
8
+ * @param directory - Directory to search (default: ./qa-tests)
9
+ * @returns Array of file paths
10
+ */
11
+ export declare function discoverTests(directory?: string): Promise<string[]>;
12
+ /**
13
+ * Load a single test definition from a file
14
+ *
15
+ * @param filePath - Path to test definition file
16
+ * @returns TestDefinition object
17
+ */
18
+ export declare function loadTestDefinition(filePath: string): Promise<TestDefinition>;
19
+ /**
20
+ * Resolve test name or path to full file path
21
+ *
22
+ * @param testNameOrPath - Test name (e.g., "auth/login") or path
23
+ * @param directory - Test directory root
24
+ * @returns Full path to test file
25
+ */
26
+ export declare function resolveTestPath(testNameOrPath: string, directory: string): string;
27
+ /**
28
+ * Load a test and all its dependencies recursively
29
+ *
30
+ * @param testName - Test name or path
31
+ * @param directory - Test directory root
32
+ * @returns Array of TestDefinitions (dependencies first, then the test)
33
+ */
34
+ export declare function loadTestWithDeps(testName: string, directory: string): Promise<TestDefinition[]>;
35
+ /**
36
+ * Load all test definitions from a directory
37
+ *
38
+ * @param directory - Test directory root
39
+ * @returns Array of TestDefinitions
40
+ */
41
+ export declare function loadAllTests(directory: string): Promise<TestDefinition[]>;
42
+ /**
43
+ * Apply variable overrides to test definitions
44
+ *
45
+ * @param definitions - Test definitions to modify
46
+ * @param overrides - Variable overrides { key: value }
47
+ */
48
+ export declare function applyVariableOverrides(definitions: TestDefinition[], overrides: Record<string, string>): void;
49
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,GAAE,MAAqB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGvF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CASlF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAoBjF;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC,CA+B3B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAc/E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,cAAc,EAAE,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,IAAI,CAQN"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Test definition file discovery and loading
3
+ */
4
+ import * as fs from 'fs/promises';
5
+ import * as path from 'path';
6
+ import { glob } from 'glob';
7
+ import * as yaml from 'yaml';
8
+ /**
9
+ * Discover test definition files in a directory
10
+ *
11
+ * @param directory - Directory to search (default: ./qa-tests)
12
+ * @returns Array of file paths
13
+ */
14
+ export async function discoverTests(directory = './qa-tests') {
15
+ const pattern = path.join(directory, '**/*.{yaml,yml,json}');
16
+ return await glob(pattern);
17
+ }
18
+ /**
19
+ * Load a single test definition from a file
20
+ *
21
+ * @param filePath - Path to test definition file
22
+ * @returns TestDefinition object
23
+ */
24
+ export async function loadTestDefinition(filePath) {
25
+ const content = await fs.readFile(filePath, 'utf-8');
26
+ if (filePath.endsWith('.json')) {
27
+ return JSON.parse(content);
28
+ }
29
+ // Parse YAML
30
+ return yaml.parse(content);
31
+ }
32
+ /**
33
+ * Resolve test name or path to full file path
34
+ *
35
+ * @param testNameOrPath - Test name (e.g., "auth/login") or path
36
+ * @param directory - Test directory root
37
+ * @returns Full path to test file
38
+ */
39
+ export function resolveTestPath(testNameOrPath, directory) {
40
+ // If it's already an absolute path, return it
41
+ if (path.isAbsolute(testNameOrPath)) {
42
+ return testNameOrPath;
43
+ }
44
+ // If it's a relative path with extension, resolve it
45
+ if (testNameOrPath.match(/\.(yaml|yml|json)$/)) {
46
+ return path.resolve(directory, testNameOrPath);
47
+ }
48
+ // Try to find file with various extensions
49
+ const extensions = ['.yaml', '.yml', '.json'];
50
+ for (const ext of extensions) {
51
+ const fullPath = path.resolve(directory, testNameOrPath + ext);
52
+ return fullPath; // Return first match (we'll check existence when reading)
53
+ }
54
+ throw new Error(`Test file not found: ${testNameOrPath}`);
55
+ }
56
+ /**
57
+ * Load a test and all its dependencies recursively
58
+ *
59
+ * @param testName - Test name or path
60
+ * @param directory - Test directory root
61
+ * @returns Array of TestDefinitions (dependencies first, then the test)
62
+ */
63
+ export async function loadTestWithDeps(testName, directory) {
64
+ const definitions = [];
65
+ const loaded = new Set();
66
+ async function loadRecursive(name) {
67
+ // Avoid circular dependencies
68
+ if (loaded.has(name))
69
+ return;
70
+ loaded.add(name);
71
+ const filePath = resolveTestPath(name, directory);
72
+ const def = await loadTestDefinition(filePath);
73
+ // Load dependency first (if it exists and is a local file)
74
+ if (def.depends_on) {
75
+ // Check if depends_on is a UUID (cloud test) or a file name
76
+ const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(def.depends_on);
77
+ if (!isUuid) {
78
+ // It's a local file reference
79
+ await loadRecursive(def.depends_on);
80
+ }
81
+ // If it's a UUID, the API will resolve it
82
+ }
83
+ definitions.push(def);
84
+ }
85
+ await loadRecursive(testName);
86
+ return definitions;
87
+ }
88
+ /**
89
+ * Load all test definitions from a directory
90
+ *
91
+ * @param directory - Test directory root
92
+ * @returns Array of TestDefinitions
93
+ */
94
+ export async function loadAllTests(directory) {
95
+ const files = await discoverTests(directory);
96
+ const definitions = [];
97
+ for (const file of files) {
98
+ try {
99
+ const def = await loadTestDefinition(file);
100
+ definitions.push(def);
101
+ }
102
+ catch (error) {
103
+ console.error(`Warning: Failed to load ${file}:`, error);
104
+ }
105
+ }
106
+ return definitions;
107
+ }
108
+ /**
109
+ * Apply variable overrides to test definitions
110
+ *
111
+ * @param definitions - Test definitions to modify
112
+ * @param overrides - Variable overrides { key: value }
113
+ */
114
+ export function applyVariableOverrides(definitions, overrides) {
115
+ for (const def of definitions) {
116
+ if (!def.variables) {
117
+ def.variables = {};
118
+ }
119
+ Object.assign(def.variables, overrides);
120
+ }
121
+ }
122
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/cli/lib/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Console output formatting utilities
3
+ */
4
+ import type { SSEEvent } from '../../../lib/api/sse.js';
5
+ /**
6
+ * Format success message
7
+ */
8
+ export declare function success(message: string): string;
9
+ /**
10
+ * Format error message
11
+ */
12
+ export declare function error(message: string): string;
13
+ /**
14
+ * Format warning message
15
+ */
16
+ export declare function warning(message: string): string;
17
+ /**
18
+ * Format info message
19
+ */
20
+ export declare function info(message: string): string;
21
+ /**
22
+ * Format step message
23
+ */
24
+ export declare function step(index: number, total: number, message: string): string;
25
+ /**
26
+ * Format duration
27
+ */
28
+ export declare function duration(seconds: number): string;
29
+ /**
30
+ * Progress bar for steps
31
+ */
32
+ export declare function progressBar(completed: number, total: number, width?: number): string;
33
+ /**
34
+ * Print SSE event progress in real-time
35
+ */
36
+ export declare function printSSEProgress(event: SSEEvent): void;
37
+ /**
38
+ * Print test list table
39
+ */
40
+ export declare function printTestList(tests: Array<{
41
+ name: string;
42
+ steps?: number;
43
+ deps?: string;
44
+ }>): void;
45
+ /**
46
+ * Print validation errors
47
+ */
48
+ export declare function printValidationErrors(errors: Array<{
49
+ path: string;
50
+ message: string;
51
+ severity: string;
52
+ }>): void;
53
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAaxD;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAOxF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CA6CtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAajG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GACjE,IAAI,CAUN"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Console output formatting utilities
3
+ */
4
+ // ANSI color codes
5
+ const colors = {
6
+ reset: '\x1b[0m',
7
+ green: '\x1b[32m',
8
+ red: '\x1b[31m',
9
+ yellow: '\x1b[33m',
10
+ blue: '\x1b[34m',
11
+ gray: '\x1b[90m',
12
+ cyan: '\x1b[36m',
13
+ };
14
+ /**
15
+ * Format success message
16
+ */
17
+ export function success(message) {
18
+ return `${colors.green}✓${colors.reset} ${message}`;
19
+ }
20
+ /**
21
+ * Format error message
22
+ */
23
+ export function error(message) {
24
+ return `${colors.red}✗${colors.reset} ${message}`;
25
+ }
26
+ /**
27
+ * Format warning message
28
+ */
29
+ export function warning(message) {
30
+ return `${colors.yellow}⚠${colors.reset} ${message}`;
31
+ }
32
+ /**
33
+ * Format info message
34
+ */
35
+ export function info(message) {
36
+ return `${colors.blue}ℹ${colors.reset} ${message}`;
37
+ }
38
+ /**
39
+ * Format step message
40
+ */
41
+ export function step(index, total, message) {
42
+ return `${colors.gray}[${index}/${total}]${colors.reset} ${message}`;
43
+ }
44
+ /**
45
+ * Format duration
46
+ */
47
+ export function duration(seconds) {
48
+ if (seconds < 1) {
49
+ return `${(seconds * 1000).toFixed(0)}ms`;
50
+ }
51
+ return `${seconds.toFixed(2)}s`;
52
+ }
53
+ /**
54
+ * Progress bar for steps
55
+ */
56
+ export function progressBar(completed, total, width = 30) {
57
+ const percentage = Math.floor((completed / total) * 100);
58
+ const filled = Math.floor((completed / total) * width);
59
+ const empty = width - filled;
60
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
61
+ return `${colors.cyan}${bar}${colors.reset} ${percentage}%`;
62
+ }
63
+ /**
64
+ * Print SSE event progress in real-time
65
+ */
66
+ export function printSSEProgress(event) {
67
+ switch (event.event) {
68
+ case 'start':
69
+ console.log(success(`Test started (run_id: ${event.data.run_id})`));
70
+ console.log(` Total steps: ${event.data.total_steps}\n`);
71
+ break;
72
+ case 'step_start':
73
+ process.stdout.write(` ${colors.gray}[${event.data.step_index + 1}]${colors.reset} ${event.data.name}...`);
74
+ break;
75
+ case 'step_complete': {
76
+ const status = event.data.status === 'passed' ? colors.green + '✓' : colors.red + '✗';
77
+ const time = duration(event.data.duration);
78
+ console.log(` ${status}${colors.reset} ${colors.gray}${time}${colors.reset}`);
79
+ break;
80
+ }
81
+ case 'complete':
82
+ console.log('');
83
+ if (event.data.status === 'passed') {
84
+ console.log(success(`Test passed in ${duration(event.data.duration_seconds)}`));
85
+ }
86
+ else {
87
+ console.log(error(`Test ${event.data.status} in ${duration(event.data.duration_seconds)}`));
88
+ }
89
+ break;
90
+ case 'error':
91
+ console.log('');
92
+ console.log(error(`Test error: ${event.data.error}`));
93
+ if (event.data.step_index !== undefined) {
94
+ console.log(` At step ${event.data.step_index + 1}`);
95
+ }
96
+ break;
97
+ case 'persisted':
98
+ console.log(success(`Test saved to cloud (ID: ${event.data.test_id})`));
99
+ break;
100
+ default:
101
+ // Log unknown events in gray
102
+ console.log(` ${colors.gray}[${event.event}]${colors.reset}`);
103
+ }
104
+ }
105
+ /**
106
+ * Print test list table
107
+ */
108
+ export function printTestList(tests) {
109
+ if (tests.length === 0) {
110
+ console.log(warning('No tests found'));
111
+ return;
112
+ }
113
+ console.log(`Found ${tests.length} test${tests.length === 1 ? '' : 's'}:\n`);
114
+ for (const test of tests) {
115
+ const stepCount = test.steps ? ` (${test.steps} steps)` : '';
116
+ const deps = test.deps ? ` ${colors.gray}[depends: ${test.deps}]${colors.reset}` : '';
117
+ console.log(` • ${test.name}${stepCount}${deps}`);
118
+ }
119
+ }
120
+ /**
121
+ * Print validation errors
122
+ */
123
+ export function printValidationErrors(errors) {
124
+ for (const err of errors) {
125
+ const icon = err.severity === 'error'
126
+ ? colors.red + '✗'
127
+ : err.severity === 'warning'
128
+ ? colors.yellow + '⚠'
129
+ : colors.blue + 'ℹ';
130
+ console.log(` ${icon}${colors.reset} ${err.path}: ${err.message}`);
131
+ }
132
+ }
133
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../../src/cli/lib/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Test execution runner with SSE progress output
3
+ */
4
+ import { ApiClient, type RunCliTestOptions, type RunCliTestResult } from '../../../lib/api/index.js';
5
+ import type { SSEEvent } from '../../../lib/api/sse.js';
6
+ /**
7
+ * Run a test with real-time progress output
8
+ *
9
+ * @param client - ApiClient instance
10
+ * @param options - Test run options
11
+ * @param onEvent - Optional additional event callback
12
+ * @returns Test result
13
+ */
14
+ export declare function runTest(client: ApiClient, options: RunCliTestOptions, onEvent?: (event: SSEEvent) => void): Promise<RunCliTestResult>;
15
+ /**
16
+ * Run multiple tests sequentially
17
+ *
18
+ * @param client - ApiClient instance
19
+ * @param tests - Array of test run options
20
+ * @returns Array of test results
21
+ */
22
+ export declare function runTests(client: ApiClient, tests: RunCliTestOptions[]): Promise<RunCliTestResult[]>;
23
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../../src/cli/lib/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,SAAS,EACT,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGxD;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAU3B;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,iBAAiB,EAAE,GACzB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAU7B"}