Testing
| Suite | Tool | Where | Command |
|---|---|---|---|
| Backend unit | vitest, happy-dom | app/sidedoc-backend/__tests__/unit/ | npm run test:unit -w @sidedoc/backend |
| Backend integration | vitest, happy-dom | app/sidedoc-backend/__tests__/integration/ | npm run test:integration -w @sidedoc/backend |
| Backend e2e | vitest, happy-dom | app/sidedoc-backend/__tests__/e2e/ | npm run test:e2e -w @sidedoc/backend |
| Frontend unit | vitest | app/sidedoc-frontend/src/**/__tests__/ | npm test -w sidedoc-frontend |
| Accessibility gate | Playwright, axe-core | app/sidedoc-frontend/tests/accessibility/ | npm run test:a11y -w sidedoc-frontend |
| Datasheet editor e2e | Playwright | app/sidedoc-frontend/tests/e2e/ | npm run test:e2e:datasheet -w sidedoc-frontend |
| Testbench smoke | Playwright | app/sidedoc-frontend/tests/smoke/ | npm run test:smoke:testbench -w sidedoc-frontend |
npm test in the root runs backend unit tests and frontend unit tests. Set SIDEDOC_SCHEMAS_DIR first: the DCAT export tests read example datasheets from the schemas repository.
Backend (vitest)
There are four configs in app/sidedoc-backend. All use globals: true and the happy-dom environment for DOM APIs. Tests use the in-memory services rather than IndexedDB.
| Config | Includes | Script |
|---|---|---|
vitest.config.ts | everything | npm test (watch), test:watch, test:coverage |
vitest.config.unit.ts | __tests__/unit/**/*.test.ts | test:unit |
vitest.config.integration.ts | __tests__/integration/**/*.test.ts | test:integration |
vitest.config.e2e.ts | __tests__/e2e/**/*.test.ts (10 s timeout) | test:e2e |
- Unit tests cover entities, the shadow model, schema utilities, services, adapters, transformers, the RDF mapping engine and registry, and each persistence provider (with mocked
fetchand browser APIs). - Integration tests cover the service container and the workspace-document update flow.
- E2E tests validate the Star Wars example datasheet against the schema and run a whole document lifecycle (create, validate, export).
Helpers in __tests__/helpers/: factories.ts (createTestWorkspace, createTestDocument, createTestFolder) and validator.ts (AJV validation against the fixture schemas in __tests__/fixtures/schemas/). Fixture schemas are a frozen copy; tests that need the current published schemas read them from SIDEDOC_SCHEMAS_DIR.
npm run gate:a-track-contracts runs a fixed set of contract tests for the active-record API plus a type check. Run it when you change the record, session or adapter APIs that the frontend uses.
Frontend unit tests (vitest)
Vitest uses vite.config.ts (there is no separate vitest config) and picks up *.test.ts and *.test.js files in __tests__/ folders next to the code: editor components and types, config (schema version, resolver, conversion), standalone controller and helpers, stores, services and the testbench model. npm run test:a-track-migrated-flows runs the subset that covers flows moved from the frontend into the backend.
Playwright suites
Each Playwright config starts its own Vite dev server on a fixed port and reuses a running one outside CI. Install browsers once with npx playwright install.
Accessibility gate
playwright.accessibility.config.js: files tests/accessibility/*.a11y.pw.js, port 4200, one worker, no retries. It loads /standalone.html and checks with axe-core and scripted keyboard journeys: focus order and naming, field labels, live regions, dialogs and mobile drawers, the rich text editor, text spacing, reflow at 320 px, colour contrast, duplicate ids, and coverage across all profiles.
This suite is the merge gate. A known failure must be recorded under the exception policy, not skipped silently. To run one check on its own:
npm run test:a11y:contrast -w sidedoc-frontend
npm run test:a11y:duplicate-ids -w sidedoc-frontend
npm run test:a11y:reflow -w sidedoc-frontendSee Accessibility for the wider picture.
Datasheet editor e2e
playwright.datasheet-e2e.config.js: tests/e2e/datasheet-editor.pw.js, port 4199, 90 s per test. It creates a new Datasheet v2.1 (ds:v00003) document in the standalone editor and exercises every control type: list add and remove, term, enum, URL, date, date-time and typed-value pickers, the agent and reference dialogs, the union type toggle, and the Validate button in several document states. It writes artifacts/datasheet-e2e-report.json.
Testbench smoke test
playwright.testbench.smoke.config.js: tests/smoke/testbench-route.smoke.pw.js, port 4173. It opens /testbench.html, runs the scenario catalog and writes:
artifacts/testbench-smoke-report.json(Playwright JSON report);artifacts/testbench-scenario-summary.json(scenario results).
npm run ci:quality-gate:testbench -w sidedoc-frontend then checks the summary: it fails when the pass rate is below TESTBENCH_MIN_PASS_RATE (default 1) or more than TESTBENCH_MAX_FAILED_SCENARIOS (default 0) scenarios failed.
User guide screenshots
playwright.docs-screenshots.config.js is not a test: it captures the screenshots used in the user guide into docs/public/screenshots/.
CI
GitLab reads only the root .gitlab-ci.yml. It currently covers the documentation: a check that the generated settings reference matches the sources (node scripts/gen-settings-docs.mjs --check), the docs build, and publishing to GitLab Pages from the default branch.
The app suites are not in the monorepo pipeline yet. app/sidedoc-frontend/.gitlab-ci.yml is the pipeline of the old frontend repository: on merge requests and the default branch it ran npm test and npm run test:a11y (in the Playwright Docker image) after cloning the backend as a sibling checkout. It does not run in the monorepo. Until app jobs are added to the root file, run these locally before you open a merge request:
npm run typecheck
npm test
npm run test:a11y -w sidedoc-frontendA monorepo job would run npm ci and the backend build with tsup (the generated files are committed, so the build needs no schemas checkout), then the commands above, using the Playwright image for the accessibility gate. npm test does need the schemas: clone the schemas repository in the job and set SIDEDOC_SCHEMAS_DIR, because dcat-export.test.ts reads example datasheets from it.