@test-station/cli 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +386 -0
  2. package/package.json +3 -3
package/README.md ADDED
@@ -0,0 +1,386 @@
1
+ # test-station
2
+
3
+ [![npm](https://img.shields.io/npm/v/%40test-station%2Fcli?label=npm)](https://www.npmjs.com/package/@test-station/cli)
4
+ [![tests](https://img.shields.io/endpoint?url=https%3A%2F%2Fsmysnk.github.io%2Ftest-station%2Fbadges%2Ftests.json)](https://smysnk.github.io/test-station/)
5
+ [![coverage](https://img.shields.io/endpoint?url=https%3A%2F%2Fsmysnk.github.io%2Ftest-station%2Fbadges%2Fcoverage.json)](https://smysnk.github.io/test-station/)
6
+
7
+ Demo: [Latest self-test report](https://smysnk.github.io/test-station/) | [Latest `report.json`](https://smysnk.github.io/test-station/report.json)
8
+
9
+ `test-station` is a framework- and language-agnostic test orchestration and reporting toolkit.
10
+
11
+ It runs suites from multiple test systems, normalizes the results into a single `report.json`, and renders a drillable HTML report with module, theme, package, suite, test, and coverage views.
12
+
13
+ Built-in adapters currently target common JavaScript tooling, but the execution contract is not tied to a specific language or framework. If a project can produce structured test results or can be wrapped by an adapter, it can be reported through `test-station`.
14
+
15
+ ## Purpose
16
+
17
+ Use `test-station` when raw test output is too fragmented to be operationally useful.
18
+
19
+ Typical cases:
20
+
21
+ - monorepos with multiple packages and mixed frameworks
22
+ - projects that combine unit, browser, e2e, and shell-driven validation
23
+ - teams that need one report surface for pass/fail, duration, ownership, and coverage
24
+ - projects that want policy-aware grouping such as modules, themes, or product areas
25
+
26
+ ## What It Produces
27
+
28
+ A run produces:
29
+
30
+ - `report.json`: normalized machine-readable results
31
+ - `index.html`: interactive HTML report
32
+ - `raw/`: per-suite raw artifacts and framework output
33
+
34
+ The HTML report supports:
35
+
36
+ - module-first and package-first views
37
+ - progressive drilldown from summary to individual test detail
38
+ - pass/fail, duration, and test-count rollups
39
+ - coverage rollups and per-file coverage tables
40
+ - optional ownership, classification, and source-analysis enrichment
41
+
42
+ ### Report Overview
43
+
44
+ ![Report overview](../../docs/assets/report-overview.png)
45
+
46
+ ### Drilldown View
47
+
48
+ ![Report drilldown](../../docs/assets/report-drilldown.png)
49
+
50
+ ## Architecture
51
+
52
+ The system is split into small packages with explicit boundaries.
53
+
54
+ 1. `@test-station/cli`
55
+ Main install package. Runs configured suites and writes JSON + HTML artifacts.
56
+ 2. `@test-station/core`
57
+ Loads config, resolves adapters, executes suites, normalizes results, applies policy, and builds the report model.
58
+ 3. `@test-station/render-html`
59
+ Renders the normalized report into the interactive HTML UI.
60
+ 4. Built-in adapters
61
+ - `@test-station/adapter-node-test`
62
+ - `@test-station/adapter-vitest`
63
+ - `@test-station/adapter-playwright`
64
+ - `@test-station/adapter-shell`
65
+ - `@test-station/adapter-jest`
66
+ 5. Built-in enrichment/plugin package
67
+ - `@test-station/plugin-source-analysis`
68
+
69
+ ### Execution Flow
70
+
71
+ ```mermaid
72
+ flowchart LR
73
+ A["test-station.config.mjs"] --> B["@test-station/cli"]
74
+ B --> C["@test-station/core"]
75
+ C --> D["Adapters"]
76
+ D --> E["Normalized suite results"]
77
+ E --> F["Policy and plugin pipeline"]
78
+ F --> G["report.json"]
79
+ F --> H["@test-station/render-html"]
80
+ H --> I["index.html"]
81
+ ```
82
+
83
+ ### Package Responsibilities
84
+
85
+ - `@test-station/cli`: command entrypoint and artifact writing
86
+ - `@test-station/core`: config loading, orchestration, normalization, aggregation, coverage rollups, policy pipeline
87
+ - `@test-station/render-html`: browser report UI and report rendering
88
+ - `@test-station/adapter-node-test`: direct `node --test` execution and normalization
89
+ - `@test-station/adapter-vitest`: Vitest execution, normalization, and coverage collection
90
+ - `@test-station/adapter-playwright`: Playwright execution and normalization
91
+ - `@test-station/adapter-shell`: arbitrary command-backed suites
92
+ - `@test-station/adapter-jest`: Jest execution, normalization, and coverage collection
93
+ - `@test-station/plugin-source-analysis`: static enrichment of assertions, setup, mocks, and source snippets
94
+
95
+ ## Quickstart
96
+
97
+ ### Local Checkout
98
+
99
+ This is the fastest way to see the reporter running against its own test suite.
100
+
101
+ ```sh
102
+ git clone https://github.com/smysnk/test-station.git
103
+ cd test-station
104
+ yarn install
105
+ yarn test:coverage
106
+ ```
107
+
108
+ Artifacts are written to:
109
+
110
+ ```text
111
+ .test-results/self-test-report/
112
+ ```
113
+
114
+ ### npm Install
115
+
116
+ For most consumers, install `@test-station/cli`. It provides the `test-station` binary and brings in `@test-station/core`, `@test-station/render-html`, and the built-in adapters used by the default runtime.
117
+
118
+ ```sh
119
+ npm install --save-dev @test-station/cli
120
+ ```
121
+
122
+ Install additional packages only when you need them directly:
123
+
124
+ - `@test-station/core` for `defineConfig(...)`, `runReport(...)`, or other programmatic control
125
+ - `@test-station/render-html` when rendering HTML from an existing `report.json`
126
+ - `@test-station/plugin-source-analysis` when importing the enrichment plugin directly
127
+ - `@test-station/adapter-*` when assembling a custom adapter registry outside the default core bundle
128
+
129
+ ### Minimal Consumer Setup
130
+
131
+ Create `test-station.config.mjs` in the target project:
132
+
133
+ ```js
134
+ const rootDir = import.meta.dirname;
135
+
136
+ export default {
137
+ schemaVersion: '1',
138
+ project: {
139
+ name: 'my-project',
140
+ rootDir,
141
+ outputDir: 'artifacts/test-report',
142
+ rawDir: 'artifacts/test-report/raw',
143
+ },
144
+ execution: {
145
+ continueOnError: true,
146
+ defaultCoverage: false,
147
+ },
148
+ suites: [
149
+ {
150
+ id: 'unit',
151
+ label: 'Unit Tests',
152
+ adapter: 'node-test',
153
+ package: 'app',
154
+ cwd: rootDir,
155
+ command: ['node', '--test', './test/**/*.test.js'],
156
+ coverage: {
157
+ enabled: true,
158
+ mode: 'same-run',
159
+ },
160
+ },
161
+ ],
162
+ };
163
+ ```
164
+
165
+ With `@test-station/cli` installed, run it with:
166
+
167
+ ```sh
168
+ npx test-station run --config ./test-station.config.mjs
169
+ npx test-station run --config ./test-station.config.mjs --coverage
170
+ ```
171
+
172
+ ### Package Script Integration
173
+
174
+ #### Yarn
175
+
176
+ ```json
177
+ {
178
+ "scripts": {
179
+ "test": "test-station run --config ./test-station.config.mjs",
180
+ "test:coverage": "test-station run --config ./test-station.config.mjs --coverage"
181
+ }
182
+ }
183
+ ```
184
+
185
+ #### npm
186
+
187
+ ```json
188
+ {
189
+ "scripts": {
190
+ "test": "test-station run --config ./test-station.config.mjs",
191
+ "test:coverage": "test-station run --config ./test-station.config.mjs --coverage"
192
+ }
193
+ }
194
+ ```
195
+
196
+ #### pnpm
197
+
198
+ ```json
199
+ {
200
+ "scripts": {
201
+ "test": "test-station run --config ./test-station.config.mjs",
202
+ "test:coverage": "test-station run --config ./test-station.config.mjs --coverage"
203
+ }
204
+ }
205
+ ```
206
+
207
+ ## Integration Model
208
+
209
+ A host project typically owns only three things:
210
+
211
+ - `test-station.config.mjs`
212
+ - a classification / coverage attribution / ownership manifest
213
+ - optional host-specific plugins or custom adapters when generic ones are not enough
214
+
215
+ Everything else should be delegated to `test-station`.
216
+
217
+ ### Uniform Runtime Contract
218
+
219
+ All built-in command-backed adapters follow the same integration rules:
220
+
221
+ - declare suites explicitly in `test-station.config.mjs`
222
+ - pass per-suite environment variables with `suite.env`
223
+ - consume normalized output from `report.json`
224
+ - use `raw/` for framework-native artifacts and intermediate reports
225
+
226
+ ### Empty Workspaces And Zero-Test Suites
227
+
228
+ If `workspaceDiscovery.packages` lists a package with no matching suites, that package still appears in the report as `skipped` with zero suites. This is the recommended way to keep explicit monorepo packages visible without inventing synthetic suite results.
229
+
230
+ If a suite runs and the underlying framework reports zero tests, the suite is normalized as `skipped`.
231
+
232
+ ### Playwright In CI
233
+
234
+ Consumers using the built-in Playwright adapter must install Playwright browsers in CI before running the reporter.
235
+
236
+ Typical prerequisite:
237
+
238
+ ```sh
239
+ yarn playwright install --with-deps
240
+ ```
241
+
242
+ ### Raw Artifact Contract
243
+
244
+ Suites can attach raw artifacts that will be written under `raw/` and linked from the HTML report.
245
+
246
+ Supported shapes:
247
+
248
+ ```js
249
+ rawArtifacts: [
250
+ {
251
+ relativePath: 'web-e2e/playwright.json',
252
+ label: 'Playwright JSON',
253
+ content: JSON.stringify(payload, null, 2),
254
+ },
255
+ {
256
+ relativePath: 'web-e2e/trace.zip',
257
+ label: 'Trace ZIP',
258
+ sourcePath: '/absolute/path/to/trace.zip',
259
+ mediaType: 'application/zip',
260
+ },
261
+ {
262
+ relativePath: 'web-e2e/test-results',
263
+ label: 'Copied test-results directory',
264
+ kind: 'directory',
265
+ sourcePath: '/absolute/path/to/test-results',
266
+ },
267
+ ]
268
+ ```
269
+
270
+ Use this contract for stable raw links. Do not treat it as a generic process-management or upload system.
271
+
272
+ ### Consumer Modes
273
+
274
+ There are two supported consumer modes:
275
+
276
+ 1. Local reference checkout
277
+ - useful while the standalone repo is being developed alongside a host project
278
+ - stable host-facing entrypoints are:
279
+ - `./references/test-station/config.mjs`
280
+ - `./references/test-station/bin/test-station.mjs`
281
+ 2. Installed package dependency
282
+ - install `@test-station/cli` for the published `test-station` binary
283
+ - install `@test-station/core` if you want `defineConfig(...)` or `runReport(...)`
284
+ - install `@test-station/render-html` only when rendering from an existing `report.json` outside the CLI
285
+ - install direct adapter or plugin packages only for custom registries and advanced embedding
286
+
287
+ For local-reference mode, keep host imports pointed at the root-level entrypoints above rather than `packages/*/src`.
288
+
289
+ ### Classification, Coverage Attribution, And Ownership
290
+
291
+ If you want the report grouped by product or subsystem instead of leaving tests uncategorized, provide a manifest file.
292
+
293
+ ```json
294
+ {
295
+ "rules": [
296
+ {
297
+ "package": "app",
298
+ "include": ["test/**/*.test.js"],
299
+ "module": "runtime",
300
+ "theme": "api"
301
+ }
302
+ ],
303
+ "coverageRules": [
304
+ {
305
+ "package": "app",
306
+ "include": ["src/**/*.js"],
307
+ "module": "runtime",
308
+ "theme": "api"
309
+ }
310
+ ],
311
+ "ownership": {
312
+ "modules": [
313
+ { "module": "runtime", "owner": "runtime-team" }
314
+ ],
315
+ "themes": [
316
+ { "module": "runtime", "theme": "api", "owner": "runtime-api-team" }
317
+ ]
318
+ }
319
+ }
320
+ ```
321
+
322
+ Reference it from config:
323
+
324
+ ```js
325
+ manifests: {
326
+ classification: './test-modules.json',
327
+ coverageAttribution: './test-modules.json',
328
+ ownership: './test-modules.json',
329
+ }
330
+ ```
331
+
332
+ ### Custom Policy Plugins
333
+
334
+ A plugin can hook into these stages:
335
+
336
+ - `classifyTest(...)`
337
+ - `attributeCoverageFile(...)`
338
+ - `lookupOwner(...)`
339
+ - `enrichTest(...)`
340
+
341
+ Register plugins like this:
342
+
343
+ ```js
344
+ plugins: [
345
+ {
346
+ handler: './scripts/test-station/my-policy-plugin.mjs',
347
+ options: {
348
+ owner: 'platform-team',
349
+ },
350
+ },
351
+ ]
352
+ ```
353
+
354
+ ## Examples
355
+
356
+ - Generic consumer example:
357
+ [`../../examples/generic-node-library/test-station.config.mjs`](../../examples/generic-node-library/test-station.config.mjs)
358
+ - Mixed-framework example:
359
+ [`../../examples/mixed-framework-monorepo/test-station.config.mjs`](../../examples/mixed-framework-monorepo/test-station.config.mjs)
360
+ - Integration guide:
361
+ [`../../docs/integrating-a-generic-project.md`](../../docs/integrating-a-generic-project.md)
362
+
363
+ ## Development
364
+
365
+ Run the standalone repo checks with:
366
+
367
+ ```sh
368
+ yarn lint
369
+ yarn test
370
+ yarn build
371
+ ```
372
+
373
+ The current external-consumer smoke path is:
374
+
375
+ ```sh
376
+ node ./bin/test-station.mjs run --config ./examples/generic-node-library/test-station.config.mjs --coverage
377
+ ```
378
+
379
+ ## Versioning
380
+
381
+ All publishable `@test-station/*` packages currently move in lockstep at `0.1.0`.
382
+
383
+ For deeper release and compatibility details, see:
384
+
385
+ - [`../../docs/integrating-a-generic-project.md`](../../docs/integrating-a-generic-project.md)
386
+ - [`../../docs/versioning-and-release-strategy.md`](../../docs/versioning-and-release-strategy.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@test-station/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -12,8 +12,8 @@
12
12
  ".": "./src/index.js"
13
13
  },
14
14
  "dependencies": {
15
- "@test-station/core": "workspace:*",
16
- "@test-station/render-html": "workspace:*"
15
+ "@test-station/core": "0.1.5",
16
+ "@test-station/render-html": "0.1.5"
17
17
  },
18
18
  "scripts": {
19
19
  "build": "node ../../scripts/check-package.mjs ./src/index.js && node --check ./src/cli.js",