Files
RenewCMS/features/variants_visual_conformance.feature

110 lines
7.3 KiB
Gherkin
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Feature: Variants and Media screens match the merged design: visual setups, and the variant form as a bottom sheet on mobile
As the maintainer of RenewCMS
I want the visual check to cover every state of the image variants screens, and the variant form to follow the overlay pattern
So that the SPA matches the merged design on desktop and mobile, in light and dark
Background:
Given the spec of record is docs/design/screens/image-variants.md, docs/design/screens/media.md, docs/design/screens/media-picker.md, docs/design/states.md, docs/design/routes.md and the overlay pattern of docs/design/components.md
And this slice is SPA only: no Go file, route or API contract changes
And the behaviours of features/image_variants_media_screens.feature, features/image_variants_screens.feature and features/image_variants_editor_picker.feature stay as they are except where this file says so
And the merged board is "RenewCMS Screens Back-office.dc.html" and web/visual/check.ts already points to it, with state names in the form "V1a · Loaded"
And every new English string has a French entry in web/src/i18n/messages.ts, the page uses Nuxt UI components and design tokens only, and no comment is added to any file
And the session is the owner "Marta Alves" unless a scenario says otherwise
Rule: Every state of the six groups has a visual setup that passes
Scenario Outline: A group of the merged board is fully covered
Given the group "<group>" of the merged board lists the states "<states>"
When "task visual:check -- image-variants" runs
Then each of those states has a setup in web/visual/states.ts keyed by its exact board name
And each capture prints PASS at desktop and mobile, in light and dark, within 10 %
And no /v1 call is left unmocked and no size mismatch is reported
Examples:
| group | states |
| Variants list | V1a to V1l |
| Add edit variant | V2a to V2k |
| Media library | V3a to V3f |
| Image detail | V4a to V4h |
| Cache panel | V5a to V5j |
| Editor picker | V6a to V6e |
Scenario: Setups reuse the board's own sample data
Then each setup mocks /v1 with the titles, names, sizes, counts and variant rows drawn in the board frame
Scenario: Clock-sensitive states are skipped, not tuned
Given a state whose rendering depends on the current date or time
Then its setup carries skip: 'clock-sensitive', the check prints SKIP and no Vitest spec freezes the system date
Scenario: No visual exception is added without the user's approval
Given a capture cannot get within 10 %
Then the setup or the SPA is fixed
And no "exception" entry is added unless the user approved it explicitly (approvedBy)
Scenario: The gate is hard
When any capture exceeds 10 %, a state has no setup, or a /v1 call is unmocked
Then "task visual:check -- image-variants" exits non-zero
Rule: The Media library V3 states render the existing variants filter and total-size sort
The filter, the sort and their request parameters already exist. Media code changes only if a V3 capture fails the check.
Scenario Outline: The V3 states render the filter and the sort
Given the 12-image fixture of features/image_variants_media_screens.feature
When the setup of "<state>" is loaded on /media
Then the SPA shows "<visible>"
And GET /v1/media/ carries "<request>"
Examples:
| state | visible | request |
| V3a · Grid with badges | "N variants" badges on cards with cached files, none on cards without, "All" selected | no variants parameter |
| V3b · Sort menu | sort menu open, "Largest total size (original + variants)" last | n/a |
| V3c · Filter: With variants, sorted by total size | "With variants" selected, meta lines "total · original + variants" | variants=with&sort=total_size |
| V3d · Filter: Without variants | "Without" selected, no variants badge | variants=without |
| V3e · Filter: nothing to show | "With variants" selected, empty cache, "No images with variants" | variants=with |
Scenario: Existing filter and sort behaviour is unchanged
Then the URL, request and meta-line behaviour of "The variants filter" and "Sorting by total size" in features/image_variants_media_screens.feature still holds
Rule: The variant form follows the overlay pattern
Scenario: Add variant is a right slide-over on desktop
Given the viewport is 640 px wide or more
When the admin activates "Add variant"
Then the form opens as a slide-over 960 px wide at the right over the scrim, full height, with the list behind it
And the header has the title and a close button (x icon, accessible name "Close")
And the form is on the left and the live preview on the right
Scenario: Add variant is a tall bottom sheet on mobile
Given the viewport is below 640 px
When the admin activates "Add variant"
Then the form opens as a bottom sheet flush to the bottom, full width, 92 % of the viewport height
And a grabber (36 × 4, --ui-border-accented) is drawn at the top, with a close x button (44 px) in the header
And it is not a full page: the list stays visible above the sheet behind the scrim
And the Preview section is stacked under the form and the body scrolls
And the footer is sticky with "Cancel" and the primary action sharing the width, 44 px high
Scenario: Edit uses the same container
When the admin chooses "Edit" on the row "hero"
Then the form opens in the same container as Add variant at the current viewport and the title is "Edit variant: hero"
Scenario Outline: Dismissing the mobile sheet
Given the viewport is below 640 px
When the user <gesture>
Then <result>
Examples:
| gesture | result |
| closes a pristine form with x or Cancel | the sheet closes with no dialog and focus returns to the opener |
| swipes down or taps the scrim, pristine | the sheet closes |
| closes a dirty form (x, Cancel, Escape, swipe, scrim) | the "Discard changes?" dialog opens and the sheet stays |
| any dismissal while Saving | nothing closes |
Scenario: Mobile no longer shows a back arrow
Given the viewport is below 640 px
Then no arrow-left back button is in the form header
Scenario: Focus
Then focus is trapped in the sheet or slide-over and returns to the opener on close, and on open it moves to the Name field in create mode