@keber/qa-framework 1.2.0-0 → 1.4.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.
- package/agent-instructions/00-module-analysis.md +3 -0
- package/agent-instructions/01-spec-generation.md +3 -0
- package/agent-instructions/02-test-plan-generation.md +3 -0
- package/agent-instructions/03-test-case-generation.md +3 -0
- package/agent-instructions/04-automation-generation.md +3 -0
- package/agent-instructions/04b-test-stabilization.md +3 -0
- package/agent-instructions/05-ado-integration.md +3 -0
- package/agent-instructions/06-maintenance.md +3 -0
- package/docs/folder-structure-guide.md +19 -18
- package/docs/skills-architecture.md +136 -0
- package/package.json +2 -1
- package/scripts/cli.js +5 -0
- package/scripts/init.js +39 -31
- package/scripts/upgrade.js +187 -0
- package/skills/qa-ado-integration/SKILL.md +103 -0
- package/skills/qa-ado-integration/references/scripts-and-config.md +201 -0
- package/skills/qa-automation/SKILL.md +101 -0
- package/skills/qa-automation/references/config-checklist.md +79 -0
- package/skills/qa-automation/references/patterns.md +180 -0
- package/skills/qa-maintenance/SKILL.md +110 -0
- package/skills/qa-maintenance/references/update-rules.md +118 -0
- package/skills/qa-module-analysis/SKILL.md +95 -0
- package/skills/qa-module-analysis/references/exploration-checklist.md +121 -0
- package/skills/qa-module-analysis/references/spec-file-formats.md +219 -0
- package/skills/qa-spec-generation/SKILL.md +93 -0
- package/skills/qa-test-cases/SKILL.md +89 -0
- package/skills/qa-test-cases/references/test-case-template.md +142 -0
- package/skills/qa-test-plan/SKILL.md +81 -0
- package/skills/qa-test-plan/references/priority-and-feasibility.md +159 -0
- package/skills/qa-test-stabilization/SKILL.md +123 -0
- package/skills/qa-test-stabilization/references/classification-protocol.md +142 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-ado-integration
|
|
3
|
+
description: >
|
|
4
|
+
Optional stage of the QA pipeline. Syncs test plans, test cases, and
|
|
5
|
+
automation results with Azure DevOps (ADO) Test Plans. Injects ADO IDs
|
|
6
|
+
back into local spec files and configures the Playwright ADO reporter.
|
|
7
|
+
Use when asked to sync with Azure DevOps, push test cases to ADO, create
|
|
8
|
+
a test plan in ADO, configure ADO reporting, inject ADO IDs, or link
|
|
9
|
+
Playwright results to ADO.
|
|
10
|
+
Requires ADO enabled in qa-framework.config.json with valid PAT in env vars.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# QA Skill: ADO Integration (Optional Stage)
|
|
14
|
+
|
|
15
|
+
**Stage**: Optional — ADO Integration (no pipeline order dependency)
|
|
16
|
+
**Prerequisite**: ADO configuration in `qa/qa-framework.config.json`; valid `ADO_PAT` env var
|
|
17
|
+
**Output**: ADO Test Plan populated + `qa/08-azure-integration/module-registry.json` updated
|
|
18
|
+
**Use any time** after Stage 4 (Test Cases) or Stage 5 (Automation) are ready to sync
|
|
19
|
+
|
|
20
|
+
> **Credential rule**: NEVER hardcode PAT, username, or organization URL in any file. Always read from env vars or `<PLACEHOLDER>` in documentation.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Inputs Required
|
|
25
|
+
|
|
26
|
+
1. `qa/qa-framework.config.json` — ADO org URL, project name, test plan ID (or "create new")
|
|
27
|
+
2. `qa/03-test-cases/automated/` — TC files with IDs to sync
|
|
28
|
+
3. `ADO_PAT` environment variable — personal access token with Test Plans read/write
|
|
29
|
+
4. Optionally: `qa/08-azure-integration/module-registry.json` for existing ID mapping
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Process
|
|
34
|
+
|
|
35
|
+
### Step 1 — Verify ADO config
|
|
36
|
+
|
|
37
|
+
Check `qa/qa-framework.config.json` for:
|
|
38
|
+
```json
|
|
39
|
+
"ado": {
|
|
40
|
+
"org": "<ADO_ORG_URL>",
|
|
41
|
+
"project": "<PROJECT_NAME>",
|
|
42
|
+
"planId": <PLAN_ID_OR_NULL>
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
If `planId` is null, a new plan will be created in Step 2.
|
|
46
|
+
|
|
47
|
+
### Step 2 — Create or verify Test Plan
|
|
48
|
+
|
|
49
|
+
Use the PowerShell script: `integrations/ado-powershell/scripts/create-testplan-from-mapping.ps1`
|
|
50
|
+
|
|
51
|
+
See `references/scripts-and-config.md` for usage, parameters, and required env vars.
|
|
52
|
+
|
|
53
|
+
Required env vars:
|
|
54
|
+
- `$env:ADO_ORG` — organization URL (e.g., `https://dev.azure.com/myorg`)
|
|
55
|
+
- `$env:ADO_PROJECT` — project name
|
|
56
|
+
- `$env:ADO_PAT` — PAT token
|
|
57
|
+
|
|
58
|
+
### Step 3 — Sync test cases
|
|
59
|
+
|
|
60
|
+
Use `inject-ado-ids.ps1` to push TCs to ADO and write the returned ADO test case IDs back into local TC files.
|
|
61
|
+
|
|
62
|
+
After sync, each TC file must have `adoId: <NNN>` in its YAML frontmatter block.
|
|
63
|
+
|
|
64
|
+
### Step 4 — Configure Playwright ADO reporter
|
|
65
|
+
|
|
66
|
+
See `references/scripts-and-config.md` for the reporter config block to add to `qa/07-automation/playwright.config.ts`.
|
|
67
|
+
|
|
68
|
+
Required fields:
|
|
69
|
+
- `orgUrl`, `projectName`, `planId`, `runName`
|
|
70
|
+
- All values must come from environment variables — no hardcoded IDs
|
|
71
|
+
|
|
72
|
+
### Step 5 — Run sync and validate
|
|
73
|
+
|
|
74
|
+
Run `sync-ado-titles.ps1` after automation runs to update ADO test outcomes from Playwright report JSON.
|
|
75
|
+
|
|
76
|
+
### Step 6 — Update registry
|
|
77
|
+
|
|
78
|
+
Update `qa/08-azure-integration/module-registry.json` with:
|
|
79
|
+
- Module name
|
|
80
|
+
- ADO Plan ID
|
|
81
|
+
- ADO Suite IDs per submodule
|
|
82
|
+
- Sync date
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Troubleshooting Quick Reference
|
|
87
|
+
|
|
88
|
+
| Symptom | Likely cause | Fix |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| 401 Unauthorized | Expired or wrong PAT | Regenerate PAT; check `$env:ADO_PAT` |
|
|
91
|
+
| Plan not found | Wrong planId in config | Verify planId or set to null to create new |
|
|
92
|
+
| TCs not appearing | Wrong suite parent ID | Check `module-registry.json` suite mapping |
|
|
93
|
+
| Reporter not posting | Missing env var at runtime | Pass vars via CI pipeline or `.env` |
|
|
94
|
+
| Duplicate TCs | Re-ran create script | Use `inject-ado-ids.ps1` idempotently |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Outputs
|
|
99
|
+
|
|
100
|
+
- ADO Test Plan populated with test cases
|
|
101
|
+
- `qa/03-test-cases/automated/TC-*.md` — ADO IDs injected
|
|
102
|
+
- `qa/08-azure-integration/module-registry.json` updated
|
|
103
|
+
- `qa/07-automation/playwright.config.ts` updated with reporter config
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Reference: ADO Scripts and Configuration
|
|
2
|
+
|
|
3
|
+
> Loaded by `skills/qa-ado-integration/` for PowerShell scripts, reporter config, and CI pipeline.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## PowerShell Scripts Usage
|
|
8
|
+
|
|
9
|
+
### create-testplan-from-mapping.ps1
|
|
10
|
+
|
|
11
|
+
Creates a new ADO Test Plan with suites and test cases from the mapping JSON file.
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
.\integrations\ado-powershell\scripts\create-testplan-from-mapping.ps1 `
|
|
15
|
+
-Organization $env:ADO_ORG `
|
|
16
|
+
-Project $env:ADO_PROJECT `
|
|
17
|
+
-Token $env:ADO_PAT `
|
|
18
|
+
-MappingFile .\qa\08-azure-integration\ado-ids-mapping-{project}.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Output: `TestPlanId` and `SuiteIds` — record in `module-registry.json`.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### inject-ado-ids.ps1
|
|
26
|
+
|
|
27
|
+
Injects ADO Work Item IDs into Playwright test titles and adds ADO annotations.
|
|
28
|
+
|
|
29
|
+
```powershell
|
|
30
|
+
# Dry run first
|
|
31
|
+
.\integrations\ado-powershell\scripts\inject-ado-ids.ps1 `
|
|
32
|
+
-MappingFile .\qa\08-azure-integration\ado-ids-mapping-{project}.json `
|
|
33
|
+
-TestDir .\qa\07-automation\e2e\tests `
|
|
34
|
+
-DryRun
|
|
35
|
+
|
|
36
|
+
# Apply
|
|
37
|
+
.\integrations\ado-powershell\scripts\inject-ado-ids.ps1 `
|
|
38
|
+
-MappingFile .\qa\08-azure-integration\ado-ids-mapping-{project}.json `
|
|
39
|
+
-TestDir .\qa\07-automation\e2e\tests
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Transforms test titles:
|
|
43
|
+
```
|
|
44
|
+
# Before
|
|
45
|
+
'[TC-OPER-CAT-001] Access catalog list @P0'
|
|
46
|
+
|
|
47
|
+
# After
|
|
48
|
+
'[22957] Access catalog list @P0'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Adds annotation:
|
|
52
|
+
```typescript
|
|
53
|
+
test.info().annotations.push({ type: 'TestCase', description: '22957' });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### sync-ado-titles.ps1
|
|
59
|
+
|
|
60
|
+
Syncs ADO TC titles with local spec file titles (detects drift):
|
|
61
|
+
|
|
62
|
+
```powershell
|
|
63
|
+
.\integrations\ado-powershell\scripts\sync-ado-titles.ps1 `
|
|
64
|
+
-Organization $env:ADO_ORG `
|
|
65
|
+
-Project $env:ADO_PROJECT `
|
|
66
|
+
-Token $env:ADO_PAT `
|
|
67
|
+
-MappingFile .\qa\08-azure-integration\ado-ids-mapping-{project}.json `
|
|
68
|
+
-DryRun
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Apply with `-DryRun:$false`.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## ADO IDs Mapping File
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"planId": 22304,
|
|
80
|
+
"module": "operacion",
|
|
81
|
+
"specsPath": "qa/07-automation/e2e/tests/operacion",
|
|
82
|
+
"suites": [
|
|
83
|
+
{
|
|
84
|
+
"suiteId": 22956,
|
|
85
|
+
"suiteName": "Suite 1.1 - {Submodule Name}",
|
|
86
|
+
"testCases": [
|
|
87
|
+
{ "id": 22957, "title": "Access catalog list @P0", "tags": ["automatable", "playwright"] },
|
|
88
|
+
{ "id": 22958, "title": "Create labor type @P1", "tags": ["automatable", "playwright"] }
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Module Registry
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"modules": [
|
|
102
|
+
{
|
|
103
|
+
"name": "{module-kebab}",
|
|
104
|
+
"specsPath": "qa/07-automation/e2e/tests/{module-kebab}",
|
|
105
|
+
"planId": 0,
|
|
106
|
+
"suiteId": 0,
|
|
107
|
+
"description": "{Module display name} — {N} submodules"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## playwright-azure-reporter Config
|
|
116
|
+
|
|
117
|
+
Add to `qa/07-automation/playwright.config.ts` reporter array:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
['@alex_neo/playwright-azure-reporter', {
|
|
121
|
+
orgUrl: `https://dev.azure.com/${process.env.ADO_ORG}`,
|
|
122
|
+
token: process.env.ADO_PAT,
|
|
123
|
+
planId: Number(process.env.ADO_PLAN_ID),
|
|
124
|
+
projectName: process.env.ADO_PROJECT,
|
|
125
|
+
isDisabled: !process.env.CI, // only publish in CI
|
|
126
|
+
publishTestResultsMode: 'testRun',
|
|
127
|
+
testRunTitle: `QA Run - ${new Date().toISOString()}`,
|
|
128
|
+
uploadAttachments: true,
|
|
129
|
+
attachmentsType: ['screenshot', 'video', 'trace'],
|
|
130
|
+
}]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**`isDisabled: !process.env.CI`** — prevents publishing from local developer runs.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## CI Pipeline Template
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
trigger:
|
|
141
|
+
branches:
|
|
142
|
+
include:
|
|
143
|
+
- {{CI_TRIGGER_BRANCH}}
|
|
144
|
+
|
|
145
|
+
pool:
|
|
146
|
+
vmImage: 'ubuntu-latest'
|
|
147
|
+
|
|
148
|
+
variables:
|
|
149
|
+
- group: qa-secrets # Must contain: QA_USER_EMAIL, QA_USER_PASSWORD, QA_BASE_URL, ADO_PAT, ADO_PLAN_ID
|
|
150
|
+
|
|
151
|
+
steps:
|
|
152
|
+
- checkout: self
|
|
153
|
+
fetchDepth: 2
|
|
154
|
+
|
|
155
|
+
- task: NodeTool@0
|
|
156
|
+
inputs:
|
|
157
|
+
versionSpec: '20.x'
|
|
158
|
+
displayName: 'Install Node.js 20'
|
|
159
|
+
|
|
160
|
+
- script: |
|
|
161
|
+
cd qa/07-automation/e2e
|
|
162
|
+
npm install
|
|
163
|
+
npx playwright install chromium --with-deps
|
|
164
|
+
displayName: 'Install Playwright'
|
|
165
|
+
|
|
166
|
+
- script: |
|
|
167
|
+
cd qa/07-automation/e2e
|
|
168
|
+
npx playwright test
|
|
169
|
+
displayName: 'Run Playwright tests'
|
|
170
|
+
env:
|
|
171
|
+
QA_BASE_URL: $(QA_BASE_URL)
|
|
172
|
+
QA_USER_EMAIL: $(QA_USER_EMAIL)
|
|
173
|
+
QA_USER_PASSWORD: $(QA_USER_PASSWORD)
|
|
174
|
+
ADO_PAT: $(ADO_PAT)
|
|
175
|
+
ADO_PLAN_ID: $(ADO_PLAN_ID)
|
|
176
|
+
CI: 'true'
|
|
177
|
+
|
|
178
|
+
- task: PublishTestResults@2
|
|
179
|
+
inputs:
|
|
180
|
+
testResultsFormat: 'JUnit'
|
|
181
|
+
testResultsFiles: '**/test-results/*.xml'
|
|
182
|
+
displayName: 'Publish JUnit results'
|
|
183
|
+
condition: always()
|
|
184
|
+
|
|
185
|
+
- task: PublishPipelineArtifact@1
|
|
186
|
+
inputs:
|
|
187
|
+
targetPath: 'qa/07-automation/e2e/playwright-report'
|
|
188
|
+
artifact: 'playwright-html-report'
|
|
189
|
+
displayName: 'Publish HTML report'
|
|
190
|
+
condition: always()
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Credential Security Rules
|
|
196
|
+
|
|
197
|
+
1. `ADO_PAT` is **never** committed to any file — always from env var or CI variable group
|
|
198
|
+
2. `ADO_PAT` is **never** logged, printed, or written to any markdown file
|
|
199
|
+
3. If a PAT appears in any log or output: revoke it immediately in ADO Portal, generate new one
|
|
200
|
+
4. Variable group `qa-secrets` must be scoped to the pipeline only — no project-wide access
|
|
201
|
+
5. PAT minimum scopes: `Work Items (Read, Write)`, `Test Management (Read, Write)` — never use full-access PATs
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-automation
|
|
3
|
+
description: >
|
|
4
|
+
Stage 5 of the QA pipeline. Implements Playwright test automation from
|
|
5
|
+
approved specifications. Generates spec files, page objects, fixtures, and
|
|
6
|
+
configures the test runner.
|
|
7
|
+
Use when asked to automate tests, write Playwright specs, implement automation,
|
|
8
|
+
implement test scripts, code the e2e suite, or generate .spec.ts files.
|
|
9
|
+
Requires completed specifications with no PENDING-CODE sections (Stage 2 complete,
|
|
10
|
+
Stage 4 recommended).
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# QA Skill: Automation Generation (Stage 5 of 6)
|
|
14
|
+
|
|
15
|
+
**Stage**: 5 — Automation
|
|
16
|
+
**Prerequisite**: All specs for the target submodule are complete and contain no `PENDING-CODE` sections
|
|
17
|
+
**Output**: `qa/07-automation/e2e/{module}/{submodule}.spec.ts` + supporting files
|
|
18
|
+
**Next stage**: Stage 6 — Maintenance (`qa-maintenance`) or Stage 5b — Stabilization (`qa-test-stabilization`) if tests fail
|
|
19
|
+
|
|
20
|
+
> **Pipeline rule**: Never automate a TC whose spec contains `PENDING-CODE`. Resolve spec gaps first.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Inputs Required
|
|
25
|
+
|
|
26
|
+
1. `qa/01-specifications/{module}/` — full spec set for target submodule
|
|
27
|
+
2. `qa/07-automation/playwright.config.ts` — confirm project name maps to submodule tag
|
|
28
|
+
3. `qa/07-automation/fixtures/auth.ts` — identify available auth fixtures
|
|
29
|
+
4. TC list (from test plan or Stage 4) — defines which TCs to automate in this session
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Process
|
|
34
|
+
|
|
35
|
+
### Step 1 — Scan for blockers
|
|
36
|
+
|
|
37
|
+
Before writing a line of code:
|
|
38
|
+
- Search all spec files for `PENDING-CODE` — stop and flag if found
|
|
39
|
+
- Confirm `playwright.config.ts` exists; scaffold it if missing using `references/config-checklist.md`
|
|
40
|
+
- Verify `fixtures/auth.ts` has the roles required by this submodule
|
|
41
|
+
|
|
42
|
+
### Step 2 — Scaffold spec file
|
|
43
|
+
|
|
44
|
+
Full spec file template and 7 implementation patterns: `references/patterns.md`
|
|
45
|
+
|
|
46
|
+
Required scaffold elements:
|
|
47
|
+
- `import { test, expect } from '@playwright/test'`
|
|
48
|
+
- `const EXEC_IDX = process.env.EXEC_IDX ?? '0'` (prevents DB conflicts in parallel runs)
|
|
49
|
+
- `test.describe('{Submodule Name}', () => { ... })`
|
|
50
|
+
- Use fixture-based auth (never hardcode credentials)
|
|
51
|
+
|
|
52
|
+
### Step 3 — Implement tests in priority order
|
|
53
|
+
|
|
54
|
+
Implement P0 TCs first, then P1. Within each priority, follow scenario order from `05-test-scenarios.md`.
|
|
55
|
+
|
|
56
|
+
For each TC:
|
|
57
|
+
1. Map TC preconditions to `beforeAll`/`beforeEach` setup
|
|
58
|
+
2. Write navigation to the starting URL (use relative paths, not hardcoded base URL)
|
|
59
|
+
3. Use `test.step()` to group logical sub-actions — improves traceability
|
|
60
|
+
4. Assert observable outcomes — avoid asserting internal implementation details
|
|
61
|
+
|
|
62
|
+
### Step 4 — Apply stability rules
|
|
63
|
+
|
|
64
|
+
- Never use `waitForTimeout` — use `waitForSelector`, `waitForResponse`, or role-based locators
|
|
65
|
+
- Prefer `getByRole`, `getByLabel`, `getByTestId` over CSS selectors
|
|
66
|
+
- Locators attached to dynamic data must use `EXEC_IDX` suffix
|
|
67
|
+
- All test data cleared in `afterAll` — never leave residue
|
|
68
|
+
|
|
69
|
+
### Step 5 — Module Completion Checklist
|
|
70
|
+
|
|
71
|
+
Before marking the submodule as ✅ Automation Complete:
|
|
72
|
+
- [ ] All P0 TCs passing in CI
|
|
73
|
+
- [ ] All P1 TCs passing or explicitly deferred (with reason in spec)
|
|
74
|
+
- [ ] No `test.skip` without a linked issue or `PENDING-CODE` tag
|
|
75
|
+
- [ ] `playwright.config.ts` project includes submodule tag
|
|
76
|
+
- [ ] `qa/README.md` automation status updated
|
|
77
|
+
- [ ] AGENT-NEXT-STEPS.md active sprint updated (remove completed items)
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Key Patterns (reference names for Layer 3)
|
|
82
|
+
|
|
83
|
+
| Pattern | When to use |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `EXEC_IDX` | Any TC that creates persistent data |
|
|
86
|
+
| `auth-fixture` | All authenticated TCs |
|
|
87
|
+
| `fast-fail` | P0 TCs — skip P1+ if P0 fails |
|
|
88
|
+
| `email-intercept` | Email verification flows |
|
|
89
|
+
| `skip-conditional` | Scenarios blocked by PENDING-CODE |
|
|
90
|
+
| `beforeAll-setup` | Shared precondition across TC group |
|
|
91
|
+
| `password-env` | Any credential usage |
|
|
92
|
+
|
|
93
|
+
See `references/patterns.md` for full TypeScript implementations.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Outputs
|
|
98
|
+
|
|
99
|
+
- `qa/07-automation/e2e/{module}/{submodule}.spec.ts`
|
|
100
|
+
- `qa/07-automation/playwright.config.ts` (updated or confirmed)
|
|
101
|
+
- `qa/README.md` automation status updated
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Reference: Playwright Config Checklist
|
|
2
|
+
|
|
3
|
+
> Loaded by `skills/qa-automation/` when scaffolding or reviewing `playwright.config.ts`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Required Configuration Template
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
11
|
+
|
|
12
|
+
export default defineConfig({
|
|
13
|
+
testDir: './tests',
|
|
14
|
+
timeout: 30_000, // Per-test timeout
|
|
15
|
+
actionTimeout: 10_000, // Per-action timeout — REQUIRED, prevents silent hangs
|
|
16
|
+
navigationTimeout: 60_000, // Per-navigation timeout (SPAs may need longer)
|
|
17
|
+
retries: process.env.CI ? 2 : 0,
|
|
18
|
+
workers: process.env.CI ? 1 : 2,
|
|
19
|
+
|
|
20
|
+
// Exclude seeds and debug scripts from normal test runs
|
|
21
|
+
testIgnore: ['**/seeds/**', '**/debug-*.spec.ts', '**/seed.spec.ts'],
|
|
22
|
+
|
|
23
|
+
use: {
|
|
24
|
+
baseURL: process.env.QA_BASE_URL,
|
|
25
|
+
storageState: '.auth/session.json',
|
|
26
|
+
locale: 'es-CL', // Adjust to app locale
|
|
27
|
+
screenshot: 'only-on-failure',
|
|
28
|
+
video: 'retain-on-failure',
|
|
29
|
+
trace: 'on-first-retry',
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
reporter: [
|
|
33
|
+
['html', { outputFolder: 'playwright-report' }],
|
|
34
|
+
// ADO reporter — add only when integration is enabled:
|
|
35
|
+
// ['@alex_neo/playwright-azure-reporter', {
|
|
36
|
+
// orgUrl: process.env.ADO_ORG,
|
|
37
|
+
// projectName: process.env.ADO_PROJECT,
|
|
38
|
+
// planId: Number(process.env.ADO_PLAN_ID),
|
|
39
|
+
// token: process.env.ADO_PAT,
|
|
40
|
+
// runName: `Automated run ${new Date().toISOString()}`,
|
|
41
|
+
// }],
|
|
42
|
+
],
|
|
43
|
+
|
|
44
|
+
projects: [
|
|
45
|
+
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
|
46
|
+
// Add when cross-browser coverage required:
|
|
47
|
+
// { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
|
|
48
|
+
// { name: 'webkit', use: { ...devices['Desktop Safari'] } },
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
globalSetup: './global-setup.ts',
|
|
52
|
+
outputDir: '../../05-test-execution/automated/test-results',
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Checklist for Review
|
|
59
|
+
|
|
60
|
+
Before marking automation as complete, confirm:
|
|
61
|
+
|
|
62
|
+
- [ ] `actionTimeout` is set — **not optional**; without it, `textContent()` and similar calls silently hang
|
|
63
|
+
- [ ] `testIgnore` excludes seed scripts and debug files
|
|
64
|
+
- [ ] `baseURL` reads from `process.env.QA_BASE_URL` (never hardcoded)
|
|
65
|
+
- [ ] `storageState` path exists (created by `globalSetup`)
|
|
66
|
+
- [ ] `outputDir` points to `qa/05-test-execution/automated/test-results`
|
|
67
|
+
- [ ] `retries: 2` in CI for flake tolerance
|
|
68
|
+
- [ ] `workers: 1` in CI (or EXEC_IDX used to handle parallel conflicts)
|
|
69
|
+
- [ ] ADO reporter commented out unless ADO integration is active
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## global-setup.ts Checklist
|
|
74
|
+
|
|
75
|
+
- [ ] Reads every credential from `process.env` — no hardcoded values
|
|
76
|
+
- [ ] Uses `evaluate()` for password input (trace safety)
|
|
77
|
+
- [ ] Saves storageState to `.auth/session.json` (or per-role paths)
|
|
78
|
+
- [ ] Handles login failure explicitly (does not silently save an unauthenticated state)
|
|
79
|
+
- [ ] Runs sequentially for multiple roles (no parallel logins)
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Reference: Automation Patterns
|
|
2
|
+
|
|
3
|
+
> Loaded by `skills/qa-automation/` when implementing Playwright tests.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Spec File Template
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
/**
|
|
11
|
+
* @module {MODULE_CODE}
|
|
12
|
+
* @submodule {SUBMODULE_CODE}
|
|
13
|
+
* @spec qa/01-specifications/module-{name}/submodule-{name}/05-test-scenarios.md
|
|
14
|
+
* @priority P0
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { test, expect } from '@playwright/test';
|
|
18
|
+
|
|
19
|
+
const EXEC_IDX = Math.floor(Date.now() / 60_000) % 100_000;
|
|
20
|
+
|
|
21
|
+
test.describe('{Feature Suite Name}', () => {
|
|
22
|
+
|
|
23
|
+
test.beforeAll(async ({ browser }) => {
|
|
24
|
+
// Provision data needed by all tests in this suite
|
|
25
|
+
// Rule: provision AT LEAST as many records as tests that consume them
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('[TC-{MODULE}-{SUB}-001] {TC title} @P0', async ({ page }) => {
|
|
29
|
+
// Arrange ... Act ... Assert
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test.skip(
|
|
33
|
+
'[TC-{MODULE}-{SUB}-003] {TC title} @P1 — DEF-{NNN}: {description}. Reactivate when {ADO WI or DEF ID} is resolved.',
|
|
34
|
+
async ({ page }) => {
|
|
35
|
+
// Write test as if bug is fixed — documents expected behavior
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Pattern 1: EXEC_IDX — Unique Test Data
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const EXEC_IDX = Math.floor(Date.now() / 60_000) % 100_000;
|
|
48
|
+
|
|
49
|
+
// Titles / names
|
|
50
|
+
const entityName = `Test-Record-${EXEC_IDX}`;
|
|
51
|
+
|
|
52
|
+
// Dates (year 2120+ avoids production data overlap; modular math always valid)
|
|
53
|
+
const year = 2120 + (EXEC_IDX % 10);
|
|
54
|
+
const month = String((EXEC_IDX % 12) + 1).padStart(2, '0');
|
|
55
|
+
const day = String((EXEC_IDX % 28) + 1).padStart(2, '0');
|
|
56
|
+
const testDate = `${year}-${month}-${day}`;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Pattern 2: Multi-Role Auth with storageState
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// global-setup.ts
|
|
65
|
+
import { chromium } from '@playwright/test';
|
|
66
|
+
|
|
67
|
+
export default async function globalSetup() {
|
|
68
|
+
const browser = await chromium.launch();
|
|
69
|
+
const page = await browser.newPage();
|
|
70
|
+
|
|
71
|
+
await page.goto(process.env.QA_BASE_URL + process.env.QA_LOGIN_PATH);
|
|
72
|
+
await page.fill(process.env.QA_LOGIN_EMAIL_SELECTOR, process.env.QA_USER_EMAIL);
|
|
73
|
+
// Use evaluate() for password — excluded from traces
|
|
74
|
+
await page.evaluate(
|
|
75
|
+
([sel, pwd]) => { (document.querySelector(sel) as HTMLInputElement).value = pwd; },
|
|
76
|
+
[process.env.QA_LOGIN_PASSWORD_SELECTOR, process.env.QA_USER_PASSWORD]
|
|
77
|
+
);
|
|
78
|
+
await page.click(process.env.QA_LOGIN_SUBMIT_SELECTOR);
|
|
79
|
+
await page.waitForURL(url => !url.includes(process.env.QA_LOGIN_PATH));
|
|
80
|
+
|
|
81
|
+
await page.context().storageState({ path: '.auth/session.json' });
|
|
82
|
+
await browser.close();
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For multiple roles: run login sequence **sequentially** (not in parallel — apps often reject concurrent sessions).
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Pattern 3: Fast-Fail for Status Checks
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// BAD — hangs silently for full test timeout
|
|
94
|
+
const status = await page.locator('.status-badge').textContent();
|
|
95
|
+
|
|
96
|
+
// GOOD — fails fast if element not available
|
|
97
|
+
const status = await page.locator('.status-badge').textContent({ timeout: 3_000 });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Pattern 4: Email Validation — 3-Layer Strategy
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Layer 1: HTTP route interception
|
|
106
|
+
const emailRequests: string[] = [];
|
|
107
|
+
await page.route('**/*mail*', (route) => {
|
|
108
|
+
emailRequests.push(route.request().url());
|
|
109
|
+
route.continue();
|
|
110
|
+
});
|
|
111
|
+
// Perform the action...
|
|
112
|
+
expect(emailRequests.length).toBeGreaterThan(0);
|
|
113
|
+
|
|
114
|
+
// Layer 2: UI confirmation (toast / banner / badge)
|
|
115
|
+
await expect(page.locator('.email-sent-indicator')).toBeVisible();
|
|
116
|
+
|
|
117
|
+
// Layer 3: skip if inbox access not available
|
|
118
|
+
test.fixme(process.env.QA_MAILBOX_ACCESS !== 'true', 'Requires mailbox access');
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Pattern 5: Skip for Known Bugs
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
test.skip(true,
|
|
127
|
+
'DEF-001: {Description}. ' +
|
|
128
|
+
'Expected: {expected behavior}. ' +
|
|
129
|
+
'Actual: {buggy behavior}. ' +
|
|
130
|
+
'Reactivate when ADO #{WI_ID} / DEF-001 is resolved.'
|
|
131
|
+
);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Never make a test pass around a bug. Document the expected behavior in the skip body.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Pattern 6: beforeAll Provisioning Ratio
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
test.beforeAll(async ({ browser }) => {
|
|
142
|
+
const page = await browser.newPage();
|
|
143
|
+
// If 3 tests each consume 1 record, create at least 3
|
|
144
|
+
const records: string[] = [];
|
|
145
|
+
for (let i = 0; i < 3; i++) {
|
|
146
|
+
const id = await createRecord(page, `Record-${EXEC_IDX}-${i}`);
|
|
147
|
+
records.push(id);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Pattern 7: Password Injection (Trace Safety)
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// Passwords must be set via evaluate() to keep them out of Playwright traces
|
|
158
|
+
await page.evaluate(
|
|
159
|
+
([selector, pwd]) => {
|
|
160
|
+
(document.querySelector(selector) as HTMLInputElement).value = pwd;
|
|
161
|
+
},
|
|
162
|
+
[process.env.QA_LOGIN_PASSWORD_SELECTOR, process.env.QA_USER_PASSWORD]
|
|
163
|
+
);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Coverage Mapping Template
|
|
169
|
+
|
|
170
|
+
Create `COVERAGE-MAPPING.md` in the test directory after automation is complete:
|
|
171
|
+
|
|
172
|
+
```markdown
|
|
173
|
+
# Coverage Mapping — {Module}
|
|
174
|
+
|
|
175
|
+
| TC ID | Title | Spec file | Playwright spec | Status |
|
|
176
|
+
|-------|-------|-----------|----------------|--------|
|
|
177
|
+
| TC-MOD-SUB-001 | {title} | 05-test-scenarios.md | tests/{module}/{file}.spec.ts | ✅ Automated |
|
|
178
|
+
| TC-MOD-SUB-002 | {title} | 05-test-scenarios.md | — | ⛔ BLOCKED-PERMISSIONS |
|
|
179
|
+
| TC-MOD-SUB-003 | {title} | 05-test-scenarios.md | — | 🔲 PENDING-CODE |
|
|
180
|
+
```
|