Unit and Contract Testing
Relevant source files
The following files were used as context for generating this wiki page:
- CLAUDE.md
- packages/cart/core/package.json
- apps/admin/src/lib/editor-runtime.test.ts
- apps/admin/e2e/header-editor.spec.ts
- packages/cms/package.json
- apps/admin/src/app/(app)/(dashboard)/[domain]/content/product-metadata/page.test.tsx/(dashboard)/[domain]/content/product-metadata/page.test.tsx)
- packages/tagtree/core/CHANGELOG.md
Introduction
The commerce repository employs a multi-tiered testing strategy designed to ensure reliability across its monorepo architecture. This strategy encompasses unit testing for isolated logic, contract testing for package interfaces, and end-to-end (E2E) testing for critical user flows. The primary goals are to maintain high code coverage, prevent regressions in shared packages, and validate complex administrative workflows such as CMS content authoring and multi-tenant configurations.
Testing is deeply integrated into the development workflow via pnpm scripts and Turbo. Unit tests are executed per-package to leverage build caching, while E2E tests drive the real application against a live deployment or local development server.
Sources: CLAUDE.md:14-25, packages/tagtree/core/CHANGELOG.md:4-7
Unit Testing Framework
The project uses Vitest as its primary unit testing framework. Tests are configured to run within each workspace package independently, allowing for optimized execution through Turbo's caching mechanism.
Execution and Coverage
Unit tests are triggered via the pnpm test command, which executes turbo run test. This ensures that only packages with changes (or affected by changes) are re-tested. Coverage reports are generated in a sharded format (e.g., coverage/coverage-final.json) and subsequently merged to enforce global coverage floors.
Sources: CLAUDE.md:20-24, packages/cms/package.json:115, packages/cart/core/package.json:34
Test Environments
The project utilizes different environments depending on the package type:
- Happy-dom: Used for apps requiring browser-like APIs, such as
apps/landing. - Node: Default for core logic packages.
- In-memory Convex: Integration suites for database logic often use
convex-testfor in-memory execution without a full backend.
Sources: apps/landing/README.md:112, CLAUDE.md:25-28
Unit Testing Architecture
The following diagram illustrates how unit tests are orchestrated across the monorepo:
The workflow ensures that unchanged packages restore results from the build cache while maintaining a unified coverage metric.
Sources: CLAUDE.md:20-25, packages/tagtree/core/CHANGELOG.md:4-7
Contract and Interface Testing
Contract testing ensures that shared packages maintain consistent APIs for consumers. The @nordcom/cart-core package specifically exports contract tests to be used by adapters or related implementations.
Cart Core Contracts
The cart system defines strict interfaces for operations like adding items, updating quantities, and clearing carts. The core package provides a contract-tests.ts file and a mock-adapter.ts to facilitate testing across different cart providers.
| Export Path | Purpose |
|---|---|
. | Main cart logic and types. |
./contract-tests | Reusable test suites for cart implementations. |
./mock-adapter | Standardized mock for cart operations in unit tests. |
Sources: packages/cart/core/package.json:13-22
Editor Runtime Integration
The admin dashboard utilizes an editorRuntime which is heavily tested to ensure it correctly binds the Convex bridge (for data operations) and media upload actions. Tests verify that the runtime flattens tenant contexts and manages form states correctly.
Sources: apps/admin/src/lib/editor-runtime.test.ts:47-66, apps/admin/src/lib/editor-runtime.test.ts:86-103
E2E Testing with Playwright
End-to-end tests are implemented using Playwright to exercise the "Real App" against a live or ephemeral deployment. These tests are located in e2e/ directories within the apps/admin and apps/storefront packages.
Editor Flows
E2E tests for the CMS editor (e.g., Header, Footer, Articles, Pages) follow a serial execution mode to build document state incrementally. Key features tested include:
- Autosave Quiescence: Polling the "Saving..." state to ensure data durability across the 2-second interval.
- Version Restore: Validating that published snapshots can be successfully re-materialized.
- Multi-block Authoring: Testing complex structures like nested columns and rich-text ProseMirror blocks.
Sources: apps/admin/e2e/header-editor.spec.ts:16-24, apps/admin/e2e/pages-editor.spec.ts:13-20, apps/admin/e2e/header-editor.spec.ts:50-62
Editor Action Flow
This sequence diagram demonstrates the interaction during an autosave and publish flow in the E2E environment:
Test Configuration Summary
The testing infrastructure relies on several key configuration files and scripts.
| Script/Config | Description |
|---|---|
vitest.config.ts | Global Vitest configuration. |
vitest.shared.ts | Shared Vitest settings and coverage floors for apps. |
pnpm test:e2e | Runs Playwright specs against an isolated Next.js instance. |
seedCanonical | Global setup fixture used to seed a tenant for E2E tests. |
pnpm cms:gen:check | CI gate to ensure CMS codegen is up to date. |
Sources: CLAUDE.md:14-25, apps/admin/e2e/header-editor.spec.ts:7-10
Conclusion
The testing ecosystem in the commerce project balances speed and thoroughness. By combining per-package unit tests with Turbo's caching and comprehensive Playwright E2E specs, the project ensures that both low-level logic and high-level business flows remain functional during rapid development. Contract tests in core packages further safeguard the stability of the platform's extensible architecture.