feat: harden mobile capture recovery (#11)
Quality gates / quality (pull_request) Failing after 58s

This commit is contained in:
timmy committed 2026-08-26 08:07:30 +00:00
1 parent 47294a98aa
commit 463dff7f22
11 files changed
+94 -5

No files matched your search

+1
View File
@@ -109,6 +109,7 @@ def main() -> int:
raise SystemExit("Acceptance server did not become ready")
run(["npm", "run", "test:ui"], tree)
run(["npm", "run", "test:photo"], tree)
run(["npm", "run", "test:mobile-capture"], tree)
run(["npm", "run", "test:sleek"], tree)
demo_raw = release_dir / f"timmy-talking-turd-{version}-demo.raw.webm"
demo_env = dict(server_env)
+23 -1
View File
@@ -100,13 +100,35 @@ async function tap(selector, after = 650) {
await sleep(after);
}
async function indicate(selector) {
const target = page.locator(selector).first();
const box = await target.boundingBox();
if (!box) throw new Error(`Missing demo target: ${selector}`);
await page.evaluate(({ x, y }) => {
document.querySelector('#demo-touch')?.remove();
const ring = document.createElement('div');
ring.id = 'demo-touch';
ring.style.left = `${x}px`;
ring.style.top = `${y}px`;
document.body.append(ring);
ring.animate([{ opacity: .2, transform: 'translate(-50%,-50%) scale(.55)' }, { opacity: 1, transform: 'translate(-50%,-50%) scale(1)' }], { duration: 400 });
setTimeout(() => ring.remove(), 550);
}, { x: box.x + box.width / 2, y: box.y + box.height / 2 });
await sleep(650);
}
await caption(`TIMMY ${version} • FEATURE DEMO`, 1200);
await caption('Automated checks replay this synthetic path before review', 1200);
await caption('One clear photo action. Manual logging stays one tap away.', 1500);
await tap('[data-scan]', 450);
await page.getByText(/Self-hosted model ready/i).waitFor();
await caption('The pinned bootstrap verifies both model files before starting on private loopback', 1500);
await page.locator('#ai-photo').setInputFiles('tests/fixtures/synthetic-type4.jpg');
await indicate('label[for="camera-photo"]');
await page.locator('#camera-photo').dispatchEvent('cancel');
await page.getByText(/Camera or photo picker closed/i).waitFor();
await caption('Camera closed cleanly — gallery and manual logging are still available', 1600);
await indicate('label[for="gallery-photo"]');
await page.locator('#gallery-photo').setInputFiles('tests/fixtures/synthetic-type4.jpg');
await caption('Nothing uploads until explicit consent', 1100);
await page.locator('#ai-consent').check();
await tap('#analyze-photo', 450);