@jterrazz/test 16.1.1 → 18.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 (309) hide show
  1. package/README.md +45 -171
  2. package/dist/browser/index.js +1 -2980
  3. package/dist/browser/services.js +1 -0
  4. package/dist/browser/stubs.js +1 -0
  5. package/dist/browser-shared-index.browser.js +3233 -0
  6. package/dist/checker.d.ts +6 -1
  7. package/dist/checker.js +3721 -2624
  8. package/dist/config.d.ts +40 -0
  9. package/dist/config.js +309 -0
  10. package/dist/in-place.global-setup.d.ts +12 -0
  11. package/dist/in-place.global-setup.js +21 -0
  12. package/dist/index.d.ts +1641 -3004
  13. package/dist/index.js +5095 -3835
  14. package/dist/mobile-session.global-setup.d.ts +15 -0
  15. package/dist/mobile-session.global-setup.js +31 -0
  16. package/dist/oxlint.cjs +6069 -5634
  17. package/dist/oxlint.d.cts +43 -7212
  18. package/dist/oxlint.d.ts +43 -7212
  19. package/dist/oxlint.js +3979 -5799
  20. package/dist/route-coverage.global-setup.d.ts +43 -0
  21. package/dist/route-coverage.global-setup.js +1 -0
  22. package/dist/services.d.ts +3 -0
  23. package/dist/services.global-setup.d.ts +43 -0
  24. package/dist/services.global-setup.js +1 -0
  25. package/dist/services.js +597 -0
  26. package/dist/shared-appium.adapter.js +428 -0
  27. package/dist/shared-artifacts.js +34 -0
  28. package/dist/shared-chapter.js +7 -0
  29. package/dist/shared-container.port.d.ts +31 -0
  30. package/dist/shared-derived-projects.js +73 -0
  31. package/dist/shared-device.port.d.ts +189 -0
  32. package/dist/shared-exchange.js +447 -0
  33. package/dist/shared-in-place.js +172 -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-listened-port.js +19 -0
  40. package/dist/shared-literate-plugin.js +184 -0
  41. package/dist/shared-manifest.js +1321 -0
  42. package/dist/shared-pause.js +22 -0
  43. package/dist/shared-peer.js +88 -0
  44. package/dist/shared-playwright.adapter.js +328 -0
  45. package/dist/shared-process-alive.js +13 -0
  46. package/dist/shared-process.adapter.js +74 -0
  47. package/dist/shared-record-key.js +13 -0
  48. package/dist/shared-refusal.js +35 -0
  49. package/dist/shared-resolve.js +24 -0
  50. package/dist/shared-route-coverage.global-setup.js +187 -0
  51. package/dist/shared-scenario-failure.js +198 -0
  52. package/dist/shared-serve.js +407 -0
  53. package/dist/shared-service-images.js +10 -0
  54. package/dist/shared-services.global-setup.js +174 -0
  55. package/dist/shared-session-ledger.js +305 -0
  56. package/dist/shared-setup-entry.js +12 -0
  57. package/dist/shared-source-scan.js +133 -0
  58. package/dist/shared-spec-document.js +303 -0
  59. package/dist/shared-spec-grammar.js +66 -0
  60. package/dist/shared-specifications.js +26 -0
  61. package/dist/shared-specs-modules.js +1033 -0
  62. package/dist/shared-stub-reply.js +167 -0
  63. package/dist/shared-stub-server.js +142 -0
  64. package/dist/shared-temp-root.global-setup.js +73 -0
  65. package/dist/shared-test-baseline.js +26 -0
  66. package/dist/shared-test-section.js +58 -0
  67. package/dist/shared-testcontainers.adapter.js +306 -0
  68. package/dist/shared-tokens.js +55 -0
  69. package/dist/shared-yaml-document.js +119 -0
  70. package/dist/stubs.d.ts +2 -0
  71. package/dist/stubs.js +657 -0
  72. package/dist/temp-root.global-setup.d.ts +7 -0
  73. package/dist/temp-root.global-setup.js +1 -0
  74. package/dist/vitest.d.ts +93 -164
  75. package/dist/vitest.js +382 -550
  76. package/docs/README.md +82 -36
  77. package/docs/concepts/architecture.md +118 -0
  78. package/docs/concepts/conventions.md +333 -0
  79. package/docs/guides/api-specs.md +374 -0
  80. package/docs/guides/cli-specs.md +566 -0
  81. package/docs/guides/component-specs.md +252 -0
  82. package/docs/guides/develop.md +97 -0
  83. package/docs/guides/integration-specs.md +181 -0
  84. package/docs/guides/job-specs.md +180 -0
  85. package/docs/guides/lint-specs.md +174 -0
  86. package/docs/guides/mobile-specs.md +319 -0
  87. package/docs/guides/module-tests.md +149 -0
  88. package/docs/guides/release.md +44 -0
  89. package/docs/guides/spec-documents.md +189 -0
  90. package/docs/guides/website-specs.md +413 -0
  91. package/docs/reference/assertions.md +345 -0
  92. package/docs/reference/glossary.md +20 -0
  93. package/docs/reference/linting.md +483 -0
  94. package/docs/reference/services.md +236 -0
  95. package/docs/reference/stubs.md +500 -0
  96. package/docs/reference/time-and-doubles.md +137 -0
  97. package/docs/reference/tokens.md +258 -0
  98. package/docs/reference/visitor.md +221 -0
  99. package/docs/start/getting-started.md +187 -0
  100. package/docs/start/set-up-a-project.md +228 -0
  101. package/package.json +56 -36
  102. package/schema/spec.schema.json +43 -17
  103. package/dist/appium.adapter.js +0 -489
  104. package/dist/artifacts.js +0 -32
  105. package/dist/fixtures.js +0 -110
  106. package/dist/literate.js +0 -1747
  107. package/dist/match.js +0 -804
  108. package/dist/playwright.adapter.js +0 -438
  109. package/dist/server.js +0 -160
  110. package/dist/stream.js +0 -321
  111. package/dist/substring-warning.js +0 -282
  112. package/docs/01-architecture.md +0 -95
  113. package/docs/02-developing.md +0 -351
  114. package/docs/03-testing.md +0 -495
  115. package/docs/04-operating.md +0 -101
  116. package/docs/05-module-tests.md +0 -152
  117. package/docs/06-integration.md +0 -180
  118. package/docs/07-component.md +0 -246
  119. package/docs/08-website.md +0 -404
  120. package/docs/09-mobile.md +0 -270
  121. package/docs/10-api.md +0 -264
  122. package/docs/11-jobs.md +0 -157
  123. package/docs/12-cli.md +0 -677
  124. package/docs/13-elements.md +0 -248
  125. package/docs/14-assertions.md +0 -314
  126. package/docs/15-tokens.md +0 -253
  127. package/docs/16-contracts.md +0 -438
  128. package/docs/17-services.md +0 -188
  129. package/docs/18-conventions.md +0 -332
  130. package/docs/19-linting.md +0 -512
  131. package/docs/decisions/001-v9-conventions-on-three-channels.md +0 -50
  132. package/docs/decisions/002-the-statique-channel-holds-only-what-upstream-does-not.md +0 -49
  133. package/docs/decisions/003-a-rendered-component-is-a-facet-on-vitest-browser-mode.md +0 -84
  134. package/docs/decisions/004-a-module-against-real-services-or-a-golden-is-the-integration-facet.md +0 -81
  135. package/docs/decisions/005-the-doubles-ladder-is-closed.md +0 -86
  136. package/docs/decisions/006-the-catalogue-reaches-a-file-by-its-role.md +0 -245
  137. package/docs/decisions/007-compose-mode-leaves-the-package.md +0 -53
  138. package/docs/decisions/008-vitest-5-node-24-and-the-native-seams-as-optional-peers.md +0 -75
  139. package/docs/decisions/_template.md +0 -22
  140. package/docs/reference/classes/Matcher.md +0 -120
  141. package/docs/reference/classes/ProcessHandle.md +0 -368
  142. package/docs/reference/functions/defineContract.md +0 -39
  143. package/docs/reference/functions/defineContracts.md +0 -36
  144. package/docs/reference/functions/disabled.md +0 -28
  145. package/docs/reference/functions/enabled.md +0 -20
  146. package/docs/reference/functions/focused.md +0 -26
  147. package/docs/reference/functions/mockOf.md +0 -79
  148. package/docs/reference/functions/postgres.md +0 -31
  149. package/docs/reference/functions/process.md +0 -33
  150. package/docs/reference/functions/redis.md +0 -28
  151. package/docs/reference/functions/required.md +0 -41
  152. package/docs/reference/functions/selected.md +0 -26
  153. package/docs/reference/functions/sqlite.md +0 -33
  154. package/docs/reference/functions/testId.md +0 -20
  155. package/docs/reference/functions/text.md +0 -40
  156. package/docs/reference/functions/valued.md +0 -28
  157. package/docs/reference/functions/waitUntil.md +0 -46
  158. package/docs/reference/functions/within.md +0 -29
  159. package/docs/reference/index.md +0 -196
  160. package/docs/reference/interfaces/BaseResult.md +0 -87
  161. package/docs/reference/interfaces/CallResult.md +0 -160
  162. package/docs/reference/interfaces/CaptureScope.md +0 -82
  163. package/docs/reference/interfaces/CliResult.md +0 -253
  164. package/docs/reference/interfaces/ContainerAccessor.md +0 -166
  165. package/docs/reference/interfaces/DirectoryAccessor.md +0 -33
  166. package/docs/reference/interfaces/FetchResult.md +0 -180
  167. package/docs/reference/interfaces/FilesystemAccessor.md +0 -46
  168. package/docs/reference/interfaces/HttpResult.md +0 -126
  169. package/docs/reference/interfaces/JsonAccessor.md +0 -46
  170. package/docs/reference/interfaces/PageResult.md +0 -356
  171. package/docs/reference/interfaces/RenderResult.md +0 -72
  172. package/docs/reference/interfaces/RenderedText.md +0 -110
  173. package/docs/reference/interfaces/ResponseAccessor.md +0 -47
  174. package/docs/reference/interfaces/ScreenResult.md +0 -128
  175. package/docs/reference/interfaces/TableAccessor.md +0 -26
  176. package/docs/reference/interfaces/TextAccessor.md +0 -96
  177. package/docs/reference/type-aliases/ApiHandle.md +0 -68
  178. package/docs/reference/type-aliases/ApiSpecification.md +0 -213
  179. package/docs/reference/type-aliases/ApiSpecificationOptions.md +0 -68
  180. package/docs/reference/type-aliases/BrowserConsoleMessage.md +0 -30
  181. package/docs/reference/type-aliases/BrowserLinkElement.md +0 -50
  182. package/docs/reference/type-aliases/BrowserMetaElement.md +0 -40
  183. package/docs/reference/type-aliases/BrowserOpenOptions.md +0 -87
  184. package/docs/reference/type-aliases/BrowserPage.md +0 -132
  185. package/docs/reference/type-aliases/BrowserPort.md +0 -51
  186. package/docs/reference/type-aliases/CliEnv.md +0 -11
  187. package/docs/reference/type-aliases/CliHandle.md +0 -80
  188. package/docs/reference/type-aliases/CliInput.md +0 -36
  189. package/docs/reference/type-aliases/CliOutput.md +0 -46
  190. package/docs/reference/type-aliases/CliPort.md +0 -58
  191. package/docs/reference/type-aliases/CliSpecification.md +0 -144
  192. package/docs/reference/type-aliases/CliSpecificationOptions.md +0 -134
  193. package/docs/reference/type-aliases/ComponentChain.md +0 -156
  194. package/docs/reference/type-aliases/ComponentScenario.md +0 -20
  195. package/docs/reference/type-aliases/ComponentUi.md +0 -47
  196. package/docs/reference/type-aliases/ComponentVisitor.md +0 -10
  197. package/docs/reference/type-aliases/ContainerPort.md +0 -113
  198. package/docs/reference/type-aliases/Contract.md +0 -68
  199. package/docs/reference/type-aliases/ContractInput.md +0 -13
  200. package/docs/reference/type-aliases/ContractRequest.md +0 -95
  201. package/docs/reference/type-aliases/ContractResponder.md +0 -23
  202. package/docs/reference/type-aliases/ContractResponse.md +0 -78
  203. package/docs/reference/type-aliases/ContractResponseValue.md +0 -13
  204. package/docs/reference/type-aliases/Contracts.md +0 -48
  205. package/docs/reference/type-aliases/DatabaseKeys.md +0 -16
  206. package/docs/reference/type-aliases/DatabasePort.md +0 -72
  207. package/docs/reference/type-aliases/DeviceOpenOptions.md +0 -46
  208. package/docs/reference/type-aliases/DevicePort.md +0 -51
  209. package/docs/reference/type-aliases/DeviceScreen.md +0 -32
  210. package/docs/reference/type-aliases/DeviceTimeouts.md +0 -39
  211. package/docs/reference/type-aliases/DockerSpecConfig.md +0 -43
  212. package/docs/reference/type-aliases/DomMount.md +0 -21
  213. package/docs/reference/type-aliases/ElementKind.md +0 -27
  214. package/docs/reference/type-aliases/ElementMatch.md +0 -74
  215. package/docs/reference/type-aliases/ElementOptions.md +0 -29
  216. package/docs/reference/type-aliases/ElementRef.md +0 -128
  217. package/docs/reference/type-aliases/ExecOptions.md +0 -37
  218. package/docs/reference/type-aliases/FileAccessor.md +0 -54
  219. package/docs/reference/type-aliases/HonoApp.md +0 -31
  220. package/docs/reference/type-aliases/HttpContractFilter.md +0 -49
  221. package/docs/reference/type-aliases/HttpResponseInit.md +0 -46
  222. package/docs/reference/type-aliases/HttpStreamInit.md +0 -58
  223. package/docs/reference/type-aliases/IntegrationHandle.md +0 -46
  224. package/docs/reference/type-aliases/IntegrationSpecification.md +0 -111
  225. package/docs/reference/type-aliases/IntegrationSpecificationOptions.md +0 -42
  226. package/docs/reference/type-aliases/Intercept.md +0 -19
  227. package/docs/reference/type-aliases/InterceptOptions.md +0 -28
  228. package/docs/reference/type-aliases/InterceptScope.md +0 -11
  229. package/docs/reference/type-aliases/IsolationStrategy.md +0 -75
  230. package/docs/reference/type-aliases/JobHandle.md +0 -34
  231. package/docs/reference/type-aliases/JobsHandle.md +0 -57
  232. package/docs/reference/type-aliases/JobsResult.md +0 -16
  233. package/docs/reference/type-aliases/JobsSpecification.md +0 -94
  234. package/docs/reference/type-aliases/JobsSpecificationOptions.md +0 -56
  235. package/docs/reference/type-aliases/LandmarkKind.md +0 -20
  236. package/docs/reference/type-aliases/LiterateRunFlags.md +0 -27
  237. package/docs/reference/type-aliases/LiterateServeRegistration.md +0 -70
  238. package/docs/reference/type-aliases/MatchFixtureOptions.md +0 -27
  239. package/docs/reference/type-aliases/MatchableRequest.md +0 -61
  240. package/docs/reference/type-aliases/MatcherKind.md +0 -34
  241. package/docs/reference/type-aliases/MobileBackendOptions.md +0 -28
  242. package/docs/reference/type-aliases/MobileElementKind.md +0 -14
  243. package/docs/reference/type-aliases/MobileElementMatch.md +0 -60
  244. package/docs/reference/type-aliases/MobileElementRef.md +0 -20
  245. package/docs/reference/type-aliases/MobileHandle.md +0 -65
  246. package/docs/reference/type-aliases/MobileScenario.md +0 -20
  247. package/docs/reference/type-aliases/MobileSpecification.md +0 -51
  248. package/docs/reference/type-aliases/MobileSpecificationOptions.md +0 -126
  249. package/docs/reference/type-aliases/MobileVisitor.md +0 -81
  250. package/docs/reference/type-aliases/MockOfOptions.md +0 -26
  251. package/docs/reference/type-aliases/MockPort.md +0 -10
  252. package/docs/reference/type-aliases/PinnedClock.md +0 -10
  253. package/docs/reference/type-aliases/PostgresOptions.md +0 -32
  254. package/docs/reference/type-aliases/ProcessOptions.md +0 -112
  255. package/docs/reference/type-aliases/RedisOptions.md +0 -20
  256. package/docs/reference/type-aliases/RenderSubject.md +0 -12
  257. package/docs/reference/type-aliases/ScreenNode.md +0 -67
  258. package/docs/reference/type-aliases/ServerPort.md +0 -36
  259. package/docs/reference/type-aliases/ServerResponse.md +0 -46
  260. package/docs/reference/type-aliases/ServerSpec.md +0 -21
  261. package/docs/reference/type-aliases/ServiceHandle.md +0 -216
  262. package/docs/reference/type-aliases/ServiceRecord.md +0 -12
  263. package/docs/reference/type-aliases/SpecDocument.md +0 -84
  264. package/docs/reference/type-aliases/SpecEnvToken.md +0 -21
  265. package/docs/reference/type-aliases/SpecFileAssertion.md +0 -27
  266. package/docs/reference/type-aliases/SpecFixture.md +0 -30
  267. package/docs/reference/type-aliases/SpecKind.md +0 -8
  268. package/docs/reference/type-aliases/SpecRun.md +0 -108
  269. package/docs/reference/type-aliases/SpecServeEntry.md +0 -40
  270. package/docs/reference/type-aliases/SpecStream.md +0 -32
  271. package/docs/reference/type-aliases/SpecificationConfig.md +0 -290
  272. package/docs/reference/type-aliases/SqliteOptions.md +0 -36
  273. package/docs/reference/type-aliases/SseEvent.md +0 -58
  274. package/docs/reference/type-aliases/StreamBody.md +0 -61
  275. package/docs/reference/type-aliases/TextFilter.md +0 -22
  276. package/docs/reference/type-aliases/VisitScenario.md +0 -20
  277. package/docs/reference/type-aliases/Visitor.md +0 -215
  278. package/docs/reference/type-aliases/WaitUntilOptions.md +0 -46
  279. package/docs/reference/type-aliases/WebsiteBackendOptions.md +0 -37
  280. package/docs/reference/type-aliases/WebsiteHandle.md +0 -51
  281. package/docs/reference/type-aliases/WebsiteSpecification.md +0 -118
  282. package/docs/reference/type-aliases/WebsiteSpecificationOptions.md +0 -40
  283. package/docs/reference/variables/anthropic.md +0 -19
  284. package/docs/reference/variables/banner.md +0 -10
  285. package/docs/reference/variables/button.md +0 -10
  286. package/docs/reference/variables/clock.md +0 -16
  287. package/docs/reference/variables/complementary.md +0 -10
  288. package/docs/reference/variables/component.md +0 -10
  289. package/docs/reference/variables/content.md +0 -10
  290. package/docs/reference/variables/contentinfo.md +0 -10
  291. package/docs/reference/variables/dialog.md +0 -10
  292. package/docs/reference/variables/field.md +0 -10
  293. package/docs/reference/variables/form.md +0 -10
  294. package/docs/reference/variables/heading.md +0 -10
  295. package/docs/reference/variables/http.md +0 -40
  296. package/docs/reference/variables/intercept.md +0 -11
  297. package/docs/reference/variables/link.md +0 -10
  298. package/docs/reference/variables/listitem.md +0 -10
  299. package/docs/reference/variables/main.md +0 -10
  300. package/docs/reference/variables/match.md +0 -8
  301. package/docs/reference/variables/navigation.md +0 -10
  302. package/docs/reference/variables/openai.md +0 -21
  303. package/docs/reference/variables/option.md +0 -17
  304. package/docs/reference/variables/region.md +0 -10
  305. package/docs/reference/variables/row.md +0 -10
  306. package/docs/reference/variables/search.md +0 -10
  307. package/docs/reference/variables/specification.md +0 -8
  308. package/docs/reference/variables/status.md +0 -10
  309. 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).