diff --git a/tests/mobile-admin/orders-list.spec.ts b/tests/mobile-admin/orders-list.spec.ts new file mode 100644 index 0000000..5def7b7 --- /dev/null +++ b/tests/mobile-admin/orders-list.spec.ts @@ -0,0 +1,42 @@ +// tests/mobile-admin/orders-list.spec.ts +import { test, expect } from "@playwright/test"; + +test.use({ viewport: { width: 390, height: 844 } }); // iPhone 13 + +test.beforeEach(async ({ page }) => { + // Sign in as a test admin (requires the seed admin from db/seed.ts). + // The mobile-admin project assumes `test-admin@example.com / + // test-password` is provisioned. If this isn't the case locally, run + // `npm run db:seed` first. + await page.goto("/login"); + await page.fill('input[name="email"]', "test-admin@example.com"); + await page.fill('input[name="password"]', "test-password"); + await page.click('button[type="submit"]'); + await page.waitForURL(/\/admin/); +}); + +test("orders list renders without horizontal scroll on iPhone 13", async ({ page }) => { + await page.goto("/admin/v2/orders"); + const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth); + const clientWidth = await page.evaluate(() => document.documentElement.clientWidth); + expect(scrollWidth).toBeLessThanOrEqual(clientWidth); +}); + +test("orders list has no touch targets smaller than 48pt", async ({ page }) => { + await page.goto("/admin/v2/orders"); + const violations = await page.evaluate(() => { + const interactive = document.querySelectorAll("a, button, input, select, textarea, [role='button']"); + const small: string[] = []; + interactive.forEach((el) => { + const rect = el.getBoundingClientRect(); + if (rect.width > 0 && rect.height > 0 && (rect.height < 48 || rect.width < 48)) { + small.push(`${el.tagName}.${(el as HTMLElement).className}: ${rect.width}x${rect.height}`); + } + }); + return small; + }); + expect( + violations, + `Found ${violations.length} small touch targets: ${violations.join(", ")}`, + ).toHaveLength(0); +});