# QA: Articles page-size memory (SPA) No Go or HTTP test applies: nothing outside web/ changes. ## Automated (Vitest, task test:web) Extend or sit beside web/src/views/__tests__/ArticlesPagination.spec.ts and reuse articleEnvelope.ts for the mocked GET /v1/article/ envelope (total 312, size from the query). localStorage.clear() in beforeEach; fresh router per test. Assert on the mocked request query string, the select label, the router URL and localStorage. 1. Choosing 5 / 25 / 50 / 100 writes "5" / "25" / "50" / "100" under renewcms-page-size-articles; URLs /article?size=5, /article, ?size=50, ?size=100. 2. Stored "5", open /article: request carries size=5 and page=1, select reads "5 per page", URL replaced (router.replace, no history entry added) with ?size=5. 3. Choose 5, navigate to another route and back (mount again): size=5 requested. 4. Choose 5, remount the app on /article and on /article?size=5 (simulated refresh): size=5 requested. 5. Stored "50", on ?size=50: Next, Drafts tab, sort Title, search "plaster" (fake timers for the 120 ms debounce, not the system date): every request has size=50, stored value unchanged. 6. Stored "5", choose 100: stored "100"; remount sends size=100. 7. Stored "5", choose 25: stored "25"; remount sends size=25, URL /article. 8. Stored "5", open /article?size=100: size=100 requested, stored still "5"; remount on /article sends size=5. 9. Stored "5", open /article?page=3: request page=3&size=5, URL replaced by ?page=3&size=5. 10. Invalid stored values 10, abc, 0, -5, 25.5, "": size=25 requested, select "25 per page", URL /article. 11. Stored "5", open /article?size=10: size=25 requested, URL /article, stored still "5". 12. Storage failures (Storage.prototype.getItem throwing; setItem throwing; window.localStorage undefined): no exception, list renders, size=25 on load, choosing 50 requests size=50 and URL ?size=50. 13. Logout (session store reset) leaves the stored value; the next /article sends size=5. 14. Unit tests for any read/write helper added next to web/src/lib/pagination.ts: valid values accepted, invalid rejected, errors swallowed. ## Visual (task visual:check -- articles) No visual change is intended. Run the full articles group as a regression and require every capture within 10 %. Setups use the board's own sample data and must not depend on a stored size. Clear localStorage before each capture so a leftover value cannot change the default 25 frame. No state is clock-sensitive for this slice. ## Manual - In a real browser, choose 5 per page, navigate away and back, then hard-refresh: it stays at 5. - Private-window or storage-blocked browser: the list still works at 25 with no error. - Keyboard: the page-size select behaves as before (ArrowDown, Enter, Esc, focus ring), and focus returns to the select after choosing. - Open a copied /article?size=100 link in a profile that has 5 stored: the link shows 100 and the next plain visit shows 5.