feat(ui): Jeff-facing copy + 3:4 inventory thumbs + fixed overlay font

Locked UI/copy pass on proto-per-user-woo-creds (Settings/Woo gate polish out of scope):
- Inventory PNG thumbs at 3:4 contain (Review, Publish preview, Photos ready); stop 1:1 cover squaring
- Dimension overlay labels fixed OVERLAY_FONT_PX=36 for every product
- Page 1–3 Jeff-plain copy; drop Measure red tech essays / px scale rows
- Review: lock SVG, consistent red missing/not-ready, View prompt gated (Settings default off)
This commit is contained in:
grokbot_ty
2026-09-27 09:04:47 -07:00
parent 14dcdc43e6
commit 20a7d7d9d5
21 changed files with 231 additions and 177 deletions
+10 -10
View File
@@ -22,7 +22,7 @@ const ensureFreshBatch = async (page: Page) => {
await page.goto('/');
// resumeProbe is async onMount — wait for either Resume or Batch.
const resumeHeading = page.getByRole('heading', { name: /resume/i });
const batchHeading = page.getByRole('heading', { name: 'Batch photos' });
const batchHeading = page.getByRole('heading', { name: 'Add slab photos' });
await expect(resumeHeading.or(batchHeading)).toBeVisible({ timeout: 15_000 });
if (await resumeHeading.isVisible().catch(() => false)) {
await page.getByRole('button', { name: /start fresh/i }).click();
@@ -74,8 +74,8 @@ test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
// Gallery multi-input (not the capture=environment camera input).
const gallery = page.locator('input[type="file"][multiple]');
await gallery.setInputFiles([FACE_A, FACE_B]);
await expect(page.getByAltText('Batch photo 1')).toBeVisible({ timeout: 30_000 });
await expect(page.getByAltText('Batch photo 2')).toBeVisible();
await expect(page.getByAltText('Photo 1')).toBeVisible({ timeout: 30_000 });
await expect(page.getByAltText('Photo 2')).toBeVisible();
await shot(page, '01-batch.png');
await page.getByRole('button', { name: 'Continue' }).click();
@@ -89,10 +89,10 @@ test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
await expect(page.getByRole('heading', { name: 'Measure' })).toBeVisible();
await shot(page, '04-tape-measure.png');
await page.getByLabel('Length L').fill('48');
await page.getByLabel('Length (in)').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('Length (in)').blur();
await page.getByLabel('Thickness').blur();
await shot(page, '05-measure.png');
@@ -105,10 +105,10 @@ test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
timeout: 120_000,
});
await expect(page.getByLabel('Photos ready')).toBeVisible();
await expect(page.getByText('Clean calibration')).toBeVisible();
await expect(page.getByText('Dimension overlay')).toBeVisible();
// Sibling face-b should appear as Batch photo 2 (capture order).
await expect(page.getByText(/Batch photo 2|Photo 2 failed/)).toBeVisible();
await expect(page.getByText('Reference photo')).toBeVisible();
await expect(page.getByText('Photo with measurements')).toBeVisible();
// Sibling face-b should appear as Photo 2 (capture order).
await expect(page.getByText(/Photo 2|Photo 2 failed/)).toBeVisible();
await shot(page, '06-photos-ready.png');
@@ -125,7 +125,7 @@ test.describe('M2 #65 Photos-ready e2e (set1-48x2)', () => {
const st = fs.existsSync(p) ? fs.statSync(p) : null;
return ` - ${s} (${st ? `${st.size} bytes` : 'MISSING'})`;
}),
`assertions: Photos ready heading; Clean calibration; Dimension overlay; batch sibling slot`,
`assertions: Photos ready heading; Reference photo; Photo with measurements; batch sibling slot`,
];
fs.writeFileSync(logPath, lines.join('\n') + '\n', 'utf8');
});