Files
RenewCMS/features/dashboard_shell_branding.qa.md

4.6 KiB

QA: DashboardShell branding (wordmark, sidebar collapse, UserMenu)

Automated (Vitest + Vue Test Utils, task test:web)

Mount DashboardShell (or a verified route rendered inside it) with a resolved session (username "marta") and a test router. Mock useApi's /v1/auth/logout call per case; no real backend, no httptest server. Stub useColorMode() so its preference can be asserted and set.

  1. Header renders AppLogo and the wordmark — mount DashboardShell expanded; assert the sidebar's #header slot renders an AppLogo followed by the text "RenewCMS"; assert neither is a link.
  2. Sidebar collapse trigger toggles the rail and aria-expanded — mount DashboardShell expanded; activate UDashboardSidebarCollapse; assert the sidebar reaches its :collapsed-size="3.5" state and the trigger's aria-expanded reflects it; activate it again; assert the sidebar returns to :default-size="14" and aria-expanded flips back.
  3. UserMenu dropdown groups and order — mount with username "marta" and useColorMode().preference set to each of "system", "light", "dark" in turn; open the UserMenu dropdown; assert the avatar shows initials "MA"; assert the trigger shows "marta"; assert the first group is the account label "marta"; assert the second group has System, Light and Dark checkbox items with exactly the current preference's item checked; assert the third, separate group contains only "Log out".
  4. Selecting a color-mode item updates the preference — Examples-driven: (system → light), (light → dark), (dark → system). Open the dropdown, activate the target item, assert useColorMode().preference is set to the target and its checkbox item is checked while the previous one is not.
  5. Successful logout clears the session and navigates — mock POST /v1/auth/logout resolving 200; open the UserMenu dropdown; activate "Log out"; assert the mock was called; assert the session store's clear() is called once it resolves; assert the router navigates to /login.
  6. Collapsed sidebar hides wordmark/username text but keeps an accessible name — mount DashboardShell and collapse the sidebar to :collapsed-size="3.5"; assert the AppLogo icon is still present but the "RenewCMS" text node is not rendered (or is visually hidden, e.g. sr-only) while an accessible name for the logo (aria-label or sr-only text reading "RenewCMS") is still present in the accessibility tree; assert the UserMenu trigger still renders the UAvatar but not the visible "marta" text node, while the trigger's accessible name still includes "marta" (via aria-label or a tooltip plus aria-label); activate the collapsed trigger and assert the same dropdown (account label, color-mode group, Log out) opens as in the expanded state.

Visual (manual verification — desktop and mobile, light and dark)

Reference: docs/design/components.md's DashboardShell section and docs/design/source/RenewCMS Screens Back-office.dc.html. Run task visual:check -- <a verified screen, e.g. home> for each state and compare the sidebar header/footer against the board frame.

  • Expanded sidebar: AppLogo plus "RenewCMS" wordmark in the header; UserMenu in the footer shows the avatar and username, matching the board exactly at desktop and mobile.
  • UserMenu dropdown: opens above the trigger (side: 'top'), left-aligned (align: 'start'), with the account label, the System/Light/Dark checkbox group and Log out visually separated as in the board.
  • Color mode selection: choosing Light/Dark/System visibly re-themes the app and moves the checkmark to the selected item.
  • Collapsed sidebar (icon-only rail): the AppLogo icon and the avatar remain visible; the "RenewCMS" wordmark and the username text are hidden; nothing overflows or clips awkwardly at the :collapsed-size="3.5" width, matching the board's collapsed rail treatment.
  • Keyboard/focus: Tab reaches UDashboardSidebarCollapse, then the UserMenu trigger; the dropdown opens with Enter/Space, arrow keys move through the checkbox group, and Esc closes it and returns focus to the trigger, in both the expanded and collapsed rail.

Manual verification

  • Real POST /v1/auth/logout against a running server — Vitest only mocks useApi; confirm the real 200 round-trip against task dev with a live SQLite file, since these automated tests never exercise the actual Go handler.
  • Real useColorMode persistence across reload — confirm a selected preference survives a full page reload via the plugin's colorMode: true storage, since Vitest only asserts the in-memory preference value.