8749b07611
.preview was width:100% inside max-height:50vh container — tall photos were clipped. Now: max-width:100%, max-height:50vh, width/height auto, object-fit:contain, flex-centered in the wrap. Added e2e regression test: loads a photo, verifies the canvas bounding box fits the viewport, preserves aspect ratio, and is not clipped by the container.
46 lines
1.8 KiB
JavaScript
46 lines
1.8 KiB
JavaScript
import { test, expect } from '@playwright/test';
|
|
|
|
const SLAB_FIXTURE = 'tests/fixtures/slab-green.jpg';
|
|
|
|
// E2E smoke: the app serves and the health route responds.
|
|
test('M1-1 harness smoke: app serves + health ok', async ({ page, request }) => {
|
|
await page.goto('/');
|
|
await expect(page).toHaveTitle(/SlabUploader/);
|
|
const res = await request.get('/api/health');
|
|
expect(res.ok()).toBeTruthy();
|
|
const body = await res.json();
|
|
expect(body.ok).toBe(true);
|
|
});
|
|
|
|
// Regression: the preview canvas must fit the full photo within the
|
|
// viewport without cropping. Spec: "Preview fits the device width.
|
|
// Height is capped so Mask and Measure controls stay on screen."
|
|
test('preview canvas fits full photo without cropping', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.locator('input[type="file"]').setInputFiles(SLAB_FIXTURE);
|
|
await page.waitForTimeout(2500); // mask recompute
|
|
|
|
const canvas = page.locator('canvas.preview');
|
|
await expect(canvas).toBeVisible();
|
|
|
|
// Get the canvas's rendered (CSS) size and its intrinsic (pixel) size.
|
|
const box = await canvas.boundingBox();
|
|
const intrinsic = await canvas.evaluate((c) => ({ w: c.width, h: c.height }));
|
|
|
|
// The rendered size must fit within the viewport.
|
|
const vp = page.viewportSize();
|
|
expect(box.width).toBeLessThanOrEqual(vp.width);
|
|
expect(box.height).toBeLessThanOrEqual(vp.height * 0.55); // 50vh cap + tolerance
|
|
|
|
// Aspect ratio must be preserved (no distortion).
|
|
const renderedRatio = box.width / box.height;
|
|
const intrinsicRatio = intrinsic.w / intrinsic.h;
|
|
expect(renderedRatio).toBeCloseTo(intrinsicRatio, 1);
|
|
|
|
// The canvas must not be clipped by its container.
|
|
const wrap = page.locator('.preview-wrap');
|
|
const wrapBox = await wrap.boundingBox();
|
|
expect(box.width).toBeLessThanOrEqual(wrapBox.width + 1);
|
|
expect(box.height).toBeLessThanOrEqual(wrapBox.height + 1);
|
|
});
|