173 lines
8.4 KiB
Gherkin
173 lines
8.4 KiB
Gherkin
Feature: Language switcher conforms to the official design
|
|
|
|
Background:
|
|
Given the design in docs/design is the visual spec of record for LanguageSwitcher and UserMenu
|
|
And the interface supports exactly two languages, English and Français
|
|
And each language is always written in its own name, whatever the interface language
|
|
And the language rules of features/spa_internationalization.feature still apply
|
|
And the language control no longer uses a form select anywhere
|
|
And no language preference is sent to the server
|
|
|
|
Scenario Outline: Account menu lists Profile, Theme, Language and Log out in design order
|
|
Given a signed-in user opens the account menu in the <surface>
|
|
Then the entries appear in this order
|
|
| Profile |
|
|
| separator |
|
|
| "Theme" section label |
|
|
| System, Light, Dark |
|
|
| separator |
|
|
| "Language" section label |
|
|
| English, Français |
|
|
| separator |
|
|
| Log out |
|
|
And the "Theme" and "Language" labels are 11 px, weight 500, uppercase, letter-spacing 0.04em and --ui-text-muted
|
|
And the label padding is <label_padding>
|
|
And the menu is <size>
|
|
And every item row is <row_height> high
|
|
|
|
Examples:
|
|
| surface | label_padding | size | row_height |
|
|
| desktop UserMenu popover | 6px 8px 2px | a 224 px popover above the chip | 32 px |
|
|
| mobile AccountMenuSheet | 8px 16px 2px | a bottom sheet with grab handle | 48 px |
|
|
|
|
Scenario Outline: Language rows are a radio group naming each language in its own name
|
|
Given the interface language is <locale>
|
|
When the account menu is open in the <surface>
|
|
Then the "Language" label names a group of two menuitemradio rows
|
|
And the rows read "English" with lang "en" and "Français" with lang "fr"
|
|
And the row for <locale_name> has aria-checked "true" and a check icon at the right edge
|
|
And the other row has aria-checked "false" and no check icon
|
|
And no Nuxt UI select, combobox or languages icon row is present in the menu
|
|
|
|
Examples:
|
|
| surface | locale | locale_name |
|
|
| desktop UserMenu popover | en | English |
|
|
| desktop UserMenu popover | fr | Français |
|
|
| mobile AccountMenuSheet | en | English |
|
|
| mobile AccountMenuSheet | fr | Français |
|
|
|
|
Scenario Outline: Theme rows are radio items that keep the menu open
|
|
Given the theme preference is <preference>
|
|
When the account menu is open in the <surface>
|
|
Then System, Light and Dark are menuitemradio rows in a group named "Theme"
|
|
And only the <preference> row has aria-checked "true" and a check icon
|
|
When the user chooses another theme row
|
|
Then the theme applies at once and the menu stays open
|
|
|
|
Examples:
|
|
| surface | preference |
|
|
| desktop UserMenu popover | light |
|
|
| mobile AccountMenuSheet | dark |
|
|
|
|
Scenario Outline: Choosing a language in the account menu applies it at once and keeps the menu open
|
|
Given the interface language is en and the user is on /profile with an unsaved display name "Alice B."
|
|
And the account menu is open in the <surface>
|
|
When the user chooses "Français"
|
|
Then all interface text, including the menu labels "Thème" and "Langue", is French
|
|
And the document lang is "fr" and localStorage "renewcms-language" is "fr"
|
|
And the Français row is checked and the menu stays open
|
|
And the route, session, theme and unsaved display name are unchanged
|
|
And no reload, navigation or /v1 request occurs
|
|
When the user chooses "English"
|
|
Then the interface is English, the document lang is "en" and the menu stays open
|
|
|
|
Examples:
|
|
| surface |
|
|
| desktop UserMenu popover |
|
|
| mobile AccountMenuSheet |
|
|
|
|
Scenario Outline: Account menu keyboard and dismissal
|
|
Given the account menu is open in the <surface>
|
|
When the user moves with ArrowDown and ArrowUp
|
|
Then focus visits Profile, the theme rows, the language rows and Log out in visual order and wraps at the ends
|
|
When the user presses Enter or Space on a language row
|
|
Then that language is applied and the menu stays open
|
|
When the user presses Escape or clicks outside
|
|
Then the menu closes without changing the language
|
|
|
|
Examples:
|
|
| surface |
|
|
| desktop UserMenu popover |
|
|
| mobile AccountMenuSheet |
|
|
|
|
Scenario Outline: Auth footer shows the language chip beside the theme chip
|
|
Given the user is signed out on <route>
|
|
And the interface language is en
|
|
Then the footer outside the card contains the language chip and the System theme chip aligned right with an 8 px gap
|
|
And any existing footer slot content stays to the left of the chips
|
|
And the chip shows the lucide languages icon at 14 px followed by "English"
|
|
And the chip has a 1 px --ui-border-accented border, --ui-text-toned text, aria-haspopup "menu", aria-expanded "false" and aria-label "Language: English"
|
|
And no language select is rendered in the card or the footer
|
|
|
|
Examples:
|
|
| route |
|
|
| /login |
|
|
| /register |
|
|
| /register/pending |
|
|
| /register/validate |
|
|
| /register/reset/request |
|
|
| /register/reset/validate |
|
|
| /invite/accept |
|
|
|
|
Scenario Outline: Auth footer is always rendered, on mobile too
|
|
Given the viewport is <viewport>
|
|
When an auth screen with no footer slot content renders
|
|
Then the footer with the language chip and the theme chip is visible
|
|
And the chip is <chip_height> high
|
|
|
|
Examples:
|
|
| viewport | chip_height |
|
|
| 1440 x 900 | 28 px |
|
|
| 390 x 844 | 44 px |
|
|
|
|
Scenario: Chip reflects the current language
|
|
Given the stored language is fr
|
|
When /login renders
|
|
Then the chip reads "Français" and its aria-label is "Langue : Français"
|
|
|
|
Scenario Outline: Auth language popover
|
|
Given the user is signed out on /login in <locale_name>
|
|
When the user activates the language chip
|
|
Then the chip has aria-expanded "true" and --ui-bg-elevated
|
|
And a popover with role "menu" named "Language" opens above the chip, right-aligned and 36 px above its bottom edge, 168 px wide, --ui-bg, 1 px --ui-border, --rc-shadow-pop and 4 px padding
|
|
And it holds menuitemradio rows "English" (lang "en") and "Français" (lang "fr") that are 32 px high on desktop and 44 px on mobile
|
|
And the current language row has aria-checked "true" and a 16 px check icon at the right edge
|
|
|
|
Examples:
|
|
| locale_name |
|
|
| English |
|
|
| Français |
|
|
|
|
Scenario: Choosing a language in the auth popover closes it
|
|
Given the auth language popover is open on /login with English current
|
|
When the user chooses "Français"
|
|
Then the whole screen is French at once, including the card, the footer and the document title
|
|
And the document lang is "fr" and localStorage "renewcms-language" is "fr"
|
|
And the popover closes and focus returns to the language chip
|
|
And the chip reads "Français"
|
|
And the form values already typed, the route and the theme are unchanged
|
|
And no /v1 request occurs
|
|
|
|
Scenario: Dismiss the auth popover without changing language
|
|
Given the auth language popover is open
|
|
When the user presses Escape or clicks outside it
|
|
Then it closes, aria-expanded is "false" and the language is unchanged
|
|
And focus returns to the chip on Escape
|
|
|
|
Scenario: Auth popover keyboard
|
|
Given the language chip has focus
|
|
When the user presses Enter, Space or ArrowDown
|
|
Then the popover opens with focus on the current language row
|
|
And ArrowUp and ArrowDown move between the two rows and Enter or Space chooses one
|
|
|
|
Scenario: Language persists across public and signed-in screens
|
|
Given the user chose Français on /login
|
|
When they sign in, open the account menu and log out
|
|
Then Français is checked in the account menu and the /login chip reads "Français" again
|
|
And a storage failure still lets the choice apply for the current session, as in spa_internationalization
|
|
|
|
Scenario: Catalog parity for the new strings
|
|
Then the en and fr catalogs contain "Theme" and "Language: {0}"
|
|
And "Language: {0}" keeps its {0} parameter in French
|
|
And the strings "English" and "Français" are not translated
|