@keber/qa-framework 1.9.1 → 1.11.3
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/CHANGELOG.md +103 -16
- package/README.md +1 -1
- package/docs/folder-structure-guide.md +6 -0
- package/integrations/ado-powershell/pipelines/azure-pipeline-qa.yml +277 -65
- package/integrations/playwright/README.md +124 -0
- package/integrations/playwright-azure-reporter/README.md +75 -24
- package/package.json +3 -4
- package/qa-framework.config.json +1 -1
- package/scripts/init.js +53 -38
- package/scripts/upgrade.js +105 -10
- package/templates/automation-scaffold/.env.example +20 -1
- package/templates/automation-scaffold/fixtures/base.ts +108 -0
- package/templates/automation-scaffold/global-setup.ts +119 -29
- package/templates/automation-scaffold/playwright.config.ts +24 -0
- package/templates/defect-report.md +1 -1
- package/templates/integration-scaffold/.env.example +40 -0
- package/templates/integration-scaffold/README.md +77 -0
- package/templates/integration-scaffold/global-setup.ts +99 -0
- package/templates/integration-scaffold/package.json +15 -0
- package/templates/integration-scaffold/playwright.config.ts +78 -0
- package/templates/integration-scaffold/tests/example.spec.ts +43 -0
- package/templates/memory/ci-pipeline-findings.md +36 -0
- package/templates/memory/data-volatility-strategies.md +70 -0
- package/templates/memory/e2e-stabilization-patterns.md +54 -0
- package/templates/qa-framework.instructions.md +9 -1
- package/templates/qa-readme.md +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,29 +7,101 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
## [1.
|
|
10
|
+
## [1.11.0] - 2026-06-24
|
|
11
11
|
|
|
12
12
|
### Added
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
-
|
|
14
|
+
- **`templates/automation-scaffold/fixtures/base.ts`** — new fixture with TTL-aware session
|
|
15
|
+
refresh. Replaces the plain `@playwright/test` import in long-running suites where the
|
|
16
|
+
server-side session may expire before the suite finishes.
|
|
17
|
+
- **`templates/automation-scaffold/global-setup.ts`** — hardened login flow:
|
|
18
|
+
- `resolveVar()` with source logging (`param` / `env:KEY` / `default`)
|
|
19
|
+
- Login retry loop (up to 3 attempts) with crash-page detection and recovery
|
|
20
|
+
- `resolveAuthUsers()` — derives which users to authenticate from `QA_AUTH_USER` env var
|
|
21
|
+
or from configured `storageState` paths in `playwright.config.ts`
|
|
22
|
+
- `dismissOnboardingFlow()` — configurable via `QA_DISMISS_ONBOARDING_LABELS`
|
|
23
|
+
(comma-separated button labels); no-op by default
|
|
24
|
+
- Support for a second test user (`.auth/user-2.json`) via `QA_USER2_EMAIL` /
|
|
25
|
+
`QA_USER2_PASSWORD`
|
|
26
|
+
- **`templates/automation-scaffold/playwright.config.ts`** — exports `SESSION_TTL_MS`
|
|
27
|
+
(default 2 h, overridable via `QA_SESSION_TTL_MS`); commented-out parallel 2-user variant
|
|
28
|
+
(`chromium-user1` / `chromium-user2`).
|
|
29
|
+
- **`templates/automation-scaffold/.env.example`** — new variables: `QA_SESSION_TTL_MS`,
|
|
30
|
+
`QA_AUTH_USER`, `QA_USER2_EMAIL`, `QA_USER2_PASSWORD`, `QA_DISMISS_ONBOARDING_LABELS`,
|
|
31
|
+
`PLAYWRIGHT_SERVICE_URL`.
|
|
32
|
+
- **`templates/integration-scaffold/`** — new scaffold for API testing with Playwright
|
|
33
|
+
`APIRequestContext`. Includes `package.json`, `playwright.config.ts`, `global-setup.ts`
|
|
34
|
+
(token-based or browser-login auth), `tests/example.spec.ts`, `README.md`, `.env.example`.
|
|
35
|
+
Deployed to `qa/07-automation/integration/` on `init` and `upgrade`.
|
|
36
|
+
- **`templates/memory/`** — three semi-guided operational memory templates:
|
|
37
|
+
`ci-pipeline-findings.md`, `e2e-stabilization-patterns.md`, `data-volatility-strategies.md`.
|
|
38
|
+
Seeded into `qa/memory/` on `init` and `upgrade`.
|
|
39
|
+
- **`qa/06-defects/disputed/`** — third defect state for cases where QA has evidence but the
|
|
40
|
+
business or dev team disputes the expected behavior. Created on `init` and `upgrade`.
|
|
41
|
+
- **`integrations/ado-powershell/pipelines/azure-pipeline-qa.yml`** — operational hardening:
|
|
42
|
+
- `suiteFilter` pipeline parameter (default `all`); auto-overridden to `all` on scheduled runs
|
|
43
|
+
- Bash array (`GREP_ARGS`) for safe grep pattern expansion with bracket characters
|
|
44
|
+
- `PublishTestResults@2` scoped to exact XML path instead of `**/*.xml`
|
|
45
|
+
- `publishRunAttachments: false` on both E2E and API stages
|
|
46
|
+
- Artifact names suffixed with `$(System.JobAttempt)` to prevent collision on retries
|
|
47
|
+
- `QA_AUTH_USER` documented as commented example for the 2-job parallel model
|
|
48
|
+
- **`integrations/playwright/README.md`** — new section: Visual AI helper optional pattern.
|
|
49
|
+
- **`templates/qa-readme.md`** — new fields: `ADO Project`, `Last Run` summary table,
|
|
50
|
+
`Flaky Tests` inline annotation convention.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- **`scripts/init.js`** — `fixtures/base.ts` added to e2e scaffold copy list; integration
|
|
55
|
+
scaffold replaces the `integration/README.md` placeholder; memory template files seeded
|
|
56
|
+
from `templates/memory/` via `fs.readFileSync`.
|
|
57
|
+
- **`scripts/upgrade.js`** — integration scaffold, `disputed/` defect folder, and memory
|
|
58
|
+
templates are all seeded idempotently on upgrade for existing projects.
|
|
59
|
+
- **`docs/folder-structure-guide.md`** — `06-defects/` updated to document `disputed/`.
|
|
60
|
+
- **`templates/defect-report.md`** — `Status` field extended with `Disputed` value.
|
|
61
|
+
- **`qa/memory/INDEX.md`** template updated to pre-populate rows for the three new memory
|
|
62
|
+
template files.
|
|
23
63
|
|
|
24
|
-
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## [1.10.0] - 2026-05-19
|
|
25
67
|
|
|
26
|
-
|
|
68
|
+
### Added
|
|
27
69
|
|
|
28
|
-
-
|
|
29
|
-
|
|
70
|
+
- **`integrations/ado-powershell/pipelines/azure-pipeline-qa.yml`** — pipeline template
|
|
71
|
+
significantly expanded:
|
|
72
|
+
- New **Stage 3: API Integration Tests** — separate stage for `qa/07-automation/integration`,
|
|
73
|
+
with its own `PublishTestResults` and `PublishPipelineArtifact` tasks.
|
|
74
|
+
- **Cross-project repository checkout** via `resources.repositories` block; each stage
|
|
75
|
+
now performs an explicit `checkout: source`.
|
|
76
|
+
- **Smoke test step** in the E2E stage — validates `QA_BASE_URL` is reachable via `curl`
|
|
77
|
+
before running the suite.
|
|
78
|
+
- **Commented placeholder** for `AzureCLI@2` login task (Playwright Workspaces / Entra ID)
|
|
79
|
+
in both E2E and API stages, with `PLAYWRIGHT_SERVICE_URL` env var placeholder.
|
|
80
|
+
- Optional nightly schedule block (commented out).
|
|
81
|
+
- `PublishPipelineArtifact` tasks for HTML report and trace artifacts in both stages.
|
|
82
|
+
- **`integrations/playwright-azure-reporter/README.md`** — fully rewritten:
|
|
83
|
+
- Variables split into local (PAT) vs CI/CD (`SYSTEM_ACCESSTOKEN`) sections.
|
|
84
|
+
- Config snippet updated to use `ADO_ORG`, `ADO_PROJECT`, `orgUrl` constructed from
|
|
85
|
+
`ADO_ORG`, and `SYSTEM_ACCESSTOKEN ?? AZURE_TOKEN` token fallback.
|
|
86
|
+
- New **Playwright Workspaces reporter** section (`@azure/playwright` +
|
|
87
|
+
`playwright.service.config.ts` + Entra ID authentication notes).
|
|
88
|
+
- Troubleshooting table expanded with pipeline-specific `401` scenario.
|
|
30
89
|
|
|
31
|
-
|
|
32
|
-
|
|
90
|
+
### Changed
|
|
91
|
+
|
|
92
|
+
- **`azure-pipeline-qa.yml`** — variable names aligned with current conventions:
|
|
93
|
+
`AZURE_TOKEN` / `ADO_ORG_URL` / `ADO_PROJECT_NAME` replaced by `ADO_ORG` / `ADO_PROJECT`;
|
|
94
|
+
`ADO_PLAN_ID` split into `ADO_E2E_PLAN_ID` / `ADO_API_PLAN_ID`; `SYSTEM_ACCESSTOKEN`
|
|
95
|
+
replaces PAT for ADO reporter authentication.
|
|
96
|
+
- **`azure-pipeline-qa.yml`** — E2E job `timeoutInMinutes` increased from 60 to 90.
|
|
97
|
+
- **`azure-pipeline-qa.yml`** — trigger reduced to `main` only (removed `qa` and
|
|
98
|
+
`release/*` branches); trigger rationale documented in comments.
|
|
99
|
+
- **`azure-pipeline-qa.yml`** — E2E test run consolidated from two `@grep`-tag steps
|
|
100
|
+
(P0 + P1/P2) into a single `--grep-invert "_inspect|_diag"` run with `continueOnError: true`.
|
|
101
|
+
- **`azure-pipeline-qa.yml`** — cache target changed from `~/.cache/ms-playwright` to
|
|
102
|
+
`node_modules` per workspace; `cacheHitVar` added to both cache tasks.
|
|
103
|
+
- **`azure-pipeline-qa.yml`** — `pool` block moved above `variables` for readability;
|
|
104
|
+
`ADO_SYNC_DISABLED` variable removed.
|
|
33
105
|
|
|
34
106
|
---
|
|
35
107
|
|
|
@@ -258,3 +330,18 @@ See `MIGRATION-NOTES.md` — section "Upgrading from a version that used `.githu
|
|
|
258
330
|
|
|
259
331
|
---
|
|
260
332
|
|
|
333
|
+
## [1.0.0] - 2026-03-04
|
|
334
|
+
|
|
335
|
+
### Added
|
|
336
|
+
|
|
337
|
+
- **Framework scaffold** — initial `qa/` directory tree with 9 numbered folders (00–08)
|
|
338
|
+
- **6-file submodule template set** — `00-inventory` through `05-test-scenarios`
|
|
339
|
+
- **Agent instructions** — 7 purpose-specific Markdown instruction files for IDE agents
|
|
340
|
+
- **Standards** — naming conventions, bug report template, test case template, test data guidelines
|
|
341
|
+
- **Automation scaffold** — generalized Playwright `playwright.config.ts`, `global-setup.ts`, `.env.example`, `fixtures/auth.ts`
|
|
342
|
+
- **Optional integrations** — stubs and READMEs for Playwright, `playwright-azure-reporter`, and ADO PowerShell
|
|
343
|
+
- **CLI entry point** — `qa-framework init`, `generate`, `validate` commands
|
|
344
|
+
- **Documentation** — architecture, comparison matrix, generalization decisions, installation guide, usage-with-agent guide, spec-driven philosophy, folder structure guide
|
|
345
|
+
- **Migration notes** — `MIGRATION-NOTES.md` for projects moving from embedded to package-based framework
|
|
346
|
+
|
|
347
|
+
---
|
package/README.md
CHANGED
|
@@ -260,10 +260,16 @@ Each skill folder contains:
|
|
|
260
260
|
├── README.md
|
|
261
261
|
├── open/
|
|
262
262
|
│ └── DEF-{NNN}-{slug}.md
|
|
263
|
+
├── disputed/
|
|
264
|
+
│ └── DEF-{NNN}-{slug}.md
|
|
263
265
|
└── resolved/
|
|
264
266
|
└── DEF-{NNN}-{slug}.md
|
|
265
267
|
```
|
|
266
268
|
|
|
269
|
+
- `open/` - confirmed defect, fix pending
|
|
270
|
+
- `disputed/` - QA has evidence but business or dev team disputes the expected behavior; pending functional decision
|
|
271
|
+
- `resolved/` - closed by fix or formal decision
|
|
272
|
+
|
|
267
273
|
**Decision guide**:
|
|
268
274
|
- ADO enabled → use ADO Work Items. `06-defects/` contains lightweight references only
|
|
269
275
|
- ADO disabled → use this folder as primary defect tracker
|
|
@@ -1,133 +1,345 @@
|
|
|
1
1
|
# -----------------------------------------------------------------------
|
|
2
|
-
# keber/qa-framework
|
|
2
|
+
# keber/qa-framework - Azure Pipeline QA Template
|
|
3
3
|
# -----------------------------------------------------------------------
|
|
4
|
-
# Parameterized CI pipeline for running Playwright E2E tests and
|
|
5
|
-
#
|
|
4
|
+
# Parameterized CI pipeline for running Playwright E2E and API tests and
|
|
5
|
+
# syncing results to Azure DevOps Test Plans via SYSTEM_ACCESSTOKEN.
|
|
6
|
+
#
|
|
7
|
+
# Cross-project repository: the test repo lives in a different ADO project.
|
|
8
|
+
# Update 'resources.repositories.name' to match your org/project/repo.
|
|
6
9
|
#
|
|
7
10
|
# Required Pipeline Library Variable Group: "QA-Variables"
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
11
|
+
# Create this group in ADO -> Pipelines -> Library and add the following:
|
|
12
|
+
#
|
|
13
|
+
# QA_BASE_URL - Target application URL (e.g. https://app-qa.example.com)
|
|
14
|
+
# QA_USER_EMAIL - Test user email / RUT
|
|
15
|
+
# QA_USER_PASSWORD - Test user password [secret]
|
|
16
|
+
# ADO_ORG - ADO organization slug (e.g. my-org)
|
|
17
|
+
# ADO_PROJECT - ADO project name (e.g. my-project)
|
|
18
|
+
# ADO_E2E_PLAN_ID - Test Plan ID for the E2E suite
|
|
19
|
+
# ADO_API_PLAN_ID - Test Plan ID for the API/integration suite
|
|
20
|
+
#
|
|
21
|
+
# NOTE on multiple Plan IDs: ADO variable groups store plain strings - there
|
|
22
|
+
# is no array type. Use one variable per suite (ADO_E2E_PLAN_ID / ADO_API_PLAN_ID).
|
|
23
|
+
# If the project has only one suite, a single ADO_PLAN_ID variable is enough.
|
|
24
|
+
# Results are reported to ADO via System.AccessToken (OAuth); no PAT required.
|
|
15
25
|
# -----------------------------------------------------------------------
|
|
16
26
|
|
|
27
|
+
# Cross-project repository - update <ADO_SOURCE_PROJECT>/<REPO_NAME> as needed
|
|
28
|
+
resources:
|
|
29
|
+
repositories:
|
|
30
|
+
- repository: source
|
|
31
|
+
type: git
|
|
32
|
+
name: <ADO_SOURCE_PROJECT>/<REPO_NAME> # e.g. my-qa-project/my-repo
|
|
33
|
+
ref: refs/heads/main
|
|
34
|
+
|
|
35
|
+
# Trigger: push and PR to main.
|
|
36
|
+
# The test repo is decoupled from the app repo, so branch triggers are minimal.
|
|
17
37
|
trigger:
|
|
18
38
|
branches:
|
|
19
39
|
include:
|
|
20
40
|
- main
|
|
21
|
-
- qa
|
|
22
|
-
- release/*
|
|
23
41
|
|
|
24
42
|
pr:
|
|
25
43
|
branches:
|
|
26
44
|
include:
|
|
27
45
|
- main
|
|
28
46
|
|
|
47
|
+
# Optional scheduled run - uncomment and adjust if a nightly regression is needed:
|
|
48
|
+
# schedules:
|
|
49
|
+
# - cron: '0 6 * * 1-5' # 06:00 UTC Mon-Fri (03:00 CLT / 02:00 CLST)
|
|
50
|
+
# displayName: Nightly regression
|
|
51
|
+
# branches:
|
|
52
|
+
# include:
|
|
53
|
+
# - main
|
|
54
|
+
# always: true
|
|
55
|
+
|
|
56
|
+
# -----------------------------------------------------------------------
|
|
57
|
+
# Pipeline parameters
|
|
58
|
+
# -----------------------------------------------------------------------
|
|
59
|
+
# suiteFilter controls which tests run when the pipeline is triggered manually
|
|
60
|
+
# or from a PR. Scheduled runs always override this to 'all' automatically
|
|
61
|
+
# (see the "Resolve suite filter" step in each test job).
|
|
62
|
+
#
|
|
63
|
+
# Default is 'all' so a plain manual run executes the full suite.
|
|
64
|
+
# Override at queue time to run a subset (e.g. 'smoke', '[P0]', 'login').
|
|
65
|
+
#
|
|
66
|
+
# The value is passed to Playwright via --grep. Special regex characters such
|
|
67
|
+
# as '[' and ']' are escaped by the bash array pattern in the run step, so
|
|
68
|
+
# values like '[P0]' are safe.
|
|
69
|
+
parameters:
|
|
70
|
+
- name: suiteFilter
|
|
71
|
+
displayName: 'Test suite filter (grep pattern, or "all" to skip filtering)'
|
|
72
|
+
type: string
|
|
73
|
+
default: 'all'
|
|
74
|
+
|
|
75
|
+
pool:
|
|
76
|
+
vmImage: 'ubuntu-latest'
|
|
77
|
+
|
|
29
78
|
variables:
|
|
30
79
|
- group: QA-Variables
|
|
31
80
|
- name: NODE_VERSION
|
|
32
81
|
value: '20.x'
|
|
33
|
-
- name:
|
|
82
|
+
- name: E2E_DIR
|
|
34
83
|
value: 'qa/07-automation/e2e'
|
|
35
|
-
- name:
|
|
36
|
-
value: '
|
|
37
|
-
|
|
38
|
-
pool:
|
|
39
|
-
vmImage: 'ubuntu-latest'
|
|
84
|
+
- name: API_DIR
|
|
85
|
+
value: 'qa/07-automation/integration'
|
|
40
86
|
|
|
41
87
|
stages:
|
|
42
88
|
# -----------------------------------------------------------------------
|
|
43
|
-
# Stage 1: Install &
|
|
89
|
+
# Stage 1: Install & cache dependencies
|
|
44
90
|
# -----------------------------------------------------------------------
|
|
45
91
|
- stage: Setup
|
|
46
92
|
displayName: 'Install Dependencies'
|
|
47
93
|
jobs:
|
|
48
94
|
- job: Install
|
|
49
|
-
displayName: 'npm
|
|
95
|
+
displayName: 'npm ci + Playwright browsers'
|
|
50
96
|
steps:
|
|
97
|
+
- checkout: source
|
|
98
|
+
displayName: 'Checkout source repo'
|
|
99
|
+
|
|
51
100
|
- task: NodeTool@0
|
|
52
101
|
inputs:
|
|
53
102
|
versionSpec: $(NODE_VERSION)
|
|
54
103
|
displayName: 'Use Node.js $(NODE_VERSION)'
|
|
55
104
|
|
|
56
105
|
- script: |
|
|
57
|
-
cd $(
|
|
106
|
+
cd $(E2E_DIR)
|
|
58
107
|
npm ci
|
|
59
108
|
npx playwright install chromium --with-deps
|
|
60
|
-
displayName: 'Install
|
|
109
|
+
displayName: 'Install E2E deps and Playwright Chromium'
|
|
110
|
+
|
|
111
|
+
- task: CacheBeta@1
|
|
112
|
+
inputs:
|
|
113
|
+
key: 'e2e | "$(Agent.OS)" | $(E2E_DIR)/package-lock.json'
|
|
114
|
+
path: '$(E2E_DIR)/node_modules'
|
|
115
|
+
cacheHitVar: 'CACHE_RESTORED_E2E'
|
|
116
|
+
displayName: 'Cache E2E node_modules'
|
|
117
|
+
|
|
118
|
+
- script: |
|
|
119
|
+
cd $(API_DIR)
|
|
120
|
+
npm ci
|
|
121
|
+
displayName: 'Install API deps'
|
|
61
122
|
|
|
62
123
|
- task: CacheBeta@1
|
|
63
124
|
inputs:
|
|
64
|
-
key: '
|
|
65
|
-
path: '
|
|
66
|
-
|
|
125
|
+
key: 'api | "$(Agent.OS)" | $(API_DIR)/package-lock.json'
|
|
126
|
+
path: '$(API_DIR)/node_modules'
|
|
127
|
+
cacheHitVar: 'CACHE_RESTORED_API'
|
|
128
|
+
displayName: 'Cache API node_modules'
|
|
67
129
|
|
|
68
130
|
# -----------------------------------------------------------------------
|
|
69
|
-
# Stage 2: E2E Tests
|
|
131
|
+
# Stage 2: E2E Tests (Playwright/Chromium)
|
|
132
|
+
# -----------------------------------------------------------------------
|
|
133
|
+
# Single-job configuration. For parallel execution with two test users,
|
|
134
|
+
# split this into two jobs and set QA_AUTH_USER per job:
|
|
135
|
+
#
|
|
136
|
+
# - job: E2E_User1
|
|
137
|
+
# variables:
|
|
138
|
+
# QA_AUTH_USER: '1'
|
|
139
|
+
# ...
|
|
140
|
+
# - job: E2E_User2
|
|
141
|
+
# variables:
|
|
142
|
+
# QA_AUTH_USER: '2'
|
|
143
|
+
# ...
|
|
144
|
+
#
|
|
145
|
+
# Each job must use a distinct Playwright project (--project=chromium-user1 /
|
|
146
|
+
# --project=chromium-user2) to avoid session conflicts between parallel users.
|
|
70
147
|
# -----------------------------------------------------------------------
|
|
71
148
|
- stage: E2E
|
|
72
|
-
displayName: 'E2E Tests'
|
|
149
|
+
displayName: 'E2E Tests (Playwright/Chromium)'
|
|
73
150
|
dependsOn: Setup
|
|
74
151
|
jobs:
|
|
75
|
-
- job:
|
|
76
|
-
displayName: 'Run
|
|
77
|
-
timeoutInMinutes:
|
|
152
|
+
- job: PlaywrightE2E
|
|
153
|
+
displayName: 'Run E2E suite'
|
|
154
|
+
timeoutInMinutes: 90
|
|
78
155
|
steps:
|
|
156
|
+
- checkout: source
|
|
157
|
+
displayName: 'Checkout source repo'
|
|
158
|
+
|
|
79
159
|
- task: NodeTool@0
|
|
80
160
|
inputs:
|
|
81
161
|
versionSpec: $(NODE_VERSION)
|
|
162
|
+
displayName: 'Use Node.js $(NODE_VERSION)'
|
|
82
163
|
|
|
83
164
|
- script: |
|
|
84
|
-
cd $(
|
|
165
|
+
cd $(E2E_DIR)
|
|
85
166
|
npm ci
|
|
86
167
|
npx playwright install chromium --with-deps
|
|
87
|
-
displayName: 'Restore dependencies'
|
|
168
|
+
displayName: 'Restore E2E dependencies'
|
|
169
|
+
|
|
170
|
+
- script: |
|
|
171
|
+
echo "QA_BASE_URL = $(QA_BASE_URL)"
|
|
172
|
+
HTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" --max-time 30 "$(QA_BASE_URL)")
|
|
173
|
+
echo "HTTP response: $HTTP_CODE"
|
|
174
|
+
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 400 ]; then
|
|
175
|
+
echo "##[error]Smoke test failed - $(QA_BASE_URL) returned HTTP $HTTP_CODE"
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
echo "Smoke test passed (HTTP $HTTP_CODE)"
|
|
179
|
+
displayName: 'Smoke test - verify QA_BASE_URL is reachable'
|
|
180
|
+
|
|
181
|
+
# ---------------------------------------------------------------
|
|
182
|
+
# Playwright Workspaces (Azure App Testing)
|
|
183
|
+
# Enable once the ADO service connection is configured.
|
|
184
|
+
# Prerequisite: the service connection must have the Contributor
|
|
185
|
+
# role on the workspace in Azure Portal (Access control IAM).
|
|
186
|
+
# ---------------------------------------------------------------
|
|
187
|
+
# - task: AzureCLI@2
|
|
188
|
+
# displayName: 'Login to Azure (Playwright Workspaces)'
|
|
189
|
+
# inputs:
|
|
190
|
+
# azureSubscription: '<AZURE_SERVICE_CONNECTION_NAME>'
|
|
191
|
+
# scriptType: bash
|
|
192
|
+
# scriptLocation: inlineScript
|
|
193
|
+
# inlineScript: echo "Authenticated via Entra ID"
|
|
88
194
|
|
|
89
195
|
- script: |
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
196
|
+
# Scheduled runs always execute the full suite, regardless of the
|
|
197
|
+
# suiteFilter parameter. This prevents accidental partial runs in
|
|
198
|
+
# nightly regressions when the parameter was changed by a prior
|
|
199
|
+
# manual queue.
|
|
200
|
+
SUITE_FILTER="${{ parameters.suiteFilter }}"
|
|
201
|
+
if [ "$(Build.Reason)" = "Schedule" ]; then
|
|
202
|
+
SUITE_FILTER="all"
|
|
203
|
+
echo "Scheduled run detected - overriding suiteFilter to 'all'"
|
|
204
|
+
fi
|
|
205
|
+
echo "Effective suiteFilter: $SUITE_FILTER"
|
|
206
|
+
|
|
207
|
+
# Build --grep args as a bash array to safely handle patterns that
|
|
208
|
+
# contain special regex characters such as '[' and ']'. Inline
|
|
209
|
+
# string interpolation would break those patterns at the shell level.
|
|
210
|
+
GREP_ARGS=()
|
|
211
|
+
if [ "$SUITE_FILTER" != "all" ]; then
|
|
212
|
+
GREP_ARGS=(--grep "$SUITE_FILTER")
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
cd $(E2E_DIR)
|
|
216
|
+
npx playwright test --project=chromium --ignore-snapshots \
|
|
217
|
+
--grep-invert "_inspect|_diag" "${GREP_ARGS[@]}"
|
|
218
|
+
displayName: 'Run E2E tests'
|
|
219
|
+
continueOnError: true
|
|
93
220
|
env:
|
|
94
|
-
QA_BASE_URL:
|
|
95
|
-
QA_USER_EMAIL:
|
|
96
|
-
QA_USER_PASSWORD:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
221
|
+
QA_BASE_URL: $(QA_BASE_URL)
|
|
222
|
+
QA_USER_EMAIL: $(QA_USER_EMAIL)
|
|
223
|
+
QA_USER_PASSWORD: $(QA_USER_PASSWORD)
|
|
224
|
+
ADO_ORG: $(ADO_ORG)
|
|
225
|
+
ADO_PROJECT: $(ADO_PROJECT)
|
|
226
|
+
ADO_PLAN_ID: $(ADO_E2E_PLAN_ID)
|
|
227
|
+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
228
|
+
CI: 'true'
|
|
229
|
+
# QA_AUTH_USER: '1' # Set explicitly when running parallel jobs (user-1 / user-2 model)
|
|
230
|
+
# PLAYWRIGHT_SERVICE_URL: $(PLAYWRIGHT_SERVICE_URL) # Playwright Workspaces endpoint - enable together with the login task
|
|
231
|
+
|
|
232
|
+
# publishRunAttachments is false because screenshots and traces are
|
|
233
|
+
# already uploaded as pipeline artifacts below. Setting it to true
|
|
234
|
+
# would double-publish the same files.
|
|
235
|
+
- task: PublishTestResults@2
|
|
236
|
+
condition: always()
|
|
237
|
+
inputs:
|
|
238
|
+
testResultsFormat: 'JUnit'
|
|
239
|
+
testResultsFiles: 'test-results/junit-results.xml'
|
|
240
|
+
searchFolder: $(E2E_DIR)
|
|
241
|
+
mergeTestResults: true
|
|
242
|
+
publishRunAttachments: false
|
|
243
|
+
failTaskOnFailedTests: true
|
|
244
|
+
testRunTitle: '[Auto E2E] $(Build.BuildNumber)'
|
|
245
|
+
displayName: 'Publish E2E test results (JUnit)'
|
|
246
|
+
|
|
247
|
+
# Artifact names include $(System.JobAttempt) to avoid name collisions
|
|
248
|
+
# when the job is retried. ADO rejects duplicate artifact names within
|
|
249
|
+
# the same pipeline run, so without the suffix a retry always fails at
|
|
250
|
+
# the publish step.
|
|
251
|
+
- task: PublishPipelineArtifact@1
|
|
252
|
+
condition: always()
|
|
253
|
+
inputs:
|
|
254
|
+
targetPath: '$(E2E_DIR)/playwright-report'
|
|
255
|
+
artifact: 'e2e-playwright-report-attempt-$(System.JobAttempt)'
|
|
256
|
+
displayName: 'Publish E2E HTML report'
|
|
257
|
+
|
|
258
|
+
- task: PublishPipelineArtifact@1
|
|
259
|
+
condition: always()
|
|
260
|
+
inputs:
|
|
261
|
+
targetPath: '$(E2E_DIR)/test-results'
|
|
262
|
+
artifact: 'e2e-test-results-attempt-$(System.JobAttempt)'
|
|
263
|
+
displayName: 'Publish E2E trace artifacts'
|
|
264
|
+
|
|
265
|
+
# -----------------------------------------------------------------------
|
|
266
|
+
# Stage 3: API Integration Tests
|
|
267
|
+
# -----------------------------------------------------------------------
|
|
268
|
+
- stage: API
|
|
269
|
+
displayName: 'API Integration Tests'
|
|
270
|
+
dependsOn: E2E
|
|
271
|
+
jobs:
|
|
272
|
+
- job: PlaywrightAPI
|
|
273
|
+
displayName: 'Run API suite'
|
|
274
|
+
timeoutInMinutes: 30
|
|
275
|
+
steps:
|
|
276
|
+
- checkout: source
|
|
277
|
+
displayName: 'Checkout source repo'
|
|
278
|
+
|
|
279
|
+
- task: NodeTool@0
|
|
280
|
+
inputs:
|
|
281
|
+
versionSpec: $(NODE_VERSION)
|
|
282
|
+
displayName: 'Use Node.js $(NODE_VERSION)'
|
|
103
283
|
|
|
104
284
|
- script: |
|
|
105
|
-
cd $(
|
|
106
|
-
|
|
107
|
-
displayName: '
|
|
108
|
-
|
|
285
|
+
cd $(API_DIR)
|
|
286
|
+
npm ci
|
|
287
|
+
displayName: 'Restore API dependencies'
|
|
288
|
+
|
|
289
|
+
# ---------------------------------------------------------------
|
|
290
|
+
# Playwright Workspaces (Azure App Testing)
|
|
291
|
+
# Enable once the ADO service connection is configured.
|
|
292
|
+
# ---------------------------------------------------------------
|
|
293
|
+
# - task: AzureCLI@2
|
|
294
|
+
# displayName: 'Login to Azure (Playwright Workspaces)'
|
|
295
|
+
# inputs:
|
|
296
|
+
# azureSubscription: '<AZURE_SERVICE_CONNECTION_NAME>'
|
|
297
|
+
# scriptType: bash
|
|
298
|
+
# scriptLocation: inlineScript
|
|
299
|
+
# inlineScript: echo "Authenticated via Entra ID"
|
|
300
|
+
|
|
301
|
+
- script: |
|
|
302
|
+
# API integration tests do not use suite tags - always run all.
|
|
303
|
+
cd $(API_DIR)
|
|
304
|
+
npx playwright test --grep-invert "_inspect|_diag"
|
|
305
|
+
displayName: 'Run API integration tests'
|
|
306
|
+
continueOnError: true
|
|
109
307
|
env:
|
|
110
|
-
QA_BASE_URL:
|
|
111
|
-
QA_USER_EMAIL:
|
|
112
|
-
QA_USER_PASSWORD:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
CI:
|
|
308
|
+
QA_BASE_URL: $(QA_BASE_URL)
|
|
309
|
+
QA_USER_EMAIL: $(QA_USER_EMAIL)
|
|
310
|
+
QA_USER_PASSWORD: $(QA_USER_PASSWORD)
|
|
311
|
+
ADO_ORG: $(ADO_ORG)
|
|
312
|
+
ADO_PROJECT: $(ADO_PROJECT)
|
|
313
|
+
ADO_PLAN_ID: $(ADO_API_PLAN_ID)
|
|
314
|
+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
315
|
+
CI: 'true'
|
|
316
|
+
# PLAYWRIGHT_SERVICE_URL: $(PLAYWRIGHT_SERVICE_URL) # Playwright Workspaces endpoint - enable together with the login task
|
|
118
317
|
|
|
318
|
+
# publishRunAttachments is false because trace artifacts are already
|
|
319
|
+
# uploaded as pipeline artifacts below.
|
|
119
320
|
- task: PublishTestResults@2
|
|
120
321
|
condition: always()
|
|
121
322
|
inputs:
|
|
122
|
-
testResultsFormat:
|
|
123
|
-
testResultsFiles:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
323
|
+
testResultsFormat: 'JUnit'
|
|
324
|
+
testResultsFiles: 'test-results/junit-results.xml'
|
|
325
|
+
searchFolder: $(API_DIR)
|
|
326
|
+
mergeTestResults: true
|
|
327
|
+
publishRunAttachments: false
|
|
328
|
+
failTaskOnFailedTests: true
|
|
329
|
+
testRunTitle: '[Auto API] $(Build.BuildNumber)'
|
|
330
|
+
displayName: 'Publish API test results (JUnit)'
|
|
331
|
+
|
|
332
|
+
# Artifact names include $(System.JobAttempt) to prevent collision on retries.
|
|
333
|
+
- task: PublishPipelineArtifact@1
|
|
334
|
+
condition: always()
|
|
335
|
+
inputs:
|
|
336
|
+
targetPath: '$(API_DIR)/playwright-report'
|
|
337
|
+
artifact: 'api-playwright-report-attempt-$(System.JobAttempt)'
|
|
338
|
+
displayName: 'Publish API HTML report'
|
|
127
339
|
|
|
128
|
-
- task:
|
|
340
|
+
- task: PublishPipelineArtifact@1
|
|
129
341
|
condition: always()
|
|
130
342
|
inputs:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
displayName: 'Publish
|
|
343
|
+
targetPath: '$(API_DIR)/test-results'
|
|
344
|
+
artifact: 'api-test-results-attempt-$(System.JobAttempt)'
|
|
345
|
+
displayName: 'Publish API trace artifacts'
|