Answer stability round 1: 0 🔴, 1 🟡 (0 misread); test the drawer opens and a link in it navigates, keep the in-flow sidebar from stretching
This commit is contained in:
@@ -148,6 +148,21 @@ test("mobile layout hides the sidebar off-canvas behind the hamburger", async ({
|
|||||||
expect(offCanvas).toBe(true);
|
expect(offCanvas).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("the hamburger opens the drawer over the scrim, and a link in it navigates", async ({ page }) => {
|
||||||
|
await page.setViewportSize({ width: 390, height: 844 });
|
||||||
|
await page.goto("/dashboard");
|
||||||
|
await page.locator(".hamburger").click();
|
||||||
|
|
||||||
|
const sidebar = page.locator(".sidebar");
|
||||||
|
await expect(sidebar).toBeInViewport({ ratio: 1 });
|
||||||
|
// A click is refused while the scrim sits above the drawer, which a lower z-index would cause.
|
||||||
|
await sidebar.locator("summary").first().click(); // the dashboard is the current page, so its links are in a folded branch
|
||||||
|
const link = sidebar.locator(".nav-children a.nav-self").first();
|
||||||
|
const target = await link.getAttribute("href");
|
||||||
|
await link.click();
|
||||||
|
await expect(page).toHaveURL((url) => url.pathname === target?.split("?")[0]);
|
||||||
|
});
|
||||||
|
|
||||||
test("Sign-out is a CSRF-guarded POST form: the token is issued on the page, a tokenless POST is refused", async ({ page }) => {
|
test("Sign-out is a CSRF-guarded POST form: the token is issued on the page, a tokenless POST is refused", async ({ page }) => {
|
||||||
await page.goto("/dashboard");
|
await page.goto("/dashboard");
|
||||||
// The page issues a CSRF cookie and embeds the same token in the Sign-out form (double-submit).
|
// The page issues a CSRF cookie and embeds the same token in the Sign-out form (double-submit).
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
App Shell Template — pure HTML/CSS, no JavaScript
|
App Shell Template — pure HTML/CSS, no JavaScript
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
Architecture
|
Architecture
|
||||||
- Design tokens are two raw palettes picked by a theme block, so
|
|
||||||
the theme follows the system by default and can be forced
|
|
||||||
Light / Dark via radio + :has().
|
|
||||||
- Everything is a reusable "block": .nav-item, .filter,
|
- Everything is a reusable "block": .nav-item, .filter,
|
||||||
.chip, .badge, .btn, .menu, .table — combine freely.
|
.chip, .badge, .btn, .menu, .table — combine freely.
|
||||||
============================================================= */
|
============================================================= */
|
||||||
@@ -682,13 +679,13 @@ th[aria-sort="descending"] .sort-ico { transform: rotate(180deg); }
|
|||||||
/* ---------- 11. RESPONSIVE / HAMBURGER --------------------- */
|
/* ---------- 11. RESPONSIVE / HAMBURGER --------------------- */
|
||||||
.scrim { display: none; }
|
.scrim { display: none; }
|
||||||
|
|
||||||
/* Off-canvas only where :has() works: without it nothing can read #nav-toggle, so the sidebar
|
|
||||||
stays in the flow above the content and the hamburger stays hidden. */
|
|
||||||
@media (max-width: 860px) {
|
@media (max-width: 860px) {
|
||||||
.app { grid-template-columns: minmax(0, 1fr); }
|
.app { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; }
|
||||||
.content { grid-column: 1; }
|
.content { grid-column: 1; grid-row: 2; }
|
||||||
.search { min-width: 150px; flex: 1 1 auto; }
|
.search { min-width: 150px; flex: 1 1 auto; }
|
||||||
|
|
||||||
|
/* Off-canvas only where :has() works: without it nothing can read #nav-toggle, so the sidebar
|
||||||
|
stays in the flow above the content and the hamburger stays hidden. */
|
||||||
@supports selector(:has(a)) {
|
@supports selector(:has(a)) {
|
||||||
.sidebar {
|
.sidebar {
|
||||||
position: fixed; inset: 0 auto 0 0; width: min(86vw, var(--nav-w));
|
position: fixed; inset: 0 auto 0 0; width: min(86vw, var(--nav-w));
|
||||||
|
|||||||
Reference in New Issue
Block a user