Files
RenewCMS/features/login_card_conformance.qa.md
T

4.0 KiB

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.