fix: changed frontend workflow and fixed login reference matching for real

This commit is contained in:
fsylvain committed 2026-09-25 22:31:44 +02:00
1 parent f1e22f7073
commit a5873f8886
12 files changed
+503 -46

No files matched your search

@@ -16,7 +16,7 @@ Feature: AuthShell and log-in screen conform to the design spec
card, per docs/design/components.md's AuthShell section and
docs/design/source/AuthCard.dc.html
And AppLogo is a reusable component (props include size) rendering the brand mark from
docs/design/source/brand/favicon.svg as inline SVG, not an <img>, so it can theme-switch
docs/design/source/brand/favicon.svg as inline SVG, not an <img>
And UPageCard's title renders through its own title slot as an h1 (tabindex="-1", so route
changes can move focus to it, per AuthShell's a11y spec), and its description renders
through UPageCard's description prop — neither is freeform markup in the default slot
@@ -42,9 +42,9 @@ Feature: AuthShell and log-in screen conform to the design spec
an <img> tag
And the logo carries alt="RenewCMS" (role="img" aria-label="RenewCMS" on the SVG)
And the logo is not wrapped in a link, since there is nothing public to go back to
And in light mode the black square has no edge stroke
And in dark mode the black square has a 1px edge in --color-chalk-600 (#444444), so it
doesn't disappear into the dark background
And the black square has no edge stroke in light mode or in dark mode, per
docs/design/source/AuthCard.dc.html's renderVals(), which computes the logo's edge as the
literal, non-theme-branched value "transparent"
Scenario: UPageCard's title is the page h1, and its description uses UPageCard's own styling
Given AuthShell renders with title "Log in" and description
+10 -9
View File
@@ -6,13 +6,14 @@ No `/v1` calls are relevant to these assertions; mount AuthShell and LoginView d
already needs `useApi`/`GET /v1/auth/registration` mocked per features/login_screen.qa.md's setup,
reused here only as scaffolding, not as the thing under test).
1. **AppLogo renders inline SVG and theme-switches** — mount AuthShell with title "Log in";
assert an inline `<svg>` (not `<img>`) renders as UPageCard's first child element, left-aligned
(not centered) above the title/description block, sharing the card's 24px gap, at 32px, with
`role="img" aria-label="RenewCMS"`, and is not inside an `<a>`; assert its outer square has no
stroke in light mode; switch to dark mode (toggle the `.dark` class the way
`nuxt_ui_shell_foundation`'s color-mode tests do) and assert a 1px stroke using
`--color-chalk-600` appears.
1. **AppLogo renders inline SVG with no edge in either mode** — mount AuthShell with title
"Log in"; assert an inline `<svg>` (not `<img>`) renders as UPageCard's first child element,
left-aligned (not centered) above the title/description block, sharing the card's 24px gap, at
32px, with `role="img" aria-label="RenewCMS"`, and is not inside an `<a>`; assert its outer
square has no stroke in light mode; switch to dark mode (toggle the `.dark` class the way
`nuxt_ui_shell_foundation`'s color-mode tests do) and assert the outer square still has no
stroke, per `docs/design/source/AuthCard.dc.html`'s literal, non-theme-branched
`edge: 'transparent'`.
2. **UPageCard title is an h1 with tabindex="-1"** — mount AuthShell with title "Log in" and
description "Welcome back. Log in to manage your articles."; assert
`wrapper.find('h1').attributes('tabindex')` is `"-1"` and its text is "Log in"; assert the
@@ -58,8 +59,8 @@ Reference: `docs/design/source/RenewCMS Screens Auth.dc.html`, group "Log in", p
- [ ] AppLogo renders inside UPageCard as its first element, left-aligned above the title (not
centered above the card), sharing the card's 24px gap; the mark matches the favicon.svg
drawing exactly (white R on a black square), desktop and mobile; in dark mode the 1px
chalk-600 edge is visible around the square, in light mode it is absent.
drawing exactly (white R on a black square), desktop and mobile; no edge stroke is visible
around the square in either light or dark mode.
- [ ] UPageCard title ("Log in") renders at the card-title size/weight from the AuthShell drawing
and receives focus (visible focus ring) on route change; description text matches
"Welcome back. Log in to manage your articles." styling, desktop and mobile, light and dark.
+102
View File
@@ -0,0 +1,102 @@
Feature: Log-in card sizing, alert placement and focus behavior match the Auth board
As the maintainer of RenewCMS
I want AuthShell's card padding, control heights, "Forgot password?" styling, field-error
presentation, theme select and h1 focus timing built exactly to the AuthCard board
(docs/design/source/AuthCard.dc.html) instead of Nuxt UI's untouched defaults
So that /login (and every other AuthShell-based public screen) matches the design board pixel
for pixel, at desktop and mobile, in light and dark
This complements features/auth_shell_login_conformance.feature, which covers AppLogo, the
UPageCard title/description wiring, the muted-background breakpoint and the neutral/error input
edge. This feature covers what that one doesn't: exact card/control measurements, the "Forgot
password?" link's own styling, the field-error icon and halo behavior, the theme select's
chevron, where the alert sits relative to the card, and when the h1 receives focus.
Background:
Given AuthShell is the layout for every public route, per docs/design/routes.md
And the card's padding, control heights and title size come from
docs/design/source/AuthCard.dc.html's renderVals(): pad "40px" and control height "40px"
from the sm breakpoint up; pad "8px 20px 0" (with a separate footer padding of
"0 20px 24px") and control height "44px" below sm; the title is always "font:600 20px/28px"
And the Password UFormField's "Forgot password?" link is styled color var(--ui-text-toned)
(muted), text-decoration underline, underline-offset 3px, per AuthCard.dc.html's f.link span
And a field error renders with the i-lucide-circle-alert icon in var(--ui-error), and the
field's edge/shadow is computed error-first, so an errored field that is also focused shows
only the single error-colored inset ring, never a focus ring stacked under or around it
And AuthShell's notice slot (the alert) renders inside the card's own layout, after the
title/description block and before the form — not as a sibling element above the card
And the footer's UColorModeSelect renders with no chevron/dropdown-arrow icon, as the last
(right-hand) child of the footer's space-between row, per AuthCard.dc.html's theme span
And on first paint, AuthShell's h1 (tabindex="-1") does not receive focus; focus moves to it
only when the title changes while AuthShell stays mounted (an in-app navigation between
public screens, e.g. /login to /register/reset/request), per components.md's AuthShell a11y
line ("On route change, focus moves to the h1")
And the h1 never shows a visible focus outline, since it is only ever focused programmatically
and is not part of the visible keyboard-tab order
Scenario: Card padding and control heights at sm and up
Given the user is on /login at a viewport of sm or wider
When AuthShell and the login form render
Then the card's own padding is 40px on every side
And the Username input, the Password input and the submit button are each 40px tall
And input text renders at 14px
Scenario: Card padding and control heights below sm
Given the user is on /login at a viewport below sm
When AuthShell and the login form render
Then the card's own padding is 8px top, 20px left and right, 0 bottom
And the footer (outside the card) has its own padding of 0 top, 20px left and right, 24px bottom
And the Username input, the Password input and the submit button are each 44px tall
And input text renders at 16px
Scenario: "Forgot password?" is underlined and muted
Given the user is on /login
When the Password field renders
Then the "Forgot password?" link uses the muted text color (--ui-text-toned)
And the link is underlined with a 3px underline offset
And the link carries no other emphasis (not bold, not the primary color)
Scenario: A field error shows the circle-alert icon with no extra focus halo
Given the user is on /login
When the user submits with Username "ma" and Password empty (the Validation errors state)
Then the Username field's error message is preceded by the i-lucide-circle-alert icon in the
error color
And the Password field's error message is preceded by the same icon in the same color
When the user tabs into the still-errored Username field so it is both errored and focused
Then the field shows exactly one inset ring, in the error color
And no second, differently colored focus ring is layered under or around it
Scenario: The theme select is right-aligned in the footer with no chevron
Given the user is on /login
When AuthShell's footer renders
Then the UColorModeSelect is the last (right-most) element in the footer's row
And it renders only its mode icon and label ("System", "Light" or "Dark")
And it renders no trailing chevron or dropdown-arrow icon
Scenario Outline: The alert renders inside the card, under the description
Given the user is redirected to <path>
When /login renders with its <state> alert
Then the alert is a child of the same card element that contains the title and description,
not a sibling positioned above the card
And the alert sits after the title/description block and before the Username field
And the alert's background uses UAlert's soft variant, which is dark-tinted automatically in
dark mode
Examples:
| path | state |
| /login?redirect=/article/12/edit&reason=expired | Session expired |
| /login?reason=password-changed | Password changed |
Scenario: The h1 is not focused on first load
Given the user navigates directly to /login (a fresh page load)
When AuthShell mounts and the h1 renders
Then the h1 does not receive focus
And focus remains on the document body (or wherever the browser places it on load)
Scenario: Focus moves to the h1 only on an in-app navigation between public screens
Given the user is on /login with AuthShell already mounted
When the user follows the "Forgot password?" link to /register/reset/request without a full
page reload
Then AuthShell's h1 receives focus once ResetRequestPage's title renders
And the h1 shows no visible outline when it receives this focus
+59
View File
@@ -0,0 +1,59 @@
# QA: Log-in card sizing, alert placement and focus behavior match the Auth board
## Automated (Vitest + Vue Test Utils, `task test:web`)
Mount AuthShell/LoginView directly; mock `useApi` (`GET /v1/auth/registration`,
`POST /v1/auth/login`) only as scaffolding, per features/login_screen.qa.md's setup.
1. **Card padding and control heights at sm+** — mount at a `>= 640px` viewport; assert the
card's own padding is 40px on every side (not Nuxt UI's untouched default); assert Username,
Password and the submit button each render at a computed height of 40px; assert input font-size
is 14px.
2. **Card padding and control heights below sm** — mount at a `< 640px` viewport; assert the
card's padding is 8px top / 20px sides / 0 bottom; assert the footer's own padding is 0 top /
20px sides / 24px bottom; assert Username, Password and the submit button are each 44px tall;
assert input font-size is 16px.
3. **"Forgot password?" styling** — assert the link's computed color equals `--ui-text-toned`,
`text-decoration-line: underline`, `text-underline-offset: 3px`, and that it carries no bold
weight or primary-color class.
4. **Field error icon and no stacked halo** — trigger the Validation errors state; assert each
field's error text is preceded by an `i-lucide-circle-alert` icon in the error color; then
focus the still-errored Username input and assert only one ring class (the error ring) is
present — the neutral/primary focus ring class is absent, not merely visually covered.
5. **Theme select has no chevron, is footer-last** — assert `UColorModeSelect` is the last child
of the footer's flex row; assert no chevron-down icon element renders inside it.
6. **Alert renders inside the card** — mount at `/login?reason=expired` and separately at
`/login?reason=password-changed`; assert the alert element's closest UPageCard/card ancestor is
the same element that contains the h1 (i.e., the alert is NOT a sibling before the card);
assert its DOM position is after the title/description block and before the Username field.
7. **h1 not focused on first load** — mount LoginView fresh (simulating first paint); assert
`document.activeElement` is not the h1.
8. **h1 focus on in-app navigation only** — mount AuthShell at /login, then update the `title`
prop the way an in-app route change to /register/reset/request would (per the existing `watch`
on `props.title`); assert the h1 now has focus.
## Visual (manual verification — `task visual:check -- log-in`, desktop and mobile, light and dark)
Reference: `docs/design/source/AuthCard.dc.html` via `RenewCMS Screens Auth.dc.html`, group
"Log in", all 9 states.
- [ ] Card padding is 40px on every side at desktop, and 8px/20px/0 (card) + 0/20px/24px
(footer) below sm, across all 9 states.
- [ ] Username, Password and the submit button are 40px tall at desktop and 44px below sm.
- [ ] "Forgot password?" is muted and underlined in every state that shows it.
- [ ] In the Validation errors state, both fields show the circle-alert icon and exactly one
ring around the field (no double ring), light and dark.
- [ ] The theme select shows icon + label only, no chevron, right-aligned in the footer.
- [ ] In Session expired and Password changed, the alert sits inside the card, under the
description, above the Username field, and is visibly dark-tinted (not a light-mode
background) in dark mode.
- [ ] Keyboard/focus: on a fresh /login load, nothing is auto-focused to the h1 (initial focus
stays with the browser/body); following "Forgot password?" to the reset-request screen moves
focus to that screen's h1, with no visible outline ring at any point.
## Manual verification
- **AppLogo edge in dark mode** — resolved by the amended
features/auth_shell_login_conformance.feature: AppLogo shows no edge stroke in either light or
dark mode, per AuthCard.dc.html's literal `edge: 'transparent'`. No check needed here; see that
feature's own QA file for the AppLogo assertions.