@rashidee/co2 1.2.5
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/dist/index.js +25449 -0
- package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
- package/drizzle/0001_wise_wolf_cub.sql +13 -0
- package/drizzle/0002_secret_spyke.sql +16 -0
- package/drizzle/0003_workspace_config_singleton.sql +16 -0
- package/drizzle/0004_terminal_claim_v120.sql +11 -0
- package/drizzle/0005_brainstorm_v124.sql +10 -0
- package/drizzle/0006_project_v140.sql +6 -0
- package/drizzle/0007_prd_wizard_v124.sql +14 -0
- package/drizzle/0008_workflow_artifact_v126.sql +24 -0
- package/drizzle/0009_project_import_v150.sql +7 -0
- package/drizzle/0010_quality_v151.sql +3 -0
- package/drizzle/meta/0000_snapshot.json +1335 -0
- package/drizzle/meta/0001_snapshot.json +1416 -0
- package/drizzle/meta/0002_snapshot.json +1510 -0
- package/drizzle/meta/_journal.json +83 -0
- package/package.json +41 -0
- package/plugin/.claude-plugin/marketplace.json +36 -0
- package/plugin/.claude-plugin/plugin.json +22 -0
- package/plugin/README.md +625 -0
- package/plugin/SKILLS.md +350 -0
- package/plugin/co2.svg +5 -0
- package/plugin/commands/brainstorm-loop.md +129 -0
- package/plugin/skills/conductor-defect/SKILL.md +898 -0
- package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
- package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
- package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
- package/plugin/skills/depgen-k8s/SKILL.md +468 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
- package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
- package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
- package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
- package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
- package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
- package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
- package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
- package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
- package/plugin/skills/modelgen-relational/SKILL.md +707 -0
- package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
- package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
- package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
- package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
- package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
- package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
- package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
- package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
- package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
- package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
- package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
- package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
- package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
- package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
- package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
- package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
- package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
- package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
- package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
- package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
- package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
- package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
- package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
- package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
- package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
- package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
- package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
- package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
- package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
- package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
- package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
- package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
- package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
- package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
- package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
- package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
- package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
- package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
- package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
- package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
- package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
- package/plugin/skills/testgen-functional/SKILL.md +1381 -0
- package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
- package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
- package/plugin/skills/util-projectinit/SKILL.md +307 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
- package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
- package/plugin/skills/util-projectsync/SKILL.md +501 -0
- package/plugin/skills/util-updprd/SKILL.md +324 -0
- package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
- package/plugin/skills/util-ustagger/SKILL.md +154 -0
- package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
- package/static/assets/arc-DRKw7sjs.js +1 -0
- package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
- package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
- package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
- package/static/assets/channel-C2nVbuwv.js +1 -0
- package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
- package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
- package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
- package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
- package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
- package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
- package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
- package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
- package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
- package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
- package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
- package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
- package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
- package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
- package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
- package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
- package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
- package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
- package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
- package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
- package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
- package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
- package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
- package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
- package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
- package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
- package/static/assets/graph-C9eacEi8.js +1 -0
- package/static/assets/index-LZSQkLE2.css +41 -0
- package/static/assets/index-y7XDSgMG.js +495 -0
- package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
- package/static/assets/init-Gi6I4Gst.js +1 -0
- package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
- package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
- package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
- package/static/assets/katex-C5jXJg4s.js +257 -0
- package/static/assets/layout-DEXfKzaS.js +1 -0
- package/static/assets/linear-CLO--ryk.js +1 -0
- package/static/assets/map-Czzmt4hB.js +1 -0
- package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
- package/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
- package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
- package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
- package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
- package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
- package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
- package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
- package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
- package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
- package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
- package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
- package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
- package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
- package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
- package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
- package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
- package/static/index.html +24 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Testing & Verification Patterns — specgen-node-cli-web
|
|
2
|
+
|
|
3
|
+
Canonical patterns for the testing strategy (root spec Section 11) and per-module test
|
|
4
|
+
sections. The verification protocol is the heart of this stack: source-only testing is
|
|
5
|
+
insufficient because shebang, bundling, native-module, and asset-path failures only
|
|
6
|
+
surface against the **built** artifact.
|
|
7
|
+
|
|
8
|
+
## 1. Verification protocol
|
|
9
|
+
|
|
10
|
+
`pnpm verify` must pass before any task is complete:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
verify = check (tsc -b + biome check .)
|
|
14
|
+
→ test (vitest run)
|
|
15
|
+
→ build (all packages)
|
|
16
|
+
→ smoke (built CLI: --version + smoke-start.mjs)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The **smoke stage is mandatory**. It executes the *built* CLI: starts the app on a random
|
|
20
|
+
port with a temp `--data-dir`, asserts HTTP 200 on `/` and on `/api/health`, asserts the
|
|
21
|
+
printed admin credentials can log in, then shuts down cleanly.
|
|
22
|
+
|
|
23
|
+
## 2. Unit/integration tests — real DB, never mocked
|
|
24
|
+
|
|
25
|
+
Tests inject `:memory:` SQLite via the connection factory with real migrations applied.
|
|
26
|
+
Never mock the DB:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { beforeEach, describe, expect, it } from 'vitest'
|
|
30
|
+
import { openDatabase, runMigrations, type Db } from '../../db/index.js'
|
|
31
|
+
import { bootstrapAdmin } from '../../db/bootstrap.js'
|
|
32
|
+
|
|
33
|
+
let db: Db
|
|
34
|
+
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
db = openDatabase(':memory:')
|
|
37
|
+
runMigrations(db)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('bootstrapAdmin', () => {
|
|
41
|
+
it('creates the admin with must_change_password on an empty database', () => {
|
|
42
|
+
const created = bootstrapAdmin(db)
|
|
43
|
+
expect(created).not.toBeNull()
|
|
44
|
+
expect(created?.username).toBe('admin')
|
|
45
|
+
expect(created?.password).toHaveLength(16)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('is a no-op once any user exists', () => {
|
|
49
|
+
bootstrapAdmin(db)
|
|
50
|
+
expect(bootstrapAdmin(db)).toBeNull()
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Route tests go through the real Hono app with `app.request()` — no HTTP server needed:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { createApp } from '../../app.js'
|
|
59
|
+
|
|
60
|
+
it('returns 403 PASSWORD_CHANGE_REQUIRED on guarded routes until the password changes', async () => {
|
|
61
|
+
const app = createApp({ db, dataDir: ':memory:' })
|
|
62
|
+
const cookie = await loginAsBootstrappedAdmin(app, db)
|
|
63
|
+
|
|
64
|
+
const guarded = await app.request('/api/users', { headers: { cookie } })
|
|
65
|
+
expect(guarded.status).toBe(403)
|
|
66
|
+
expect((await guarded.json()).code).toBe('PASSWORD_CHANGE_REQUIRED')
|
|
67
|
+
|
|
68
|
+
const change = await app.request('/api/auth/change-password', {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: { cookie, 'content-type': 'application/json' },
|
|
71
|
+
body: JSON.stringify({ currentPassword: BOOT_PASSWORD, newPassword: 'a-longer-password' }),
|
|
72
|
+
})
|
|
73
|
+
expect(change.status).toBe(200)
|
|
74
|
+
|
|
75
|
+
const after = await app.request('/api/users', { headers: { cookie } })
|
|
76
|
+
expect(after.status).toBe(200)
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Mandatory coverage (security invariants)
|
|
81
|
+
|
|
82
|
+
Every generated spec requires tests for:
|
|
83
|
+
|
|
84
|
+
1. Forced-change middleware — 403 on every guarded route; login/change-password/logout
|
|
85
|
+
exempt
|
|
86
|
+
2. Last-admin deletion invariant
|
|
87
|
+
3. Session revocation on password change (other sessions revoked, current kept)
|
|
88
|
+
4. Login rate limiting (attempt 11 within the window rejected)
|
|
89
|
+
5. First-run bootstrap no-op on second start
|
|
90
|
+
|
|
91
|
+
Per business module: every PRD constraint becomes a service-level test; every route gets
|
|
92
|
+
a validation-rejection test (bad body → 400 from zValidator).
|
|
93
|
+
|
|
94
|
+
## 3. Smoke script
|
|
95
|
+
|
|
96
|
+
`scripts/smoke-start.mjs` — runs against the built CLI (default) or a globally installed
|
|
97
|
+
command (`--command <name>` for the pre-publish check):
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
import { spawn } from 'node:child_process'
|
|
101
|
+
import { mkdtempSync, rmSync } from 'node:fs'
|
|
102
|
+
import { tmpdir } from 'node:os'
|
|
103
|
+
import { join } from 'node:path'
|
|
104
|
+
|
|
105
|
+
const command = getArg('--command') ?? 'node'
|
|
106
|
+
const args = command === 'node' ? ['packages/cli/dist/index.js'] : []
|
|
107
|
+
const port = 3000 + Math.floor(Math.random() * 30000)
|
|
108
|
+
const dataDir = mkdtempSync(join(tmpdir(), 'smoke-'))
|
|
109
|
+
|
|
110
|
+
const child = spawn(command, [...args, 'start', '--port', String(port), '--data-dir', dataDir], {
|
|
111
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
let stdout = ''
|
|
115
|
+
child.stdout.on('data', (chunk) => {
|
|
116
|
+
stdout += chunk
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
await waitFor(() => fetchOk(`http://127.0.0.1:${port}/api/health`), 15000)
|
|
121
|
+
await assertOk(`http://127.0.0.1:${port}/`, 'SPA index')
|
|
122
|
+
await assertOk(`http://127.0.0.1:${port}/api/health`, 'health endpoint')
|
|
123
|
+
|
|
124
|
+
const password = /password:\s+(\S+)/.exec(stdout)?.[1]
|
|
125
|
+
if (!password) throw new Error('printed admin credentials not found in start output')
|
|
126
|
+
const login = await fetch(`http://127.0.0.1:${port}/api/auth/login`, {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: { 'content-type': 'application/json' },
|
|
129
|
+
body: JSON.stringify({ username: 'admin', password }),
|
|
130
|
+
})
|
|
131
|
+
if (login.status !== 200) throw new Error(`login with printed credentials failed: ${login.status}`)
|
|
132
|
+
|
|
133
|
+
console.log('smoke: OK')
|
|
134
|
+
} finally {
|
|
135
|
+
child.kill('SIGINT')
|
|
136
|
+
await new Promise((resolve) => child.once('exit', resolve))
|
|
137
|
+
rmSync(dataDir, { recursive: true, force: true })
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
(Include the small `getArg`/`waitFor`/`fetchOk`/`assertOk` helpers in the generated spec
|
|
142
|
+
so the file is complete and runnable.)
|
|
143
|
+
|
|
144
|
+
## 4. Playwright E2E
|
|
145
|
+
|
|
146
|
+
`e2e/` runs against a started instance. `playwright.config.ts` uses a `globalSetup` that
|
|
147
|
+
launches the built CLI exactly like the smoke script (random port, temp data dir),
|
|
148
|
+
captures the printed credentials into `process.env`, and tears the process down in
|
|
149
|
+
`globalTeardown`.
|
|
150
|
+
|
|
151
|
+
The canonical scenario mirrors the full user lifecycle, in order:
|
|
152
|
+
|
|
153
|
+
1. First-run login with the printed credentials → lands on the forced password change
|
|
154
|
+
screen
|
|
155
|
+
2. Forced password change succeeds → redirected into the app
|
|
156
|
+
3. Admin creates a second user (temp password)
|
|
157
|
+
4. Second user logs in → forced change → succeeds
|
|
158
|
+
5. Password change from the settings page (with current password) succeeds
|
|
159
|
+
|
|
160
|
+
Per business module: one spec file exercising the module's list/create/edit/delete flows
|
|
161
|
+
through the real UI, matching the mockup screens.
|
|
162
|
+
|
|
163
|
+
## 5. Pre-publish check
|
|
164
|
+
|
|
165
|
+
After `pnpm verify` is green:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
npm pack ./packages/cli
|
|
169
|
+
npm i -g ./{{PACKAGE_NAME}}-{{VERSION}}.tgz
|
|
170
|
+
node scripts/smoke-start.mjs --command {{PACKAGE_NAME}}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
This validates the `files` whitelist, the shebang, and native-module resolution in the
|
|
174
|
+
exact artifact end users receive.
|