M1-4: Length axis (TDD)
- Add axis.js: length axis rectangle state, 28 tests - 71/71 unit tests green
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
// M1-4: Playwright tests for the Length axis state.
|
||||
// RED first — the live UI lands in M1-5. These tests describe the
|
||||
// contract the UI must honour once the Mask state approves.
|
||||
//
|
||||
// Spec ground truth (docs/CAPTURE.md §Length axis):
|
||||
// - min-area bounding rectangle of the mask
|
||||
// - length axis on the long side of that rectangle
|
||||
// - user rotates the axis if it does not follow the slab length
|
||||
// - approve the axis
|
||||
|
||||
const SLAB_FIXTURE = 'tests/fixtures/slab-green.jpg';
|
||||
|
||||
test.describe('Length axis state (M1-5 live UI)', () => {
|
||||
test('advances to Length axis after approving the mask', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.locator('input[type="file"]').setInputFiles(SLAB_FIXTURE);
|
||||
// Wait for the initial mask recompute.
|
||||
await page.waitForTimeout(2200);
|
||||
// Approve the mask.
|
||||
await page.getByRole('button', { name: /approve/i }).tap();
|
||||
// The Length axis state is now visible.
|
||||
await expect(page.getByText(/length axis/i)).toBeVisible();
|
||||
});
|
||||
|
||||
test('shows the bounding rectangle and the proposed length axis', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto('/');
|
||||
await page.locator('input[type="file"]').setInputFiles(SLAB_FIXTURE);
|
||||
await page.waitForTimeout(2200);
|
||||
await page.getByRole('button', { name: /approve/i }).tap();
|
||||
// The bounding rectangle is drawn on the photo.
|
||||
await expect(
|
||||
page.locator('[data-testid="bounding-rect"]'),
|
||||
).toBeVisible();
|
||||
// The proposed length axis is drawn along the long side.
|
||||
await expect(
|
||||
page.locator('[data-testid="length-axis"]'),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test('rotate control adjusts the axis', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.locator('input[type="file"]').setInputFiles(SLAB_FIXTURE);
|
||||
await page.waitForTimeout(2200);
|
||||
await page.getByRole('button', { name: /approve/i }).tap();
|
||||
// The rotate control is present.
|
||||
const rotate = page.getByRole('slider', { name: /rotate axis/i });
|
||||
await expect(rotate).toBeVisible();
|
||||
// Rotating changes the axis angle.
|
||||
const before = await page
|
||||
.locator('[data-testid="length-axis"]')
|
||||
.getAttribute('data-angle');
|
||||
await rotate.fill('90');
|
||||
const after = await page
|
||||
.locator('[data-testid="length-axis"]')
|
||||
.getAttribute('data-angle');
|
||||
expect(before).not.toBe(after);
|
||||
});
|
||||
|
||||
test('approve the axis advances to Measure', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.locator('input[type="file"]').setInputFiles(SLAB_FIXTURE);
|
||||
await page.waitForTimeout(2200);
|
||||
// Approve the mask -> Length axis.
|
||||
await page.getByRole('button', { name: /approve/i }).tap();
|
||||
// Approve the axis -> Measure.
|
||||
const approveAxis = page.getByRole('button', {
|
||||
name: /approve axis/i,
|
||||
});
|
||||
await expect(approveAxis).toBeVisible();
|
||||
await approveAxis.tap();
|
||||
await expect(page.getByText(/measure/i)).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user