@agents-forge/aiqa 1.0.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 (43) hide show
  1. package/CLAUDE.md +112 -0
  2. package/README.md +281 -0
  3. package/dist/agent.d.ts +41 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +485 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/cli.d.ts +13 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +195 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +59 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +53 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/index.d.ts +18 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +15 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/session.d.ts +50 -0
  20. package/dist/session.d.ts.map +1 -0
  21. package/dist/session.js +99 -0
  22. package/dist/session.js.map +1 -0
  23. package/dist/subagents/analyst.d.ts +3 -0
  24. package/dist/subagents/analyst.d.ts.map +1 -0
  25. package/dist/subagents/analyst.js +96 -0
  26. package/dist/subagents/analyst.js.map +1 -0
  27. package/dist/subagents/qa-engineer.d.ts +4 -0
  28. package/dist/subagents/qa-engineer.d.ts.map +1 -0
  29. package/dist/subagents/qa-engineer.js +139 -0
  30. package/dist/subagents/qa-engineer.js.map +1 -0
  31. package/dist/subagents/qa-planner.d.ts +3 -0
  32. package/dist/subagents/qa-planner.d.ts.map +1 -0
  33. package/dist/subagents/qa-planner.js +69 -0
  34. package/dist/subagents/qa-planner.js.map +1 -0
  35. package/dist/subagents/qa-reporter.d.ts +4 -0
  36. package/dist/subagents/qa-reporter.d.ts.map +1 -0
  37. package/dist/subagents/qa-reporter.js +94 -0
  38. package/dist/subagents/qa-reporter.js.map +1 -0
  39. package/dist/subagents/qa-reviewer.d.ts +3 -0
  40. package/dist/subagents/qa-reviewer.d.ts.map +1 -0
  41. package/dist/subagents/qa-reviewer.js +97 -0
  42. package/dist/subagents/qa-reviewer.js.map +1 -0
  43. package/package.json +65 -0
@@ -0,0 +1,4 @@
1
+ import type { Session } from "../session.js";
2
+ import type { AIQAPaths } from "../config.js";
3
+ export declare function buildQAEngineerPrompt(session: Session, paths: Required<AIQAPaths>): string;
4
+ //# sourceMappingURL=qa-engineer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-engineer.d.ts","sourceRoot":"","sources":["../../src/subagents/qa-engineer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,MAAM,CA2I1F"}
@@ -0,0 +1,139 @@
1
+ export function buildQAEngineerPrompt(session, paths) {
2
+ const base = paths.base;
3
+ const scriptsDir = `${base}/${paths.testScripts}`;
4
+ const reportsDir = `${base}/${paths.reports}`;
5
+ const resultsDir = `${reportsDir}/test-results`;
6
+ const htmlDir = `${reportsDir}/playwright-report`;
7
+ const authState = `${base}/auth-state.json`;
8
+ const snapshotList = Object.values(session.snapshots)
9
+ .map((s) => `- ${s.page}: ${s.filePath} (${s.url})`)
10
+ .join("\n") || "- No snapshots available";
11
+ return `You are acting as a Senior QA Engineer with 15+ years experience.
12
+
13
+ INPUTS:
14
+ - Test plan: "${session.outputs.testPlan}"
15
+ - Snapshots:
16
+ ${snapshotList}
17
+ - Auth state: "${session.outputs.authState}" (if exists)
18
+
19
+ OUTPUTS:
20
+ - Test cases: "${session.outputs.testCasesDir}/<module>.md"
21
+ - Spec files: "${session.outputs.specsDir}/<module>.spec.ts"
22
+ - Playwright config: "${session.outputs.playwrightConfig}"
23
+
24
+ BASE URL: "${session.baseUrl}"
25
+
26
+ ## Process
27
+
28
+ ### Step 1 — Read all inputs
29
+ Read the test plan and every snapshot file.
30
+ The snapshots contain accessibility trees with element refs — use these for accurate selectors.
31
+
32
+ ### Step 2 — For each module in the test plan
33
+
34
+ #### 2a. Write test-cases/<module>.md
35
+ \`\`\`markdown
36
+ # <Module> — Test Cases
37
+
38
+ ## Smoke Tests (@smoke @p0)
39
+ | ID | Title | Preconditions | Steps | Expected Result |
40
+ |---|---|---|---|---|
41
+ | TC-<MOD>-S-001 | ... | ... | 1. ... | ... |
42
+
43
+ ## Regression Tests (@regression @p1)
44
+ ## Negative Tests (@negative @p1)
45
+ ## Edge Cases (@edge @p2)
46
+ \`\`\`
47
+
48
+ #### 2b. Generate tests/<module>.spec.ts using playwright-cli
49
+
50
+ First check if playwright-cli is available:
51
+ \`\`\`bash
52
+ playwright-cli --version
53
+ \`\`\`
54
+
55
+ If available — use it to generate scripts:
56
+ \`\`\`bash
57
+ playwright-cli generate "${session.outputs.specsDir}/<module>.spec.ts" --url "${session.baseUrl}/<module-path>"
58
+ \`\`\`
59
+
60
+ Then enhance the generated file by:
61
+ - Reading the snapshot for this module to verify selectors
62
+ - Organising into describe blocks by test type
63
+ - Adding TC IDs matching the .md file
64
+ - Adding tags (@smoke @p0 etc.)
65
+ - Replacing any weak selectors with ones from the snapshot accessibility tree
66
+
67
+ If playwright-cli is NOT available — write spec files directly using snapshot refs:
68
+
69
+ \`\`\`typescript
70
+ import { test, expect } from "@playwright/test";
71
+
72
+ const BASE_URL = process.env.BASE_URL || "${session.baseUrl}";
73
+
74
+ test.describe("<Module> — Smoke", () => {
75
+ test("TC-<MOD>-S-001 — <title> @smoke @p0", async ({ page }) => {
76
+ await page.goto(BASE_URL);
77
+ // Use REAL selectors from snapshot accessibility tree
78
+ await page.getByRole("button", { name: "<actual name from snapshot>" }).click();
79
+ await expect(page.getByRole("<role>", { name: "<name>" })).toBeVisible();
80
+ });
81
+ });
82
+
83
+ test.describe("<Module> — Regression", () => { /* ... */ });
84
+ test.describe("<Module> — Negative", () => { /* ... */ });
85
+ test.describe("<Module> — Edge Cases", () => { /* ... */ });
86
+ \`\`\`
87
+
88
+ ### Step 3 — Write the Playwright config to "${session.outputs.playwrightConfig}"
89
+ The config lives at the project root, but ALL generated test artifacts live under .aiqa/.
90
+ Use these exact paths:
91
+ \`\`\`typescript
92
+ import { defineConfig, devices } from "@playwright/test";
93
+ import fs from "fs";
94
+
95
+ export default defineConfig({
96
+ testDir: "./${scriptsDir}",
97
+ // Keep ALL Playwright output under ${base}/ so nothing lands in the repo root.
98
+ outputDir: "./${resultsDir}",
99
+ fullyParallel: true,
100
+ forbidOnly: !!process.env.CI,
101
+ retries: process.env.CI ? 2 : 0,
102
+ workers: process.env.CI ? 1 : undefined,
103
+ reporter: [
104
+ ["html", { outputFolder: "./${htmlDir}", open: "never" }],
105
+ ["json", { outputFile: "./${resultsDir}/results.json" }],
106
+ ["junit", { outputFile: "./${resultsDir}/results.xml" }],
107
+ ],
108
+ use: {
109
+ baseURL: process.env.BASE_URL || "${session.baseUrl}",
110
+ trace: "on-first-retry",
111
+ screenshot: "only-on-failure",
112
+ video: "on-first-retry",
113
+ storageState: fs.existsSync("./${authState}")
114
+ ? "./${authState}"
115
+ : undefined,
116
+ },
117
+ projects: [
118
+ { name: "chromium", use: { ...devices["Desktop Chrome"] } },
119
+ { name: "firefox", use: { ...devices["Desktop Firefox"] } },
120
+ { name: "webkit", use: { ...devices["Desktop Safari"] } },
121
+ { name: "mobile", use: { ...devices["Pixel 5"] } },
122
+ ],
123
+ });
124
+ \`\`\`
125
+
126
+ ### Step 4 — Verify files
127
+ \`\`\`bash
128
+ find "${session.outputs.testCasesDir}" -name "*.md" | sort
129
+ find "${session.outputs.specsDir}" -name "*.spec.ts" | sort
130
+ \`\`\`
131
+
132
+ ## Quality standards
133
+ - ALWAYS use selectors from snapshot accessibility trees — never guess
134
+ - Every spec test must map to a TC ID in the corresponding .md file
135
+ - Tests must be fully independent — no shared state
136
+ - Use getByRole(), getByLabel(), getByTestId() — never CSS classes or XPath
137
+ - If auth-state.json exists, use it so tests start authenticated where needed`;
138
+ }
139
+ //# sourceMappingURL=qa-engineer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-engineer.js","sourceRoot":"","sources":["../../src/subagents/qa-engineer.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CAAC,OAAgB,EAAE,KAA0B;IAChF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,UAAU,GAAG,GAAG,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,GAAG,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,GAAG,UAAU,eAAe,CAAC;IAChD,MAAM,OAAO,GAAG,GAAG,UAAU,oBAAoB,CAAC;IAClD,MAAM,SAAS,GAAG,GAAG,IAAI,kBAAkB,CAAC;IAE5C,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAClD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC;SACnD,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC;IAE5C,OAAO;;;gBAGO,OAAO,CAAC,OAAO,CAAC,QAAQ;;EAEtC,YAAY;iBACG,OAAO,CAAC,OAAO,CAAC,SAAS;;;iBAGzB,OAAO,CAAC,OAAO,CAAC,YAAY;iBAC5B,OAAO,CAAC,OAAO,CAAC,QAAQ;wBACjB,OAAO,CAAC,OAAO,CAAC,gBAAgB;;aAE3C,OAAO,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiCD,OAAO,CAAC,OAAO,CAAC,QAAQ,6BAA6B,OAAO,CAAC,OAAO;;;;;;;;;;;;;;;4CAenD,OAAO,CAAC,OAAO;;;;;;;;;;;;;;;;+CAgBZ,OAAO,CAAC,OAAO,CAAC,gBAAgB;;;;;;;;gBAQ/D,UAAU;wCACc,IAAI;kBAC1B,UAAU;;;;;;kCAMM,OAAO;gCACT,UAAU;iCACT,UAAU;;;wCAGH,OAAO,CAAC,OAAO;;;;qCAIlB,SAAS;aACjC,SAAS;;;;;;;;;;;;;;QAcd,OAAO,CAAC,OAAO,CAAC,YAAY;QAC5B,OAAO,CAAC,OAAO,CAAC,QAAQ;;;;;;;;8EAQ8C,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Session } from "../session.js";
2
+ export declare function buildQAPlannerPrompt(session: Session): string;
3
+ //# sourceMappingURL=qa-planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-planner.d.ts","sourceRoot":"","sources":["../../src/subagents/qa-planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAoE7D"}
@@ -0,0 +1,69 @@
1
+ export function buildQAPlannerPrompt(session) {
2
+ const snapshotList = Object.values(session.snapshots)
3
+ .map((s) => `- ${s.page}: ${s.filePath} (${s.url})`)
4
+ .join("\n") || "- No snapshots yet (analyst may still be running)";
5
+ return `You are acting as a Senior QA Lead / Test Manager with 15+ years experience.
6
+
7
+ INPUT: "${session.outputs.requirements}"
8
+ SNAPSHOTS:
9
+ ${snapshotList}
10
+ OUTPUT: "${session.outputs.testPlan}"
11
+ BASE URL: "${session.baseUrl}"
12
+
13
+ ## Process
14
+
15
+ ### Step 1 — Read inputs
16
+ Use the Read tool to read:
17
+ 1. "${session.outputs.requirements}" — the requirements document
18
+ 2. Each snapshot file listed above — to understand actual UI complexity
19
+
20
+ ### Step 2 — Analyse snapshot complexity
21
+ For each snapshot, assess:
22
+ - Number of interactive elements (forms, buttons, links)
23
+ - Authentication requirements
24
+ - Dynamic content (lists, pagination, filters)
25
+ - Integration points (payment, maps, social login)
26
+ Use this to assign accurate P0/P1/P2 priorities and risk levels.
27
+
28
+ ### Step 3 — Write "${session.outputs.testPlan}"
29
+
30
+ Sections:
31
+ 1. **Document Info** — version, date, status
32
+ 2. **Executive Summary** — testing objectives
33
+ 3. **Scope** — in scope / out of scope (reference actual features from requirements)
34
+ 4. **Test Objectives** — numbered, measurable goals
35
+ 5. **Test Strategy**
36
+ | Type | Description | Priority |
37
+ | Smoke | Critical path | P0 |
38
+ | Regression | Full coverage | P1 |
39
+ | Negative | Error handling | P1 |
40
+ | Edge | Boundaries | P2 |
41
+ | Accessibility | WCAG 2.1 AA | P2 |
42
+
43
+ 6. **Feature Areas & Test Coverage**
44
+ For each feature from requirements:
45
+ - Feature name
46
+ - Snapshot reference (which .yml file shows this)
47
+ - Test types needed
48
+ - Priority (P0/P1/P2)
49
+ - Risk level (High/Medium/Low)
50
+ - Risk reason (based on what you saw in the snapshot)
51
+
52
+ 7. **Risk Analysis** — table with likelihood, impact, mitigation
53
+ 8. **Test Environments** — browsers, devices, test data
54
+ 9. **Entry & Exit Criteria**
55
+ 10. **Test Tagging Model**
56
+ \`\`\`
57
+ @smoke @regression @negative @edge @p0 @p1 @p2
58
+ \`\`\`
59
+ 11. **Module List** — list every module to be tested (one per feature area)
60
+ This list will be used by qa-engineer to create one spec file per module.
61
+ 12. **Assumptions & Dependencies**
62
+ 13. **Sign-off**
63
+
64
+ ## Quality standards
65
+ - Every feature area must reference its snapshot file
66
+ - Risk levels must be justified by what you actually saw in the UI
67
+ - Module list must be explicit — qa-engineer uses it directly`;
68
+ }
69
+ //# sourceMappingURL=qa-planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-planner.js","sourceRoot":"","sources":["../../src/subagents/qa-planner.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAClD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC;SACnD,IAAI,CAAC,IAAI,CAAC,IAAI,mDAAmD,CAAC;IAErE,OAAO;;UAEC,OAAO,CAAC,OAAO,CAAC,YAAY;;EAEpC,YAAY;WACH,OAAO,CAAC,OAAO,CAAC,QAAQ;aACtB,OAAO,CAAC,OAAO;;;;;;MAMtB,OAAO,CAAC,OAAO,CAAC,YAAY;;;;;;;;;;;sBAWZ,OAAO,CAAC,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8DAuCgB,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Session } from "../session.js";
2
+ import type { AIQAPaths } from "../config.js";
3
+ export declare function buildQAReporterPrompt(session: Session, grep?: string, paths?: Required<AIQAPaths>): string;
4
+ //# sourceMappingURL=qa-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-reporter.d.ts","sourceRoot":"","sources":["../../src/subagents/qa-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,MAAM,CA6F1G"}
@@ -0,0 +1,94 @@
1
+ export function buildQAReporterPrompt(session, grep, paths) {
2
+ const resultsJson = `${session.outputs.testResultsDir}/results.json`;
3
+ const reportsRel = paths ? `${paths.base}/${paths.reports}` : ".aiqa/reports";
4
+ const resultsRel = `${reportsRel}/test-results`;
5
+ const htmlRel = `${reportsRel}/playwright-report`;
6
+ return `You are acting as a Senior QA Lead writing an executive test execution report.
7
+
8
+ INPUTS:
9
+ - Review report: "${session.outputs.reviewReport}"
10
+ - Playwright config: "${session.outputs.playwrightConfig}"
11
+ - Test results (after run): "${resultsJson}"
12
+ - Snapshots dir: "${session.outputs.snapshotsDir}" (for failure context)
13
+
14
+ OUTPUT: "${session.outputs.summaryReport}"
15
+ BASE URL: "${session.baseUrl}"
16
+ ${grep ? `TEST FILTER: ${grep}` : ""}
17
+
18
+ ## Process
19
+
20
+ ### Step 1 — Run Playwright tests
21
+ Use the Bash tool (run from the project root so playwright.config.ts is picked up):
22
+ \`\`\`bash
23
+ ${grep
24
+ ? `npx playwright test --grep "${grep}" --reporter=json --reporter=html`
25
+ : `npx playwright test --reporter=json --reporter=html`}
26
+ \`\`\`
27
+
28
+ Note the exit code — 0 means all passed, non-zero means failures.
29
+
30
+ ### Step 2 — Read results
31
+ \`\`\`bash
32
+ cat "${resultsJson}"
33
+ \`\`\`
34
+ Extract:
35
+ - Total: passed, failed, skipped, flaky
36
+ - Duration
37
+ - Per-suite breakdown
38
+ - Failed test names + error messages + stack traces
39
+
40
+ ### Step 3 — Capture failure snapshots
41
+ For each FAILED test, use playwright-cli to capture the failure state:
42
+ \`\`\`bash
43
+ playwright-cli open "${session.baseUrl}"
44
+ playwright-cli navigate <failed-test-url>
45
+ playwright-cli snapshot > "${session.outputs.snapshotsDir}/failure-<test-name>.yml"
46
+ playwright-cli screenshot > "${session.outputs.testResultsDir}/failure-<test-name>.png"
47
+ \`\`\`
48
+ This gives visual context for every failure.
49
+
50
+ ### Step 4 — Cross-reference review report
51
+ Read "${session.outputs.reviewReport}".
52
+ For each failure — was it predicted by the reviewer?
53
+ - Yes → "Known issue — flagged in review"
54
+ - No → "Unexpected failure — needs investigation"
55
+
56
+ ### Step 5 — Write "${session.outputs.summaryReport}"
57
+
58
+ \`\`\`markdown
59
+ # Test Execution Report
60
+ Date: <today>
61
+ Environment: ${session.baseUrl}
62
+ Run ID: ${session.runId}
63
+ ${grep ? `Filter: ${grep}` : "Full suite"}
64
+ Status: ✅ PASSED / ❌ FAILED / ⚠️ PARTIAL
65
+ Generated by: @agents-forge/aiqa
66
+
67
+ ## Results Summary
68
+ | ✅ Passed | ❌ Failed | ⏭️ Skipped | 🔄 Flaky | Total | Duration |
69
+
70
+ ## Test Suite Breakdown
71
+ | Module | Passed | Failed | Skipped | Duration |
72
+
73
+ ## ❌ Failed Tests
74
+ For each failure:
75
+ ### <Test Name>
76
+ - **TC ID:** TC-XXX-S-001
77
+ - **Error:** <exact error>
78
+ - **Predicted by reviewer:** Yes/No
79
+ - **Failure snapshot:** ${resultsRel}/failure-<name>.png
80
+ - **Likely cause:** <plain English>
81
+ - **Recommended fix:** <specific action>
82
+
83
+ ## 🔄 Flaky Tests
84
+ ## ⏱️ Slowest Tests (top 5)
85
+ ## Browser Matrix Results
86
+ ## Known Issues Cross-reference
87
+ ## Recommendations
88
+ ## Next Steps
89
+ - [ ] Fix failing tests
90
+ - [ ] Re-run: npx playwright test --grep "<failed-test>"
91
+ - [ ] View HTML report: npx playwright show-report ${htmlRel}
92
+ \`\`\``;
93
+ }
94
+ //# sourceMappingURL=qa-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-reporter.js","sourceRoot":"","sources":["../../src/subagents/qa-reporter.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CAAC,OAAgB,EAAE,IAAa,EAAE,KAA2B;IAChG,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,eAAe,CAAC;IACrE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC;IAC9E,MAAM,UAAU,GAAG,GAAG,UAAU,eAAe,CAAC;IAChD,MAAM,OAAO,GAAG,GAAG,UAAU,oBAAoB,CAAC;IAElD,OAAO;;;oBAGW,OAAO,CAAC,OAAO,CAAC,YAAY;wBACxB,OAAO,CAAC,OAAO,CAAC,gBAAgB;+BACzB,WAAW;oBACtB,OAAO,CAAC,OAAO,CAAC,YAAY;;WAErC,OAAO,CAAC,OAAO,CAAC,aAAa;aAC3B,OAAO,CAAC,OAAO;EAC1B,IAAI,CAAC,CAAC,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;EAOlC,IAAI;QACJ,CAAC,CAAC,+BAA+B,IAAI,mCAAmC;QACxE,CAAC,CAAC,qDAAqD;;;;;;;OAOlD,WAAW;;;;;;;;;;;uBAWK,OAAO,CAAC,OAAO;;6BAET,OAAO,CAAC,OAAO,CAAC,YAAY;+BAC1B,OAAO,CAAC,OAAO,CAAC,cAAc;;;;;QAKrD,OAAO,CAAC,OAAO,CAAC,YAAY;;;;;sBAKd,OAAO,CAAC,OAAO,CAAC,aAAa;;;;;eAKpC,OAAO,CAAC,OAAO;UACpB,OAAO,CAAC,KAAK;EACrB,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC,YAAY;;;;;;;;;;;;;;;;0BAgBf,UAAU;;;;;;;;;;;;qDAYiB,OAAO;OACrD,CAAC;AACR,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Session } from "../session.js";
2
+ export declare function buildQAReviewerPrompt(session: Session): string;
3
+ //# sourceMappingURL=qa-reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-reviewer.d.ts","sourceRoot":"","sources":["../../src/subagents/qa-reviewer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAgG9D"}
@@ -0,0 +1,97 @@
1
+ export function buildQAReviewerPrompt(session) {
2
+ const snapshotList = Object.values(session.snapshots)
3
+ .map((s) => `- ${s.page}: ${s.filePath}`)
4
+ .join("\n") || "- No snapshots available";
5
+ return `You are acting as a Principal QA Engineer / Test Architect conducting a peer review.
6
+
7
+ INPUTS:
8
+ - Test plan: "${session.outputs.testPlan}"
9
+ - Test cases dir: "${session.outputs.testCasesDir}"
10
+ - Specs dir: "${session.outputs.specsDir}"
11
+ - Playwright config: "${session.outputs.playwrightConfig}"
12
+ - Snapshots (ground truth for selector validation):
13
+ ${snapshotList}
14
+
15
+ OUTPUT: "${session.outputs.reviewReport}"
16
+
17
+ ## Process
18
+
19
+ ### Step 1 — Read all files
20
+ Use Read and Glob tools to read:
21
+ 1. "${session.outputs.testPlan}"
22
+ 2. All files in "${session.outputs.testCasesDir}/*.md"
23
+ 3. All files in "${session.outputs.specsDir}/*.spec.ts"
24
+ 4. "${session.outputs.playwrightConfig}"
25
+ 5. Every snapshot file listed above
26
+
27
+ ### Step 2 — Validate selectors against snapshots (KEY FEATURE)
28
+ For every selector used in spec files:
29
+ - Find the corresponding snapshot file for that module
30
+ - Check the selector exists in the accessibility tree
31
+ - Flag any selector that does NOT appear in the snapshot as a 🔴 Critical Issue
32
+
33
+ Example check:
34
+ - Spec uses: page.getByRole("button", { name: "Add to Cart" })
35
+ - Snapshot shows: role=button name="Add to Basket"
36
+ - → Flag as CRITICAL: selector mismatch
37
+
38
+ ### Step 3 — Review test cases
39
+ For each test-cases/<module>.md:
40
+ - ✅ All test types present? (smoke/regression/negative/edge)
41
+ - ✅ TC IDs unique and correctly formatted?
42
+ - ✅ Steps clear and specific?
43
+ - ✅ Expected results measurable?
44
+ - ✅ Coverage complete vs test plan feature areas?
45
+ - ❌ Missing negative/edge cases?
46
+ - ❌ Vague steps or expected results?
47
+
48
+ ### Step 4 — Review spec files
49
+ For each tests/<module>.spec.ts:
50
+ - ✅ Selectors validated against snapshots?
51
+ - ✅ Describe blocks by test type?
52
+ - ✅ TC IDs in test names?
53
+ - ✅ Tests independent?
54
+ - ✅ BASE_URL from env var?
55
+ - ✅ Meaningful assertions?
56
+ - ❌ Brittle selectors?
57
+ - ❌ Missing assertions?
58
+ - ❌ Hardcoded credentials or URLs?
59
+
60
+ ### Step 5 — Check traceability
61
+ Every TC ID in .md files → must have matching test in .spec.ts
62
+ Every feature in test_plan.md → must have test cases
63
+
64
+ ### Step 6 — Write "${session.outputs.reviewReport}"
65
+
66
+ \`\`\`markdown
67
+ # QA Review Report
68
+ Date: <today>
69
+ Status: PASSED / PASSED WITH WARNINGS / NEEDS REVISION
70
+
71
+ ## Executive Summary
72
+ ## Selector Validation Results (vs snapshots)
73
+ | Selector | Spec File | Found in Snapshot | Status |
74
+ |---|---|---|---|
75
+
76
+ ## Coverage Summary
77
+ | Module | Test Cases | Spec Tests | Traceability | Status |
78
+
79
+ ## Issues Found
80
+ ### 🔴 Critical (selector mismatches, missing tests)
81
+ ### 🟡 Warnings (weak assertions, style issues)
82
+ ### 🟢 Suggestions
83
+
84
+ ## Module Reviews
85
+ (per module: test case quality + spec quality)
86
+
87
+ ## Traceability Matrix
88
+ ## Recommendations
89
+ ## Sign-off checklist
90
+ \`\`\`
91
+
92
+ ## Quality standards
93
+ - Selector validation against snapshots is MANDATORY — this is the key value of this reviewer
94
+ - Be specific — reference actual file names, TC IDs, line content
95
+ - Every critical issue must have a recommended fix`;
96
+ }
97
+ //# sourceMappingURL=qa-reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qa-reviewer.js","sourceRoot":"","sources":["../../src/subagents/qa-reviewer.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAClD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;SACxC,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC;IAE5C,OAAO;;;gBAGO,OAAO,CAAC,OAAO,CAAC,QAAQ;qBACnB,OAAO,CAAC,OAAO,CAAC,YAAY;gBACjC,OAAO,CAAC,OAAO,CAAC,QAAQ;wBAChB,OAAO,CAAC,OAAO,CAAC,gBAAgB;;EAEtD,YAAY;;WAEH,OAAO,CAAC,OAAO,CAAC,YAAY;;;;;;MAMjC,OAAO,CAAC,OAAO,CAAC,QAAQ;mBACX,OAAO,CAAC,OAAO,CAAC,YAAY;mBAC5B,OAAO,CAAC,OAAO,CAAC,QAAQ;MACrC,OAAO,CAAC,OAAO,CAAC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAwChB,OAAO,CAAC,OAAO,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mDA+BC,CAAC;AACpD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@agents-forge/aiqa",
3
+ "version": "1.0.0",
4
+ "description": "AI Assisted Quality Engineering — single unified agent with playwright-cli snapshot-aware testing. analyst → qa-planner → qa-engineer → qa-reviewer → qa-reporter",
5
+ "keywords": [
6
+ "ai",
7
+ "agent",
8
+ "qa",
9
+ "playwright",
10
+ "playwright-cli",
11
+ "quality-engineering",
12
+ "test-automation",
13
+ "claude",
14
+ "anthropic",
15
+ "agents-forge",
16
+ "aiqa"
17
+ ],
18
+ "author": "Rohan Patil",
19
+ "license": "MIT",
20
+ "type": "module",
21
+ "main": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "import": "./dist/index.js",
26
+ "types": "./dist/index.d.ts"
27
+ }
28
+ },
29
+ "bin": {
30
+ "aiqa": "dist/cli.js"
31
+ },
32
+ "files": [
33
+ "dist/",
34
+ "CLAUDE.md",
35
+ "README.md"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "dev": "npx tsx src/cli.ts",
40
+ "typecheck": "tsc --noEmit",
41
+ "prepublishOnly": "npm run build"
42
+ },
43
+ "engines": {
44
+ "node": ">=20.0.0"
45
+ },
46
+ "dependencies": {
47
+ "@anthropic-ai/claude-agent-sdk": "latest",
48
+ "jiti": "^2.7.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.0.0",
52
+ "dotenv": "^16.0.0",
53
+ "tsx": "^4.0.0",
54
+ "typescript": "^5.4.0"
55
+ },
56
+ "peerDependencies": {
57
+ "@playwright/test": ">=1.40.0",
58
+ "dotenv": ">=16"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "dotenv": {
62
+ "optional": true
63
+ }
64
+ }
65
+ }