Test coverage and evidence
This page is the living coverage register for snappycart.
It is intended for two audiences:
- contributors, who need to understand what is already covered and where to add new tests
- package users, who want confidence that the core cart contract and UI flows are already exercised by automated tests
This page is not a replacement for the test strategy, state transition matrix, or decision tables.
It answers a different question:
what is currently covered, by which framework, where is the test, and where is the execution evidence?
Why this page exists
snappycart uses multiple testing layers and multiple tools:
- Vitest for unit and integration-style library tests
- Cypress for component tests and demo-level browser tests
- Playwright for component tests and end-to-end smoke tests
Some coverage is intentionally duplicated across Cypress and Playwright.
That duplication is acceptable when it improves confidence at different layers or validates the same behaviour through different test runners.
How to use this page
Each row in the tables below represents a coverage entry.
Contributors should update this page when they:
- add a new automated test
- replace one framework with another
- add a new browser-level flow
- upload a new video walkthrough for an existing automated test
Required fields for each coverage entry
Every coverage row should include:
- Status
- Area
- Level
- Framework
- What is covered
- GitHub test link
- Video evidence link
- Notes
Status legend
| Status | Meaning |
|---|---|
| Confirmed | Test exists in the repository and is linked below |
| Partial | Coverage exists, but the flow is only partially validated |
| Planned | Intended coverage, but no committed automated test yet |
| Deprecated | Historical entry kept for reference but no longer current |
Coverage model
The tables are grouped by testing level:
- unit
- integration
- component
- end-to-end
Frameworks are listed separately even when they overlap.
That is intentional.
The point of this page is not to hide duplication. The point is to make duplication visible and understandable.
Unit and integration coverage
These tests validate core cart behaviour inside the package itself.
Vitest coverage
For the canonical Vitest inventory and test IDs, read Vitest Testing.
Vitest unit coverage
| Test ID | Status | Area | Level | Framework | What is covered | GitHub test link | Matrix reference | Notes |
|---|---|---|---|---|---|---|---|---|
| VT-01 | Confirmed | Cart reducer | Unit | Vitest | add new item | cartReducer.test.ts | VT-01 | Confirms a new cart line is inserted with the expected quantity and values |
| VT-02 | Confirmed | Cart reducer | Unit | Vitest | add existing item and merge quantity | cartReducer.test.ts | VT-02 | Confirms duplicate adds increase quantity instead of creating a second line |
| VT-03 | Confirmed | Cart reducer | Unit | Vitest | add item with invalid quantity and normalise it | cartReducer.test.ts | VT-03 | Confirms invalid quantity input is normalised to a safe stored value |
| VT-04 | Confirmed | Cart reducer | Unit | Vitest | add item with decimal quantity and floor it | cartReducer.test.ts | VT-04 | Confirms decimal quantity is normalised before storage |
| VT-05 | Confirmed | Cart reducer | Unit | Vitest | remove item | cartReducer.test.ts | VT-05 | Confirms the matching reducer line is removed |
| VT-06 | Confirmed | Cart reducer | Unit | Vitest | increment item | cartReducer.test.ts | VT-06 | Confirms quantity increases by one |
| VT-07 | Confirmed | Cart reducer | Unit | Vitest | decrement item above one | cartReducer.test.ts | VT-07 | Confirms quantity decreases without removing the line |
| VT-08 | Confirmed | Cart reducer | Unit | Vitest | decrement item from one and remove the line | cartReducer.test.ts | VT-08 | Confirms the item is removed when decrement reaches the removal boundary |
| VT-09 | Confirmed | Cart reducer | Unit | Vitest | set positive quantity | cartReducer.test.ts | VT-09 | Confirms quantity updates directly to the requested value |
| VT-10 | Confirmed | Cart reducer | Unit | Vitest | set decimal quantity and floor it | cartReducer.test.ts | VT-10 | Confirms decimal quantity is normalised before storage |
| VT-11 | Confirmed | Cart reducer | Unit | Vitest | set quantity to zero and remove the line | cartReducer.test.ts | VT-11 | Confirms zero quantity removes the line from state |
| VT-12 | Confirmed | Cart reducer | Unit | Vitest | set negative quantity and remove the line | cartReducer.test.ts | VT-12 | Confirms invalid negative quantity does not remain in state |
| VT-13 | Confirmed | Cart reducer | Unit | Vitest | clear cart | cartReducer.test.ts | VT-13 | Confirms reducer state resets to an empty cart |
| VT-14 | Confirmed | Cart reducer | Unit | Vitest | calculate total items | cartReducer.test.ts | VT-14 | Confirms derived total item count is correct |
| VT-15 | Confirmed | Cart reducer | Unit | Vitest | calculate subtotal | cartReducer.test.ts | VT-15 | Confirms derived subtotal is correct |
Vitest integration coverage
| Test ID | Status | Area | Level | Framework | What is covered | GitHub test link | Matrix reference | Notes |
|---|---|---|---|---|---|---|---|---|
| VT-16 | Confirmed | Cart provider and hook contract | Integration | Vitest | throws outside provider | CartProvider.test.tsx | VT-16 | Confirms useCart throws when used outside CartProvider |
| VT-17 | Confirmed | Cart provider and hook contract | Integration | Vitest | exposes empty initial state | CartProvider.test.tsx | VT-17 | Confirms the default empty cart contract on first render |
| VT-18 | Confirmed | Cart provider and hook contract | Integration | Vitest | add item updates items, totalItems, and subtotal | CartProvider.test.tsx | VT-18 | Validates provider state update through hook usage |
| VT-19 | Confirmed | Cart provider and hook contract | Integration | Vitest | remove item updates derived values | CartProvider.test.tsx | VT-19 | Confirms line removal updates totals correctly |
| VT-20 | Confirmed | Cart provider and hook contract | Integration | Vitest | increment and decrement update derived values | CartProvider.test.tsx | VT-20 | Covers quantity mutation path and keeps derived values in sync |
| VT-21 | Confirmed | Cart provider and hook contract | Integration | Vitest | clear resets state | CartProvider.test.tsx | VT-21 | Confirms full cart reset |
| VT-22 | Confirmed | Cart provider and hook contract | Integration | Vitest | add item with explicit quantity | CartProvider.test.tsx | VT-22 | Additional integration scenario covering explicit quantity input |
Guidance for contributors
Use this section for:
- cart reducer logic
- provider and hook behaviour
- derived totals
- safe handling of cart mutations inside the library
If the change is purely internal and does not require a browser, this is usually the cheapest layer.
Component coverage
These tests validate library components in an interactive browser-like environment.
Cypress component coverage
Cypress component testing video evidence
Shared execution video for the full Cypress Component Testing run covering CT-01 to CT-24.
Cypress component coverage table
| Status | Area | Level | Framework | What is covered | GitHub test link | Video evidence link | Matrix reference | What this test confirms |
|---|---|---|---|---|---|---|---|---|
| Confirmed | CartDrawer | Component | Cypress | drawer does not render when closed | CartDrawer.cy.tsx | CT-1 video | CT-01 | Confirms that the drawer stays absent from the DOM when mounted in the closed state |
| Confirmed | CartDrawer | Component | Cypress | empty state renders when open with no items | CartDrawer.cy.tsx | CT-2 video | CT-02 | Validates the empty drawer output when the drawer is opened with no cart items |
| Confirmed | CartDrawer | Component | Cypress | close button receives focus on open | CartDrawer.cy.tsx | CT-03 video | CT-03 | Confirms initial focus placement on the close button for accessibility and keyboard usability |
| Confirmed | CartDrawer | Component | Cypress | Escape triggers onClose | CartDrawer.cy.tsx | CT-04 video | CT-04 | Confirms that pressing Escape requests the drawer to close |
| Confirmed | CartDrawer | Component | Cypress | overlay click triggers onClose | CartDrawer.cy.tsx | CT-05 video | CT-05 | Confirms that clicking the overlay requests the drawer to close |
| Confirmed | CartIcon | Component | Cypress | empty badge behaviour matches the current cart state | CartIcon.cy.tsx | CT-06 video | CT-06 | Validates the empty cart badge state without relying on CSS selectors |
| Confirmed | CartIcon | Component | Cypress | badge updates to 1 when the cart has one item | CartIcon.cy.tsx | CT-07 video | CT-07 | Confirms the single-item badge transition |
| Confirmed | CartIcon | Component | Cypress | badge reflects the total item count when the cart has multiple items | CartIcon.cy.tsx | CT-08 video | CT-08 | Confirms total quantity rendering rather than distinct line count |
| Confirmed | CartIcon + CartDrawer integration | Component | Cypress | clicking the cart icon opens the empty drawer state | CartIntegration.cy.tsx | CT-09 video | CT-09 | Confirms that clicking the cart entry point opens the drawer in its empty state |
| Confirmed | CartIcon + CartDrawer + CartProvider | Component | Cypress | adding the first item updates the badge and drawer title count | CartIntegration.cy.tsx | CT-10 video | CT-10 | Confirms that the first seeded item transitions the cart from empty to non-empty and updates both the badge and drawer count |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | populated row is shown after seeding the first item | CartDrawer.cy.tsx | CT-11 video | CT-11 | Confirms that the first seeded item is rendered as a visible cart row with quantity 1 |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | incrementing quantity from 1 to 2 updates the subtotal | CartDrawer.cy.tsx | CT-12 video | CT-12 | Confirms quantity growth and immediate subtotal recalculation after increment |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | decrementing quantity from 2 to 1 updates the subtotal | CartDrawer.cy.tsx | CT-13 video | CT-13 | Confirms quantity reduction and immediate subtotal recalculation after decrement |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | decrementing at quantity 1 removes the item and returns the cart to the empty state | CartDrawer.cy.tsx | CT-14 video | CT-14 | Confirms the single-item decrement-to-empty transition |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | clicking remove deletes the item and returns the cart to the empty state | CartDrawer.cy.tsx | CT-15 video | CT-15 | Confirms explicit item removal and empty-state rendering |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | multiple distinct items render as separate rows and subtotal matches their combined value | CartDrawer.cy.tsx | CT-16 video | CT-16 | Confirms multi-item row rendering and subtotal aggregation |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | removing one item leaves the remaining item visible and recalculates subtotal | CartDrawer.cy.tsx | CT-17 video | CT-17 | Confirms partial removal without losing the rest of the cart state |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | removing the last remaining item returns the cart to the empty state | CartDrawer.cy.tsx | CT-18 video | CT-18 | Confirms the final-item removal transition back to an empty cart |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | clicking clear empties the cart and removes all rendered rows | CartDrawer.cy.tsx | CT-19 video | CT-19 | Confirms the bulk clear action resets the drawer to its empty state |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | subtotal recalculates immediately after increment and decrement actions | CartDrawer.cy.tsx | CT-20 video | CT-20 | Confirms subtotal consistency across rapid quantity changes |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | closing and reopening the drawer preserves the same items, quantities, and subtotal | CartDrawer.cy.tsx | CT-21 video | CT-21 | Confirms drawer visibility changes do not reset cart state |
| Confirmed | CartIcon + CartDrawer + CartProvider | Component | Cypress | closing the drawer preserves the current cart state | CartIntegration.cy.tsx | CT-22 video | CT-22 | Confirms that the drawer can close without clearing the cart and that the badge still reflects the current item count |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | visible product metadata renders correctly for a representative product | CartDrawer.cy.tsx | CT-23 video | CT-23 | Confirms that a seeded product is rendered with visible metadata in the drawer, including its product name |
| Confirmed | CartDrawer + CartProvider | Component | Cypress | the UI stays in sync across increment, decrement, and remove actions | CartDrawer.cy.tsx | CT-24 video | CT-24 | Confirms that repeated cart interactions keep rows, quantities, and subtotal consistent after each transition |
Playwright component coverage
| Status | Area | Level | Framework | What is covered | GitHub test link | Video evidence link | Notes |
|---|---|---|---|---|---|---|---|
| Confirmed | CartDrawer | Component | Playwright CT | clicking Close triggers onClose | CartDrawer.pw.spec.tsx | Add Drive or YouTube link | Confirms callback wiring in Playwright component runner |
Guidance for contributors
Use this section for:
- component visibility
- focus behaviour
- keyboard handling
- overlay behaviour
- callback wiring
- visual browser-level interactions that do not require full app navigation
If the same component rule is covered in both Cypress and Playwright, keep both rows.
That overlap should be visible, not hidden.
End-to-end coverage
These tests validate demo-level user flows through the running application.
Cypress end-to-end coverage
Cypress E2E testing video evidence
Shared execution video for the Cypress end-to-end test run.
Cypress end-to-end coverage table
| Status | Area | Level | Framework | What is covered | GitHub test link | Video evidence link | Notes |
|---|---|---|---|---|---|---|---|
| Confirmed | Demo cart smoke | E2E | Cypress | add item from demo and show it in drawer | demo-cart.cy.ts | Add Drive or YouTube link | Demo-level add-to-cart smoke |
| Confirmed | Demo cart smoke | E2E | Cypress | increment and decrement quantity from drawer | demo-cart.cy.ts | Add Drive or YouTube link | Quantity mutation flow |
| Confirmed | Demo cart smoke | E2E | Cypress | remove item from drawer | demo-cart.cy.ts | Add Drive or YouTube link | Remove line flow |
| Confirmed | Demo cart smoke | E2E | Cypress | clear cart after starter set | demo-cart.cy.ts | Add Drive or YouTube link | Bulk reset flow |
Playwright end-to-end coverage
| Status | Area | Level | Framework | What is covered | GitHub test link | Video evidence link | Notes |
|---|---|---|---|---|---|---|---|
| Confirmed | Demo cart smoke | E2E | Playwright | add item to cart and verify it appears in drawer | cart-add-item.spec.ts | Add Drive or YouTube link | Add item, badge update, drawer visibility |
| Confirmed | Drawer smoke | E2E | Playwright | drawer opens and closes in the demo | cart-drawer-open-close.spec.ts | Add Drive or YouTube link | Focused drawer visibility flow |
Guidance for contributors
Use this section for:
- smoke flows through the demo app
- top-level user actions
- browser behaviour that depends on real navigation and mounted UI
Cypress and Playwright may overlap here.
That is acceptable when:
- one runner acts as the main regression smoke
- the second runner validates the same flow from another browser toolchain
- the project is comparing or migrating runners over time
Duplicate coverage policy
Overlap between Cypress and Playwright is allowed when it is intentional.
Typical valid reasons include:
- validating the same critical flow in two different browser runners
- comparing reliability during framework migration
- keeping one smoke path in each tool while broader coverage is still evolving
Overlap becomes a problem only when it creates maintenance cost without adding confidence.
Contributors should avoid blind duplication.
When adding a new row, ask:
- does this duplicate an existing flow exactly
- does the second runner add confidence that the first does not
- is this duplication temporary, strategic, or accidental
If the duplication is intentional, say so in the Notes column.
Video evidence policy
Each browser-level test entry should ideally include a short execution video.
Recommended workflow:
- contributor records the automated test execution
- contributor uploads the video to the agreed shared drive
- maintainer publishes or mirrors the final version to YouTube if needed
- this table is updated with a stable video link
Preferred video format
- short and focused
- one test flow per video where possible
- no unnecessary narration required
- stable viewport
- clear visible assertions
- either Drive or YouTube link is acceptable
Where video evidence is most useful
Video evidence is most valuable for:
- component tests with visible interaction
- end-to-end flows
- UI regressions
- onboarding new contributors to expected behaviour
Video evidence is optional for pure library-level unit tests, unless a maintainer specifically wants a visual walkthrough.
How contributors should update this page
When you add a new automated test:
- add the test file to the repository
- commit and push the test normally
- add a new row to the correct table in this page
- link the exact GitHub test file
- add a Drive or YouTube link if video evidence exists
- describe the covered behaviour in one short sentence
- mark overlap clearly if the same flow already exists in another framework
How package users should read this page
Package users do not need to read every test file.
This page gives a high-level confidence map:
- what the package already tests
- which framework covers each area
- where the source test lives
- where to find visual evidence of the flow
It should be read together with:
- the cart testing plan
- the cart state transition matrix
- the cart decision tables
Recommended future additions
The current coverage register can be expanded over time with:
- broader component coverage for
CartIconandCartDrawerintegration flows - more unit coverage for reducer-only logic
- CI report artifact links
- coverage percentage badges
- links to generated HTML reports if the project publishes them
Summary
snappycart uses multiple testing layers and multiple frameworks.
This page exists to make that coverage visible.
It is a living register of:
- what is covered
- how it is covered
- where the test lives
- where the execution evidence can be inspected