qa360 2.0.12 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/ai.js +26 -14
- package/dist/commands/ask.d.ts +75 -23
- package/dist/commands/ask.js +413 -265
- package/dist/commands/crawl.d.ts +24 -0
- package/dist/commands/crawl.js +121 -0
- package/dist/commands/history.js +38 -3
- package/dist/commands/init.d.ts +89 -95
- package/dist/commands/init.js +282 -200
- package/dist/commands/run.d.ts +1 -0
- package/dist/core/adapters/playwright-native-adapter.d.ts +121 -0
- package/dist/core/adapters/playwright-native-adapter.js +339 -0
- package/dist/core/adapters/playwright-ui.d.ts +83 -7
- package/dist/core/adapters/playwright-ui.js +525 -59
- package/dist/core/artifacts/index.d.ts +6 -0
- package/dist/core/artifacts/index.js +6 -0
- package/dist/core/artifacts/ui-artifacts.d.ts +133 -0
- package/dist/core/artifacts/ui-artifacts.js +304 -0
- package/dist/core/assertions/engine.d.ts +51 -0
- package/dist/core/assertions/engine.js +530 -0
- package/dist/core/assertions/index.d.ts +11 -0
- package/dist/core/assertions/index.js +11 -0
- package/dist/core/assertions/types.d.ts +121 -0
- package/dist/core/assertions/types.js +37 -0
- package/dist/core/crawler/index.d.ts +57 -0
- package/dist/core/crawler/index.js +281 -0
- package/dist/core/crawler/journey-generator.d.ts +49 -0
- package/dist/core/crawler/journey-generator.js +412 -0
- package/dist/core/crawler/page-analyzer.d.ts +88 -0
- package/dist/core/crawler/page-analyzer.js +709 -0
- package/dist/core/crawler/selector-generator.d.ts +34 -0
- package/dist/core/crawler/selector-generator.js +240 -0
- package/dist/core/crawler/types.d.ts +353 -0
- package/dist/core/crawler/types.js +6 -0
- package/dist/core/generation/crawler-pack-generator.d.ts +44 -0
- package/dist/core/generation/crawler-pack-generator.js +231 -0
- package/dist/core/generation/index.d.ts +2 -0
- package/dist/core/generation/index.js +2 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +13 -0
- package/dist/core/parallel/index.d.ts +6 -0
- package/dist/core/parallel/index.js +6 -0
- package/dist/core/parallel/parallel-runner.d.ts +107 -0
- package/dist/core/parallel/parallel-runner.js +192 -0
- package/dist/core/reporting/html-reporter.d.ts +119 -0
- package/dist/core/reporting/html-reporter.js +737 -0
- package/dist/core/reporting/index.d.ts +6 -0
- package/dist/core/reporting/index.js +6 -0
- package/dist/core/runner/phase3-runner.js +5 -1
- package/dist/core/types/pack-v1.d.ts +90 -0
- package/dist/core/vault/cas.d.ts +5 -1
- package/dist/core/vault/cas.js +6 -0
- package/dist/core/visual/index.d.ts +6 -0
- package/dist/core/visual/index.js +6 -0
- package/dist/core/visual/visual-regression.d.ts +113 -0
- package/dist/core/visual/visual-regression.js +236 -0
- package/dist/index.js +6 -2
- package/examples/README.md +38 -0
- package/examples/accessibility.yml +39 -16
- package/examples/api-basic.yml +19 -14
- package/examples/complete.yml +134 -42
- package/examples/crawler.yml +38 -0
- package/examples/fullstack.yml +66 -31
- package/examples/security.yml +47 -15
- package/examples/ui-advanced.yml +49 -0
- package/examples/ui-basic.yml +16 -12
- package/package.json +1 -1
package/dist/commands/ai.js
CHANGED
|
@@ -31,12 +31,24 @@ export async function aiListCommand() {
|
|
|
31
31
|
const status = provider.available
|
|
32
32
|
? chalk.green('✓ Available')
|
|
33
33
|
: chalk.gray('✗ Not set up');
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
// Get cost level display
|
|
35
|
+
let costLevel;
|
|
36
|
+
switch (provider.costLevel) {
|
|
37
|
+
case 'free':
|
|
38
|
+
costLevel = chalk.green('FREE');
|
|
39
|
+
break;
|
|
40
|
+
case 'low':
|
|
41
|
+
costLevel = chalk.yellow('LOW');
|
|
42
|
+
break;
|
|
43
|
+
case 'medium':
|
|
44
|
+
costLevel = chalk.yellow('MED');
|
|
45
|
+
break;
|
|
46
|
+
case 'high':
|
|
47
|
+
costLevel = chalk.red('HIGH');
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
costLevel = provider.costLevel;
|
|
51
|
+
}
|
|
40
52
|
table.push([
|
|
41
53
|
chalk.bold(provider.name),
|
|
42
54
|
status,
|
|
@@ -46,33 +58,33 @@ export async function aiListCommand() {
|
|
|
46
58
|
}
|
|
47
59
|
console.log(table.toString());
|
|
48
60
|
// Show setup instructions for unavailable providers
|
|
49
|
-
const unavailable = providers.filter(p => !p.available && p.type !== 'mock');
|
|
61
|
+
const unavailable = providers.filter((p) => !p.available && p.type !== 'mock');
|
|
50
62
|
if (unavailable.length > 0) {
|
|
51
63
|
console.log(chalk.yellow('\n[INFO] Setup available providers:\n'));
|
|
52
|
-
if (!providers.find(p => p.type === 'deepseek')?.available) {
|
|
64
|
+
if (!providers.find((p) => p.type === 'deepseek')?.available) {
|
|
53
65
|
console.log(chalk.cyan('DeepSeek (Recommended - Best Value):'));
|
|
54
66
|
console.log(chalk.gray(' 1. Get API key: https://platform.deepseek.com/api_keys'));
|
|
55
67
|
console.log(chalk.gray(' 2. Run: qa360 secrets add DEEPSEEK_API_KEY\n'));
|
|
56
68
|
}
|
|
57
|
-
if (!providers.find(p => p.type === 'ollama')?.available) {
|
|
69
|
+
if (!providers.find((p) => p.type === 'ollama')?.available) {
|
|
58
70
|
console.log(chalk.cyan('Ollama (Free - Local):'));
|
|
59
71
|
console.log(chalk.gray(' 1. Install: brew install ollama'));
|
|
60
72
|
console.log(chalk.gray(' 2. Run: ollama serve'));
|
|
61
73
|
console.log(chalk.gray(' 3. Pull model: ollama pull deepseek-coder\n'));
|
|
62
74
|
}
|
|
63
|
-
if (!providers.find(p => p.type === 'openai')?.available) {
|
|
75
|
+
if (!providers.find((p) => p.type === 'openai')?.available) {
|
|
64
76
|
console.log(chalk.cyan('OpenAI:'));
|
|
65
77
|
console.log(chalk.gray(' 1. Get API key: https://platform.openai.com/api-keys'));
|
|
66
78
|
console.log(chalk.gray(' 2. Run: qa360 secrets add OPENAI_API_KEY\n'));
|
|
67
79
|
}
|
|
68
|
-
if (!providers.find(p => p.type === 'anthropic')?.available) {
|
|
80
|
+
if (!providers.find((p) => p.type === 'anthropic')?.available) {
|
|
69
81
|
console.log(chalk.cyan('Anthropic:'));
|
|
70
82
|
console.log(chalk.gray(' 1. Get API key: https://console.anthropic.com/'));
|
|
71
83
|
console.log(chalk.gray(' 2. Run: qa360 secrets add ANTHROPIC_API_KEY\n'));
|
|
72
84
|
}
|
|
73
85
|
}
|
|
74
86
|
// Show best provider
|
|
75
|
-
const bestProvider = providers.find(p => p.available && p.type !== 'mock');
|
|
87
|
+
const bestProvider = providers.find((p) => p.available && p.type !== 'mock');
|
|
76
88
|
if (bestProvider) {
|
|
77
89
|
console.log(chalk.green(`\n[STAR] Best available: ${chalk.bold(bestProvider.name)}`));
|
|
78
90
|
console.log(chalk.gray(` ${bestProvider.description}`));
|
|
@@ -263,7 +275,7 @@ export async function aiGenerateCommand(prompt, options = {}) {
|
|
|
263
275
|
spinner?.fail('Generation failed');
|
|
264
276
|
if (error instanceof DeepSeekError) {
|
|
265
277
|
console.error(chalk.red('\nDeepSeek Error:'), error.message);
|
|
266
|
-
if (error.details) {
|
|
278
|
+
if ('details' in error && error.details) {
|
|
267
279
|
console.error(chalk.gray(JSON.stringify(error.details, null, 2)));
|
|
268
280
|
}
|
|
269
281
|
}
|
|
@@ -277,7 +289,7 @@ export async function aiGenerateCommand(prompt, options = {}) {
|
|
|
277
289
|
console.error(chalk.red('\nAnthropic Error:'), error.message);
|
|
278
290
|
}
|
|
279
291
|
else {
|
|
280
|
-
console.error(chalk.red('Error:'), error.message);
|
|
292
|
+
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
281
293
|
}
|
|
282
294
|
}
|
|
283
295
|
}
|
package/dist/commands/ask.d.ts
CHANGED
|
@@ -1,32 +1,84 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* QA360 Ask Command - Natural language to pack.yml generation
|
|
2
|
+
* QA360 Ask Command - Natural language to pack.yml generation (v2)
|
|
3
3
|
*/
|
|
4
|
-
export interface
|
|
4
|
+
export interface PackConfigV2 {
|
|
5
|
+
version: 2;
|
|
5
6
|
name: string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
hooks?:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
description?: string;
|
|
8
|
+
profile?: string;
|
|
9
|
+
auth?: AuthConfigV2;
|
|
10
|
+
gates: Record<string, GateConfigV2>;
|
|
11
|
+
hooks?: HooksConfig;
|
|
12
|
+
execution?: ExecutionConfigV2;
|
|
13
|
+
variables?: Record<string, string>;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface AuthConfigV2 {
|
|
17
|
+
api?: string;
|
|
18
|
+
ui?: string;
|
|
19
|
+
profiles?: Record<string, AuthProfile>;
|
|
20
|
+
}
|
|
21
|
+
export interface AuthProfile {
|
|
22
|
+
type: string;
|
|
23
|
+
config: Record<string, unknown>;
|
|
24
|
+
cache?: {
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
ttl?: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface GateConfigV2 {
|
|
30
|
+
adapter?: string;
|
|
31
|
+
test_files?: string[];
|
|
32
|
+
config?: Record<string, unknown>;
|
|
33
|
+
auth?: string;
|
|
34
|
+
budgets?: Record<string, unknown>;
|
|
35
|
+
options?: {
|
|
36
|
+
timeout?: number;
|
|
37
|
+
retries?: number;
|
|
38
|
+
continue_on_failure?: boolean;
|
|
39
|
+
};
|
|
40
|
+
enabled?: boolean;
|
|
41
|
+
depends_on?: string[];
|
|
42
|
+
parallel?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface HooksConfig {
|
|
45
|
+
beforeAll?: Hook[];
|
|
46
|
+
afterAll?: Hook[];
|
|
47
|
+
beforeEach?: Hook[];
|
|
48
|
+
afterEach?: Hook[];
|
|
49
|
+
}
|
|
50
|
+
export interface Hook {
|
|
51
|
+
type: 'run' | 'wait_on' | 'script' | 'docker';
|
|
52
|
+
command?: string;
|
|
53
|
+
cwd?: string;
|
|
18
54
|
timeout?: number;
|
|
19
|
-
|
|
55
|
+
env?: Record<string, string>;
|
|
56
|
+
wait_for?: {
|
|
57
|
+
resource: string;
|
|
58
|
+
timeout?: number;
|
|
59
|
+
};
|
|
60
|
+
compose?: {
|
|
61
|
+
file?: string;
|
|
62
|
+
services?: string[];
|
|
63
|
+
command?: string;
|
|
64
|
+
};
|
|
20
65
|
}
|
|
21
|
-
export interface
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
66
|
+
export interface ExecutionConfigV2 {
|
|
67
|
+
parallel?: boolean;
|
|
68
|
+
max_concurrency?: number;
|
|
69
|
+
default_timeout?: number;
|
|
70
|
+
default_retries?: number;
|
|
71
|
+
on_failure: 'stop' | 'continue' | 'proceed';
|
|
72
|
+
limits?: {
|
|
73
|
+
cpu?: string;
|
|
74
|
+
memory?: string;
|
|
75
|
+
};
|
|
76
|
+
compose_file?: string;
|
|
77
|
+
hook_timeout_ms?: number;
|
|
26
78
|
}
|
|
27
79
|
export declare class QA360Ask {
|
|
28
80
|
private qa360Dir;
|
|
29
|
-
generatePack(query?: string): Promise<
|
|
81
|
+
generatePack(query?: string): Promise<PackConfigV2>;
|
|
30
82
|
private interactiveMode;
|
|
31
83
|
private parseNaturalLanguage;
|
|
32
84
|
private generatePackFromAnswers;
|
|
@@ -36,7 +88,7 @@ export declare class QA360Ask {
|
|
|
36
88
|
private generateSecurityPack;
|
|
37
89
|
private generateAccessibilityPack;
|
|
38
90
|
private generateCompletePack;
|
|
39
|
-
savePack(pack:
|
|
40
|
-
displayPack(pack:
|
|
91
|
+
savePack(pack: PackConfigV2): Promise<string>;
|
|
92
|
+
displayPack(pack: PackConfigV2): void;
|
|
41
93
|
}
|
|
42
94
|
export declare function askCommand(query?: string): Promise<void>;
|