@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.
- package/README.md +45 -171
- package/dist/browser/index.js +1 -2980
- package/dist/browser/services.js +1 -0
- package/dist/browser/stubs.js +1 -0
- package/dist/browser-shared-index.browser.js +3233 -0
- package/dist/checker.d.ts +6 -1
- package/dist/checker.js +3721 -2624
- package/dist/config.d.ts +40 -0
- package/dist/config.js +309 -0
- package/dist/in-place.global-setup.d.ts +12 -0
- package/dist/in-place.global-setup.js +21 -0
- package/dist/index.d.ts +1641 -3004
- package/dist/index.js +5095 -3835
- package/dist/mobile-session.global-setup.d.ts +15 -0
- package/dist/mobile-session.global-setup.js +31 -0
- package/dist/oxlint.cjs +6069 -5634
- package/dist/oxlint.d.cts +43 -7212
- package/dist/oxlint.d.ts +43 -7212
- package/dist/oxlint.js +3979 -5799
- package/dist/route-coverage.global-setup.d.ts +43 -0
- package/dist/route-coverage.global-setup.js +1 -0
- package/dist/services.d.ts +3 -0
- package/dist/services.global-setup.d.ts +43 -0
- package/dist/services.global-setup.js +1 -0
- package/dist/services.js +597 -0
- package/dist/shared-appium.adapter.js +428 -0
- package/dist/shared-artifacts.js +34 -0
- package/dist/shared-chapter.js +7 -0
- package/dist/shared-container.port.d.ts +31 -0
- package/dist/shared-derived-projects.js +73 -0
- package/dist/shared-device.port.d.ts +189 -0
- package/dist/shared-exchange.js +447 -0
- package/dist/shared-in-place.js +172 -0
- package/dist/shared-index.services.d.ts +346 -0
- package/dist/shared-index.stubs.d.ts +287 -0
- package/dist/shared-json-shape.js +17 -0
- package/dist/shared-landmarks.js +71 -0
- package/dist/shared-ledger.js +68 -0
- package/dist/shared-listened-port.js +19 -0
- package/dist/shared-literate-plugin.js +184 -0
- package/dist/shared-manifest.js +1321 -0
- package/dist/shared-pause.js +22 -0
- package/dist/shared-peer.js +88 -0
- package/dist/shared-playwright.adapter.js +328 -0
- package/dist/shared-process-alive.js +13 -0
- package/dist/shared-process.adapter.js +74 -0
- package/dist/shared-record-key.js +13 -0
- package/dist/shared-refusal.js +35 -0
- package/dist/shared-resolve.js +24 -0
- package/dist/shared-route-coverage.global-setup.js +187 -0
- package/dist/shared-scenario-failure.js +198 -0
- package/dist/shared-serve.js +407 -0
- package/dist/shared-service-images.js +10 -0
- package/dist/shared-services.global-setup.js +174 -0
- package/dist/shared-session-ledger.js +305 -0
- package/dist/shared-setup-entry.js +12 -0
- package/dist/shared-source-scan.js +133 -0
- package/dist/shared-spec-document.js +303 -0
- package/dist/shared-spec-grammar.js +66 -0
- package/dist/shared-specifications.js +26 -0
- package/dist/shared-specs-modules.js +1033 -0
- package/dist/shared-stub-reply.js +167 -0
- package/dist/shared-stub-server.js +142 -0
- package/dist/shared-temp-root.global-setup.js +73 -0
- package/dist/shared-test-baseline.js +26 -0
- package/dist/shared-test-section.js +58 -0
- package/dist/shared-testcontainers.adapter.js +306 -0
- package/dist/shared-tokens.js +55 -0
- package/dist/shared-yaml-document.js +119 -0
- package/dist/stubs.d.ts +2 -0
- package/dist/stubs.js +657 -0
- package/dist/temp-root.global-setup.d.ts +7 -0
- package/dist/temp-root.global-setup.js +1 -0
- package/dist/vitest.d.ts +93 -164
- package/dist/vitest.js +382 -550
- package/docs/README.md +82 -36
- package/docs/concepts/architecture.md +118 -0
- package/docs/concepts/conventions.md +333 -0
- package/docs/guides/api-specs.md +374 -0
- package/docs/guides/cli-specs.md +566 -0
- package/docs/guides/component-specs.md +252 -0
- package/docs/guides/develop.md +97 -0
- package/docs/guides/integration-specs.md +181 -0
- package/docs/guides/job-specs.md +180 -0
- package/docs/guides/lint-specs.md +174 -0
- package/docs/guides/mobile-specs.md +319 -0
- package/docs/guides/module-tests.md +149 -0
- package/docs/guides/release.md +44 -0
- package/docs/guides/spec-documents.md +189 -0
- package/docs/guides/website-specs.md +413 -0
- package/docs/reference/assertions.md +345 -0
- package/docs/reference/glossary.md +20 -0
- package/docs/reference/linting.md +483 -0
- package/docs/reference/services.md +236 -0
- package/docs/reference/stubs.md +500 -0
- package/docs/reference/time-and-doubles.md +137 -0
- package/docs/reference/tokens.md +258 -0
- package/docs/reference/visitor.md +221 -0
- package/docs/start/getting-started.md +187 -0
- package/docs/start/set-up-a-project.md +228 -0
- package/package.json +56 -36
- package/schema/spec.schema.json +43 -17
- package/dist/appium.adapter.js +0 -489
- package/dist/artifacts.js +0 -32
- package/dist/fixtures.js +0 -110
- package/dist/literate.js +0 -1747
- package/dist/match.js +0 -804
- package/dist/playwright.adapter.js +0 -438
- package/dist/server.js +0 -160
- package/dist/stream.js +0 -321
- package/dist/substring-warning.js +0 -282
- package/docs/01-architecture.md +0 -95
- package/docs/02-developing.md +0 -351
- package/docs/03-testing.md +0 -495
- package/docs/04-operating.md +0 -101
- package/docs/05-module-tests.md +0 -152
- package/docs/06-integration.md +0 -180
- package/docs/07-component.md +0 -246
- package/docs/08-website.md +0 -404
- package/docs/09-mobile.md +0 -270
- package/docs/10-api.md +0 -264
- package/docs/11-jobs.md +0 -157
- package/docs/12-cli.md +0 -677
- package/docs/13-elements.md +0 -248
- package/docs/14-assertions.md +0 -314
- package/docs/15-tokens.md +0 -253
- package/docs/16-contracts.md +0 -438
- package/docs/17-services.md +0 -188
- package/docs/18-conventions.md +0 -332
- package/docs/19-linting.md +0 -512
- package/docs/decisions/001-v9-conventions-on-three-channels.md +0 -50
- package/docs/decisions/002-the-statique-channel-holds-only-what-upstream-does-not.md +0 -49
- package/docs/decisions/003-a-rendered-component-is-a-facet-on-vitest-browser-mode.md +0 -84
- package/docs/decisions/004-a-module-against-real-services-or-a-golden-is-the-integration-facet.md +0 -81
- package/docs/decisions/005-the-doubles-ladder-is-closed.md +0 -86
- package/docs/decisions/006-the-catalogue-reaches-a-file-by-its-role.md +0 -245
- package/docs/decisions/007-compose-mode-leaves-the-package.md +0 -53
- package/docs/decisions/008-vitest-5-node-24-and-the-native-seams-as-optional-peers.md +0 -75
- package/docs/decisions/_template.md +0 -22
- package/docs/reference/classes/Matcher.md +0 -120
- package/docs/reference/classes/ProcessHandle.md +0 -368
- package/docs/reference/functions/defineContract.md +0 -39
- package/docs/reference/functions/defineContracts.md +0 -36
- package/docs/reference/functions/disabled.md +0 -28
- package/docs/reference/functions/enabled.md +0 -20
- package/docs/reference/functions/focused.md +0 -26
- package/docs/reference/functions/mockOf.md +0 -79
- package/docs/reference/functions/postgres.md +0 -31
- package/docs/reference/functions/process.md +0 -33
- package/docs/reference/functions/redis.md +0 -28
- package/docs/reference/functions/required.md +0 -41
- package/docs/reference/functions/selected.md +0 -26
- package/docs/reference/functions/sqlite.md +0 -33
- package/docs/reference/functions/testId.md +0 -20
- package/docs/reference/functions/text.md +0 -40
- package/docs/reference/functions/valued.md +0 -28
- package/docs/reference/functions/waitUntil.md +0 -46
- package/docs/reference/functions/within.md +0 -29
- package/docs/reference/index.md +0 -196
- package/docs/reference/interfaces/BaseResult.md +0 -87
- package/docs/reference/interfaces/CallResult.md +0 -160
- package/docs/reference/interfaces/CaptureScope.md +0 -82
- package/docs/reference/interfaces/CliResult.md +0 -253
- package/docs/reference/interfaces/ContainerAccessor.md +0 -166
- package/docs/reference/interfaces/DirectoryAccessor.md +0 -33
- package/docs/reference/interfaces/FetchResult.md +0 -180
- package/docs/reference/interfaces/FilesystemAccessor.md +0 -46
- package/docs/reference/interfaces/HttpResult.md +0 -126
- package/docs/reference/interfaces/JsonAccessor.md +0 -46
- package/docs/reference/interfaces/PageResult.md +0 -356
- package/docs/reference/interfaces/RenderResult.md +0 -72
- package/docs/reference/interfaces/RenderedText.md +0 -110
- package/docs/reference/interfaces/ResponseAccessor.md +0 -47
- package/docs/reference/interfaces/ScreenResult.md +0 -128
- package/docs/reference/interfaces/TableAccessor.md +0 -26
- package/docs/reference/interfaces/TextAccessor.md +0 -96
- package/docs/reference/type-aliases/ApiHandle.md +0 -68
- package/docs/reference/type-aliases/ApiSpecification.md +0 -213
- package/docs/reference/type-aliases/ApiSpecificationOptions.md +0 -68
- package/docs/reference/type-aliases/BrowserConsoleMessage.md +0 -30
- package/docs/reference/type-aliases/BrowserLinkElement.md +0 -50
- package/docs/reference/type-aliases/BrowserMetaElement.md +0 -40
- package/docs/reference/type-aliases/BrowserOpenOptions.md +0 -87
- package/docs/reference/type-aliases/BrowserPage.md +0 -132
- package/docs/reference/type-aliases/BrowserPort.md +0 -51
- package/docs/reference/type-aliases/CliEnv.md +0 -11
- package/docs/reference/type-aliases/CliHandle.md +0 -80
- package/docs/reference/type-aliases/CliInput.md +0 -36
- package/docs/reference/type-aliases/CliOutput.md +0 -46
- package/docs/reference/type-aliases/CliPort.md +0 -58
- package/docs/reference/type-aliases/CliSpecification.md +0 -144
- package/docs/reference/type-aliases/CliSpecificationOptions.md +0 -134
- package/docs/reference/type-aliases/ComponentChain.md +0 -156
- package/docs/reference/type-aliases/ComponentScenario.md +0 -20
- package/docs/reference/type-aliases/ComponentUi.md +0 -47
- package/docs/reference/type-aliases/ComponentVisitor.md +0 -10
- package/docs/reference/type-aliases/ContainerPort.md +0 -113
- package/docs/reference/type-aliases/Contract.md +0 -68
- package/docs/reference/type-aliases/ContractInput.md +0 -13
- package/docs/reference/type-aliases/ContractRequest.md +0 -95
- package/docs/reference/type-aliases/ContractResponder.md +0 -23
- package/docs/reference/type-aliases/ContractResponse.md +0 -78
- package/docs/reference/type-aliases/ContractResponseValue.md +0 -13
- package/docs/reference/type-aliases/Contracts.md +0 -48
- package/docs/reference/type-aliases/DatabaseKeys.md +0 -16
- package/docs/reference/type-aliases/DatabasePort.md +0 -72
- package/docs/reference/type-aliases/DeviceOpenOptions.md +0 -46
- package/docs/reference/type-aliases/DevicePort.md +0 -51
- package/docs/reference/type-aliases/DeviceScreen.md +0 -32
- package/docs/reference/type-aliases/DeviceTimeouts.md +0 -39
- package/docs/reference/type-aliases/DockerSpecConfig.md +0 -43
- package/docs/reference/type-aliases/DomMount.md +0 -21
- package/docs/reference/type-aliases/ElementKind.md +0 -27
- package/docs/reference/type-aliases/ElementMatch.md +0 -74
- package/docs/reference/type-aliases/ElementOptions.md +0 -29
- package/docs/reference/type-aliases/ElementRef.md +0 -128
- package/docs/reference/type-aliases/ExecOptions.md +0 -37
- package/docs/reference/type-aliases/FileAccessor.md +0 -54
- package/docs/reference/type-aliases/HonoApp.md +0 -31
- package/docs/reference/type-aliases/HttpContractFilter.md +0 -49
- package/docs/reference/type-aliases/HttpResponseInit.md +0 -46
- package/docs/reference/type-aliases/HttpStreamInit.md +0 -58
- package/docs/reference/type-aliases/IntegrationHandle.md +0 -46
- package/docs/reference/type-aliases/IntegrationSpecification.md +0 -111
- package/docs/reference/type-aliases/IntegrationSpecificationOptions.md +0 -42
- package/docs/reference/type-aliases/Intercept.md +0 -19
- package/docs/reference/type-aliases/InterceptOptions.md +0 -28
- package/docs/reference/type-aliases/InterceptScope.md +0 -11
- package/docs/reference/type-aliases/IsolationStrategy.md +0 -75
- package/docs/reference/type-aliases/JobHandle.md +0 -34
- package/docs/reference/type-aliases/JobsHandle.md +0 -57
- package/docs/reference/type-aliases/JobsResult.md +0 -16
- package/docs/reference/type-aliases/JobsSpecification.md +0 -94
- package/docs/reference/type-aliases/JobsSpecificationOptions.md +0 -56
- package/docs/reference/type-aliases/LandmarkKind.md +0 -20
- package/docs/reference/type-aliases/LiterateRunFlags.md +0 -27
- package/docs/reference/type-aliases/LiterateServeRegistration.md +0 -70
- package/docs/reference/type-aliases/MatchFixtureOptions.md +0 -27
- package/docs/reference/type-aliases/MatchableRequest.md +0 -61
- package/docs/reference/type-aliases/MatcherKind.md +0 -34
- package/docs/reference/type-aliases/MobileBackendOptions.md +0 -28
- package/docs/reference/type-aliases/MobileElementKind.md +0 -14
- package/docs/reference/type-aliases/MobileElementMatch.md +0 -60
- package/docs/reference/type-aliases/MobileElementRef.md +0 -20
- package/docs/reference/type-aliases/MobileHandle.md +0 -65
- package/docs/reference/type-aliases/MobileScenario.md +0 -20
- package/docs/reference/type-aliases/MobileSpecification.md +0 -51
- package/docs/reference/type-aliases/MobileSpecificationOptions.md +0 -126
- package/docs/reference/type-aliases/MobileVisitor.md +0 -81
- package/docs/reference/type-aliases/MockOfOptions.md +0 -26
- package/docs/reference/type-aliases/MockPort.md +0 -10
- package/docs/reference/type-aliases/PinnedClock.md +0 -10
- package/docs/reference/type-aliases/PostgresOptions.md +0 -32
- package/docs/reference/type-aliases/ProcessOptions.md +0 -112
- package/docs/reference/type-aliases/RedisOptions.md +0 -20
- package/docs/reference/type-aliases/RenderSubject.md +0 -12
- package/docs/reference/type-aliases/ScreenNode.md +0 -67
- package/docs/reference/type-aliases/ServerPort.md +0 -36
- package/docs/reference/type-aliases/ServerResponse.md +0 -46
- package/docs/reference/type-aliases/ServerSpec.md +0 -21
- package/docs/reference/type-aliases/ServiceHandle.md +0 -216
- package/docs/reference/type-aliases/ServiceRecord.md +0 -12
- package/docs/reference/type-aliases/SpecDocument.md +0 -84
- package/docs/reference/type-aliases/SpecEnvToken.md +0 -21
- package/docs/reference/type-aliases/SpecFileAssertion.md +0 -27
- package/docs/reference/type-aliases/SpecFixture.md +0 -30
- package/docs/reference/type-aliases/SpecKind.md +0 -8
- package/docs/reference/type-aliases/SpecRun.md +0 -108
- package/docs/reference/type-aliases/SpecServeEntry.md +0 -40
- package/docs/reference/type-aliases/SpecStream.md +0 -32
- package/docs/reference/type-aliases/SpecificationConfig.md +0 -290
- package/docs/reference/type-aliases/SqliteOptions.md +0 -36
- package/docs/reference/type-aliases/SseEvent.md +0 -58
- package/docs/reference/type-aliases/StreamBody.md +0 -61
- package/docs/reference/type-aliases/TextFilter.md +0 -22
- package/docs/reference/type-aliases/VisitScenario.md +0 -20
- package/docs/reference/type-aliases/Visitor.md +0 -215
- package/docs/reference/type-aliases/WaitUntilOptions.md +0 -46
- package/docs/reference/type-aliases/WebsiteBackendOptions.md +0 -37
- package/docs/reference/type-aliases/WebsiteHandle.md +0 -51
- package/docs/reference/type-aliases/WebsiteSpecification.md +0 -118
- package/docs/reference/type-aliases/WebsiteSpecificationOptions.md +0 -40
- package/docs/reference/variables/anthropic.md +0 -19
- package/docs/reference/variables/banner.md +0 -10
- package/docs/reference/variables/button.md +0 -10
- package/docs/reference/variables/clock.md +0 -16
- package/docs/reference/variables/complementary.md +0 -10
- package/docs/reference/variables/component.md +0 -10
- package/docs/reference/variables/content.md +0 -10
- package/docs/reference/variables/contentinfo.md +0 -10
- package/docs/reference/variables/dialog.md +0 -10
- package/docs/reference/variables/field.md +0 -10
- package/docs/reference/variables/form.md +0 -10
- package/docs/reference/variables/heading.md +0 -10
- package/docs/reference/variables/http.md +0 -40
- package/docs/reference/variables/intercept.md +0 -11
- package/docs/reference/variables/link.md +0 -10
- package/docs/reference/variables/listitem.md +0 -10
- package/docs/reference/variables/main.md +0 -10
- package/docs/reference/variables/match.md +0 -8
- package/docs/reference/variables/navigation.md +0 -10
- package/docs/reference/variables/openai.md +0 -21
- package/docs/reference/variables/option.md +0 -17
- package/docs/reference/variables/region.md +0 -10
- package/docs/reference/variables/row.md +0 -10
- package/docs/reference/variables/search.md +0 -10
- package/docs/reference/variables/specification.md +0 -8
- package/docs/reference/variables/status.md +0 -10
- package/docs/reference/variables/table.md +0 -10
package/README.md
CHANGED
|
@@ -1,197 +1,71 @@
|
|
|
1
1
|
# @jterrazz/test
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
//
|
|
21
|
-
import {
|
|
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
|
-
|
|
31
|
-
expect(rank(posts).map((post) => post.id)).toStrictEqual(['fresh', 'stale']);
|
|
32
|
-
});
|
|
33
|
-
```
|
|
10
|
+
import { api } from '../../api.specification.js';
|
|
34
11
|
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
17
|
+
// Then - the whole response
|
|
18
|
+
expect(result.response).toMatch(`
|
|
19
|
+
HTTP/1.1 200 OK
|
|
20
|
+
content-type: application/json
|
|
40
21
|
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
126
|
-
// Given - an empty users table
|
|
127
|
-
const result = await api.seed('empty.sql').request('create-user.http');
|
|
36
|
+
## Install
|
|
128
37
|
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
46
|
+
## What you can test
|
|
173
47
|
|
|
174
|
-
|
|
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
|
-
|
|
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
|
-
|
|
62
|
+
## Documentation
|
|
190
63
|
|
|
191
|
-
|
|
64
|
+
The manual is [`docs/`](docs/README.md), mapped by the same four families as the package's exports:
|
|
192
65
|
|
|
193
|
-
|
|
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
|
-
|
|
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).
|