Skip to content

Commit 3e35a9b

Browse files
test: add E2E tests for responsive sidebar behavior (#226) (#233)
Co-authored-by: Ona <no-reply@ona.com>
1 parent 27ca5f9 commit 3e35a9b

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

e2e/sidebar-responsive.spec.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { test, expect } from "./fixtures/auth";
2+
3+
const MOBILE_VIEWPORT = { width: 375, height: 667 };
4+
const DESKTOP_VIEWPORT = { width: 1280, height: 720 };
5+
6+
test.describe("Responsive sidebar behavior", () => {
7+
test("mobile: sidebar is hidden by default and opens as a Sheet overlay", async ({
8+
authenticatedPage: page,
9+
}) => {
10+
await page.setViewportSize(MOBILE_VIEWPORT);
11+
12+
// Wait for the app to settle after viewport change
13+
await page.waitForTimeout(500);
14+
15+
// Desktop aside should not be visible at mobile viewport
16+
const aside = page.locator("aside");
17+
await expect(aside).toHaveCount(0);
18+
19+
// The Sheet content should not be visible initially
20+
const sheetContent = page.locator('[data-slot="sheet-content"]');
21+
await expect(sheetContent).toBeHidden();
22+
23+
// Mobile header with hamburger button should be visible
24+
const toggleButton = page.getByRole("button", { name: "Toggle sidebar" });
25+
await expect(toggleButton).toBeVisible({ timeout: 5_000 });
26+
27+
// Click the hamburger to open the Sheet sidebar
28+
await toggleButton.click();
29+
30+
// Sheet overlay and content should now be visible
31+
await expect(sheetContent).toBeVisible({ timeout: 5_000 });
32+
expect(await sheetContent.getAttribute("data-side")).toBe("left");
33+
34+
// Verify the Sheet rendered with sidebar structure
35+
const sidebarContent = sheetContent.locator("div").first();
36+
await expect(sidebarContent).toBeVisible();
37+
});
38+
39+
test("desktop: sidebar is visible as a persistent aside", async ({
40+
authenticatedPage: page,
41+
}) => {
42+
await page.setViewportSize(DESKTOP_VIEWPORT);
43+
44+
// Wait for the app to settle after viewport change
45+
await page.waitForTimeout(500);
46+
47+
// Desktop aside should be visible
48+
const aside = page.locator("aside");
49+
await expect(aside).toBeVisible({ timeout: 5_000 });
50+
51+
// Aside should have non-zero width (open state = 240px)
52+
const box = await aside.boundingBox();
53+
expect(box).not.toBeNull();
54+
expect(box!.width).toBeGreaterThan(0);
55+
56+
// The mobile hamburger toggle should NOT be visible on desktop
57+
const toggleButton = page.getByRole("button", { name: "Toggle sidebar" });
58+
await expect(toggleButton).toBeHidden();
59+
60+
// Sheet overlay should not be present
61+
const sheetContent = page.locator('[data-slot="sheet-content"]');
62+
await expect(sheetContent).toBeHidden();
63+
});
64+
65+
test("keyboard shortcut Ctrl+\\ toggles sidebar visibility on desktop", async ({
66+
authenticatedPage: page,
67+
}) => {
68+
await page.setViewportSize(DESKTOP_VIEWPORT);
69+
await page.waitForTimeout(500);
70+
71+
// Sidebar should be open initially
72+
const aside = page.locator("aside");
73+
await expect(aside).toBeVisible({ timeout: 5_000 });
74+
75+
const initialBox = await aside.boundingBox();
76+
expect(initialBox).not.toBeNull();
77+
expect(initialBox!.width).toBeGreaterThan(0);
78+
79+
// Press Ctrl+\ to close the sidebar
80+
await page.keyboard.press("Control+\\");
81+
82+
// Wait for the CSS transition (duration-200) to complete
83+
await expect(async () => {
84+
const box = await aside.boundingBox();
85+
expect(box).not.toBeNull();
86+
expect(box!.width).toBeLessThanOrEqual(1);
87+
}).toPass({ timeout: 3_000 });
88+
89+
// Press Ctrl+\ again to reopen
90+
await page.keyboard.press("Control+\\");
91+
92+
// Wait for the sidebar to expand back
93+
await expect(async () => {
94+
const box = await aside.boundingBox();
95+
expect(box).not.toBeNull();
96+
expect(box!.width).toBeGreaterThan(100);
97+
}).toPass({ timeout: 3_000 });
98+
});
99+
});

0 commit comments

Comments
 (0)