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>
53 lines
1.8 KiB
TypeScript
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);
|
|
}
|