qa360 2.1.6 → 2.1.7
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.d.ts +2 -0
- package/dist/commands/ai.js +106 -1
- package/package.json +1 -1
package/dist/commands/ai.d.ts
CHANGED
package/dist/commands/ai.js
CHANGED
|
@@ -236,6 +236,11 @@ export async function aiBenchmarkCommand(options = {}) {
|
|
|
236
236
|
export async function aiGenerateCommand(prompt, options = {}) {
|
|
237
237
|
let spinner;
|
|
238
238
|
try {
|
|
239
|
+
// Use pack generation if --pack flag is set
|
|
240
|
+
if (options.pack) {
|
|
241
|
+
await generatePackCommand(prompt, options);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
239
244
|
const systemPrompt = buildSystemPrompt(options.type || 'api');
|
|
240
245
|
const provider = options.provider
|
|
241
246
|
? await createLLMProvider({ preferred: options.provider })
|
|
@@ -289,10 +294,61 @@ export async function aiGenerateCommand(prompt, options = {}) {
|
|
|
289
294
|
console.error(chalk.red('\nAnthropic Error:'), error.message);
|
|
290
295
|
}
|
|
291
296
|
else {
|
|
292
|
-
|
|
297
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
298
|
+
console.error(chalk.red('Error:'), errMsg);
|
|
293
299
|
}
|
|
294
300
|
}
|
|
295
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Generate a QA360 pack YAML using AI
|
|
304
|
+
*/
|
|
305
|
+
async function generatePackCommand(prompt, options = {}) {
|
|
306
|
+
const spinner = ora('Generating QA360 pack...').start();
|
|
307
|
+
try {
|
|
308
|
+
const systemPrompt = buildPackSystemPrompt();
|
|
309
|
+
const provider = options.provider
|
|
310
|
+
? await createLLMProvider({ preferred: options.provider })
|
|
311
|
+
: await createBest();
|
|
312
|
+
const providerType = provider.getProviderType();
|
|
313
|
+
const enhancedPrompt = `Generate a QA360 v2 pack YAML for: ${prompt}
|
|
314
|
+
|
|
315
|
+
Important: Return ONLY valid YAML starting with "version: 2". No code blocks, no explanations, just the YAML.`;
|
|
316
|
+
const response = await provider.generate({
|
|
317
|
+
prompt: enhancedPrompt,
|
|
318
|
+
systemPrompt,
|
|
319
|
+
maxTokens: 4096,
|
|
320
|
+
temperature: 0.3, // Lower temperature for more structured output
|
|
321
|
+
});
|
|
322
|
+
spinner.succeed(`Generated pack using ${chalk.cyan(providerType)}!\n`);
|
|
323
|
+
// Extract YAML from response (remove code blocks if present)
|
|
324
|
+
let yamlContent = response.content;
|
|
325
|
+
// Remove markdown code blocks
|
|
326
|
+
yamlContent = yamlContent.replace(/```yaml\n?/g, '').replace(/```\n?/g, '');
|
|
327
|
+
// Remove leading/trailing whitespace
|
|
328
|
+
yamlContent = yamlContent.trim();
|
|
329
|
+
// Determine output path
|
|
330
|
+
const outputPath = options.output || './qa360-pack.yml';
|
|
331
|
+
// Save the pack
|
|
332
|
+
const { writeFileSync } = await import('fs');
|
|
333
|
+
writeFileSync(outputPath, yamlContent, 'utf-8');
|
|
334
|
+
console.log(chalk.bold('Generated QA360 Pack:\n'));
|
|
335
|
+
console.log(chalk.gray('─'.repeat(70)));
|
|
336
|
+
console.log(yamlContent);
|
|
337
|
+
console.log(chalk.gray('─'.repeat(70)));
|
|
338
|
+
console.log(chalk.green(`\n✓ Pack saved to: ${outputPath}`));
|
|
339
|
+
console.log(chalk.gray(`\n[INFO] Tokens: ${response.usage.totalTokens} (${response.usage.promptTokens} in + ${response.usage.completionTokens} out)`));
|
|
340
|
+
console.log(chalk.gray(`[INFO] Provider: ${providerType} (${response.model})\n`));
|
|
341
|
+
// Show usage instructions
|
|
342
|
+
console.log(chalk.yellow('Next steps:'));
|
|
343
|
+
console.log(chalk.gray(` 1. Review the pack: cat ${outputPath}`));
|
|
344
|
+
console.log(chalk.gray(` 2. Run tests: qa360 run ${outputPath}`));
|
|
345
|
+
console.log(chalk.gray(` 3. Or validate: qa360 pack validate ${outputPath}\n`));
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
spinner.fail('Pack generation failed');
|
|
349
|
+
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
296
352
|
/**
|
|
297
353
|
* Show AI configuration
|
|
298
354
|
*/
|
|
@@ -436,6 +492,53 @@ For accessibility tests:
|
|
|
436
492
|
};
|
|
437
493
|
return typePrompts[type] || typePrompts.api;
|
|
438
494
|
}
|
|
495
|
+
/**
|
|
496
|
+
* Build system prompt for QA360 pack YAML generation
|
|
497
|
+
*/
|
|
498
|
+
function buildPackSystemPrompt() {
|
|
499
|
+
return `You are a QA360 pack YAML generator. Generate VALID QA360 v2 pack YAML files.
|
|
500
|
+
|
|
501
|
+
QA360 Pack v2 Structure:
|
|
502
|
+
\`\`\`yaml
|
|
503
|
+
version: 2
|
|
504
|
+
name: test-pack-name
|
|
505
|
+
description: Test pack description
|
|
506
|
+
gates:
|
|
507
|
+
gate-name:
|
|
508
|
+
adapter: playwright-api|playwright-ui|k6-perf
|
|
509
|
+
enabled: true
|
|
510
|
+
config:
|
|
511
|
+
baseUrl: "https://example.com"
|
|
512
|
+
# API adapter: use "smoke" array with "METHOD path -> status" format
|
|
513
|
+
smoke:
|
|
514
|
+
- "GET /api/health -> 200"
|
|
515
|
+
- "POST /api/users -> 201"
|
|
516
|
+
# UI adapter: use "scenario" array or "pages" array
|
|
517
|
+
scenario:
|
|
518
|
+
- action: navigate
|
|
519
|
+
url: /login
|
|
520
|
+
- action: fill
|
|
521
|
+
selector: "#email"
|
|
522
|
+
value: "test@example.com"
|
|
523
|
+
- action: click
|
|
524
|
+
selector: "button[type='submit']"
|
|
525
|
+
options:
|
|
526
|
+
timeout: 10000
|
|
527
|
+
budgets:
|
|
528
|
+
a11y_min: 70
|
|
529
|
+
perf_p95_ms: 3000
|
|
530
|
+
\`\`\`
|
|
531
|
+
|
|
532
|
+
Rules:
|
|
533
|
+
1. ALWAYS start with "version: 2"
|
|
534
|
+
2. Use "adapter:" not "type:"
|
|
535
|
+
3. For API tests: use adapter: playwright-api with smoke: array
|
|
536
|
+
4. For UI tests: use adapter: playwright-ui with scenario: array or pages: array
|
|
537
|
+
5. Smoke format: "METHOD path -> status" (e.g., "GET /users -> 200")
|
|
538
|
+
6. Scenario actions: navigate, fill, click, waitForSelector, assertText, assertVisible
|
|
539
|
+
7. Return ONLY the YAML, no markdown code blocks, no explanations
|
|
540
|
+
8. Make sure YAML is valid and properly indented`;
|
|
541
|
+
}
|
|
439
542
|
/**
|
|
440
543
|
* Create AI commands
|
|
441
544
|
*/
|
|
@@ -486,6 +589,8 @@ export function createAICommands() {
|
|
|
486
589
|
.option('-P, --provider <provider>', 'Use specific provider (deepseek, ollama, openai, anthropic)')
|
|
487
590
|
.option('-t, --type <type>', 'Test type (api, ui, perf, a11y)', 'api')
|
|
488
591
|
.option('--json', 'Output as JSON')
|
|
592
|
+
.option('--pack', 'Generate a QA360 pack YAML (instead of test code)')
|
|
593
|
+
.option('-o, --output <path>', 'Output file path (for --pack: ./qa360-pack.yml)')
|
|
489
594
|
.action(async (prompt, options) => {
|
|
490
595
|
try {
|
|
491
596
|
await aiGenerateCommand(prompt, options);
|