Files
RenewCMS/features/articles_pagination_screen.qa.md
T

43 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QA: Articles list pagination (SPA)
## Automated (Vitest + Vue Test Utils, `task test:web`)
Mock `useApi` for `GET /v1/article/?format=html&...` (the route key includes the query) per case. Mount ArticlesPage inside DashboardShell with a verified session and a test router at /article, as in features/articles_list.qa.md. The fixture is 312 articles at 25 per page, built by a helper, with counts {all, online, draft}. No system date freezing.
1. First page: no page/size in the URL, "Showing 1–25 of 312", First/Previous disabled, page 1 aria-current.
2. Middle page: ?page=7 -> "Showing 151–175 of 312", aria-current on 7, ellipsis present.
3. Last page: ?page=13 -> "Showing 301–312 of 312", Next/Last disabled.
4. Single page: total 6 -> no paginator nav, summary "Showing 1–6 of 6", select present, tabs "All 6" "Online 4" "Drafts 2".
5. Loading next page: unresolved page-2 promise -> skeleton rows, aria-busy, controls disabled, "Loading page 2…"; resolve -> rows, URL ?page=2 (URL unchanged before the response).
6. Error (500 and network rejection): rows and URL (?page=6) kept, notice "Couldn't load page 7. Showing page 6.", Retry resends page 7, success clears the notice and sets ?page=7.
7. Out of range: ?page=99 returns {items:[], total:312} -> router.replace to ?page=13 (assert no extra history entry), second request page=13, notice text. 7b: total 0 -> empty state, no redirect.
8. Search resets: from ?page=7 type "plaster" (fake timers past 120 ms) -> request q=plaster&page=1, URL /article?q=plaster after the response, tab counts unchanged. Same assertion for tab, sort (request sort=title:asc&page=1) and size.
8a. Sort headers: for Title, Status, Created, Updated, a first click sends sort=<field>:asc&page=1, the URL becomes /article?sort=<field>:asc only after the response, the arrow icon shows and counts are unchanged.
8b. A second click toggles to desc; returning to updated_at:desc drops sort from the URL.
8c. Sort kept across Next, size change and search.
8d. A sorted URL on load (?sort=created_at:desc&page=2) sends it and shows the Created arrow-down; an invalid ?sort=body:asc sends no sort and the URL is replaced by /article.
8e. No client-side re-sorting: with the mock returning rows in a fixed order, the table shows exactly that order whatever the sorting state.
8f. Caption: default "Articles, sorted by last updated, newest first"; sorted by Title ascending "Articles, sorted by title, ascending"; French strings present.
8g. Mobile card list renders no sort control.
9. Empty after search: paginator and summary absent, copy and "Clear search", tab counts unchanged.
10. Page-size menu: 5/25/50/100 -> request and URL; ArrowDown opens, Enter selects, Esc closes and restores focus. 10b: ?size=10&page=abc -> request page=1&size=25, URL replaced.
11. Focus-visible: the focus-ring tokens on every control (the pixel outline is a visual check).
12. Tabs on the server: Drafts -> status=draft&page=1, counts unchanged.
13. Mobile: below md, Previous / "Page 2 of 13" / Next, no numbers.
14. Delete last row of last page: reloads the previous page, counts refreshed.
15. HomeView, ArticleView and useArticles: with the envelope mocked, they render from `items`; no code path reads a bare array (a mocked bare array makes the test fail).
16. Existing specs amended: features/articles_list.qa.md items 1-18 (search and tab counts server-driven, `GET /v1/article/` mocked as the envelope), `web/src/i18n/spa.spec.ts` (mock around line 417), the ArticleTable specs that rely on client-side TanStack sorting, and the Home, ArticleView and Integration specs. List them in the diff.
## Visual (`task visual:check -- articles`)
Add a setup per state in `web/visual/states.ts`, reusing the board's own sample data from group "Articles: pagination" in `docs/design/source/RenewCMS Screens Back-office.dc.html` (total 312, size 25, titles from the frame script), at 1440x900 and 390x844, light and dark; every capture within 10 %. States: First page, Middle page, Last page, Single page, Loading next page, Error loading a page, Page out of range, Search resets to page 1, Empty after search, Page size menu, Focus-visible. A state whose frame shows relative dates ("2 hours ago") is `skip: 'clock-sensitive'`; confirm per frame when coding. Take layout (summary vs paginator vs select, select opening upward) from the frame markup, not from components.md prose. The Articles group's existing states are re-run, since the list now comes from the envelope.
## Manual
- Keyboard order and focus return (Tab path, Enter/Space, ArrowDown/Enter/Esc), hover and motion (the skeleton pulse stops under reduced motion).
- Keyboard activation (Enter/Space) of the sort headers and the screen-reader announcement of the sort direction (aria-sort).
- The sorted-header arrow is part of the existing Articles board states; if a frame lacks it, raise it with the user rather than inventing a state.
- Real round trip with `task dev`: page, size, q, status, total and counts from a live SQLite file; a reload keeps the URL state; browser Back after a size change.
- Out-of-range redirect against a real shrinking list (delete rows in another tab).
- Home and Article views against the real API after the envelope change.