kammer/e2e/support/layout.ts
Christopher Mühl 307ef24b78 test: E2E test suite + handoff documentation
50 Playwright E2E tests across 13 spec files covering all routes and
user flows (items CRUD, check-out/in, locations, labels, scanning,
search/filter). Uses vitest as runner with playwright-core for browser
automation (bun-compatible alternative to @playwright/test).

Includes Gherkin .feature files as living documentation, test support
infrastructure (IDB seeding, item factories, assertion helpers, layout
measurement), and HANDOFF.md covering project state, deployment, and
open design decisions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:53:08 +01:00

53 lines
1.8 KiB
TypeScript

import type { Locator, Page } from 'playwright-core';
import { expect } from 'vitest';
/**
* Assert that an element meets the minimum touch target size (44x44px per WCAG).
*/
export async function assertMinTouchTarget(locator: Locator, minSize = 44) {
const box = await locator.boundingBox();
expect(box, 'Element must be visible and have a bounding box').toBeTruthy();
expect(box!.width).toBeGreaterThanOrEqual(minSize);
expect(box!.height).toBeGreaterThanOrEqual(minSize);
}
/**
* Assert the gap between two elements in a given direction.
*/
export async function assertGapBetween(
locatorA: Locator,
locatorB: Locator,
options: { min?: number; max?: number; direction?: 'vertical' | 'horizontal' },
) {
const { min = 0, max = Infinity, direction = 'vertical' } = options;
const boxA = await locatorA.boundingBox();
const boxB = await locatorB.boundingBox();
expect(boxA, 'Element A must be visible').toBeTruthy();
expect(boxB, 'Element B must be visible').toBeTruthy();
let gap: number;
if (direction === 'vertical') {
gap = boxB!.y - (boxA!.y + boxA!.height);
} else {
gap = boxB!.x - (boxA!.x + boxA!.width);
}
expect(gap).toBeGreaterThanOrEqual(min);
expect(gap).toBeLessThanOrEqual(max);
}
/**
* Assert that an element is fully within the viewport (not clipped).
*/
export async function assertWithinViewport(locator: Locator, page: Page) {
const box = await locator.boundingBox();
expect(box, 'Element must be visible').toBeTruthy();
const viewport = page.viewportSize();
expect(viewport, 'Page must have a viewport').toBeTruthy();
expect(box!.x).toBeGreaterThanOrEqual(0);
expect(box!.y).toBeGreaterThanOrEqual(0);
expect(box!.x + box!.width).toBeLessThanOrEqual(viewport!.width);
expect(box!.y + box!.height).toBeLessThanOrEqual(viewport!.height);
}