Design system registry and contract tests¶
Maintenance notes for Easy8 developers who change design system component APIs. Customer plugins do not need this page.
The Vue components and the Ruby wrappers are two views of the same component API. Contract tests keep them in sync, so a prop added on one side cannot silently drift from the other.
The contract is mediated by a committed snapshot:
app/easy_design/design_system/registry_snapshot.json: generated description of every DS custom element (props with types, prop type hints, model value type, exposed methods, and slots)
The snapshot is derived from the Vue components. Never edit it by hand. Regenerate it with:
Three test layers check the contract:
- A vitest freshness guard (
app/frontend/src/tests/tests/design_system/tests/dsRegistrySnapshot.spec.ts) fails when the committed snapshot no longer matches the Vue components - A vitest registry contract (
dsRegistryContract.spec.tsin the same folder) verifies that the custom elements registry (DS_CUSTOM_ELEMENTS_REGISTRYinapp/frontend/src/design_system/shared/constants/customElements.ts) describes real components: every Boolean, Number, and Date prop has aPROP_TYPE_HINT(without one,data-*attributes reach Vue as raw strings and"false"is truthy), exposed methods exist on a mounted instance, and the model value type matches - An RSpec contract (
spec/easy_design/design_system/registry_contract_spec.rb) renders every Ruby DS component with sentinel values derived from the snapshot and checks the emitteddata-*attributes and<script data-prop>props against the Vue runtime props. Every Vue prop must be settable through a Ruby component param, and every component param must be accepted by itsds_*helper
Props that are intentionally not exposed on the Ruby side (for example frontend-only validation rules) are exempted in spec/easy_design/design_system/registry_contract_config.yml. Every exemption needs a documented reason.
Typical workflow when changing a DS component API:
- Change the Vue component props, slots, or exposed methods, and update the registry entry in
shared/constants/customElements.ts - Run
yarn ds:registry:exportand commit the regenerated snapshot - If the RSpec contract reports a missing param, update the Ruby wrapper in
app/easy_design/design_system/components/and itsds_*helper, or add a documented exemption toregistry_contract_config.yml