6.4 KiB
QA: AuthShell and log-in screen conform to the design spec
Automated (Vitest + Vue Test Utils, task test:web)
No /v1 calls are relevant to these assertions; mount AuthShell and LoginView directly (LoginView
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).
- 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, withrole="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.darkclass the waynuxt_ui_shell_foundation's color-mode tests do) and assert the outer square still has no stroke, perdocs/design/source/AuthCard.dc.html's literal, non-theme-branchededge: 'transparent'. - 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 description text "Welcome back. Log in to manage your articles." renders via UPageCard'sdescriptionprop (not as a sibling<p>hand-authored in AuthShell's template). This replaces the older assertion inAuthShell.spec.tsthat only checked for any<h1>; keep that assertion passing (h1 text still equals the title) while adding the tabindex check. - Muted background at sm and up — mount AuthShell at a
>= 640pxviewport (mockuseBreakpoints/matchMedia the way other shell tests do); assert<main>'s class list includes the muted background utility (e.g.bg-muted); assert the card renders with a border and is capped at 400px width, offset 12vh from the top. - Default background, borderless card, 20px padding, xl controls below sm — mount AuthShell
at a
< 640pxviewport; assert<main>'s class list includes the default background utility (bg-default) and not the muted one; assert the card has no border class; assert the card's padding is 20px; assert the Username/Password inputs and submit button render atsize="xl". - Login form is a UForm — mount LoginView at /login; assert the form wrapping the fields is
a UForm component instance, not a bare
<form>element with only@submit.preventwired by hand. - Forgot password in the #hint slot — mount LoginView at /login; assert the Password
UFormField is passed content (or renders content) in its
hintslot containing a "Forgot password?" link to /register/reset/request; assert the field's rendered label text is exactly "Password" with no link inside it. - Inputs default to neutral, then highlight red on error — mount LoginView at /login; assert
the Username and Password
UInputcomponents render withhighlightfalsy (or absent) and the theme's default ring class (ring-(--ui-border-accented)); then trigger the Validation errors state (type "ma" into Username, submit with Password empty); assert bothUInputs now receive:highlight="true"(or the field's error is otherwise truthy) so the edge renders in--ui-error, alongside "Use at least 3 characters." and "Enter your password." respectively.
Implementation finding for coder
web/src/views/LoginView.vue's Username and Password UInputs currently receive no :highlight
prop at all — UFormField gets :error="usernameError" / :error="passwordError", but that value
is never forwarded to the inner UInput. Today the edge never turns red in the Validation errors
state; this isn't a stale/inverted binding, it's a missing one. Wiring :highlight="!!usernameError"
/ :highlight="!!passwordError" (or equivalent) onto each UInput is the fix scenario 7 above
pins down.
Visual (manual verification — desktop and mobile, light and dark)
Reference: docs/design/source/RenewCMS Screens Auth.dc.html, group "Log in", plus
docs/design/source/RenewCMS Components Product.dc.html's AuthShell drawing and
docs/design/source/RenewCMS Components Primitives.dc.html's Input drawing.
- 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; 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.
- At sm and up: 400px card with its border, 12vh top offset, on the muted page canvas, light and dark.
- Below sm: card fills the screen borderless with 20px padding on the default (not muted) background; fields and the submit button render at the touch (xl, 44px) size, light and dark.
- The Password field's "Forgot password?" link sits right-aligned on the label row (the hint position), matching the Auth board, desktop and mobile, light and dark.
- Username and Password fields show the neutral control-edge border by default; in the Validation errors state (short username, empty password) both fields' edges turn to the error color alongside their messages, in both light and dark.
- Keyboard/focus: Tab order remains Username → Password → show/hide toggle → "Forgot password?" → submit; UPageCard's h1 is reachable/focusable via tabindex="-1" on route change, matching AuthShell's existing a11y spec.
Manual verification
- AppLogo reused in DashboardShell — out of scope for this slice (AuthShell/login only).
DashboardShell.vue's sidebar header is currently a plain<span class="font-semibold"> RenewCMS</span>(not AppLogo), and its footer is a bare<span>Log out</span>instead of the UserMenu component components.md specifies. Both need their own "Built from" conformance pass in a later DashboardShell slice; AppLogo (built here with asizeprop) will be ready to drop in at that point without changes.