@jterrazz/test 16.1.1 → 17.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.
Files changed (304) hide show
  1. package/README.md +45 -171
  2. package/dist/browser/index.js +2 -2980
  3. package/dist/browser/services.js +2 -0
  4. package/dist/browser/stubs.js +2 -0
  5. package/dist/checker.d.ts +6 -1
  6. package/dist/checker.js +4534 -2628
  7. package/dist/config.d.ts +40 -0
  8. package/dist/config.js +309 -0
  9. package/dist/in-place.global-setup.d.ts +11 -0
  10. package/dist/in-place.global-setup.js +21 -0
  11. package/dist/index.d.ts +1653 -3004
  12. package/dist/index.js +5226 -3845
  13. package/dist/mobile-session.global-setup.d.ts +14 -0
  14. package/dist/mobile-session.global-setup.js +31 -0
  15. package/dist/oxlint.cjs +6069 -5634
  16. package/dist/oxlint.d.cts +43 -7212
  17. package/dist/oxlint.d.ts +43 -7212
  18. package/dist/oxlint.js +6127 -5693
  19. package/dist/route-coverage.global-setup.d.ts +42 -0
  20. package/dist/route-coverage.global-setup.js +2 -0
  21. package/dist/services.d.ts +3 -0
  22. package/dist/services.global-setup.d.ts +43 -0
  23. package/dist/services.global-setup.js +2 -0
  24. package/dist/services.js +597 -0
  25. package/dist/shared-appium.adapter.js +428 -0
  26. package/dist/shared-artifacts.js +32 -0
  27. package/dist/shared-chapter.js +7 -0
  28. package/dist/shared-container.port.d.ts +31 -0
  29. package/dist/shared-derived-projects.js +58 -0
  30. package/dist/shared-device.port.d.ts +189 -0
  31. package/dist/shared-exchange.js +447 -0
  32. package/dist/shared-in-place.js +172 -0
  33. package/dist/shared-index.browser.js +3191 -0
  34. package/dist/shared-index.services.d.ts +346 -0
  35. package/dist/shared-index.stubs.d.ts +287 -0
  36. package/dist/shared-json-shape.js +17 -0
  37. package/dist/shared-landmarks.js +71 -0
  38. package/dist/shared-ledger.js +68 -0
  39. package/dist/shared-literate-plugin.js +183 -0
  40. package/dist/shared-manifest.js +1321 -0
  41. package/dist/shared-pause.js +11 -0
  42. package/dist/shared-peer.js +88 -0
  43. package/dist/shared-playwright.adapter.js +330 -0
  44. package/dist/shared-process.adapter.js +74 -0
  45. package/dist/shared-refusal.js +35 -0
  46. package/dist/shared-resolve.js +24 -0
  47. package/dist/shared-route-coverage.global-setup.js +187 -0
  48. package/dist/shared-scenario-failure.js +198 -0
  49. package/dist/shared-serve.js +365 -0
  50. package/dist/shared-service-images.js +10 -0
  51. package/dist/shared-services.global-setup.js +179 -0
  52. package/dist/shared-session-ledger.js +301 -0
  53. package/dist/shared-setup-entry.js +12 -0
  54. package/dist/shared-source-scan.js +133 -0
  55. package/dist/shared-spec-document.js +365 -0
  56. package/dist/shared-specifications.js +26 -0
  57. package/dist/shared-stream-body.js +130 -0
  58. package/dist/shared-stub-server.js +190 -0
  59. package/dist/shared-temp-root.global-setup.js +80 -0
  60. package/dist/shared-test-baseline.js +26 -0
  61. package/dist/shared-test-section.js +58 -0
  62. package/dist/shared-testcontainers.adapter.js +203 -0
  63. package/dist/shared-tokens.js +55 -0
  64. package/dist/shared-yaml-document.js +119 -0
  65. package/dist/stubs.d.ts +2 -0
  66. package/dist/stubs.js +657 -0
  67. package/dist/temp-root.global-setup.d.ts +7 -0
  68. package/dist/temp-root.global-setup.js +2 -0
  69. package/dist/vitest.d.ts +97 -163
  70. package/dist/vitest.js +373 -525
  71. package/docs/README.md +82 -36
  72. package/docs/concepts/architecture.md +118 -0
  73. package/docs/concepts/conventions.md +333 -0
  74. package/docs/guides/api-specs.md +374 -0
  75. package/docs/guides/cli-specs.md +564 -0
  76. package/docs/guides/component-specs.md +252 -0
  77. package/docs/guides/develop.md +94 -0
  78. package/docs/guides/integration-specs.md +181 -0
  79. package/docs/guides/job-specs.md +180 -0
  80. package/docs/guides/lint-specs.md +174 -0
  81. package/docs/guides/mobile-specs.md +319 -0
  82. package/docs/guides/module-tests.md +149 -0
  83. package/docs/guides/release.md +43 -0
  84. package/docs/guides/spec-documents.md +189 -0
  85. package/docs/guides/website-specs.md +413 -0
  86. package/docs/reference/assertions.md +345 -0
  87. package/docs/reference/glossary.md +20 -0
  88. package/docs/reference/linting.md +483 -0
  89. package/docs/reference/services.md +236 -0
  90. package/docs/reference/stubs.md +498 -0
  91. package/docs/reference/time-and-doubles.md +137 -0
  92. package/docs/reference/tokens.md +258 -0
  93. package/docs/reference/visitor.md +221 -0
  94. package/docs/start/getting-started.md +187 -0
  95. package/docs/start/set-up-a-project.md +214 -0
  96. package/package.json +50 -30
  97. package/schema/spec.schema.json +43 -17
  98. package/dist/appium.adapter.js +0 -489
  99. package/dist/artifacts.js +0 -32
  100. package/dist/fixtures.js +0 -110
  101. package/dist/literate.js +0 -1747
  102. package/dist/match.js +0 -804
  103. package/dist/playwright.adapter.js +0 -438
  104. package/dist/server.js +0 -160
  105. package/dist/stream.js +0 -321
  106. package/dist/substring-warning.js +0 -282
  107. package/docs/01-architecture.md +0 -95
  108. package/docs/02-developing.md +0 -351
  109. package/docs/03-testing.md +0 -495
  110. package/docs/04-operating.md +0 -101
  111. package/docs/05-module-tests.md +0 -152
  112. package/docs/06-integration.md +0 -180
  113. package/docs/07-component.md +0 -246
  114. package/docs/08-website.md +0 -404
  115. package/docs/09-mobile.md +0 -270
  116. package/docs/10-api.md +0 -264
  117. package/docs/11-jobs.md +0 -157
  118. package/docs/12-cli.md +0 -677
  119. package/docs/13-elements.md +0 -248
  120. package/docs/14-assertions.md +0 -314
  121. package/docs/15-tokens.md +0 -253
  122. package/docs/16-contracts.md +0 -438
  123. package/docs/17-services.md +0 -188
  124. package/docs/18-conventions.md +0 -332
  125. package/docs/19-linting.md +0 -512
  126. package/docs/decisions/001-v9-conventions-on-three-channels.md +0 -50
  127. package/docs/decisions/002-the-statique-channel-holds-only-what-upstream-does-not.md +0 -49
  128. package/docs/decisions/003-a-rendered-component-is-a-facet-on-vitest-browser-mode.md +0 -84
  129. package/docs/decisions/004-a-module-against-real-services-or-a-golden-is-the-integration-facet.md +0 -81
  130. package/docs/decisions/005-the-doubles-ladder-is-closed.md +0 -86
  131. package/docs/decisions/006-the-catalogue-reaches-a-file-by-its-role.md +0 -245
  132. package/docs/decisions/007-compose-mode-leaves-the-package.md +0 -53
  133. package/docs/decisions/008-vitest-5-node-24-and-the-native-seams-as-optional-peers.md +0 -75
  134. package/docs/decisions/_template.md +0 -22
  135. package/docs/reference/classes/Matcher.md +0 -120
  136. package/docs/reference/classes/ProcessHandle.md +0 -368
  137. package/docs/reference/functions/defineContract.md +0 -39
  138. package/docs/reference/functions/defineContracts.md +0 -36
  139. package/docs/reference/functions/disabled.md +0 -28
  140. package/docs/reference/functions/enabled.md +0 -20
  141. package/docs/reference/functions/focused.md +0 -26
  142. package/docs/reference/functions/mockOf.md +0 -79
  143. package/docs/reference/functions/postgres.md +0 -31
  144. package/docs/reference/functions/process.md +0 -33
  145. package/docs/reference/functions/redis.md +0 -28
  146. package/docs/reference/functions/required.md +0 -41
  147. package/docs/reference/functions/selected.md +0 -26
  148. package/docs/reference/functions/sqlite.md +0 -33
  149. package/docs/reference/functions/testId.md +0 -20
  150. package/docs/reference/functions/text.md +0 -40
  151. package/docs/reference/functions/valued.md +0 -28
  152. package/docs/reference/functions/waitUntil.md +0 -46
  153. package/docs/reference/functions/within.md +0 -29
  154. package/docs/reference/index.md +0 -196
  155. package/docs/reference/interfaces/BaseResult.md +0 -87
  156. package/docs/reference/interfaces/CallResult.md +0 -160
  157. package/docs/reference/interfaces/CaptureScope.md +0 -82
  158. package/docs/reference/interfaces/CliResult.md +0 -253
  159. package/docs/reference/interfaces/ContainerAccessor.md +0 -166
  160. package/docs/reference/interfaces/DirectoryAccessor.md +0 -33
  161. package/docs/reference/interfaces/FetchResult.md +0 -180
  162. package/docs/reference/interfaces/FilesystemAccessor.md +0 -46
  163. package/docs/reference/interfaces/HttpResult.md +0 -126
  164. package/docs/reference/interfaces/JsonAccessor.md +0 -46
  165. package/docs/reference/interfaces/PageResult.md +0 -356
  166. package/docs/reference/interfaces/RenderResult.md +0 -72
  167. package/docs/reference/interfaces/RenderedText.md +0 -110
  168. package/docs/reference/interfaces/ResponseAccessor.md +0 -47
  169. package/docs/reference/interfaces/ScreenResult.md +0 -128
  170. package/docs/reference/interfaces/TableAccessor.md +0 -26
  171. package/docs/reference/interfaces/TextAccessor.md +0 -96
  172. package/docs/reference/type-aliases/ApiHandle.md +0 -68
  173. package/docs/reference/type-aliases/ApiSpecification.md +0 -213
  174. package/docs/reference/type-aliases/ApiSpecificationOptions.md +0 -68
  175. package/docs/reference/type-aliases/BrowserConsoleMessage.md +0 -30
  176. package/docs/reference/type-aliases/BrowserLinkElement.md +0 -50
  177. package/docs/reference/type-aliases/BrowserMetaElement.md +0 -40
  178. package/docs/reference/type-aliases/BrowserOpenOptions.md +0 -87
  179. package/docs/reference/type-aliases/BrowserPage.md +0 -132
  180. package/docs/reference/type-aliases/BrowserPort.md +0 -51
  181. package/docs/reference/type-aliases/CliEnv.md +0 -11
  182. package/docs/reference/type-aliases/CliHandle.md +0 -80
  183. package/docs/reference/type-aliases/CliInput.md +0 -36
  184. package/docs/reference/type-aliases/CliOutput.md +0 -46
  185. package/docs/reference/type-aliases/CliPort.md +0 -58
  186. package/docs/reference/type-aliases/CliSpecification.md +0 -144
  187. package/docs/reference/type-aliases/CliSpecificationOptions.md +0 -134
  188. package/docs/reference/type-aliases/ComponentChain.md +0 -156
  189. package/docs/reference/type-aliases/ComponentScenario.md +0 -20
  190. package/docs/reference/type-aliases/ComponentUi.md +0 -47
  191. package/docs/reference/type-aliases/ComponentVisitor.md +0 -10
  192. package/docs/reference/type-aliases/ContainerPort.md +0 -113
  193. package/docs/reference/type-aliases/Contract.md +0 -68
  194. package/docs/reference/type-aliases/ContractInput.md +0 -13
  195. package/docs/reference/type-aliases/ContractRequest.md +0 -95
  196. package/docs/reference/type-aliases/ContractResponder.md +0 -23
  197. package/docs/reference/type-aliases/ContractResponse.md +0 -78
  198. package/docs/reference/type-aliases/ContractResponseValue.md +0 -13
  199. package/docs/reference/type-aliases/Contracts.md +0 -48
  200. package/docs/reference/type-aliases/DatabaseKeys.md +0 -16
  201. package/docs/reference/type-aliases/DatabasePort.md +0 -72
  202. package/docs/reference/type-aliases/DeviceOpenOptions.md +0 -46
  203. package/docs/reference/type-aliases/DevicePort.md +0 -51
  204. package/docs/reference/type-aliases/DeviceScreen.md +0 -32
  205. package/docs/reference/type-aliases/DeviceTimeouts.md +0 -39
  206. package/docs/reference/type-aliases/DockerSpecConfig.md +0 -43
  207. package/docs/reference/type-aliases/DomMount.md +0 -21
  208. package/docs/reference/type-aliases/ElementKind.md +0 -27
  209. package/docs/reference/type-aliases/ElementMatch.md +0 -74
  210. package/docs/reference/type-aliases/ElementOptions.md +0 -29
  211. package/docs/reference/type-aliases/ElementRef.md +0 -128
  212. package/docs/reference/type-aliases/ExecOptions.md +0 -37
  213. package/docs/reference/type-aliases/FileAccessor.md +0 -54
  214. package/docs/reference/type-aliases/HonoApp.md +0 -31
  215. package/docs/reference/type-aliases/HttpContractFilter.md +0 -49
  216. package/docs/reference/type-aliases/HttpResponseInit.md +0 -46
  217. package/docs/reference/type-aliases/HttpStreamInit.md +0 -58
  218. package/docs/reference/type-aliases/IntegrationHandle.md +0 -46
  219. package/docs/reference/type-aliases/IntegrationSpecification.md +0 -111
  220. package/docs/reference/type-aliases/IntegrationSpecificationOptions.md +0 -42
  221. package/docs/reference/type-aliases/Intercept.md +0 -19
  222. package/docs/reference/type-aliases/InterceptOptions.md +0 -28
  223. package/docs/reference/type-aliases/InterceptScope.md +0 -11
  224. package/docs/reference/type-aliases/IsolationStrategy.md +0 -75
  225. package/docs/reference/type-aliases/JobHandle.md +0 -34
  226. package/docs/reference/type-aliases/JobsHandle.md +0 -57
  227. package/docs/reference/type-aliases/JobsResult.md +0 -16
  228. package/docs/reference/type-aliases/JobsSpecification.md +0 -94
  229. package/docs/reference/type-aliases/JobsSpecificationOptions.md +0 -56
  230. package/docs/reference/type-aliases/LandmarkKind.md +0 -20
  231. package/docs/reference/type-aliases/LiterateRunFlags.md +0 -27
  232. package/docs/reference/type-aliases/LiterateServeRegistration.md +0 -70
  233. package/docs/reference/type-aliases/MatchFixtureOptions.md +0 -27
  234. package/docs/reference/type-aliases/MatchableRequest.md +0 -61
  235. package/docs/reference/type-aliases/MatcherKind.md +0 -34
  236. package/docs/reference/type-aliases/MobileBackendOptions.md +0 -28
  237. package/docs/reference/type-aliases/MobileElementKind.md +0 -14
  238. package/docs/reference/type-aliases/MobileElementMatch.md +0 -60
  239. package/docs/reference/type-aliases/MobileElementRef.md +0 -20
  240. package/docs/reference/type-aliases/MobileHandle.md +0 -65
  241. package/docs/reference/type-aliases/MobileScenario.md +0 -20
  242. package/docs/reference/type-aliases/MobileSpecification.md +0 -51
  243. package/docs/reference/type-aliases/MobileSpecificationOptions.md +0 -126
  244. package/docs/reference/type-aliases/MobileVisitor.md +0 -81
  245. package/docs/reference/type-aliases/MockOfOptions.md +0 -26
  246. package/docs/reference/type-aliases/MockPort.md +0 -10
  247. package/docs/reference/type-aliases/PinnedClock.md +0 -10
  248. package/docs/reference/type-aliases/PostgresOptions.md +0 -32
  249. package/docs/reference/type-aliases/ProcessOptions.md +0 -112
  250. package/docs/reference/type-aliases/RedisOptions.md +0 -20
  251. package/docs/reference/type-aliases/RenderSubject.md +0 -12
  252. package/docs/reference/type-aliases/ScreenNode.md +0 -67
  253. package/docs/reference/type-aliases/ServerPort.md +0 -36
  254. package/docs/reference/type-aliases/ServerResponse.md +0 -46
  255. package/docs/reference/type-aliases/ServerSpec.md +0 -21
  256. package/docs/reference/type-aliases/ServiceHandle.md +0 -216
  257. package/docs/reference/type-aliases/ServiceRecord.md +0 -12
  258. package/docs/reference/type-aliases/SpecDocument.md +0 -84
  259. package/docs/reference/type-aliases/SpecEnvToken.md +0 -21
  260. package/docs/reference/type-aliases/SpecFileAssertion.md +0 -27
  261. package/docs/reference/type-aliases/SpecFixture.md +0 -30
  262. package/docs/reference/type-aliases/SpecKind.md +0 -8
  263. package/docs/reference/type-aliases/SpecRun.md +0 -108
  264. package/docs/reference/type-aliases/SpecServeEntry.md +0 -40
  265. package/docs/reference/type-aliases/SpecStream.md +0 -32
  266. package/docs/reference/type-aliases/SpecificationConfig.md +0 -290
  267. package/docs/reference/type-aliases/SqliteOptions.md +0 -36
  268. package/docs/reference/type-aliases/SseEvent.md +0 -58
  269. package/docs/reference/type-aliases/StreamBody.md +0 -61
  270. package/docs/reference/type-aliases/TextFilter.md +0 -22
  271. package/docs/reference/type-aliases/VisitScenario.md +0 -20
  272. package/docs/reference/type-aliases/Visitor.md +0 -215
  273. package/docs/reference/type-aliases/WaitUntilOptions.md +0 -46
  274. package/docs/reference/type-aliases/WebsiteBackendOptions.md +0 -37
  275. package/docs/reference/type-aliases/WebsiteHandle.md +0 -51
  276. package/docs/reference/type-aliases/WebsiteSpecification.md +0 -118
  277. package/docs/reference/type-aliases/WebsiteSpecificationOptions.md +0 -40
  278. package/docs/reference/variables/anthropic.md +0 -19
  279. package/docs/reference/variables/banner.md +0 -10
  280. package/docs/reference/variables/button.md +0 -10
  281. package/docs/reference/variables/clock.md +0 -16
  282. package/docs/reference/variables/complementary.md +0 -10
  283. package/docs/reference/variables/component.md +0 -10
  284. package/docs/reference/variables/content.md +0 -10
  285. package/docs/reference/variables/contentinfo.md +0 -10
  286. package/docs/reference/variables/dialog.md +0 -10
  287. package/docs/reference/variables/field.md +0 -10
  288. package/docs/reference/variables/form.md +0 -10
  289. package/docs/reference/variables/heading.md +0 -10
  290. package/docs/reference/variables/http.md +0 -40
  291. package/docs/reference/variables/intercept.md +0 -11
  292. package/docs/reference/variables/link.md +0 -10
  293. package/docs/reference/variables/listitem.md +0 -10
  294. package/docs/reference/variables/main.md +0 -10
  295. package/docs/reference/variables/match.md +0 -8
  296. package/docs/reference/variables/navigation.md +0 -10
  297. package/docs/reference/variables/openai.md +0 -21
  298. package/docs/reference/variables/option.md +0 -17
  299. package/docs/reference/variables/region.md +0 -10
  300. package/docs/reference/variables/row.md +0 -10
  301. package/docs/reference/variables/search.md +0 -10
  302. package/docs/reference/variables/specification.md +0 -8
  303. package/docs/reference/variables/status.md +0 -10
  304. package/docs/reference/variables/table.md +0 -10
package/README.md CHANGED
@@ -1,197 +1,71 @@
1
1
  # @jterrazz/test
2
2
 
3
- Declarative testing framework for modules, APIs, jobs, CLIs, rendered components, websites and native apps. Six constructors — `specification.api()`, `specification.jobs()`, `specification.cli()`, `specification.integration()`, `specification.website()`, `specification.mobile()` — plus the `component` chain, which starts nothing and needs none, and the module test, which needs neither.
4
-
5
- A spec reads as a sentence: given → action → assertions. The vitest test name is its only description, every assertion goes through `expect()` with subject-typed matchers, and the infrastructure a spec declares — Postgres, Redis, SQLite, a child process, a real Chromium, an iOS simulator — is started, isolated per worker and cleaned up for you.
6
-
7
- ```bash
8
- npm install -D @jterrazz/test vitest
9
- ```
10
-
11
- Everything a spec needs imports from `@jterrazz/test`; the entries beside it are tools no spec imports, and they are listed once — [docs/01 § What the tree publishes](docs/01-architecture.md#what-the-tree-publishes).
12
-
13
- ## One kind of test, one example
14
-
15
- Which kind a test is, is the first question — [the fork](docs/18-conventions.md#the-fork--which-kind-of-test-this-is) asks it in nine lines and the answer fixes the folder, the constructor and the project.
16
-
17
- **A module** — beside its code, nothing started ([docs/05](docs/05-module-tests.md)):
3
+ A testing framework on vitest for whole products: HTTP APIs, background jobs, CLIs, websites, native mobile apps, rendered components, modules against real databases, and the lint rules a project ships. You declare what a test needs (Postgres, a built binary, a real Chromium, an iOS simulator), and the framework starts it, isolates it per worker and cleans it up. Each test is one sentence: a few setups, one action, and the whole result compared with `expect()`.
18
4
 
19
5
  ```typescript
20
- // src/domain/ranking.test.ts
21
- import { clock } from '@jterrazz/test';
22
- import { expect, test } from 'vitest';
23
-
24
- import { rank } from './ranking.js';
25
-
26
- test('ranks a fresher post above an older one of equal score', () => {
27
- // Given - two posts of equal score, one written this morning
28
- using _ = clock.at('2026-03-04T09:30:00Z');
6
+ // specs/api/users/list/shape.spec.ts
7
+ import { file } from '@jterrazz/test';
8
+ import { describe, expect, test } from 'vitest';
29
9
 
30
- // Then - the fresher one leads
31
- expect(rank(posts).map((post) => post.id)).toStrictEqual(['fresh', 'stale']);
32
- });
33
- ```
10
+ import { api } from '../../api.specification.js';
34
11
 
35
- **An integration spec** — a module against the real thing, or against a golden ([docs/06](docs/06-integration.md)):
12
+ describe('shape', () => {
13
+ test('lists the users the database holds', async () => {
14
+ // Given - two users, from the seed beside the test
15
+ const result = await api.seed(file('./__seeds__/two-users.sql')).get('/users');
36
16
 
37
- ```typescript
38
- // specs/integration/posts/find.spec.ts
39
- import { expect, test } from 'vitest';
17
+ // Then - the whole response
18
+ expect(result.response).toMatch(`
19
+ HTTP/1.1 200 OK
20
+ content-type: application/json
40
21
 
41
- import { integration } from '../integration.specification.js';
42
-
43
- test('finds the post the migration wrote', async () => {
44
- // Given - a seeded database
45
- const result = await integration.seed('posts.sql').call(({ db }) => findPost(db, 'p-1'));
46
-
47
- // Then - the row comes back as the repository shapes it
48
- expect(result.value).toMatch('found.json');
49
- });
50
- ```
51
-
52
- **A component** — a rendered unit in a real browser, beside its code ([docs/07](docs/07-component.md)):
53
-
54
- ```tsx
55
- // src/presentation/post-table.test.tsx
56
- import { component, content } from '@jterrazz/test';
57
- import { expect, test } from 'vitest';
58
-
59
- import { PostTable } from './post-table.js';
60
-
61
- test('says how much of the collection the table is showing', async () => {
62
- // Given - a page of one row answering for a collection of two hundred
63
- const result = await component.intercept(listing).render(<PostTable />, async (visitor) => {
64
- await visitor.see(content('Showing 1 of 200 posts'));
22
+ {"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}
23
+ `);
65
24
  });
66
-
67
- // Then - the table is qualified by what it is not showing
68
- await expect(result.tree).toMatch('one-of-two-hundred.aria.yaml');
69
25
  });
70
26
  ```
71
27
 
72
- **A website** — the served page, driven in a browser ([docs/08](docs/08-website.md)):
28
+ `api` comes from a specification file that builds it once for the suite: `specification.api({ services: { db: sqlite() }, server: ... })` starts the database, wires your app to it and serves it in the test process. [Getting started](docs/start/getting-started.md) walks through it from `npm install` to a green run.
73
29
 
74
- ```typescript
75
- // specs/website/subscribe/subscribe.spec.ts
76
- import { button, content, field } from '@jterrazz/test';
77
- import { expect, test } from 'vitest';
78
-
79
- import { website } from '../website.specification.js';
80
-
81
- test('subscribes through the form and captures the final state', async () => {
82
- // Given - a visitor on the homepage
83
- const result = await website.visit('/', async (visitor) => {
84
- await visitor.fill(field('Email'), 'visitor@site.test');
85
- await visitor.click(button('Subscribe'));
86
- await visitor.see(content('Thanks for subscribing'));
87
- });
30
+ ## Why
88
31
 
89
- // Then - the page says so, and the console is clean
90
- expect(result.content).toContain('Thanks for subscribing');
91
- await expect(result.errors).toBeEmpty();
92
- });
93
- ```
94
-
95
- **A mobile screen** — the installed app on a simulator ([docs/09](docs/09-mobile.md)):
96
-
97
- ```typescript
98
- // specs/mobile/events/bookmark.spec.ts
99
- import { button, content } from '@jterrazz/test';
100
- import { expect, test } from 'vitest';
101
-
102
- import { mobile } from '../mobile.specification.js';
103
-
104
- test('bookmarks an event from its detail screen', async () => {
105
- // Given - a visitor on the events feed
106
- const result = await mobile.open('news://events', async (visitor) => {
107
- await visitor.tap(button('Fauci inquiry'));
108
- await visitor.see(content('reports'));
109
- await visitor.tap(button('Bookmark'));
110
- });
111
-
112
- // Then - the capture reflects the screen after the interaction
113
- expect(result.content).toContain('Bookmarked');
114
- });
115
- ```
116
-
117
- **An API** — the assembled app, met through a complete HTTP exchange ([docs/10](docs/10-api.md)):
118
-
119
- ```typescript
120
- // specs/api/users/create-user.spec.ts
121
- import { expect, test } from 'vitest';
122
-
123
- import { api } from '../api.specification.js';
32
+ - **The infrastructure is declared, not scripted.** `postgres()`, `redis()`, `sqlite()` and `process()` are started for you, one database per worker, reset before every test.
33
+ - **A result is compared whole.** The full response, table, output or page outline, written in the test or in a file beside it, with `{{tokens}}` for values that move. `TEST_UPDATE=1` writes the expected values for you to review.
34
+ - **The conventions are a linter.** Where a test lives, how it is named and what it may import are checked by an oxlint plugin and a checker, and every finding says what it found, why, how to fix this case, and where to read more.
124
35
 
125
- test('creates a user and returns its location', async () => {
126
- // Given - an empty users table
127
- const result = await api.seed('empty.sql').request('create-user.http');
36
+ ## Install
128
37
 
129
- // Then - the response matches the golden, tokens and all
130
- expect(result.response).toMatch('user-created.http');
131
- await expect(result.table('users')).toMatchRows({
132
- columns: ['name'],
133
- rows: [['Alice']],
134
- });
135
- });
38
+ ```bash
39
+ npm install -D @jterrazz/test @jterrazz/typescript vitest
136
40
  ```
137
41
 
138
- **A job** — what a name triggers, in-process ([docs/11](docs/11-jobs.md)):
139
-
140
- ```typescript
141
- // specs/jobs/digest/daily-digest.spec.ts
142
- import { expect, test } from 'vitest';
143
-
144
- import { jobs } from '../jobs.specification.js';
42
+ [`@jterrazz/typescript`](https://github.com/jterrazz/package-typescript) is the toolchain the framework is built for: one devDependency that builds, type-checks, lints and formats a project, run as `npx typescript check` and `npx typescript fix` (its bin is named `typescript`; it is not Microsoft's compiler package). It is a required peer ([why](docs/start/set-up-a-project.md#what-to-install)), and its lint conventions are opt-in: a project that never lists the framework's preset in `jterrazz.config.ts` runs none of them, and writes its tests all the same.
145
43
 
146
- test('writes one digest row per active subscriber', async () => {
147
- // Given - two active subscribers and one cancelled
148
- const result = await jobs.seed('subscribers.sql').trigger('daily-digest');
149
-
150
- // Then - only the active ones were written
151
- await expect(result.table('digests')).toMatchRows({
152
- columns: ['to'],
153
- rows: [['a@site.test'], ['b@site.test']],
154
- });
155
- });
156
- ```
157
-
158
- **A CLI** — the built binary, usually as a document ([docs/12](docs/12-cli.md)):
159
-
160
- ```yaml
161
- # specs/cli/scaffold/new-project.spec.yaml
162
- description: scaffolds a project into an empty directory
163
- fixture: empty-dir
164
- runs:
165
- - command: new my-app
166
- exitCode: 0
167
- stdout: scaffolded.txt
168
- files:
169
- my-app/package.json: package.json
170
- ```
44
+ An ES module project on Node 24, vitest 5 and `@jterrazz/typescript` 11 is required ([Setting up § Project requirements](docs/start/set-up-a-project.md#project-requirements)). A browser, a database driver or a simulator is installed only by a project that tests through it, and the error names the package when one is missing: see [Setting up a project](docs/start/set-up-a-project.md#what-to-install).
171
45
 
172
- ## The map
46
+ ## What you can test
173
47
 
174
- Everything is stated ONCE, in the chapter that owns it — a second copy here would be a second answer, and the one a reader meets first is the one that goes stale. The corpus map is [docs/README.md](docs/README.md).
48
+ | Kind | Subject | Entry point |
49
+ | ----------------------------------------------- | --------------------------------------------------------------- | ------------------------------ |
50
+ | [Module](docs/guides/module-tests.md) | One module, beside its code, nothing started | plain vitest, `<file>.test.ts` |
51
+ | [Integration](docs/guides/integration-specs.md) | A module against real services, or against a golden | `specification.integration()` |
52
+ | [Component](docs/guides/component-specs.md) | A React component, hook or DOM function in a real Chromium | `component.render()` |
53
+ | [Website](docs/guides/website-specs.md) | A served page, fetched or driven in a browser | `specification.website()` |
54
+ | [Mobile](docs/guides/mobile-specs.md) | A native app on an iOS simulator | `specification.mobile()` |
55
+ | [API](docs/guides/api-specs.md) | An HTTP app, through complete requests | `specification.api()` |
56
+ | [Job](docs/guides/job-specs.md) | A pipeline triggered by name | `specification.job()` |
57
+ | [CLI](docs/guides/cli-specs.md) | A binary in a fresh working directory, often as a YAML document | `specification.cli()` |
58
+ | [Lint](docs/guides/lint-specs.md) | The rules a project ships, over fixture trees | `specification.lint()` |
175
59
 
176
- | Subject | Chapter |
177
- | ---------------------------------------------------------------- | ---------------------------------------------------------------- |
178
- | What the framework is, its trees, its channels, its four entries | [docs/01](docs/01-architecture.md) |
179
- | Installing it, the preset, the project helpers | [docs/02](docs/02-developing.md#vitest-config-the-preset) |
180
- | What a consumer must bring: the peers, Docker, the pinned pair | [docs/04](docs/04-operating.md#what-a-consumer-must-bring) |
181
- | Each kind of test, one chapter, the same seven sections | [docs/05](docs/05-module-tests.md)–[docs/12](docs/12-cli.md) |
182
- | Naming an element: descriptors, verbs, `within`, exact names | [docs/13](docs/13-elements.md) |
183
- | Every matcher, by subject | [docs/14](docs/14-assertions.md) |
184
- | The `{{token}}` grammar, `#ref` captures, update mode | [docs/15](docs/15-tokens.md) |
185
- | Contracts, selection, provider builders, `intercept()` | [docs/16](docs/16-contracts.md) |
186
- | Services, init scripts, per-worker isolation, `process()` | [docs/17](docs/17-services.md) |
187
- | The conventions, and the catalogue that enforces them | [docs/18](docs/18-conventions.md), [docs/19](docs/19-linting.md) |
60
+ Which kind a test is depends on its subject, and one ordered list of questions decides it: [Which kind of test](docs/start/getting-started.md#which-kind-of-test).
188
61
 
189
- The conventions are not prose alone: the package ships an oxlint plugin (`@jterrazz/test/oxlint`) and a `jterrazz-test-check` binary that reads the fixtures and cross-file relationships oxlint cannot. Every diagnostic ends in a rule id and an anchor into the generated catalogue.
62
+ ## Documentation
190
63
 
191
- Node 24 and vitest 5 are the required peers; everything else — a browser, a database driver, a simulator — is an optional peer, loaded the first time a spec needs it and named in the refusal when it is not there. What to install, and when: [docs/04](docs/04-operating.md#what-a-consumer-must-bring).
64
+ The manual is [`docs/`](docs/README.md), mapped by the same four families as the package's exports:
192
65
 
193
- ## Docs
66
+ - **What is tested:** one guide per kind, linked above.
67
+ - **What surrounds the subject:** [stubs](docs/reference/stubs.md) for the network, [services](docs/reference/services.md) for databases and processes, [time and doubles](docs/reference/time-and-doubles.md).
68
+ - **Acting on a screen:** [the visitor](docs/reference/visitor.md): `click`, `fill`, `see`, and how elements are named.
69
+ - **Judging the result:** [assertions](docs/reference/assertions.md) and [tokens](docs/reference/tokens.md).
194
70
 
195
- - The corpus: [docs/README.md](docs/README.md) — the spine, one chapter per kind, the shared references, the enforcement.
196
- - API reference: [docs/reference/](docs/reference/) — compiled from source by `npm run docs`.
197
- - Agent skill: [skills/jterrazz-test/](skills/jterrazz-test/) — the fork, the mental model, and a generated signature card per kind.
71
+ The conventions and their reasons are [Conventions](docs/concepts/conventions.md); every rule, generated from the code, is [Linting](docs/reference/linting.md). The API is the types the package publishes, one declaration file per entry (`dist/index.d.ts` for `@jterrazz/test`, `dist/services.d.ts` and `dist/stubs.d.ts` for `@jterrazz/test/services` and `@jterrazz/test/stubs`, then `dist/vitest.d.ts`, `dist/config.d.ts` and `dist/oxlint.d.ts`), which your editor reads, and which you can browse without one in `node_modules/@jterrazz/test/dist/` or on [npm's Code tab](https://www.npmjs.com/package/@jterrazz/test?activeTab=code); each guide shows its kind's constructor, chain and result. Agents read [`skills/jterrazz-test/SKILL.md`](skills/jterrazz-test/SKILL.md).