Phase 14: desktop e2e coverage (add blocking Desktop Chrome Playwright gate) #10

Merged
luckberg merged 14 commits from gsd/phase-14-desktop-e2e-coverage into main 2026-06-12 09:32:27 -04:00
Showing only changes of commit f75bc4239f - Show all commits
+26 -7
View File
@@ -60,8 +60,13 @@ test.describe('Rule 1/3/4 — BottomTabBar tap targets and in-viewport position'
expect(box!.height, 'Lists tab height ≥ 44px').toBeGreaterThanOrEqual(44);
});
test('BottomTabBar is fully in-viewport (Rule 3 — safe-area-inset)', async ({ page }, testInfo) => {
test.skip(testInfo.project.name === 'desktop', 'On desktop the Main navigation landmark resolves to the DesktopNav sidebar; the safe-area-inset bottom-edge assertion is semantically wrong for a sidebar (BottomTabBar returns null at ≥768px)');
test('BottomTabBar is fully in-viewport (Rule 3 — safe-area-inset)', async ({
page,
}, testInfo) => {
test.skip(
testInfo.project.name === 'desktop',
'On desktop the Main navigation landmark resolves to the DesktopNav sidebar; the safe-area-inset bottom-edge assertion is semantically wrong for a sidebar (BottomTabBar returns null at ≥768px)',
);
// The bar uses env(safe-area-inset-bottom, 0px). In emulation there is no
// safe-area-inset, so the bar's bottom edge must be ≤ viewport height.
const nav = page.getByRole('navigation', { name: 'Main navigation' });
@@ -91,7 +96,10 @@ test.describe('Rule 1/3/4 — BottomTabBar tap targets and in-viewport position'
});
test('New Event FAB meets 56×56px touch-target minimum (Rule 1)', async ({ page }, testInfo) => {
test.skip(testInfo.project.name === 'desktop', 'On desktop getByRole(button, New Event) resolves to the toolbar button (CalendarShell.tsx:436-457), not the 56×56 FAB; FAB geometry assertion does not apply to the toolbar button');
test.skip(
testInfo.project.name === 'desktop',
'On desktop getByRole(button, New Event) resolves to the toolbar button (CalendarShell.tsx:436-457), not the 56×56 FAB; FAB geometry assertion does not apply to the toolbar button',
);
// Phone-only FAB — aria-label="New Event", fixed 56×56px (CalendarShell.tsx)
const fab = page.getByRole('button', { name: 'New Event' });
const box = await fab.boundingBox();
@@ -103,12 +111,20 @@ test.describe('Rule 1/3/4 — BottomTabBar tap targets and in-viewport position'
// D-04 parity: desktop toolbar "New Event" button meets ≥44px minimum (Rule 1)
// CalendarShell.tsx:443 sets minHeight:'44px' on the desktop toolbar button.
// Guarded to run only on desktop — the FAB test above covers mobile profiles.
test('New Event toolbar button meets 44px touch-target minimum on desktop (Rule 1 — D-04 parity)', async ({ page }, testInfo) => {
test.skip(testInfo.project.name !== 'desktop', 'Desktop parity assertion — toolbar button only renders at ≥768px (Desktop Chrome); FAB test covers iphone/pixel');
test('New Event toolbar button meets 44px touch-target minimum on desktop (Rule 1 — D-04 parity)', async ({
page,
}, testInfo) => {
test.skip(
testInfo.project.name !== 'desktop',
'Desktop parity assertion — toolbar button only renders at ≥768px (Desktop Chrome); FAB test covers iphone/pixel',
);
const toolbarBtn = page.getByRole('button', { name: 'New Event' });
const box = await toolbarBtn.boundingBox();
expect(box, 'New Event toolbar button bounding box must not be null').not.toBeNull();
expect(box!.height, 'New Event toolbar button height ≥ 44px (Rule 1 desktop parity)').toBeGreaterThanOrEqual(44);
expect(
box!.height,
'New Event toolbar button height ≥ 44px (Rule 1 desktop parity)',
).toBeGreaterThanOrEqual(44);
});
});
@@ -142,7 +158,10 @@ test.describe('Rule 1/3/4 — BottomTabBar on /lists', () => {
});
test('BottomTabBar is fully in-viewport on /lists (Rule 3)', async ({ page }, testInfo) => {
test.skip(testInfo.project.name === 'desktop', 'On desktop the Main navigation landmark resolves to the DesktopNav sidebar; the safe-area-inset bottom-edge assertion is semantically wrong for a sidebar (BottomTabBar returns null at ≥768px)');
test.skip(
testInfo.project.name === 'desktop',
'On desktop the Main navigation landmark resolves to the DesktopNav sidebar; the safe-area-inset bottom-edge assertion is semantically wrong for a sidebar (BottomTabBar returns null at ≥768px)',
);
const nav = page.getByRole('navigation', { name: 'Main navigation' });
await expect(nav).toBeVisible();
const box = await nav.boundingBox();