quality-intelligence-engine 2.2.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.
Files changed (65) hide show
  1. package/README.md +123 -0
  2. package/dist/bin/qi.js +27 -0
  3. package/dist/src/adapters/playwright-folder.adapter.js +68 -0
  4. package/dist/src/adapters/playwright-json.adapter.js +46 -0
  5. package/dist/src/adapters/playwright.adapter.js +36 -0
  6. package/dist/src/cli/qi-test.js +20 -0
  7. package/dist/src/cli/qi.js +59 -0
  8. package/dist/src/cli/ui/divider.js +10 -0
  9. package/dist/src/cli/ui/failureLogger.js +24 -0
  10. package/dist/src/configLoader.js +60 -0
  11. package/dist/src/console/issue-view.js +122 -0
  12. package/dist/src/failure-analysis/failure-analyzer.js +38 -0
  13. package/dist/src/final-run.js +130 -0
  14. package/dist/src/final-runner.js +27 -0
  15. package/dist/src/fixtures/networkCollector.js +18 -0
  16. package/dist/src/history/failure-history.store.js +25 -0
  17. package/dist/src/history/failure-history.types.js +4 -0
  18. package/dist/src/history/failure-trend.analyzer.js +31 -0
  19. package/dist/src/index.js +10 -0
  20. package/dist/src/integrations/ci/ci-annotator.js +26 -0
  21. package/dist/src/intelligence/confidence-calibration.engine.js +21 -0
  22. package/dist/src/intelligence/decision-intelligence/confidence.engine.js +16 -0
  23. package/dist/src/intelligence/decision-intelligence/decision.config.js +21 -0
  24. package/dist/src/intelligence/decision-intelligence/decision.engine.js +23 -0
  25. package/dist/src/intelligence/decision-intelligence/decision.types.js +2 -0
  26. package/dist/src/intelligence/failure-fingerprinting/failure.classifier.js +20 -0
  27. package/dist/src/intelligence/failure-fingerprinting/failure.store.js +39 -0
  28. package/dist/src/intelligence/failure-fingerprinting/failure.tracker.js +15 -0
  29. package/dist/src/intelligence/failure-fingerprinting/fingerprint.generator.js +28 -0
  30. package/dist/src/intelligence/failure-fingerprinting/fingerprint.types.js +2 -0
  31. package/dist/src/intelligence/flakiness-intelligence/flakiness.analyzer.js +21 -0
  32. package/dist/src/intelligence/flakiness-intelligence/flakiness.fingerprint.js +16 -0
  33. package/dist/src/intelligence/flakiness-intelligence/flakiness.store.js +24 -0
  34. package/dist/src/intelligence/flakiness-intelligence/flakiness.tracker.js +28 -0
  35. package/dist/src/intelligence/flakiness-intelligence/flakiness.types.js +2 -0
  36. package/dist/src/intelligence/intelligence.pipeline.js +17 -0
  37. package/dist/src/intelligence/llm-explainer.js +19 -0
  38. package/dist/src/intelligence/root-cause/rootcause.engine.js +25 -0
  39. package/dist/src/intelligence/trend-intelligence/trend.engine.js +25 -0
  40. package/dist/src/markdownWriter.js +64 -0
  41. package/dist/src/normalizer.js +17 -0
  42. package/dist/src/passAnalyzer.js +38 -0
  43. package/dist/src/pipeline/ai.summarizer.js +32 -0
  44. package/dist/src/pipeline/failure-analysis.pipeline.js +11 -0
  45. package/dist/src/pipeline/failure-grouping.pipeline.js +47 -0
  46. package/dist/src/reporter.js +46 -0
  47. package/dist/src/rules.js +32 -0
  48. package/dist/src/runManager.js +19 -0
  49. package/dist/src/runner.js +13 -0
  50. package/dist/src/runtime/networkCollector.js +34 -0
  51. package/dist/src/stackParser.js +17 -0
  52. package/dist/src/test-run.js +48 -0
  53. package/dist/src/types/analysis-result.js +2 -0
  54. package/dist/src/types/failure.types.js +3 -0
  55. package/dist/src/types/playwright-failure.js +2 -0
  56. package/dist/src/types.js +5 -0
  57. package/dist/src/utils/artifact.locator.js +35 -0
  58. package/dist/src/utils/confidence-constants.js +90 -0
  59. package/dist/src/utils/file-utils.js +121 -0
  60. package/dist/src/v2/llm/llm-advisor.js +17 -0
  61. package/dist/src/v2/pipeline/v2-intelligence.pipeline.js +17 -0
  62. package/dist/src/v2/self-healing/self-healer.js +44 -0
  63. package/dist/src/v2/trace-intelligence/trace-analyzer.js +33 -0
  64. package/dist/src/v2-test-run.js +59 -0
  65. package/package.json +23 -0
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeTrend = analyzeTrend;
4
+ function analyzeTrend(history, windowSize = 10) {
5
+ const recent = history.slice(-windowSize);
6
+ const totalRuns = recent.length;
7
+ const passCount = recent.filter(r => r === 'PASS').length;
8
+ const failCount = recent.filter(r => r === 'FAIL').length;
9
+ const passRate = totalRuns ? passCount / totalRuns : 0;
10
+ const failRate = totalRuns ? failCount / totalRuns : 0;
11
+ const oscillations = recent.filter((v, i, arr) => i > 0 && v !== arr[i - 1]).length;
12
+ let flakiness = 'LOW';
13
+ if (oscillations >= 4)
14
+ flakiness = 'HIGH';
15
+ else if (oscillations >= 2)
16
+ flakiness = 'MEDIUM';
17
+ const stability = flakiness === 'HIGH' || failRate > 0.4 ? 'UNSTABLE' : 'STABLE';
18
+ return {
19
+ totalRuns,
20
+ passRate,
21
+ failRate,
22
+ flakiness,
23
+ stability
24
+ };
25
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeAnalysisMarkdown = writeAnalysisMarkdown;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function writeAnalysisMarkdown(baseDir, issueId, result, occurrences) {
10
+ const issueDir = path_1.default.join(baseDir, issueId);
11
+ fs_1.default.mkdirSync(issueDir, { recursive: true });
12
+ const mdPath = path_1.default.join(issueDir, 'analysis.md');
13
+ const content = `
14
+ # ❌ ${result.category}
15
+
16
+ **Occurrences** : ${occurrences}
17
+ **Confidence** : ${result.confidence}
18
+
19
+ ---
20
+
21
+ ## 📍 Failure Location
22
+ - **File** : ${result.location.file}
23
+ - **Line** : ${result.location.line}
24
+
25
+ ---
26
+
27
+ ## 🌐 Failed API Call
28
+ - **Method** : ${result.failedApi.method}
29
+ - **Endpoint** : ${result.failedApi.endpoint}
30
+ - **Status** : ${result.failedApi.status}
31
+ - **Response** : ${result.failedApi.response ?? '-'}
32
+
33
+ ---
34
+
35
+ ## 🧠 Root Cause
36
+ ${result.rootCause}
37
+
38
+ ---
39
+
40
+ ## 🔁 Retry Guidance
41
+ ${result.retryGuidance}
42
+
43
+ ---
44
+
45
+ ## ▶️ Reproduction Steps
46
+ ${result.reproductionSteps.map((s, i) => `${i + 1}. ${s}`).join('\n')}
47
+
48
+ ---
49
+
50
+ ## ✅ Expected Result
51
+ ${result.expected}
52
+
53
+ ---
54
+
55
+ ## ❌ Actual Result
56
+ ${result.actual}
57
+
58
+ ---
59
+
60
+ ## 🛠 Suggested Actions
61
+ ${result.suggestedActions.map(a => `- ${a}`).join('\n')}
62
+ `.trim();
63
+ fs_1.default.writeFileSync(mdPath, content, 'utf-8');
64
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /* src/normalizer.ts */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.normalizeRawInput = normalizeRawInput;
5
+ /**
6
+ * Public normalizer API
7
+ */
8
+ function normalizeRawInput(items) {
9
+ return items.map((item) => {
10
+ const safeItem = item;
11
+ return {
12
+ rootCause: safeItem.message,
13
+ actual: safeItem.message,
14
+ response: safeItem.api?.response
15
+ };
16
+ });
17
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.analyzePasses = analyzePasses;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function analyzePasses() {
10
+ const passPath = path_1.default.join(process.cwd(), 'input/raw-pass.json');
11
+ const items = JSON.parse(fs_1.default.readFileSync(passPath, 'utf-8'));
12
+ const risks = [];
13
+ items.forEach((item) => {
14
+ // Flaky pass
15
+ if (item.retries > 0) {
16
+ risks.push({
17
+ test: item.test,
18
+ riskType: 'FLAKY_PASS',
19
+ location: { file: item.test, line: -1 },
20
+ reason: 'Test passed after retry',
21
+ fix: 'Stabilize locator or add explicit waits'
22
+ });
23
+ }
24
+ // API warnings during pass
25
+ item.apiEvents?.forEach((api) => {
26
+ if (api.status >= 400 && api.recovered) {
27
+ risks.push({
28
+ test: item.test,
29
+ riskType: 'API_WARNING',
30
+ location: { file: item.test, line: -1 },
31
+ reason: `${api.method} ${api.endpoint} failed with ${api.status} but recovered`,
32
+ fix: 'Investigate backend instability or add retry with backoff'
33
+ });
34
+ }
35
+ });
36
+ });
37
+ return risks;
38
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.summarizeWithAI = summarizeWithAI;
4
+ async function summarizeWithAI(input) {
5
+ // 🔒 Safety first — AI is OPTIONAL
6
+ if (!process.env.AI_ENABLED) {
7
+ return deterministicFallback(input);
8
+ }
9
+ try {
10
+ // 🔹 Placeholder for real LLM call
11
+ // 🔹 Intentionally simple & replaceable
12
+ return `
13
+ This failure occurred in the test "${input.testName}".
14
+ Based on the observed error and system heuristics, the root cause is classified as:
15
+ "${input.rootCause}"
16
+
17
+ The confidence score (${(input.confidence / 100).toFixed(2)}) indicates a stable and repeatable issue.
18
+ Recommended action is to follow the suggested remediation rather than retrying the test.
19
+ `.trim();
20
+ }
21
+ catch {
22
+ // 🔒 Never crash pipeline because of AI
23
+ return deterministicFallback(input);
24
+ }
25
+ }
26
+ function deterministicFallback(input) {
27
+ return `
28
+ Failure in "${input.testName}" was analyzed deterministically.
29
+ Root cause identified as: ${input.rootCause}.
30
+ Confidence level: ${(input.confidence / 100).toFixed(2)}.
31
+ `.trim();
32
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ // src/pipeline/failure-analysis.pipeline.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.runFailureAnalysisFromPlaywright = runFailureAnalysisFromPlaywright;
5
+ const playwright_folder_adapter_1 = require("../adapters/playwright-folder.adapter");
6
+ /**
7
+ * Phase 1 – Playwright Failure Intake (Folder-based)
8
+ */
9
+ async function runFailureAnalysisFromPlaywright(playwrightResultsDir) {
10
+ return (0, playwright_folder_adapter_1.parsePlaywrightFailureFolders)(playwrightResultsDir);
11
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ // src/pipeline/failure-grouping.pipeline.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.groupFailures = groupFailures;
5
+ const failure_history_store_1 = require("../history/failure-history.store");
6
+ const failure_trend_analyzer_1 = require("../history/failure-trend.analyzer");
7
+ function groupFailures(results) {
8
+ const groupedCounts = {};
9
+ let flakyCount = 0;
10
+ for (const r of results) {
11
+ const key = r.classification ?? "UNKNOWN";
12
+ groupedCounts[key] = (groupedCounts[key] || 0) + 1;
13
+ if (key === "FLAKY") {
14
+ flakyCount++;
15
+ }
16
+ }
17
+ let dominantCategory = "UNKNOWN";
18
+ let dominantCount = 0;
19
+ for (const [category, count] of Object.entries(groupedCounts)) {
20
+ if (count > dominantCount) {
21
+ dominantCategory = category;
22
+ dominantCount = count;
23
+ }
24
+ }
25
+ const total = results.length || 1;
26
+ let confidence = dominantCount / total;
27
+ // 🔻 FLAKY PENALTY (KEY LOGIC)
28
+ if (flakyCount > 0) {
29
+ const penalty = Math.min(0.3, flakyCount / total);
30
+ confidence = Math.max(0, confidence - penalty);
31
+ }
32
+ const summary = {
33
+ dominantCategory,
34
+ groupedCounts,
35
+ confidence,
36
+ flakyCount
37
+ };
38
+ (0, failure_history_store_1.saveFailureHistory)({
39
+ runId: Date.now().toString(),
40
+ timestamp: new Date().toISOString(),
41
+ dominantCategory,
42
+ groupedCounts,
43
+ confidence
44
+ });
45
+ summary.trend = (0, failure_trend_analyzer_1.analyzeFailureTrends)((0, failure_history_store_1.loadFailureHistory)());
46
+ return summary;
47
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.printSummaryAndWriteReports = printSummaryAndWriteReports;
4
+ exports.printPassRisks = printPassRisks;
5
+ const markdownWriter_1 = require("./markdownWriter");
6
+ /**
7
+ * FAILURES: Print summary + write markdown reports
8
+ */
9
+ function printSummaryAndWriteReports(grouped, run, config) {
10
+ let printed = 0;
11
+ grouped.forEach((items, key) => {
12
+ const sample = items[0];
13
+ // Respect confidence threshold
14
+ if (sample.confidence <
15
+ config.engine.confidenceThresholds.fail) {
16
+ return;
17
+ }
18
+ if (printed === 0) {
19
+ console.log(`❌ Failures Detected (${grouped.size} unique issues)\n`);
20
+ }
21
+ printed++;
22
+ console.log(`${printed}) ${sample.category} (${items.length} occurrences)`);
23
+ console.log(` Location : ${sample.location.file}:${sample.location.line}`);
24
+ console.log(` API : ${sample.failedApi.endpoint} → ${sample.failedApi.status}`);
25
+ console.log(` Cause : ${sample.rootCause}`);
26
+ console.log(` Details : output/${run.runDir.split('/').pop()}/${key}/analysis.md\n`);
27
+ (0, markdownWriter_1.writeAnalysisMarkdown)(run.runDir, key, sample, items.length);
28
+ });
29
+ if (printed === 0) {
30
+ console.log('✅ No failures exceeded confidence threshold\n');
31
+ }
32
+ }
33
+ /**
34
+ * PASSES: Print non-blocking risk warnings
35
+ */
36
+ function printPassRisks(risks, _run) {
37
+ if (risks.length === 0)
38
+ return;
39
+ console.log(`⚠️ Pass Risks Detected (${risks.length})\n`);
40
+ risks.forEach((risk, i) => {
41
+ console.log(`${i + 1}) ${risk.test} → ${risk.riskType}`);
42
+ console.log(` Location : ${risk.location.file}`);
43
+ console.log(` Reason : ${risk.reason}`);
44
+ console.log(` Fix : ${risk.fix}\n`);
45
+ });
46
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDummyResult = generateDummyResult;
4
+ function generateDummyResult() {
5
+ return {
6
+ category: 'BACKEND_API_FAILURE',
7
+ confidence: 0.93,
8
+ location: {
9
+ file: 'AuthController.java',
10
+ line: 87
11
+ },
12
+ failedApi: {
13
+ method: 'GET',
14
+ endpoint: '/users/{id}',
15
+ status: 404,
16
+ response: 'User not found'
17
+ },
18
+ rootCause: 'The requested user ID does not exist in the database.',
19
+ retryGuidance: 'Automated CI retry is not advised (high confidence application failure).',
20
+ reproductionSteps: [
21
+ 'Start backend service',
22
+ 'Run: curl GET /users/{id}',
23
+ 'Observe: 404 Not Found'
24
+ ],
25
+ expected: 'User details are returned successfully.',
26
+ actual: 'API returns 404 and request fails in AuthController.java:87',
27
+ suggestedActions: [
28
+ 'Validate user existence before API call',
29
+ 'Add graceful handling for missing user records'
30
+ ]
31
+ };
32
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createRunContext = createRunContext;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function createRunContext() {
10
+ const now = new Date();
11
+ const runId = now
12
+ .toISOString()
13
+ .replace(/[:.]/g, '-')
14
+ .replace('T', '_')
15
+ .replace('Z', '');
16
+ const runDir = path_1.default.join(process.cwd(), 'output', `run-${runId}`);
17
+ fs_1.default.mkdirSync(runDir, { recursive: true });
18
+ return { runId, runDir };
19
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // src/runner.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.runQualityIntelligence = runQualityIntelligence;
5
+ const failure_analysis_pipeline_1 = require("./pipeline/failure-analysis.pipeline");
6
+ const failure_grouping_pipeline_1 = require("./pipeline/failure-grouping.pipeline");
7
+ const intelligence_pipeline_1 = require("./intelligence/intelligence.pipeline");
8
+ async function runQualityIntelligence(input) {
9
+ const analysisResults = await (0, failure_analysis_pipeline_1.runFailureAnalysisFromPlaywright)(input);
10
+ const summary = (0, failure_grouping_pipeline_1.groupFailures)(analysisResults);
11
+ const enriched = await (0, intelligence_pipeline_1.enrichWithIntelligence)(summary);
12
+ return enriched;
13
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.attachNetworkCollector = attachNetworkCollector;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function attachNetworkCollector(page, testId) {
10
+ const failures = [];
11
+ page.on('response', response => {
12
+ if (response.status() >= 400) {
13
+ failures.push({
14
+ method: response.request().method(),
15
+ url: new URL(response.url()).pathname,
16
+ status: response.status()
17
+ });
18
+ }
19
+ });
20
+ page.on('requestfailed', request => {
21
+ failures.push({
22
+ method: request.method(),
23
+ url: new URL(request.url()).pathname,
24
+ error: request.failure()?.errorText
25
+ });
26
+ });
27
+ process.on('exit', () => {
28
+ if (failures.length === 0)
29
+ return;
30
+ const dir = path_1.default.join('test-results', testId);
31
+ fs_1.default.mkdirSync(dir, { recursive: true });
32
+ fs_1.default.writeFileSync(path_1.default.join(dir, 'network.json'), JSON.stringify(failures, null, 2));
33
+ });
34
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseStackTrace = parseStackTrace;
4
+ function parseStackTrace(stack) {
5
+ if (!stack || stack.length === 0) {
6
+ return { file: 'Unknown', line: -1 };
7
+ }
8
+ // Supports formats like: Class.method(File.java:87)
9
+ const match = stack[0].match(/\((.*):(\d+)\)/);
10
+ if (!match) {
11
+ return { file: 'Unknown', line: -1 };
12
+ }
13
+ return {
14
+ file: match[1],
15
+ line: Number(match[2])
16
+ };
17
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ // src/test-run.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const runner_1 = require("./runner");
5
+ function line(char = "=", count = 60) {
6
+ console.log(char.repeat(count));
7
+ }
8
+ async function main() {
9
+ const playwrightResultsDir = "playwright-results";
10
+ const result = await (0, runner_1.runQualityIntelligence)(playwrightResultsDir);
11
+ line();
12
+ console.log("QUALITY INTELLIGENCE – FINAL OUTPUT");
13
+ line();
14
+ console.log(`Primary Failure : ${result.dominantCategory}`);
15
+ console.log(`Confidence Score : ${result.confidence}`);
16
+ console.log(`Flaky Failures : ${result.flakyCount}`);
17
+ console.log(`Trend Signal : ${result.trend?.signal ?? "N/A"}`);
18
+ line("-");
19
+ console.log("Failure Breakdown:");
20
+ for (const [k, v] of Object.entries(result.groupedCounts)) {
21
+ console.log(` - ${k}: ${v}`);
22
+ }
23
+ line("-");
24
+ console.log("Confidence Diagnosis:");
25
+ for (const lineText of result.intelligence.confidence.explanation) {
26
+ console.log(` • ${lineText}`);
27
+ }
28
+ line("-");
29
+ console.log("AI Explanation:");
30
+ console.log(` Summary: ${result.intelligence.explanation.summary}`);
31
+ if (result.intelligence.explanation.reasoning?.length) {
32
+ console.log(" Reasoning:");
33
+ for (const r of result.intelligence.explanation.reasoning) {
34
+ console.log(` - ${r}`);
35
+ }
36
+ }
37
+ if (result.intelligence.explanation.recommendedAction?.length) {
38
+ console.log(" Recommended Actions:");
39
+ for (const a of result.intelligence.explanation.recommendedAction) {
40
+ console.log(` - ${a}`);
41
+ }
42
+ }
43
+ line();
44
+ }
45
+ main().catch(err => {
46
+ console.error("QUALITY INTELLIGENCE FAILED");
47
+ console.error(err);
48
+ });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // src/types/failure.types.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ // =====================
3
+ // RAW INPUT TYPES
4
+ // =====================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.locatePlaywrightArtifacts = locatePlaywrightArtifacts;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function locatePlaywrightArtifacts() {
10
+ const resultsDir = path_1.default.resolve('test-results');
11
+ const screenshots = [];
12
+ let trace;
13
+ if (!fs_1.default.existsSync(resultsDir)) {
14
+ return { screenshots, trace };
15
+ }
16
+ const runDirs = fs_1.default.readdirSync(resultsDir);
17
+ for (const dir of runDirs) {
18
+ const fullDir = path_1.default.join(resultsDir, dir);
19
+ if (!fs_1.default.statSync(fullDir).isDirectory())
20
+ continue;
21
+ const files = fs_1.default.readdirSync(fullDir);
22
+ for (const file of files) {
23
+ const fullPath = path_1.default.join(fullDir, file);
24
+ // 🎥 Trace ZIP (take the latest retry if exists)
25
+ if (file === 'trace.zip') {
26
+ trace = fullPath;
27
+ }
28
+ // 📸 Screenshots
29
+ if (file.endsWith('.png')) {
30
+ screenshots.push(fullPath);
31
+ }
32
+ }
33
+ }
34
+ return { trace, screenshots };
35
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ /**
3
+ * Confidence Calculation Constants
4
+ *
5
+ * These constants define the base confidence levels and adjustments
6
+ * used throughout the quality intelligence engine.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.TAXONOMY_BASE_CONFIDENCE = exports.CONFIDENCE_THRESHOLDS = exports.CONFIDENCE_BOUNDS = exports.CONFIDENCE_ADJUSTMENTS = exports.BASE_CONFIDENCE = void 0;
10
+ exports.clampConfidence = clampConfidence;
11
+ exports.formatConfidence = formatConfidence;
12
+ /**
13
+ * Base confidence levels for different error types
14
+ */
15
+ exports.BASE_CONFIDENCE = {
16
+ /** Strong backend failure signal (5xx errors) */
17
+ BACKEND_SERVER_ERROR: 0.95,
18
+ /** Backend API failure (any API error) */
19
+ BACKEND_API_ERROR: 0.9,
20
+ /** Test or automation failure */
21
+ TEST_ERROR: 0.75,
22
+ /** Unknown or weak signal */
23
+ UNKNOWN: 0.6,
24
+ };
25
+ /**
26
+ * Confidence adjustments based on test context and signals
27
+ */
28
+ exports.CONFIDENCE_ADJUSTMENTS = {
29
+ /** UI successfully rendered and reached assertion */
30
+ UI_RENDERED: 0.05,
31
+ /** Test involves authentication or login flow */
32
+ AUTH_FLOW_DETECTED: 0.05,
33
+ /** Explicit authentication failure detected */
34
+ EXPLICIT_AUTH_FAILURE: 0.1,
35
+ /** Test involves inventory or data operations */
36
+ DATA_OPERATION_DETECTED: 0.05,
37
+ /** Numeric mismatch detected in assertions */
38
+ NUMERIC_MISMATCH: 0.05,
39
+ };
40
+ /**
41
+ * Maximum and minimum confidence bounds
42
+ */
43
+ exports.CONFIDENCE_BOUNDS = {
44
+ /** Maximum confidence score (never 100% certain) */
45
+ MAX: 0.95,
46
+ /** Minimum confidence score for reporting */
47
+ MIN: 0.5,
48
+ };
49
+ /**
50
+ * Confidence thresholds for decision making
51
+ */
52
+ exports.CONFIDENCE_THRESHOLDS = {
53
+ /** Threshold for blocking CI/CD (high confidence failure) */
54
+ FAIL: 0.85,
55
+ /** Threshold for reporting pass risks */
56
+ PASS_RISK: 0.6,
57
+ /** Threshold for investigating (medium confidence) */
58
+ INVESTIGATE: 0.7,
59
+ /** Threshold for shipping (high confidence in safety) */
60
+ SHIP: 0.85,
61
+ };
62
+ /**
63
+ * Taxonomy rule base confidence levels
64
+ */
65
+ exports.TAXONOMY_BASE_CONFIDENCE = {
66
+ /** Numeric data mismatch */
67
+ NUMERIC_MISMATCH: 0.6,
68
+ /** Authentication failure */
69
+ AUTH_FAILURE: 0.7,
70
+ /** UI visibility issue */
71
+ VISIBILITY: 0.7,
72
+ /** Network timeout */
73
+ TIMEOUT: 0.65,
74
+ /** Element not found */
75
+ ELEMENT_NOT_FOUND: 0.7,
76
+ /** Default fallback */
77
+ DEFAULT: 0.7,
78
+ };
79
+ /**
80
+ * Helper function to clamp confidence within bounds
81
+ */
82
+ function clampConfidence(value) {
83
+ return Math.max(exports.CONFIDENCE_BOUNDS.MIN, Math.min(exports.CONFIDENCE_BOUNDS.MAX, value));
84
+ }
85
+ /**
86
+ * Helper function to format confidence as percentage string
87
+ */
88
+ function formatConfidence(value) {
89
+ return `${(value * 100).toFixed(1)}%`;
90
+ }