qa-skills 3.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/README.md +168 -0
- package/bin/cli.js +42 -0
- package/dist/agents/registry.d.ts +5 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +101 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +9 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/dependencies.d.ts +21 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +125 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/installer.d.ts +25 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +437 -0
- package/dist/installer.js.map +1 -0
- package/dist/scaffold.d.ts +27 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +182 -0
- package/dist/scaffold.js.map +1 -0
- package/package.json +40 -0
- package/skills/qa-accessibility-test-writer/SKILL.md +127 -0
- package/skills/qa-accessibility-test-writer/references/axe-core-patterns.md +349 -0
- package/skills/qa-accessibility-test-writer/references/best-practices.md +184 -0
- package/skills/qa-accessibility-test-writer/references/wcag-tests.md +331 -0
- package/skills/qa-api-contract-curator/SKILL.md +104 -0
- package/skills/qa-api-contract-curator/references/breaking-changes.md +363 -0
- package/skills/qa-api-contract-curator/references/openapi-structure.md +404 -0
- package/skills/qa-browser-data-collector/SKILL.md +132 -0
- package/skills/qa-browser-data-collector/references/data-collection-checklist.md +91 -0
- package/skills/qa-browser-data-collector/references/playwright-mcp-patterns.md +113 -0
- package/skills/qa-bug-ticket-creator/SKILL.md +148 -0
- package/skills/qa-bug-ticket-creator/references/bug-report-format.md +149 -0
- package/skills/qa-bug-ticket-creator/references/severity-guide.md +81 -0
- package/skills/qa-bug-ticket-creator/templates/bug-ticket-template.md +39 -0
- package/skills/qa-changelog-analyzer/SKILL.md +134 -0
- package/skills/qa-changelog-analyzer/references/git-analysis-patterns.md +138 -0
- package/skills/qa-changelog-analyzer/references/impact-mapping.md +120 -0
- package/skills/qa-clickup-integration/SKILL.md +166 -0
- package/skills/qa-clickup-integration/references/api-patterns.md +102 -0
- package/skills/qa-clickup-integration/references/field-mapping.md +71 -0
- package/skills/qa-codeceptjs-writer/SKILL.md +136 -0
- package/skills/qa-codeceptjs-writer/references/best-practices.md +207 -0
- package/skills/qa-codeceptjs-writer/references/config.md +255 -0
- package/skills/qa-codeceptjs-writer/references/patterns.md +285 -0
- package/skills/qa-coverage-analyzer/SKILL.md +166 -0
- package/skills/qa-coverage-analyzer/references/best-practices.md +142 -0
- package/skills/qa-coverage-analyzer/references/coverage-dimensions.md +155 -0
- package/skills/qa-coverage-analyzer/references/tools.md +204 -0
- package/skills/qa-cypress-writer/SKILL.md +134 -0
- package/skills/qa-cypress-writer/references/assertions.md +121 -0
- package/skills/qa-cypress-writer/references/best-practices.md +82 -0
- package/skills/qa-cypress-writer/references/config.md +121 -0
- package/skills/qa-cypress-writer/references/patterns.md +170 -0
- package/skills/qa-data-factory/SKILL.md +126 -0
- package/skills/qa-data-factory/references/factory-patterns.md +164 -0
- package/skills/qa-data-factory/references/faker-guide.md +131 -0
- package/skills/qa-diagram-generator/SKILL.md +125 -0
- package/skills/qa-diagram-generator/references/c4-model.md +53 -0
- package/skills/qa-diagram-generator/references/charts.md +58 -0
- package/skills/qa-diagram-generator/references/class-diagram.md +85 -0
- package/skills/qa-diagram-generator/references/er-diagram.md +69 -0
- package/skills/qa-diagram-generator/references/flowchart.md +92 -0
- package/skills/qa-diagram-generator/references/from-screenshot.md +45 -0
- package/skills/qa-diagram-generator/references/gantt.md +49 -0
- package/skills/qa-diagram-generator/references/journey.md +50 -0
- package/skills/qa-diagram-generator/references/mindmap.md +75 -0
- package/skills/qa-diagram-generator/references/sequence.md +69 -0
- package/skills/qa-diagram-generator/references/state-diagram.md +56 -0
- package/skills/qa-discovery-interview/SKILL.md +182 -0
- package/skills/qa-discovery-interview/references/completeness-checklist.md +53 -0
- package/skills/qa-discovery-interview/references/conflict-patterns.md +101 -0
- package/skills/qa-discovery-interview/references/qa-categories.md +147 -0
- package/skills/qa-discovery-interview/templates/qa-brief-template.md +168 -0
- package/skills/qa-environment-checker/SKILL.md +142 -0
- package/skills/qa-environment-checker/references/dependency-matrix.md +101 -0
- package/skills/qa-environment-checker/references/health-checks.md +209 -0
- package/skills/qa-environment-checker/templates/env-readiness-template.md +64 -0
- package/skills/qa-flaky-detector/SKILL.md +153 -0
- package/skills/qa-flaky-detector/references/ci-analysis.md +140 -0
- package/skills/qa-flaky-detector/references/flaky-patterns.md +247 -0
- package/skills/qa-github-issues-enhanced/SKILL.md +175 -0
- package/skills/qa-github-issues-enhanced/references/issue-templates.md +425 -0
- package/skills/qa-github-issues-enhanced/references/label-taxonomy.md +130 -0
- package/skills/qa-github-issues-enhanced/references/workflow-patterns.md +188 -0
- package/skills/qa-httpx-writer/SKILL.md +138 -0
- package/skills/qa-httpx-writer/references/assertions.md +195 -0
- package/skills/qa-httpx-writer/references/best-practices.md +140 -0
- package/skills/qa-httpx-writer/references/config.md +212 -0
- package/skills/qa-httpx-writer/references/patterns.md +262 -0
- package/skills/qa-jest-writer/SKILL.md +131 -0
- package/skills/qa-jest-writer/references/assertions.md +125 -0
- package/skills/qa-jest-writer/references/best-practices.md +136 -0
- package/skills/qa-jest-writer/references/config.md +134 -0
- package/skills/qa-jest-writer/references/patterns.md +172 -0
- package/skills/qa-jira-integration/SKILL.md +135 -0
- package/skills/qa-jira-integration/references/api-patterns.md +143 -0
- package/skills/qa-jira-integration/references/field-mapping.md +79 -0
- package/skills/qa-jira-integration/references/xray-integration.md +85 -0
- package/skills/qa-jmeter-writer/SKILL.md +171 -0
- package/skills/qa-jmeter-writer/references/best-practices.md +157 -0
- package/skills/qa-jmeter-writer/references/config.md +204 -0
- package/skills/qa-jmeter-writer/references/patterns.md +242 -0
- package/skills/qa-junit5-writer/SKILL.md +157 -0
- package/skills/qa-junit5-writer/references/assertions.md +118 -0
- package/skills/qa-junit5-writer/references/config.md +97 -0
- package/skills/qa-junit5-writer/references/patterns.md +162 -0
- package/skills/qa-k6-writer/SKILL.md +155 -0
- package/skills/qa-k6-writer/references/best-practices.md +236 -0
- package/skills/qa-k6-writer/references/config.md +219 -0
- package/skills/qa-k6-writer/references/patterns.md +304 -0
- package/skills/qa-linear-integration/SKILL.md +137 -0
- package/skills/qa-linear-integration/references/api-patterns.md +249 -0
- package/skills/qa-linear-integration/references/field-mapping.md +121 -0
- package/skills/qa-locust-writer/SKILL.md +151 -0
- package/skills/qa-locust-writer/references/best-practices.md +126 -0
- package/skills/qa-locust-writer/references/config.md +170 -0
- package/skills/qa-locust-writer/references/patterns.md +235 -0
- package/skills/qa-manual-test-designer/SKILL.md +145 -0
- package/skills/qa-manual-test-designer/references/exploratory-charters.md +138 -0
- package/skills/qa-manual-test-designer/references/personas.md +146 -0
- package/skills/qa-manual-test-designer/templates/exploratory-charter-template.md +47 -0
- package/skills/qa-manual-test-designer/templates/test-case-template.md +31 -0
- package/skills/qa-mobile-test-writer/SKILL.md +144 -0
- package/skills/qa-mobile-test-writer/references/best-practices.md +214 -0
- package/skills/qa-mobile-test-writer/references/config.md +309 -0
- package/skills/qa-mobile-test-writer/references/patterns.md +304 -0
- package/skills/qa-nfr-analyst/SKILL.md +177 -0
- package/skills/qa-nfr-analyst/references/iso-25010-model.md +159 -0
- package/skills/qa-nfr-analyst/references/owasp-wstg-baseline.md +202 -0
- package/skills/qa-nfr-analyst/references/wcag-checklist.md +184 -0
- package/skills/qa-nfr-analyst/templates/owasp-checklist-template.md +89 -0
- package/skills/qa-nfr-analyst/templates/wcag-checklist-template.md +48 -0
- package/skills/qa-orchestrator/SKILL.md +132 -0
- package/skills/qa-orchestrator/references/handoff-chains.md +105 -0
- package/skills/qa-orchestrator/references/pipeline-modes.md +115 -0
- package/skills/qa-orchestrator/references/scheduler-rules.md +84 -0
- package/skills/qa-pact-writer/SKILL.md +133 -0
- package/skills/qa-pact-writer/references/best-practices.md +100 -0
- package/skills/qa-pact-writer/references/config.md +135 -0
- package/skills/qa-pact-writer/references/patterns.md +161 -0
- package/skills/qa-plan-creator/SKILL.md +139 -0
- package/skills/qa-plan-creator/references/introduction-plan.md +43 -0
- package/skills/qa-plan-creator/references/migration-plan.md +44 -0
- package/skills/qa-plan-creator/references/onboarding-plan.md +46 -0
- package/skills/qa-plan-creator/references/performance-plan.md +44 -0
- package/skills/qa-plan-creator/references/regression-plan.md +45 -0
- package/skills/qa-plan-creator/references/release-plan.md +45 -0
- package/skills/qa-plan-creator/references/sprint-plan.md +44 -0
- package/skills/qa-plan-creator/references/test-plan.md +59 -0
- package/skills/qa-plan-creator/references/uat-plan.md +43 -0
- package/skills/qa-plan-creator/templates/checklist-template.md +36 -0
- package/skills/qa-plan-creator/templates/regression-checklist-template.md +49 -0
- package/skills/qa-plan-creator/templates/release-checklist-template.md +46 -0
- package/skills/qa-plan-creator/templates/test-plan-template.md +74 -0
- package/skills/qa-playwright-py-writer/SKILL.md +156 -0
- package/skills/qa-playwright-py-writer/references/best-practices.md +194 -0
- package/skills/qa-playwright-py-writer/references/config.md +195 -0
- package/skills/qa-playwright-py-writer/references/patterns.md +212 -0
- package/skills/qa-playwright-ts-writer/SKILL.md +151 -0
- package/skills/qa-playwright-ts-writer/references/assertions.md +109 -0
- package/skills/qa-playwright-ts-writer/references/best-practices.md +191 -0
- package/skills/qa-playwright-ts-writer/references/config.md +144 -0
- package/skills/qa-playwright-ts-writer/references/patterns.md +171 -0
- package/skills/qa-pytest-writer/SKILL.md +145 -0
- package/skills/qa-pytest-writer/references/assertions.md +149 -0
- package/skills/qa-pytest-writer/references/best-practices.md +97 -0
- package/skills/qa-pytest-writer/references/config.md +176 -0
- package/skills/qa-pytest-writer/references/patterns.md +251 -0
- package/skills/qa-qase-integration/SKILL.md +149 -0
- package/skills/qa-qase-integration/references/api-reference.md +354 -0
- package/skills/qa-qase-integration/references/ci-integration.md +196 -0
- package/skills/qa-qase-integration/references/field-mapping.md +157 -0
- package/skills/qa-requirements-generator/SKILL.md +152 -0
- package/skills/qa-requirements-generator/references/iso-29148-structure.md +153 -0
- package/skills/qa-requirements-generator/references/requirement-patterns.md +278 -0
- package/skills/qa-rest-assured-writer/SKILL.md +137 -0
- package/skills/qa-rest-assured-writer/references/best-practices.md +50 -0
- package/skills/qa-rest-assured-writer/references/config.md +124 -0
- package/skills/qa-rest-assured-writer/references/patterns.md +192 -0
- package/skills/qa-risk-analyzer/SKILL.md +158 -0
- package/skills/qa-risk-analyzer/references/impact-analysis.md +133 -0
- package/skills/qa-risk-analyzer/references/risk-factors.md +123 -0
- package/skills/qa-robot-framework-writer/SKILL.md +147 -0
- package/skills/qa-robot-framework-writer/references/best-practices.md +249 -0
- package/skills/qa-robot-framework-writer/references/config.md +204 -0
- package/skills/qa-robot-framework-writer/references/libraries.md +273 -0
- package/skills/qa-robot-framework-writer/references/patterns.md +216 -0
- package/skills/qa-security-test-writer/SKILL.md +123 -0
- package/skills/qa-security-test-writer/references/best-practices.md +155 -0
- package/skills/qa-security-test-writer/references/owasp-top10.md +331 -0
- package/skills/qa-security-test-writer/references/zap-config.md +258 -0
- package/skills/qa-selenium-java-writer/SKILL.md +143 -0
- package/skills/qa-selenium-java-writer/references/best-practices.md +59 -0
- package/skills/qa-selenium-java-writer/references/config.md +143 -0
- package/skills/qa-selenium-java-writer/references/patterns.md +170 -0
- package/skills/qa-selenium-py-writer/SKILL.md +150 -0
- package/skills/qa-selenium-py-writer/references/best-practices.md +175 -0
- package/skills/qa-selenium-py-writer/references/config.md +224 -0
- package/skills/qa-selenium-py-writer/references/patterns.md +255 -0
- package/skills/qa-shortcut-integration/SKILL.md +143 -0
- package/skills/qa-shortcut-integration/references/api-patterns.md +126 -0
- package/skills/qa-shortcut-integration/references/field-mapping.md +66 -0
- package/skills/qa-spec-auditor/SKILL.md +162 -0
- package/skills/qa-spec-auditor/references/audit-checklist.md +144 -0
- package/skills/qa-spec-auditor/references/drift-patterns.md +207 -0
- package/skills/qa-spec-writer/SKILL.md +143 -0
- package/skills/qa-spec-writer/references/gherkin-guide.md +253 -0
- package/skills/qa-spec-writer/references/specification-patterns.md +274 -0
- package/skills/qa-spring-test-writer/SKILL.md +170 -0
- package/skills/qa-spring-test-writer/references/best-practices.md +57 -0
- package/skills/qa-spring-test-writer/references/config.md +179 -0
- package/skills/qa-spring-test-writer/references/patterns.md +235 -0
- package/skills/qa-supertest-writer/SKILL.md +150 -0
- package/skills/qa-supertest-writer/references/assertions.md +192 -0
- package/skills/qa-supertest-writer/references/best-practices.md +102 -0
- package/skills/qa-supertest-writer/references/config.md +166 -0
- package/skills/qa-supertest-writer/references/patterns.md +242 -0
- package/skills/qa-task-creator/SKILL.md +142 -0
- package/skills/qa-task-creator/references/linking-patterns.md +127 -0
- package/skills/qa-task-creator/references/task-types.md +169 -0
- package/skills/qa-task-creator/templates/task-template.md +24 -0
- package/skills/qa-test-doc-compiler/SKILL.md +114 -0
- package/skills/qa-test-doc-compiler/references/agile-tailoring.md +220 -0
- package/skills/qa-test-doc-compiler/references/iso-29119-3-documents.md +302 -0
- package/skills/qa-test-healer/SKILL.md +101 -0
- package/skills/qa-test-healer/references/diagnosis-patterns.md +142 -0
- package/skills/qa-test-healer/references/fix-strategies.md +177 -0
- package/skills/qa-test-reporter/SKILL.md +130 -0
- package/skills/qa-test-reporter/references/best-practices.md +162 -0
- package/skills/qa-test-reporter/references/iso-29119-reports.md +236 -0
- package/skills/qa-test-reporter/references/report-formats.md +287 -0
- package/skills/qa-test-reviewer/SKILL.md +142 -0
- package/skills/qa-test-reviewer/references/anti-patterns.md +268 -0
- package/skills/qa-test-reviewer/references/review-checklist.md +93 -0
- package/skills/qa-test-strategy/SKILL.md +133 -0
- package/skills/qa-test-strategy/references/entry-exit-criteria.md +176 -0
- package/skills/qa-test-strategy/references/risk-matrix.md +102 -0
- package/skills/qa-test-strategy/references/testing-types.md +143 -0
- package/skills/qa-testcase-from-docs/SKILL.md +161 -0
- package/skills/qa-testcase-from-docs/references/test-case-format.md +196 -0
- package/skills/qa-testcase-from-docs/references/test-design-techniques.md +126 -0
- package/skills/qa-testcase-from-docs/templates/test-case-template.md +31 -0
- package/skills/qa-testcase-from-ui/SKILL.md +109 -0
- package/skills/qa-testcase-from-ui/references/ui-element-patterns.md +126 -0
- package/skills/qa-testcase-from-ui/references/visual-analysis-guide.md +146 -0
- package/skills/qa-testcase-from-ui/templates/test-case-template.md +31 -0
- package/skills/qa-visual-regression-writer/SKILL.md +175 -0
- package/skills/qa-visual-regression-writer/references/best-practices.md +154 -0
- package/skills/qa-visual-regression-writer/references/config.md +220 -0
- package/skills/qa-visual-regression-writer/references/patterns.md +213 -0
- package/skills/qa-vitest-writer/SKILL.md +141 -0
- package/skills/qa-vitest-writer/references/assertions.md +105 -0
- package/skills/qa-vitest-writer/references/best-practices.md +62 -0
- package/skills/qa-vitest-writer/references/config.md +127 -0
- package/skills/qa-vitest-writer/references/patterns.md +141 -0
- package/skills/qa-webdriverio-writer/SKILL.md +145 -0
- package/skills/qa-webdriverio-writer/references/best-practices.md +176 -0
- package/skills/qa-webdriverio-writer/references/config.md +240 -0
- package/skills/qa-webdriverio-writer/references/patterns.md +269 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-supertest-writer
|
|
3
|
+
description: Generate Supertest API and integration tests for TypeScript/Node.js with Express/Koa integration, chained assertions, and authentication handling.
|
|
4
|
+
output_dir: tests/api
|
|
5
|
+
dependencies:
|
|
6
|
+
recommended:
|
|
7
|
+
- qa-api-contract-curator
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# QA Supertest Writer
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Write API and integration tests using Supertest from test case specifications and API contracts. Transform structured test cases (from qa-testcase-from-docs, qa-manual-test-designer) and OpenAPI contracts (from qa-api-contract-curator) into executable Supertest code with chained assertions, authentication support, and response validation.
|
|
15
|
+
|
|
16
|
+
## Trigger Phrases
|
|
17
|
+
|
|
18
|
+
- "Write Supertest tests for [API/endpoint]"
|
|
19
|
+
- "Generate API tests from OpenAPI contract"
|
|
20
|
+
- "Create Supertest integration tests for Express"
|
|
21
|
+
- "Add API tests for [endpoint] with auth"
|
|
22
|
+
- "Supertest tests from test cases"
|
|
23
|
+
- "API contract to Supertest tests"
|
|
24
|
+
- "Test file upload with Supertest"
|
|
25
|
+
- "Supertest tests for Koa server"
|
|
26
|
+
|
|
27
|
+
## Key Features
|
|
28
|
+
|
|
29
|
+
| Feature | Description |
|
|
30
|
+
| ------- | ----------- |
|
|
31
|
+
| **Express/Koa integration** | `request(app)` — no server startup; tests run against app instance |
|
|
32
|
+
| **Chained HTTP assertions** | `.expect(statusCode)`, `.expect(contentType)`, `.expect(body)` — fluent API |
|
|
33
|
+
| **Request/response validation** | Headers, status, body shape; JSON Schema or Zod/Joi for schema validation |
|
|
34
|
+
| **Authentication support** | Bearer tokens, cookies, API keys via `.set()` |
|
|
35
|
+
| **File upload testing** | `.attach()` for multipart/form-data |
|
|
36
|
+
|
|
37
|
+
## Workflow
|
|
38
|
+
|
|
39
|
+
1. **Read test cases + API contract** — From qa-testcase-from-docs, qa-manual-test-designer, or qa-api-contract-curator (OpenAPI)
|
|
40
|
+
2. **Generate API test files** — Produce `{endpoint}.api.test.ts` with `describe` per endpoint, `it` per scenario
|
|
41
|
+
3. **Add auth setup** — Bearer token, cookies, or API key fixtures in `beforeEach`/`beforeAll`
|
|
42
|
+
4. **Validate responses** — Status codes, headers, body matching; optional schema validation (Zod, Joi, JSON Schema)
|
|
43
|
+
|
|
44
|
+
## Context7 MCP
|
|
45
|
+
|
|
46
|
+
Use **Context7 MCP** for current Supertest documentation when:
|
|
47
|
+
- API signatures or chaining behavior are uncertain
|
|
48
|
+
- New Supertest features need verification
|
|
49
|
+
- Express vs Koa setup differences require clarification
|
|
50
|
+
|
|
51
|
+
## Key Patterns
|
|
52
|
+
|
|
53
|
+
| Pattern | Usage |
|
|
54
|
+
| ------- | ----- |
|
|
55
|
+
| `request(app)` | Wrap Express/Koa app; no `listen()` needed |
|
|
56
|
+
| `.get(path)` / `.post(path)` / `.put(path)` / `.delete(path)` | HTTP method + path |
|
|
57
|
+
| `.set(header, value)` | Set request headers (Authorization, Content-Type, etc.) |
|
|
58
|
+
| `.send(body)` | Request body (JSON, form) |
|
|
59
|
+
| `.expect(statusCode)` | Assert response status |
|
|
60
|
+
| `.expect(contentType, /json/)` | Assert Content-Type header |
|
|
61
|
+
| `.expect(body)` | Assert response body (string, regex, function) |
|
|
62
|
+
| Chained assertions | `.get('/users').expect(200).expect('Content-Type', /json/)` |
|
|
63
|
+
| Bearer token | `.set('Authorization', 'Bearer ' + token)` |
|
|
64
|
+
| Cookies | `.set('Cookie', cookieString)` or use agent for session |
|
|
65
|
+
| File upload | `.attach(field, filePath)` |
|
|
66
|
+
|
|
67
|
+
See `references/patterns.md` for CRUD, auth, file upload, error responses, pagination.
|
|
68
|
+
|
|
69
|
+
## Test Structure
|
|
70
|
+
|
|
71
|
+
- **describe** per endpoint (e.g., `describe('GET /users')`)
|
|
72
|
+
- **it** per scenario: success, validation error, unauthorized, not found, conflict
|
|
73
|
+
- **beforeAll/beforeEach** for auth tokens, DB seeding, cleanup
|
|
74
|
+
- **afterEach/afterAll** for cleanup (e.g., truncate test data)
|
|
75
|
+
|
|
76
|
+
## Integration with Express/Koa
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import request from 'supertest'
|
|
80
|
+
import { app } from '../src/app'
|
|
81
|
+
|
|
82
|
+
describe('API', () => {
|
|
83
|
+
it('GET /health returns 200', () =>
|
|
84
|
+
request(app).get('/health').expect(200))
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
No `app.listen()` — Supertest handles the request internally.
|
|
89
|
+
|
|
90
|
+
## Schema Validation
|
|
91
|
+
|
|
92
|
+
- **JSON Schema** — Use `ajv` or similar to validate response against schema
|
|
93
|
+
- **Zod** — `zodSchema.parse(response.body)` in custom `.expect()` callback
|
|
94
|
+
- **Joi** — `Joi.assert(response.body, schema)` in callback
|
|
95
|
+
|
|
96
|
+
## File Naming
|
|
97
|
+
|
|
98
|
+
- `{endpoint}.api.test.ts` — e.g., `users.api.test.ts`, `auth.api.test.ts`
|
|
99
|
+
- `{resource}.api.test.ts` — e.g., `products.api.test.ts`
|
|
100
|
+
|
|
101
|
+
## Scope
|
|
102
|
+
|
|
103
|
+
**Can do (autonomous):**
|
|
104
|
+
- Generate Supertest API tests from test cases and OpenAPI contracts
|
|
105
|
+
- Add auth setup (Bearer, cookies, API key)
|
|
106
|
+
- Use chained assertions, `.set()`, `.send()`, `.attach()`
|
|
107
|
+
- Configure test server, DB seeding, cleanup
|
|
108
|
+
- Validate responses with status, headers, body; add schema validation (Zod/Joi)
|
|
109
|
+
- Call qa-api-contract-curator for contract when needed
|
|
110
|
+
- Use Context7 MCP for Supertest docs
|
|
111
|
+
|
|
112
|
+
**Cannot do (requires confirmation):**
|
|
113
|
+
- Change production API implementation
|
|
114
|
+
- Add dependencies not in package.json
|
|
115
|
+
- Override project test config without approval
|
|
116
|
+
|
|
117
|
+
**Will not do (out of scope):**
|
|
118
|
+
- Execute tests (user runs `npm test` or `vitest`)
|
|
119
|
+
- Write E2E browser tests (use qa-playwright-ts-writer)
|
|
120
|
+
- Modify CI/CD pipelines
|
|
121
|
+
|
|
122
|
+
## References
|
|
123
|
+
|
|
124
|
+
- `references/patterns.md` — CRUD, auth, file upload, error responses, pagination
|
|
125
|
+
- `references/assertions.md` — Status codes, headers, body matching, schema validation
|
|
126
|
+
- `references/config.md` — Test server config, DB seeding, cleanup
|
|
127
|
+
- `references/best-practices.md` — Test isolation, DB state, auth fixtures, response validation
|
|
128
|
+
|
|
129
|
+
## Quality Checklist
|
|
130
|
+
|
|
131
|
+
- [ ] Tests match test case steps and expected results
|
|
132
|
+
- [ ] Each endpoint has success and error scenarios (validation, 401, 404)
|
|
133
|
+
- [ ] Auth setup is correct (Bearer, cookies) and isolated per test
|
|
134
|
+
- [ ] No hardcoded secrets; use env vars or test fixtures
|
|
135
|
+
- [ ] Response assertions are specific (status, body shape, headers)
|
|
136
|
+
- [ ] File naming follows `{endpoint}.api.test.ts`
|
|
137
|
+
- [ ] DB state is reset or isolated between tests
|
|
138
|
+
- [ ] Schema validation used where contract specifies response shape
|
|
139
|
+
|
|
140
|
+
## Troubleshooting
|
|
141
|
+
|
|
142
|
+
| Symptom | Likely Cause | Fix |
|
|
143
|
+
| ------- | ------------ | --- |
|
|
144
|
+
| `request(app)` returns 404 | App not mounted or route missing | Verify app exports; check route registration order |
|
|
145
|
+
| Tests pass individually, fail together | Shared DB state or auth leakage | Reset DB in `beforeEach`; use fresh tokens per test |
|
|
146
|
+
| `.expect(body)` fails on dynamic fields | Body has timestamps, IDs, etc. | Use partial match, regex, or custom callback |
|
|
147
|
+
| Auth not working | Token expired or wrong header | Check `Authorization` format; ensure token in scope |
|
|
148
|
+
| File upload fails | Wrong field name or path | Match `field` to form field; use absolute path |
|
|
149
|
+
| Koa app not working | Different API than Express | Use `request(app.callback())` for Koa |
|
|
150
|
+
| CORS errors in tests | CORS middleware blocking | Supertest bypasses network; check middleware order |
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Supertest Assertion Reference
|
|
2
|
+
|
|
3
|
+
Supertest provides chained `.expect()` methods for HTTP assertions. Combine with Vitest/Jest `expect()` for body validation.
|
|
4
|
+
|
|
5
|
+
## Status Codes
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
request(app).get('/users').expect(200)
|
|
9
|
+
request(app).post('/users').send({}).expect(201)
|
|
10
|
+
request(app).get('/users/999').expect(404)
|
|
11
|
+
request(app).get('/users').expect(401) // Unauthorized
|
|
12
|
+
request(app).post('/users').send({}).expect(400) // Bad Request
|
|
13
|
+
request(app).get('/error').expect(500) // Server Error
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
| Code | Typical Use |
|
|
17
|
+
| ---- | ----------- |
|
|
18
|
+
| 200 | OK — GET, PUT, PATCH success |
|
|
19
|
+
| 201 | Created — POST success |
|
|
20
|
+
| 204 | No Content — DELETE success |
|
|
21
|
+
| 400 | Bad Request — validation error |
|
|
22
|
+
| 401 | Unauthorized — missing/invalid auth |
|
|
23
|
+
| 403 | Forbidden — insufficient permissions |
|
|
24
|
+
| 404 | Not Found — resource missing |
|
|
25
|
+
| 409 | Conflict — duplicate, constraint violation |
|
|
26
|
+
| 422 | Unprocessable Entity — semantic validation |
|
|
27
|
+
| 500 | Internal Server Error |
|
|
28
|
+
|
|
29
|
+
## Content-Type
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
request(app)
|
|
33
|
+
.get('/users')
|
|
34
|
+
.expect('Content-Type', /json/)
|
|
35
|
+
.expect(200)
|
|
36
|
+
|
|
37
|
+
// Exact match
|
|
38
|
+
request(app)
|
|
39
|
+
.get('/users')
|
|
40
|
+
.expect('Content-Type', 'application/json; charset=utf-8')
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Body Assertions
|
|
44
|
+
|
|
45
|
+
### String Match
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
request(app)
|
|
49
|
+
.get('/health')
|
|
50
|
+
.expect(200)
|
|
51
|
+
.expect('OK')
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Regex Match
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
request(app)
|
|
58
|
+
.get('/users/1')
|
|
59
|
+
.expect((res) => {
|
|
60
|
+
expect(res.body.email).toMatch(/^[\w.-]+@[\w.-]+\.\w+$/)
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Custom Callback
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
request(app)
|
|
68
|
+
.get('/users')
|
|
69
|
+
.expect(200)
|
|
70
|
+
.expect((res) => {
|
|
71
|
+
expect(res.body).toHaveProperty('users')
|
|
72
|
+
expect(res.body.users.length).toBeGreaterThan(0)
|
|
73
|
+
expect(res.body.users[0]).toHaveProperty('id')
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### With Vitest/Jest expect()
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const res = await request(app).get('/users').expect(200)
|
|
81
|
+
|
|
82
|
+
expect(res.body).toHaveProperty('users')
|
|
83
|
+
expect(res.body.users).toEqual(expect.arrayContaining([
|
|
84
|
+
expect.objectContaining({ id: 1, email: expect.any(String) }),
|
|
85
|
+
]))
|
|
86
|
+
expect(res.body.users[0]).toMatchObject({ id: 1, name: 'Alice' })
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Header Assertions
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
request(app)
|
|
93
|
+
.get('/users')
|
|
94
|
+
.expect('Content-Type', /json/)
|
|
95
|
+
.expect('X-Request-ID', (val) => expect(val).toBeDefined())
|
|
96
|
+
.expect(200)
|
|
97
|
+
|
|
98
|
+
// Or capture and assert
|
|
99
|
+
const res = await request(app).get('/users').expect(200)
|
|
100
|
+
expect(res.headers['content-type']).toMatch(/json/)
|
|
101
|
+
expect(res.headers['x-request-id']).toBeDefined()
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Schema Validation
|
|
105
|
+
|
|
106
|
+
### Zod
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { z } from 'zod'
|
|
110
|
+
|
|
111
|
+
const UserSchema = z.object({
|
|
112
|
+
id: z.number(),
|
|
113
|
+
email: z.string().email(),
|
|
114
|
+
name: z.string(),
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
request(app)
|
|
118
|
+
.get('/users/1')
|
|
119
|
+
.expect(200)
|
|
120
|
+
.expect((res) => {
|
|
121
|
+
const parsed = UserSchema.parse(res.body)
|
|
122
|
+
expect(parsed.id).toBe(1)
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Joi
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import Joi from 'joi'
|
|
130
|
+
|
|
131
|
+
const userSchema = Joi.object({
|
|
132
|
+
id: Joi.number().required(),
|
|
133
|
+
email: Joi.string().email().required(),
|
|
134
|
+
name: Joi.string().required(),
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
request(app)
|
|
138
|
+
.get('/users/1')
|
|
139
|
+
.expect(200)
|
|
140
|
+
.expect((res) => {
|
|
141
|
+
Joi.assert(res.body, userSchema)
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### JSON Schema (ajv)
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import Ajv from 'ajv'
|
|
149
|
+
|
|
150
|
+
const ajv = new Ajv()
|
|
151
|
+
const validate = ajv.compile(userJsonSchema)
|
|
152
|
+
|
|
153
|
+
request(app)
|
|
154
|
+
.get('/users/1')
|
|
155
|
+
.expect(200)
|
|
156
|
+
.expect((res) => {
|
|
157
|
+
const valid = validate(res.body)
|
|
158
|
+
expect(valid).toBe(true)
|
|
159
|
+
if (!valid) expect(validate.errors).toBeDefined()
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Chained Assertions
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
await request(app)
|
|
167
|
+
.post('/users')
|
|
168
|
+
.set('Content-Type', 'application/json')
|
|
169
|
+
.send({ email: 'a@b.com', name: 'Alice' })
|
|
170
|
+
.expect(201)
|
|
171
|
+
.expect('Content-Type', /json/)
|
|
172
|
+
.expect((res) => {
|
|
173
|
+
expect(res.body).toHaveProperty('id')
|
|
174
|
+
expect(res.body.email).toBe('a@b.com')
|
|
175
|
+
})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Async vs Sync
|
|
179
|
+
|
|
180
|
+
Use `await` when you need the response for further assertions:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
const res = await request(app).get('/users').expect(200)
|
|
184
|
+
const firstUser = res.body.users[0]
|
|
185
|
+
expect(firstUser).toHaveProperty('email')
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Return the chain when Supertest assertions are sufficient:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
it('returns 200', () => request(app).get('/users').expect(200))
|
|
192
|
+
```
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# API Testing Best Practices
|
|
2
|
+
|
|
3
|
+
## Test Isolation
|
|
4
|
+
|
|
5
|
+
1. **Independent tests** — Each test should pass or fail regardless of order. Use `beforeEach` to reset state.
|
|
6
|
+
2. **No shared mutable state** — Avoid global variables that tests modify; use fixtures or factories.
|
|
7
|
+
3. **Clean database** — Truncate or delete test data between tests, or use transactions that rollback.
|
|
8
|
+
|
|
9
|
+
## Database State
|
|
10
|
+
|
|
11
|
+
| Approach | Pros | Cons |
|
|
12
|
+
| -------- | ---- | ---- |
|
|
13
|
+
| **Truncate + seed** | Clean slate each run | Slower; may conflict with parallel tests |
|
|
14
|
+
| **Transactions** | Fast; automatic rollback | Requires transaction support in app |
|
|
15
|
+
| **Isolated DB per worker** | No cross-test pollution | More setup; resource usage |
|
|
16
|
+
| **Factory + unique data** | Flexible; no truncate | Must avoid collisions (unique emails, etc.) |
|
|
17
|
+
|
|
18
|
+
### Transaction Rollback Example
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
beforeEach(async () => {
|
|
22
|
+
await db.transaction.begin()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
await db.transaction.rollback()
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Auth Fixtures
|
|
31
|
+
|
|
32
|
+
1. **Use test-only accounts** — Never use production credentials.
|
|
33
|
+
2. **Create tokens in beforeAll** — Reuse when tests don't mutate auth state.
|
|
34
|
+
3. **Fresh token per test** — When testing logout, token expiry, or auth changes.
|
|
35
|
+
4. **Store in env** — `TEST_USER_EMAIL`, `TEST_USER_PASSWORD` in `.env.test`.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
beforeAll(async () => {
|
|
39
|
+
token = await getAuthToken(
|
|
40
|
+
process.env.TEST_USER_EMAIL!,
|
|
41
|
+
process.env.TEST_USER_PASSWORD!
|
|
42
|
+
)
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Response Validation
|
|
47
|
+
|
|
48
|
+
1. **Assert status first** — `.expect(200)` before body checks.
|
|
49
|
+
2. **Prefer partial match** — Use `toMatchObject` for dynamic fields (id, createdAt).
|
|
50
|
+
3. **Schema validation** — Use Zod/Joi for contract compliance when OpenAPI is available.
|
|
51
|
+
4. **Avoid over-asserting** — Test what matters; don't lock in implementation details.
|
|
52
|
+
|
|
53
|
+
## Error Scenarios
|
|
54
|
+
|
|
55
|
+
Cover at least:
|
|
56
|
+
|
|
57
|
+
- **Success** — 200/201/204 as per contract
|
|
58
|
+
- **Validation error** — 400 with error payload
|
|
59
|
+
- **Unauthorized** — 401 when missing/invalid auth
|
|
60
|
+
- **Forbidden** — 403 when insufficient permissions
|
|
61
|
+
- **Not found** — 404 for missing resources
|
|
62
|
+
- **Conflict** — 409 for duplicates (where applicable)
|
|
63
|
+
|
|
64
|
+
## File Naming and Structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
tests/
|
|
68
|
+
api/
|
|
69
|
+
users.api.test.ts
|
|
70
|
+
auth.api.test.ts
|
|
71
|
+
products.api.test.ts
|
|
72
|
+
fixtures/
|
|
73
|
+
seed.ts
|
|
74
|
+
users.ts
|
|
75
|
+
helpers/
|
|
76
|
+
auth.ts
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Avoid
|
|
80
|
+
|
|
81
|
+
1. **Hardcoded secrets** — Use env vars or test fixtures.
|
|
82
|
+
2. **Testing implementation** — Test behavior and contract, not internal routes.
|
|
83
|
+
3. **Flaky tests** — No sleep/timeout; use deterministic data.
|
|
84
|
+
4. **Large payloads** — Minimize fixture size; use factories for scale.
|
|
85
|
+
5. **External services** — Mock HTTP calls to third-party APIs.
|
|
86
|
+
|
|
87
|
+
## Parallel Execution
|
|
88
|
+
|
|
89
|
+
When running tests in parallel:
|
|
90
|
+
|
|
91
|
+
- Use separate DB/schema per worker, or
|
|
92
|
+
- Use unique data (UUIDs, timestamps) to avoid collisions, or
|
|
93
|
+
- Run API tests sequentially (`--pool=forks` or `--run` with single worker)
|
|
94
|
+
|
|
95
|
+
## Contract-Driven Tests
|
|
96
|
+
|
|
97
|
+
When using OpenAPI from qa-api-contract-curator:
|
|
98
|
+
|
|
99
|
+
1. Generate tests from paths and operations.
|
|
100
|
+
2. Map status codes from `responses` to `.expect()`.
|
|
101
|
+
3. Use `requestBody` schema for `.send()` payloads.
|
|
102
|
+
4. Use `responses.*.content.*.schema` for body validation (Zod/JSON Schema).
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Supertest Configuration
|
|
2
|
+
|
|
3
|
+
## Test Server Configuration
|
|
4
|
+
|
|
5
|
+
### Express
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import request from 'supertest'
|
|
9
|
+
import { app } from '../src/app'
|
|
10
|
+
|
|
11
|
+
// app is the Express instance; no listen() needed
|
|
12
|
+
describe('API', () => {
|
|
13
|
+
it('works', () => request(app).get('/health').expect(200))
|
|
14
|
+
})
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Koa
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import request from 'supertest'
|
|
21
|
+
import { app } from '../src/app'
|
|
22
|
+
|
|
23
|
+
// Koa: use app.callback()
|
|
24
|
+
describe('API', () => {
|
|
25
|
+
it('works', () => request(app.callback()).get('/health').expect(200))
|
|
26
|
+
})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### HTTP Server (if app is wrapped)
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import http from 'http'
|
|
33
|
+
import { app } from '../src/app'
|
|
34
|
+
|
|
35
|
+
const server = http.createServer(app)
|
|
36
|
+
|
|
37
|
+
describe('API', () => {
|
|
38
|
+
it('works', () => request(server).get('/health').expect(200))
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Test Runner Setup
|
|
43
|
+
|
|
44
|
+
### Vitest
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// vitest.config.ts
|
|
48
|
+
import { defineConfig } from 'vitest/config'
|
|
49
|
+
|
|
50
|
+
export default defineConfig({
|
|
51
|
+
test: {
|
|
52
|
+
environment: 'node',
|
|
53
|
+
include: ['**/*.api.test.ts'],
|
|
54
|
+
testTimeout: 10000,
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Jest
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// jest.config.js
|
|
63
|
+
module.exports = {
|
|
64
|
+
testEnvironment: 'node',
|
|
65
|
+
testMatch: ['**/*.api.test.ts'],
|
|
66
|
+
testTimeout: 10000,
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Database Seeding
|
|
71
|
+
|
|
72
|
+
### beforeAll (once per suite)
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { seedTestData } from '../test/fixtures/seed'
|
|
76
|
+
|
|
77
|
+
beforeAll(async () => {
|
|
78
|
+
await seedTestData()
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### beforeEach (per test)
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
beforeEach(async () => {
|
|
86
|
+
await db.users.truncate()
|
|
87
|
+
await db.users.insert(testUsers)
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Factory-based
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
beforeEach(async () => {
|
|
95
|
+
await userFactory.create({ email: 'test@example.com' })
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Cleanup
|
|
100
|
+
|
|
101
|
+
### afterEach
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
afterEach(async () => {
|
|
105
|
+
await db.users.deleteMany({ email: { $regex: /@test\.example\.com$/ } })
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### afterAll
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
afterAll(async () => {
|
|
113
|
+
await db.disconnect()
|
|
114
|
+
})
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Environment Variables
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
// tests/setup.ts or vitest.config.ts
|
|
121
|
+
process.env.NODE_ENV = 'test'
|
|
122
|
+
process.env.DATABASE_URL = process.env.TEST_DATABASE_URL ?? 'postgres://localhost:5432/test_db'
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Base URL (when testing remote)
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
// For remote API (not typical with Supertest)
|
|
129
|
+
import request from 'supertest'
|
|
130
|
+
|
|
131
|
+
const baseUrl = process.env.API_BASE_URL ?? 'http://localhost:3000'
|
|
132
|
+
|
|
133
|
+
describe('Remote API', () => {
|
|
134
|
+
it('works', () => request(baseUrl).get('/health').expect(200))
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Timeouts
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
// vitest.config.ts
|
|
142
|
+
test: {
|
|
143
|
+
testTimeout: 15000, // 15s for slow DB/API tests
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Shared Auth Fixture
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
// tests/helpers/auth.ts
|
|
151
|
+
export async function getAuthToken(): Promise<string> {
|
|
152
|
+
const res = await request(app)
|
|
153
|
+
.post('/auth/login')
|
|
154
|
+
.send({ email: 'test@example.com', password: 'test' })
|
|
155
|
+
return res.body.token
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
// In test file
|
|
161
|
+
let token: string
|
|
162
|
+
|
|
163
|
+
beforeAll(async () => {
|
|
164
|
+
token = await getAuthToken()
|
|
165
|
+
})
|
|
166
|
+
```
|