feat(07-02): landscape capture legs — cockpit + pending card in the driving posture (PX-04.e, SC2)

- captureLeg accepts a per-leg viewport (default 390x844 unchanged)
- shell-guidance-landscape.png: corridor drive leg verbatim at 844x390 — the
  @media (orientation: landscape) block exercised in a real browser
- shell-route-pending-landscape.png: the designed pending card in landscape
- both legs under the existing MIN_BYTES blank bar; capture 22/22 non-blank
This commit is contained in:
araharah-executor
2026-10-25 04:17:43 +08:00
parent add860bceb
commit 7536ce5d38
+47 -2
View File
@@ -40,6 +40,8 @@
* shell-guidance-tripend.png the trip-ended card, chrome cleared (06-08) * shell-guidance-tripend.png the trip-ended card, chrome cleared (06-08)
* shell-guidance-dark.png the cockpit, Telegram dark theme (PX-02, 06-08) * shell-guidance-dark.png the cockpit, Telegram dark theme (PX-02, 06-08)
* guidance-gallery-compare.png DSGN-02 guidance fidelity artifact vs active_route_guidance/screen.png (06-08) * guidance-gallery-compare.png DSGN-02 guidance fidelity artifact vs active_route_guidance/screen.png (06-08)
* shell-guidance-landscape.png the cockpit in landscape (driving posture) (07-02, PX-04)
* shell-route-pending-landscape.png the designed pending card in landscape (07-02, SC2)
* *
* Also runs the GEO-03 runtime probe in-page after boot-to-live and fails * Also runs the GEO-03 runtime probe in-page after boot-to-live and fails
* the run on any non-empty storage surface. * the run on any non-empty storage surface.
@@ -485,10 +487,10 @@ const guideQuery = `mock=android&dest=${guidePair.destinationId}&fixpair=${guide
* leg's console; the replay's ?drive= knob streams * leg's console; the replay's ?drive= knob streams
* the committed fixture through the real watch * the committed fixture through the real watch
*/ */
async function captureLeg({ name, query, colorScheme, grantGeo, waitMode, expectState, expectText, expectGuide, setup, interact }) { async function captureLeg({ name, query, colorScheme, grantGeo, waitMode, expectState, expectText, expectGuide, setup, interact, viewport }) {
const target = join(SHOTS, name); const target = join(SHOTS, name);
const context = await browser.newContext({ const context = await browser.newContext({
viewport: { width: 390, height: 844 }, viewport: viewport ?? { width: 390, height: 844 },
colorScheme, colorScheme,
deviceScaleFactor: 2, deviceScaleFactor: 2,
}); });
@@ -1105,6 +1107,47 @@ async function composeCompare(target, implementedFile, implementedCaption, mocku
failures.push(`guidance-gallery-compare.png: ${err.message}`); failures.push(`guidance-gallery-compare.png: ${err.message}`);
} }
} }
/* 21 — 07-02 — the landscape leg (PX-04.e) —————
* The driving posture: the phone rotated. The cockpit geometry adapts via
* the @media (orientation: landscape) block (07-02 task 1); the map stays
* Rams-constant. A 844x390 viewport IS the landscape orientation the media
* query matches (orientation: landscape + max-height: 560px).
* The setup + query + waitMode/expectGuide are copied VERBATIM from the
* existing corridor guidance leg — only the name, the scheme, and the
* viewport differ. */
await captureLeg({
name: 'shell-guidance-landscape.png',
setup: (page) => stubGuidanceRoute(page, corridorModel),
query: guideQuery,
colorScheme: 'light',
grantGeo: true,
waitMode: 'guide',
expectGuide: 'on_route',
expectText: [guideDestEntry.name, 'END TRIP'],
viewport: { width: 844, height: 390 },
interact: async (page) => {
const banner = await assertCockpitChrome(page, guideDestEntry.name);
log.push(`shell-guidance-landscape: banner ${JSON.stringify({ distance: banner.distance + ' M', street: banner.street, bg: banner.bg })}`);
await page.waitForTimeout(300); // the frozen chrome settles
},
});
/* 22 — 07-02 — the landscape failure-state leg (SC2) —————
* The pending card in landscape: the designed surface, never a blank map.
* The query/waitMode/expectState/expectText are the shell-route-pending
* leg's values verbatim (the empty/error route class) — only the
* viewport differs. */
await captureLeg({
name: 'shell-route-pending-landscape.png',
query: `mock=android&dest=national-museum&fixpair=${demoPair.pairId}`,
colorScheme: 'light',
grantGeo: true,
waitMode: 'route',
expectState: 'pending',
expectText: ['not wired up yet'],
viewport: { width: 844, height: 390 },
});
} finally { } finally {
await browser.close(); await browser.close();
server.close(); server.close();
@@ -1134,6 +1177,8 @@ const expected = [
'shell-guidance-tripend.png', 'shell-guidance-tripend.png',
'shell-guidance-dark.png', 'shell-guidance-dark.png',
'guidance-gallery-compare.png', 'guidance-gallery-compare.png',
'shell-guidance-landscape.png',
'shell-route-pending-landscape.png',
]; ];
const missing = expected.filter((f) => !existsSync(join(SHOTS, f))); const missing = expected.filter((f) => !existsSync(join(SHOTS, f)));
const undersized = expected.filter((f) => existsSync(join(SHOTS, f)) && sizeOf(join(SHOTS, f)) < MIN_BYTES); const undersized = expected.filter((f) => existsSync(join(SHOTS, f)) && sizeOf(join(SHOTS, f)) < MIN_BYTES);