fix(m4): keep tape calibration on one page (#99)

This commit is contained in:
Ty
2026-09-24 22:33:23 -07:00
parent 6000ac2b0f
commit 7908a99ec3
10 changed files with 335 additions and 247 deletions
+2 -2
View File
@@ -28,8 +28,8 @@ Fixtures: `tests/fixtures/set1-48x2/` (L=48, thickness=2) and `set2-31x2p5/` (L=
| `01-batch.png` | Batch with fixtures loaded |
| `02-pick-calibration.png` | Pick calibration |
| `03-mask.png` | Mask (Black sheet) ready to approve |
| `04-axis.png` | Length axis |
| `05-measure.png` | Measure with L / thickness filled |
| `04-axis.png` | Tape calibration page |
| `05-tape-calibration.png` | Length and thickness entered on the tape page |
| `06-photos-ready.png` | Photos ready lineup (clean + overlay + siblings) |
Large regenerating `*.png` and Playwright `test-results/` / `playwright-report/` are gitignored.
+1 -1
View File
@@ -1,5 +1,5 @@
// e2e helper: seed an in-progress device draft (stage='measure', with results) so
// the Resume path restores straight to the Photos-ready Measure step — the
// the Resume path restores straight to the Photos-ready result step — the
// deterministic driver for the create→review→publish flow (no live camera/canvas
// in e2e). The draft is written to the real idb-keyval DB ('keyval-store'/'keyval',
// key 'slabuploader-draft') exactly as `saveDraft` would, so `resumeProbe` +
+8 -12
View File
@@ -64,7 +64,7 @@ const prepareMaskForApprove = async (page: Page) => {
};
test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
test('batch → pick → mask → axis → measure → photos ready + screenshots', async ({ page }) => {
test('batch → pick → mask → tape calibration → photos ready + screenshots', async ({ page }) => {
test.setTimeout(180_000);
expect(fs.existsSync(FACE_A), 'fixture face-a').toBeTruthy();
expect(fs.existsSync(FACE_B), 'fixture face-b').toBeTruthy();
@@ -87,20 +87,16 @@ test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
await shot(page, '03-mask.png');
await page.getByRole('button', { name: 'Approve mask' }).click();
await expect(page.getByRole('heading', { name: 'Length axis' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Length' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Measure' })).toHaveCount(0);
await shot(page, '04-axis.png');
await page.getByRole('button', { name: 'Approve axis' }).click();
await expect(page.getByRole('heading', { name: 'Measure' })).toBeVisible();
await page.getByLabel('Length L').fill('48');
await page.getByLabel('Thickness').fill('2');
// blur/change commits eighths into session before Calculate.
await page.getByLabel('Length L').blur();
await page.getByLabel('Thickness').blur();
await shot(page, '05-measure.png');
const calc = page.getByRole('button', { name: 'Calculate' });
await expect(calc).toBeDisabled();
await page.getByLabel('Length L').fill('48');
await page.getByLabel('Thickness').fill('2');
await expect(calc).toBeEnabled();
await shot(page, '05-tape-calibration.png');
await calc.click();
// Calculate encodes calibration PNG + overlay + sibling batch apply.
@@ -117,7 +113,7 @@ test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
// Write a short run log for parent AI visual review (not a substitute for eyes).
const logPath = path.join(ARTIFACTS, 'run-log.txt');
const shots = ['01-batch.png', '02-pick-calibration.png', '03-mask.png', '04-axis.png', '05-measure.png', '06-photos-ready.png'];
const shots = ['01-batch.png', '02-pick-calibration.png', '03-mask.png', '04-axis.png', '05-tape-calibration.png', '06-photos-ready.png'];
const lines = [
`M2 #65 Playwright e2e — set1-48x2 (L=48, thickness=2)`,
`baseURL: ${page.url().split('/').slice(0, 3).join('/')}`,