@freshworks/shiftleft-tools 1.1.8
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/README.md +351 -0
- package/bin/shiftleft.js +95 -0
- package/package.json +57 -0
- package/src/commands/doctor.js +208 -0
- package/src/commands/init-postman.js +298 -0
- package/src/commands/init-rules.js +78 -0
- package/src/commands/link.js +172 -0
- package/src/commands/protect.js +61 -0
- package/src/commands/run-tests.js +182 -0
- package/src/commands/setup-pipeline.js +209 -0
- package/src/commands/update.js +203 -0
- package/src/index.js +4 -0
- package/src/utils/copy-tree.js +98 -0
- package/src/utils/gitignore.js +26 -0
- package/src/utils/logger.js +9 -0
- package/src/utils/manifest.js +145 -0
- package/src/utils/stack.js +80 -0
- package/src/utils/template.js +135 -0
- package/templates/AGENTS.md +109 -0
- package/templates/CLAUDE.md +3 -0
- package/templates/jenkins/Jenkinsfile-java.groovy +432 -0
- package/templates/jenkins/Jenkinsfile-node.groovy +450 -0
- package/templates/postman/.husky/pre-commit +19 -0
- package/templates/postman/.prettierrc.json +5 -0
- package/templates/postman/README.md.ejs +147 -0
- package/templates/postman/collections/01-core.json.ejs +91 -0
- package/templates/postman/config/local.json.ejs +12 -0
- package/templates/postman/config/staging.json.ejs +26 -0
- package/templates/postman/environments/local.postman_environment.json.ejs +31 -0
- package/templates/postman/environments/staging.postman_environment.json.ejs +31 -0
- package/templates/postman/gitignore +16 -0
- package/templates/postman/npmrc +31 -0
- package/templates/postman/package.json.ejs +66 -0
- package/templates/postman/run-all-shim.sh +16 -0
- package/templates/postman/scripts/auth/generate-jwt.sh +113 -0
- package/templates/postman/scripts/auth/get-issuer-secret.sh +140 -0
- package/templates/postman/scripts/infra/start-mocks.sh +138 -0
- package/templates/postman/scripts/infra/stop-mocks.sh +43 -0
- package/templates/postman/scripts/lib/api_coverage.py +1122 -0
- package/templates/postman/scripts/lib/cleanup-reports.sh +101 -0
- package/templates/postman/scripts/lib/cleanup-stryker.sh +44 -0
- package/templates/postman/scripts/lib/report_combined.py +527 -0
- package/templates/postman/scripts/lib/report_consolidated.py +363 -0
- package/templates/postman/scripts/lib/report_generator.py +121 -0
- package/templates/postman/scripts/lib/report_migration.py +156 -0
- package/templates/postman/scripts/lib/report_mutation.py +110 -0
- package/templates/postman/scripts/lib/report_unit.py +353 -0
- package/templates/postman/scripts/lib/report_utils.py +973 -0
- package/templates/postman/scripts/report-generators/generate-consolidated-report.sh +445 -0
- package/templates/postman/scripts/report-generators/java-api-coverage-matrix.sh +257 -0
- package/templates/postman/scripts/report-generators/mutation-report.sh +672 -0
- package/templates/postman/scripts/report-generators/node-api-coverage-matrix.sh +167 -0
- package/templates/postman/scripts/report-generators/stage-report-artifacts.sh +27 -0
- package/templates/postman/scripts/run-all.sh +452 -0
- package/templates/postman/scripts/runners/run-mutation-tests.sh +113 -0
- package/templates/postman/scripts/runners/run-tests-local.sh +936 -0
- package/templates/postman/scripts/runners/run-tests-staging.sh +741 -0
- package/templates/postman-node/README.md.ejs +26 -0
- package/templates/postman-node/collections/crud/01-bootstrap.json.ejs +34 -0
- package/templates/postman-node/config/local.json.ejs +46 -0
- package/templates/postman-node/config/staging.json.ejs +31 -0
- package/templates/postman-node/local.test.env.ejs +3 -0
- package/templates/postman-node/mocks/external.js +14 -0
- package/templates/postman-node/package.json.ejs +39 -0
- package/templates/postman-node/requirements.txt +1 -0
- package/templates/postman-node/scripts/database/cleanup-mysql.sh +12 -0
- package/templates/postman-node/scripts/database/run-migrations.js +29 -0
- package/templates/postman-node/scripts/database/start-mysql.sh +34 -0
- package/templates/postman-node/scripts/database/wait-for-mysql.sh +36 -0
- package/templates/postman-node/scripts/lib/api_coverage_node.py +1137 -0
- package/templates/postman-node/scripts/lib/fetch-jwt.sh +86 -0
- package/templates/postman-node/scripts/lib/run-newman.sh +104 -0
- package/templates/postman-node/scripts/lib/setup-database.sh +55 -0
- package/templates/postman-node/scripts/lib/start-app.sh +48 -0
- package/templates/postman-node/scripts/lib/utils.sh +114 -0
- package/templates/postman-node/scripts/report-generators/stage-report-artifacts.sh +26 -0
- package/templates/postman-node/scripts/run-all.sh +303 -0
- package/templates/postman-node/scripts/runners/run-tests.sh +123 -0
- package/templates/postman-node/scripts/setup-mocks.js.ejs +29 -0
- package/templates/postman-node/stryker.config.js.ejs +51 -0
- package/templates/rules/local-test-setup.mdc +420 -0
- package/templates/rules/testing-node.mdc +66 -0
- package/templates/rules/testing.mdc +248 -0
- package/templates/skills/_shared/postman-standards.md +380 -0
- package/templates/skills/enhance-test-pipeline/SKILL-java.md +483 -0
- package/templates/skills/enhance-test-pipeline/SKILL-node.md +431 -0
- package/templates/skills/enhance-test-pipeline/SKILL.md +9 -0
- package/templates/skills/review-test-suite/SKILL-java.md +137 -0
- package/templates/skills/review-test-suite/SKILL-node.md +78 -0
- package/templates/skills/review-test-suite/SKILL.md +9 -0
- package/templates/skills/run-test-suite/SKILL-java.md +186 -0
- package/templates/skills/run-test-suite/SKILL-node.md +191 -0
- package/templates/skills/run-test-suite/SKILL.md +9 -0
- package/templates/skills/setup-api-tests/SKILL-java.md +1094 -0
- package/templates/skills/setup-api-tests/SKILL-node.md +141 -0
- package/templates/skills/setup-api-tests/SKILL.md +9 -0
- package/templates/skills/setup-mutation-tests/SKILL-java.md +303 -0
- package/templates/skills/setup-mutation-tests/SKILL-node.md +408 -0
- package/templates/skills/setup-mutation-tests/SKILL.md +9 -0
- package/templates/skills/setup-test-pipeline/SKILL-java.md +454 -0
- package/templates/skills/setup-test-pipeline/SKILL-node.md +318 -0
- package/templates/skills/setup-test-pipeline/SKILL.md +9 -0
- package/templates/skills/write-api-tests/SKILL-java.md +115 -0
- package/templates/skills/write-api-tests/SKILL-node.md +83 -0
- package/templates/skills/write-api-tests/SKILL.md +9 -0
- package/templates/stryker.config.js +50 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Setup Test Pipeline — Node.js / Express
|
|
2
|
+
|
|
3
|
+
Set up a complete test pipeline from scratch (or near-scratch) for a Node.js/Express repo. This skill orchestrates the full pipeline: unit tests, nyc/Istanbul coverage, Stryker mutation tests, Postman API tests, API coverage matrix, combined quality report, and Jenkins integration.
|
|
4
|
+
|
|
5
|
+
Use this skill when a repo has NOTHING (or only bare unit tests). For repos that already have partial pipeline setup, use `/enhance-test-pipeline` instead.
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
Invoke when:
|
|
10
|
+
- "set up the full test pipeline"
|
|
11
|
+
- "add complete test infrastructure to this Node.js repo"
|
|
12
|
+
- "set up unit tests, mutation tests, and postman tests"
|
|
13
|
+
- "I want everything: unit tests, coverage, mutation, API tests, quality report"
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Phase 1: Inspect — Audit What Exists
|
|
18
|
+
|
|
19
|
+
Run each check and record the result (present/missing/partial).
|
|
20
|
+
|
|
21
|
+
### 1.1 Unit tests
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cat package.json | grep -E '"test"|"mocha"|"jest"'
|
|
25
|
+
ls test/ test/unit/ 2>/dev/null | head -20
|
|
26
|
+
yarn test 2>&1 | tail -5
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- Present and passing: unit tests exist and pass
|
|
30
|
+
- Present but failing: tests exist but have failures (must fix before mutation tests)
|
|
31
|
+
- Missing: no test directory or test script
|
|
32
|
+
|
|
33
|
+
### 1.2 nyc / Istanbul coverage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cat package.json | grep -E '"nyc"|"istanbul"|"c8"'
|
|
37
|
+
grep -r "nyc\|istanbul\|c8" package.json
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- Present: coverage already configured
|
|
41
|
+
- Missing: needs to be added
|
|
42
|
+
|
|
43
|
+
### 1.3 Postman infrastructure
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ls postman/ 2>/dev/null
|
|
47
|
+
ls postman/collections/ 2>/dev/null
|
|
48
|
+
ls postman/scripts/ 2>/dev/null
|
|
49
|
+
ls postman/scripts/run-all.sh 2>/dev/null
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- Present: full postman/ directory with collections and scripts
|
|
53
|
+
- Partial: directory exists but scripts or collections missing
|
|
54
|
+
- Missing: no postman/ directory
|
|
55
|
+
|
|
56
|
+
### 1.4 Stryker mutation testing
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cat package.json | grep stryker
|
|
60
|
+
ls stryker.config.js 2>/dev/null
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- Present: Stryker configured (check mutate scope — should target business logic only)
|
|
64
|
+
- Missing: needs to be added
|
|
65
|
+
|
|
66
|
+
### 1.5 API coverage matrix
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
ls postman/scripts/report-generators/node-api-coverage-matrix.sh 2>/dev/null
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 1.6 Quality report
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
ls postman/scripts/run-all.sh 2>/dev/null
|
|
76
|
+
grep "skip-report\|skip-unit\|skip-mutation" postman/scripts/run-all.sh 2>/dev/null | head -5
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Present and modern: run-all.sh exists and has --skip-* flags
|
|
80
|
+
- Present but stale: run-all.sh exists but is an old version without flags
|
|
81
|
+
- Missing
|
|
82
|
+
|
|
83
|
+
### 1.7 Jenkinsfile
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
ls Jenkinsfile
|
|
87
|
+
grep -E "Mutation|ShiftLeft|Quality|quality-report|stryker" Jenkinsfile 2>/dev/null
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- Complete: has Unit Tests, Mutation Tests, ShiftLeft stages with quality report generation
|
|
91
|
+
- Partial: has some stages but missing mutation or quality report
|
|
92
|
+
- Missing: no Jenkinsfile
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Phase 2: Report Gaps
|
|
97
|
+
|
|
98
|
+
Present a clear status table to the user:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Pipeline Audit Results
|
|
102
|
+
======================
|
|
103
|
+
Component Status
|
|
104
|
+
-----------------------------------------------
|
|
105
|
+
Unit Tests [PRESENT / MISSING / FAILING]
|
|
106
|
+
nyc Coverage [PRESENT / MISSING]
|
|
107
|
+
Postman Infrastructure [PRESENT / PARTIAL / MISSING]
|
|
108
|
+
Stryker Mutation Tests [PRESENT / MISSING]
|
|
109
|
+
API Coverage Matrix [PRESENT / MISSING]
|
|
110
|
+
run-all.sh (modern) [PRESENT / STALE / MISSING]
|
|
111
|
+
Jenkinsfile [COMPLETE / PARTIAL / MISSING]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Phase 3: Confirm
|
|
117
|
+
|
|
118
|
+
Tell the user exactly what will be set up:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
I will set up the following components in order:
|
|
122
|
+
1. [if missing] Postman infrastructure (collections, scripts, config)
|
|
123
|
+
2. [if missing] nyc coverage in package.json
|
|
124
|
+
3. [if missing] Stryker mutation testing (discover actual src structure first)
|
|
125
|
+
4. Stage library scripts from the shiftleft-tools package (`shiftleft stage-scripts`):
|
|
126
|
+
run-all.sh, runners/run-mutation-tests.sh,
|
|
127
|
+
report-generators/node-api-coverage-matrix.sh, generate-consolidated-report.sh,
|
|
128
|
+
report-generators/stage-report-artifacts.sh,
|
|
129
|
+
lib/report_generator.py (entry point), lib/report_utils.py, lib/report_consolidated.py,
|
|
130
|
+
lib/report_migration.py, lib/report_mutation.py, lib/report_unit.py, lib/report_combined.py,
|
|
131
|
+
lib/api_coverage_node.py
|
|
132
|
+
5. [if partial] Update Jenkinsfile with mutation + ShiftLeft + quality report stages
|
|
133
|
+
|
|
134
|
+
This will take approximately 5-10 minutes.
|
|
135
|
+
Proceed? [Y/n]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Wait for confirmation before making any changes.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Phase 4: Execute in Order
|
|
143
|
+
|
|
144
|
+
### Step A: Postman infrastructure (if missing)
|
|
145
|
+
|
|
146
|
+
If no `postman/` directory exists, invoke `/setup-api-tests` skill for the full Postman setup.
|
|
147
|
+
|
|
148
|
+
### Step B: nyc coverage (if missing)
|
|
149
|
+
|
|
150
|
+
Add nyc configuration to `package.json`:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"scripts": {
|
|
155
|
+
"test:coverage": "nyc mocha test/unit/**/*.test.js"
|
|
156
|
+
},
|
|
157
|
+
"nyc": {
|
|
158
|
+
"reporter": ["lcov", "text", "html"],
|
|
159
|
+
"report-dir": "coverage/unit",
|
|
160
|
+
"exclude": [
|
|
161
|
+
"test/**",
|
|
162
|
+
"postman/**",
|
|
163
|
+
"coverage/**",
|
|
164
|
+
"node_modules/**"
|
|
165
|
+
],
|
|
166
|
+
"include": [
|
|
167
|
+
"src/**/*.js"
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Install if missing:
|
|
174
|
+
```bash
|
|
175
|
+
yarn add --dev nyc
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Step C: Stryker mutation testing (if missing)
|
|
179
|
+
|
|
180
|
+
Follow the `setup-mutation-tests` SKILL-node.md skill in full:
|
|
181
|
+
1. Discover source folders — **only** actions, services, serializers, middlewares (+ selective helpers)
|
|
182
|
+
2. **Exclude** controllers, routes, models, config, migrations
|
|
183
|
+
3. Inspect helpers file-by-file — exclude external SDK wrappers
|
|
184
|
+
4. **Count files** — mutate scope must stay **under 80 files** (never `src/**`)
|
|
185
|
+
5. Confirm narrow scope with user before writing config
|
|
186
|
+
6. Install `@stryker-mutator/core` and appropriate runner
|
|
187
|
+
7. Create `stryker.config.js` with the audited scope only
|
|
188
|
+
8. Add `mutation-tests` (since mode) and `mutation-tests:full` scripts to package.json
|
|
189
|
+
|
|
190
|
+
Key requirements:
|
|
191
|
+
- **Never** `mutate: ['src/**/*.js']` — Stryker will run for hours
|
|
192
|
+
- `coverageAnalysis: 'perTest'` — fastest
|
|
193
|
+
- `incremental: true` — reuse previous results
|
|
194
|
+
- `concurrency: 4`
|
|
195
|
+
- `thresholds: { high: 80, low: 60, break: 0 }` — break:0 means CI never hard-fails on score
|
|
196
|
+
- `htmlReporter: { fileName: 'coverage/mutation/index.html' }`
|
|
197
|
+
- `run-mutation-tests.sh` for the two-mode approach (since vs full)
|
|
198
|
+
|
|
199
|
+
### Step D: Stage scripts from the shiftleft-tools package
|
|
200
|
+
|
|
201
|
+
Run `shiftleft stage-scripts` to pull the library scripts from the installed
|
|
202
|
+
package into `postman/scripts/` — do not copy or write them by hand. They are
|
|
203
|
+
gitignored and refreshed on every `shiftleft test` run. The staged set includes:
|
|
204
|
+
|
|
205
|
+
**Core pipeline scripts (required):**
|
|
206
|
+
- `run-all.sh` — master pipeline runner with `--skip-*` and `--env` flags
|
|
207
|
+
- `runners/run-mutation-tests.sh` — Stryker two-mode runner (since vs full)
|
|
208
|
+
- `report-generators/node-api-coverage-matrix.sh` — Express route coverage matrix
|
|
209
|
+
- `report-generators/generate-consolidated-report.sh` — aggregates Newman JSON results
|
|
210
|
+
- `report-generators/stage-report-artifacts.sh` — copies nyc/Stryker HTML for Jenkins linking
|
|
211
|
+
|
|
212
|
+
**Support scripts:**
|
|
213
|
+
- `run-tests.sh` (or `run-all.sh`) — runs Postman tests locally and against staging
|
|
214
|
+
- `get-issuer-secret.sh` / `auth/get-issuer-secret.sh` — fetches JWT secret from AWS
|
|
215
|
+
|
|
216
|
+
**Lib folder (required):**
|
|
217
|
+
- `lib/report_generator.py` — CLI entry point, dispatches to report modules
|
|
218
|
+
- `lib/report_utils.py` — shared CSS, helpers, UI component builders
|
|
219
|
+
- `lib/report_consolidated.py` — consolidated Newman test results report
|
|
220
|
+
- `lib/report_migration.py` — migration comparison report
|
|
221
|
+
- `lib/report_mutation.py` — PIT/Stryker mutation testing report
|
|
222
|
+
- `lib/report_unit.py` — unit test parsers and report
|
|
223
|
+
- `lib/report_combined.py` — combined quality report (unit + API tabs)
|
|
224
|
+
- `lib/api_coverage_node.py` — generates API coverage matrix from Express routes + Postman
|
|
225
|
+
- `lib/cleanup-stryker.sh` — kills Stryker processes and cleans temp files
|
|
226
|
+
|
|
227
|
+
Make all `.sh` files executable:
|
|
228
|
+
```bash
|
|
229
|
+
chmod +x postman/scripts/*.sh postman/scripts/lib/*.sh
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Step E: Update Jenkinsfile (if missing stages)
|
|
233
|
+
|
|
234
|
+
If the Jenkinsfile is missing mutation or quality report stages, update it to match the `templates/jenkins/Jenkinsfile-node.groovy` pattern:
|
|
235
|
+
|
|
236
|
+
Required stages:
|
|
237
|
+
1. `Unit Tests` — `yarn test`
|
|
238
|
+
2. `Mutation Tests` — `yarn mutation-tests:full` (full mode for CI), publish Stryker HTML report
|
|
239
|
+
3. `Staging Postman, API Coverage & Quality Report` — ShiftLeft isolation, Postman, API coverage matrix, quality report
|
|
240
|
+
|
|
241
|
+
Key quality report pattern:
|
|
242
|
+
```groovy
|
|
243
|
+
// API coverage (after ShiftLeft Postman):
|
|
244
|
+
sh "./postman/scripts/report-generators/node-api-coverage-matrix.sh ./src/controllers ./postman"
|
|
245
|
+
publishHTML([reportDir: 'postman/reports', reportFiles: 'api-coverage-matrix-latest.html', reportName: 'API Coverage Matrix'])
|
|
246
|
+
|
|
247
|
+
// Quality report:
|
|
248
|
+
sh "./postman/scripts/run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage --no-delay"
|
|
249
|
+
publishHTML([reportDir: 'postman/reports', reportFiles: 'quality-report-*.html', reportName: 'QualityReport'])
|
|
250
|
+
archiveArtifacts artifacts: 'postman/reports/**', allowEmptyArchive: true
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Replace placeholders:
|
|
254
|
+
- `SERVICE_NAME` → your actual service name (e.g. `freshapps_api_node`)
|
|
255
|
+
- `NAMESPACE` → your Kubernetes namespace
|
|
256
|
+
- `ISO_HEADER` → isoforge routing header
|
|
257
|
+
- `ISO_HEADER_VALUE` → the account ID or regex value
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Phase 5: Verify
|
|
262
|
+
|
|
263
|
+
### Verify Phase A: Unit + Mutation + Coverage (no Postman needed)
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
yarn test # Unit tests
|
|
267
|
+
yarn mutation-tests # Stryker since-mode (only changed files)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Verify Phase B: Postman + API Coverage + Quality Report
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
cd postman/scripts
|
|
274
|
+
./run-all.sh --skip-mutation --no-delay
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Expected: Postman tests run locally, API coverage matrix generates, quality report generates.
|
|
278
|
+
|
|
279
|
+
### Verify Phase C: Full pipeline
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
cd postman/scripts
|
|
283
|
+
./run-all.sh --no-delay
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Report to user
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
Pipeline setup complete!
|
|
290
|
+
|
|
291
|
+
Verification results:
|
|
292
|
+
Unit Tests: [PASS/FAIL] — N tests, M% line coverage
|
|
293
|
+
Mutation Tests: [PASS/FAIL] — X% mutation score (since mode)
|
|
294
|
+
Postman Tests: [PASS/FAIL] — N collections, M assertions
|
|
295
|
+
API Coverage: [PASS/FAIL] — X% endpoints covered
|
|
296
|
+
Quality Report: [GENERATED] — postman/reports/quality-report-*.html
|
|
297
|
+
|
|
298
|
+
Next steps:
|
|
299
|
+
- Local run-all: cd postman/scripts && ./run-all.sh
|
|
300
|
+
- Fast mutation check: yarn mutation-tests (only changed files)
|
|
301
|
+
- Full mutation check: yarn mutation-tests:full (all scoped files)
|
|
302
|
+
- Staging run: cd postman/scripts && ./run-all.sh --env staging
|
|
303
|
+
- Jenkins: push a PR and comment "shiftleft" to trigger integration tests
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Verification Checklist
|
|
309
|
+
|
|
310
|
+
- [ ] `yarn test` passes
|
|
311
|
+
- [ ] `yarn test:coverage` generates coverage report
|
|
312
|
+
- [ ] `yarn mutation-tests` works in since mode
|
|
313
|
+
- [ ] `yarn mutation-tests:full` runs full Stryker scan
|
|
314
|
+
- [ ] `./run-all.sh --skip-mutation --no-delay` completes successfully
|
|
315
|
+
- [ ] `postman/reports/quality-report-*.html` is generated
|
|
316
|
+
- [ ] All `.sh` files are executable
|
|
317
|
+
- [ ] Jenkinsfile has Mutation Tests stage (full mode) and Quality Report generation
|
|
318
|
+
- [ ] `node-api-coverage-matrix.sh` is configured with correct routes dir
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Setup Test Pipeline Skill
|
|
2
|
+
|
|
3
|
+
## Detect Project Type First
|
|
4
|
+
|
|
5
|
+
Before doing anything, detect the stack:
|
|
6
|
+
|
|
7
|
+
1. `pom.xml` in project root → **Java Spring Boot** → read `SKILL-java.md` in this folder and follow it completely
|
|
8
|
+
2. `package.json` (no `pom.xml`) → **Node.js** → read `SKILL-node.md` in this folder and follow it completely
|
|
9
|
+
3. If unsure → ask the user: "Is this a Java or Node.js project?"
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Write API Tests Skill — Java Spring Boot
|
|
2
|
+
|
|
3
|
+
Write and manage Postman/Newman integration tests for a Java Spring Boot API.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
Invoke this skill when the user mentions:
|
|
8
|
+
- "write api tests", "add api test", "add postman test"
|
|
9
|
+
- "add test for endpoint", "write tests for [endpoint]", "test coverage"
|
|
10
|
+
- "API test", "integration test", "newman"
|
|
11
|
+
|
|
12
|
+
**Note:** If the project doesn't have a `postman/` folder yet, use the **setup-api-tests** skill first to create the infrastructure.
|
|
13
|
+
|
|
14
|
+
## Arguments
|
|
15
|
+
|
|
16
|
+
Arguments are passed after the skill invocation. Parse them before deciding what to write.
|
|
17
|
+
|
|
18
|
+
| Argument form | Behaviour |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `/write-api-tests GET /apps` | Write tests for that specific endpoint only |
|
|
21
|
+
| `/write-api-tests POST /apps PUT /apps/{id}` | Write tests for each listed endpoint |
|
|
22
|
+
| `/write-api-tests` (no argument) | Ask the user which endpoint(s) to target, OR run `java-api-coverage-matrix.sh` to find untested endpoints and offer to write tests for those |
|
|
23
|
+
|
|
24
|
+
### Argument Parsing Rules
|
|
25
|
+
|
|
26
|
+
1. Check if the user passed an HTTP method + path after the skill name (e.g. `GET /apps`, `POST /apps/{id}`)
|
|
27
|
+
2. **If a specific endpoint is given** — scope all work to that endpoint only. Do not touch other collections or endpoints.
|
|
28
|
+
3. **If multiple endpoints are given** — handle each one in sequence, same collection if they belong together, separate if not.
|
|
29
|
+
4. **If no argument** — do one of the following (ask the user which they prefer):
|
|
30
|
+
- **Option A**: Specify an endpoint now (e.g. `GET /apps`)
|
|
31
|
+
- **Option B**: Run `./postman/scripts/report-generators/java-api-coverage-matrix.sh` to find untested endpoints, then let the user pick
|
|
32
|
+
|
|
33
|
+
### When Writing for a Specific Endpoint
|
|
34
|
+
|
|
35
|
+
Before writing any test:
|
|
36
|
+
1. Read the controller file to confirm the exact path, method, request params, and response DTO
|
|
37
|
+
2. Read the response DTO to get correct field names
|
|
38
|
+
3. Check the existing collections to find the right file to add tests to
|
|
39
|
+
4. Confirm the JSON naming strategy (snake_case vs camelCase) from `application.properties`
|
|
40
|
+
5. Write tests, then run `./runners/run-tests-local.sh` and `./java-api-coverage-matrix.sh` to verify
|
|
41
|
+
|
|
42
|
+
## Dual Environment Support
|
|
43
|
+
|
|
44
|
+
### Local Environment
|
|
45
|
+
- **Database**: H2 in-memory (no MySQL needed)
|
|
46
|
+
- **External Services**: WireMock mocks
|
|
47
|
+
- **Authentication**: Hardcoded test JWT token
|
|
48
|
+
- **Command**: `cd postman/scripts && ./runners/run-tests-local.sh`
|
|
49
|
+
|
|
50
|
+
### Staging Environment
|
|
51
|
+
- **Database**: Real MySQL
|
|
52
|
+
- **External Services**: Real services (FreshID, other Freshworks services)
|
|
53
|
+
- **Authentication**: JWT from AWS Secrets Manager
|
|
54
|
+
- **Command**: `cd postman/scripts && ./runners/run-tests-staging.sh`
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
> **Assertion standards, skip patterns, query/include coverage, and the submission checklist are in `../_shared/postman-standards.md`. Read that file for all Postman assertion rules before writing any tests.**
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Running Tests
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Local environment
|
|
66
|
+
cd postman/scripts && ./runners/run-tests-local.sh
|
|
67
|
+
|
|
68
|
+
# Staging environment
|
|
69
|
+
cd postman/scripts && ./runners/run-tests-staging.sh
|
|
70
|
+
|
|
71
|
+
# API coverage report (must show 100% 2xx coverage)
|
|
72
|
+
./postman/scripts/report-generators/java-api-coverage-matrix.sh
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Adding a New Test
|
|
76
|
+
|
|
77
|
+
1. **Choose the right collection** based on endpoint type
|
|
78
|
+
2. **Add request** with descriptive name: `"Verb - Description"`
|
|
79
|
+
3. **Add status code assertion** (exactly one per request)
|
|
80
|
+
4. **Add value assertions** for response fields
|
|
81
|
+
5. **Add skip logic** if environment-specific
|
|
82
|
+
6. **Run locally**: `cd postman/scripts && ./runners/run-tests-local.sh`
|
|
83
|
+
7. **Check coverage**: `./postman/scripts/report-generators/java-api-coverage-matrix.sh`
|
|
84
|
+
|
|
85
|
+
## Adding a New Collection
|
|
86
|
+
|
|
87
|
+
1. Create `postman/collections/XX-feature-name.json` (follow existing collection structure)
|
|
88
|
+
2. Add collection to the arrays in `run-tests-local.sh` and `run-tests-staging.sh`
|
|
89
|
+
3. Format: `cd postman && npm run format`
|
|
90
|
+
4. Test: `cd postman/scripts && ./runners/run-tests-local.sh`
|
|
91
|
+
|
|
92
|
+
## Setting Up Postman in a New Project
|
|
93
|
+
|
|
94
|
+
If the project doesn't have Postman tests yet, use the **setup-api-tests** skill which provides:
|
|
95
|
+
- Complete folder structure
|
|
96
|
+
- package.json with secure dependencies
|
|
97
|
+
- Environment files (local/staging)
|
|
98
|
+
- Config files
|
|
99
|
+
- Script templates
|
|
100
|
+
- Maven integration
|
|
101
|
+
- Spring integration profile
|
|
102
|
+
|
|
103
|
+
## Coverage Report Validation
|
|
104
|
+
|
|
105
|
+
The `java-api-coverage-matrix.sh` script validates all tests. It will flag:
|
|
106
|
+
|
|
107
|
+
| Issue | What It Detects | Fix |
|
|
108
|
+
|-------|-----------------|-----|
|
|
109
|
+
| **No 2xx test** | Endpoint has no success path test | Add 200/201 test |
|
|
110
|
+
| **Weak assertions (oneOf)** | `oneOf([200, 201])` patterns | Split into separate tests |
|
|
111
|
+
| **5xx assertions** | Tests asserting 500 status | Remove - bugs aren't expected behavior |
|
|
112
|
+
| **Missing query params** | `@RequestParam` not tested | Add tests for each param |
|
|
113
|
+
| **Missing include values** | Expected include values not tested | Add tests for each value |
|
|
114
|
+
| **Undocumented skips** | `skipRequest()` without `[SKIP] Reason:` | Add skip reason |
|
|
115
|
+
| **Low body assertions** | No response field validation | Add `pm.expect(json.field)` |
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Write API Tests Skill — Node.js / Express
|
|
2
|
+
|
|
3
|
+
Write Postman/Newman tests for Express API endpoints.
|
|
4
|
+
|
|
5
|
+
Reference: `freshapps_api_node` (`postman/collections/crud/`)
|
|
6
|
+
|
|
7
|
+
## Arguments
|
|
8
|
+
|
|
9
|
+
| Form | Behaviour |
|
|
10
|
+
|------|-----------|
|
|
11
|
+
| `/write-api-tests GET /api/v2/apps` | Tests for that endpoint only |
|
|
12
|
+
| `/write-api-tests` (no args) | Run coverage matrix, offer untested endpoints |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Before Writing
|
|
17
|
+
|
|
18
|
+
1. **Read the controller** — find exact path, method, middleware:
|
|
19
|
+
```bash
|
|
20
|
+
grep -r "router\.\(get\|post\|patch\|put\|delete\)" src/controllers/ -l
|
|
21
|
+
cat src/controllers/v2/<resource>.js
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. **Read the serializer/response shape** — Node APIs often use serializers, not DTOs:
|
|
25
|
+
```bash
|
|
26
|
+
ls src/serializers/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. **Check JSON naming** — default Express is camelCase unless a serializer transforms keys
|
|
30
|
+
|
|
31
|
+
4. **Check auth** — which `authorize('resource.action')` permission is required?
|
|
32
|
+
|
|
33
|
+
5. **Find the right collection** — match domain to `postman/collections/crud/NN-*.json`
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Express route patterns
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
appsRouter.get('/', [authorize('apps.read'), ...], handler);
|
|
41
|
+
appsRouter.get(`/:app_id(${numberRegex})`, [...], handler);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Full path = mount prefix from `controllers/index.js` + route path.
|
|
45
|
+
Example: `/api/v2` + `/apps` → `GET /api/v2/apps`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Writing tests
|
|
50
|
+
|
|
51
|
+
Follow `../_shared/postman-standards.md`:
|
|
52
|
+
- One status code assertion per request
|
|
53
|
+
- Specific value assertions (not just `pm.expect(json).to.be.an('object')`)
|
|
54
|
+
- Document skips: `[SKIP] Reason: ... | Env: staging`
|
|
55
|
+
|
|
56
|
+
### Collection item naming
|
|
57
|
+
`"Verb - Description"` e.g. `"GET - List apps returns 200"`
|
|
58
|
+
|
|
59
|
+
### Environment variables
|
|
60
|
+
Use `{{base_url}}`, `{{auth_token}}` from Postman environment files.
|
|
61
|
+
Multi-role: `auth_token_developer`, etc. (set by JWT scripts from `config/local.json` users map)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Run and verify
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
cd postman/scripts
|
|
69
|
+
./runners/run-tests.sh local
|
|
70
|
+
./report-generators/node-api-coverage-matrix.sh ../../src/controllers ..
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Target: **100% 2xx coverage** on all controller endpoints.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Adding a new collection
|
|
78
|
+
|
|
79
|
+
1. Create `postman/collections/crud/NN-feature-name.json` (numbered for order)
|
|
80
|
+
2. Run `cd postman && npm run format`
|
|
81
|
+
3. Verify with `./runners/run-tests.sh local`
|
|
82
|
+
|
|
83
|
+
Bootstrap (`01-*`) must run first; cleanup (`99-*`) must run last.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Write API Tests Skill
|
|
2
|
+
|
|
3
|
+
## Detect Project Type First
|
|
4
|
+
|
|
5
|
+
Before doing anything, detect the stack:
|
|
6
|
+
|
|
7
|
+
1. `pom.xml` in project root → **Java Spring Boot** → read `SKILL-java.md` in this folder and follow it completely
|
|
8
|
+
2. `package.json` (no `pom.xml`) → **Node.js** → read `SKILL-node.md` in this folder and follow it completely
|
|
9
|
+
3. If unsure → ask the user: "Is this a Java or Node.js project?"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** @type {import('@stryker-mutator/api/core').PartialStrykerOptions} */
|
|
4
|
+
module.exports = {
|
|
5
|
+
packageManager: 'yarn',
|
|
6
|
+
testRunner: 'mocha',
|
|
7
|
+
reporters: ['html', 'json', 'clear-text', 'progress'],
|
|
8
|
+
htmlReporter: {
|
|
9
|
+
fileName: 'coverage/mutation/index.html'
|
|
10
|
+
},
|
|
11
|
+
jsonReporter: {
|
|
12
|
+
fileName: 'coverage/mutation/mutation-report.json'
|
|
13
|
+
},
|
|
14
|
+
mutate: [
|
|
15
|
+
'src/actions/**/*.js',
|
|
16
|
+
'src/helpers/**/*.js',
|
|
17
|
+
'src/serializers/**/*.js',
|
|
18
|
+
'src/middlewares/**/*.js',
|
|
19
|
+
'!src/helpers/validator/schema/**/*.js',
|
|
20
|
+
'!src/helpers/aws.js',
|
|
21
|
+
'!src/helpers/chargebee.js',
|
|
22
|
+
'!src/helpers/freshid.js',
|
|
23
|
+
'!src/helpers/launchdarkly.js',
|
|
24
|
+
'!src/helpers/emailNotifications.js',
|
|
25
|
+
'!src/helpers/analytics.js',
|
|
26
|
+
'!src/helpers/observability.js',
|
|
27
|
+
'!src/helpers/mcp-gateway.js',
|
|
28
|
+
'!src/helpers/mcp-gateway-util.js',
|
|
29
|
+
'!src/helpers/mp-listings.js',
|
|
30
|
+
'!src/helpers/mp-apps.js',
|
|
31
|
+
'!src/helpers/constants.js',
|
|
32
|
+
'!src/helpers/config.js'
|
|
33
|
+
],
|
|
34
|
+
coverageAnalysis: 'perTest',
|
|
35
|
+
concurrency: 4,
|
|
36
|
+
incremental: true,
|
|
37
|
+
incrementalFile: 'coverage/mutation/stryker-incremental.json',
|
|
38
|
+
ignorePatterns: ['postman/**', 'coverage/**'],
|
|
39
|
+
mochaOpts: {
|
|
40
|
+
files: 'test/unit/**/*.test.js',
|
|
41
|
+
require: ['test/unit/setup.js'],
|
|
42
|
+
timeout: 10000
|
|
43
|
+
},
|
|
44
|
+
thresholds: {
|
|
45
|
+
high: 80,
|
|
46
|
+
low: 60,
|
|
47
|
+
break: 0
|
|
48
|
+
},
|
|
49
|
+
tempDirName: 'coverage/mutation/.stryker-tmp'
|
|
50
|
+
};
|