test: verify first visible vertical slice
Drives the full world/travel flow in Chromium via Playwright against the live API and seeded Postgres, capturing the three required desktop viewports and comparing them against the accepted design reference. Fixes two evidenced defects found during verification: - world-page scene sizing overflowed the viewport at all three required desktop sizes, pushing the footer (and, at 1440x900/1366x768, the travel button) below the fold; scene height now accounts for surrounding chrome so nothing is clipped. - the generic HTTP-failure fallback message was hardcoded in English while the rest of the UI is German; now uses a matching German string. Adds Playwright as a web devDependency for this and future browser verification passes (no product-code dependency).
This commit is contained in:
180
docs/verification/first-visible-slice-fidelity.md
Normal file
180
docs/verification/first-visible-slice-fidelity.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# First Visible Vertical Slice — Fidelity Ledger
|
||||
|
||||
Reference: `docs/references/world-travel-screen.png` (concept mock, Graufurt hub with
|
||||
full RPG chrome: currencies, mail/friends/settings icons, "Shop" nav item, region
|
||||
detail panel with encounters/rewards, "Gebiet erkunden" action).
|
||||
|
||||
Renders (this task, post-fix): `docs/verification/first-visible-slice-1920x1080.png`,
|
||||
`docs/verification/first-visible-slice-1440x900.png`,
|
||||
`docs/verification/first-visible-slice-1366x768.png`. All three captured with
|
||||
Playwright/Chromium at `http://localhost:4200/world`, live API + seeded Postgres,
|
||||
with Verbrannte Straße selected as the travel target (matches the reference's
|
||||
state: travel panel populated).
|
||||
|
||||
Scope reminder: the reference is a full-game concept mock. This slice implements
|
||||
only the demo character, two locations, and travel — currencies, mail/social,
|
||||
settings, Shop, encounters/rewards, and "Gebiet erkunden" exploration are
|
||||
out of scope by design (see Task 1–10 rulings) and are recorded below as
|
||||
deliberate deviations, not defects.
|
||||
|
||||
## Comparison points
|
||||
|
||||
### 1. Shell proportions and persistent regions
|
||||
|
||||
- Reference: top bar (portrait, name/level, HP bar, currencies, icon row) +
|
||||
left icon nav (Karte/Jagd/Quests/Inventar/Charakter/Shop) + center map +
|
||||
right context panel + footer (chat/system line, world/online/time).
|
||||
- Render: top bar (portrait, name/level, HP bar, brand wordmark) + left nav
|
||||
(Karte enabled; Jagd/Quests/Inventar/Charakter present but disabled,
|
||||
`aria-label="… ist noch nicht verfügbar"`) + center map + right
|
||||
"Gebietsinfo" panel + footer (status dot + text, ornament, region name).
|
||||
- Result: structural grid matches (top bar / nav+main+context / footer).
|
||||
Currency row, mail/friends/settings/logout icons, and "Shop" nav item are
|
||||
absent — deliberate, no such systems exist yet. No fix needed.
|
||||
|
||||
### 2. Artwork dominance and crop
|
||||
|
||||
- Reference: large painterly Graufurt gate artwork fills the map region,
|
||||
`background-size: cover`-style dominant visual, quiet areas reserved for
|
||||
path/nodes/panel.
|
||||
- Render: `.world-page__scene` uses the project's own generated
|
||||
Südtor/Aschenstraße artwork (`/images/backgrounds/Suedtor.png` /
|
||||
`Aschestrasse.png`), `background-size: cover`, same compositional role.
|
||||
Visible and readable at all three captured sizes.
|
||||
- Result: matches intent. Different concrete artwork (project-specific,
|
||||
generated per the style guide) is expected, not a defect.
|
||||
|
||||
### 3. Typography hierarchy and control typography
|
||||
|
||||
- Reference: large serif location title overlaid top-left of the map, green
|
||||
safety subtitle, short descriptive paragraph in the same overlay; serif
|
||||
headers in the side panel.
|
||||
- Render: serif (`Georgia`) location title top-left of the map
|
||||
(`.world-page__location-title`); description/safety/level facts live in
|
||||
the right "Gebietsinfo" panel instead of a second overlay block on the
|
||||
map. Control typography (buttons, dl labels) uses the app's sans body
|
||||
font with small-caps-style eyebrows ("REISEN", "GEBIETSINFO").
|
||||
- Result: title hierarchy matches (serif, large, top-left). The map-overlay
|
||||
vs. side-panel placement of description text is an established
|
||||
information-architecture choice from earlier tasks (Task 8/9), not a
|
||||
regression introduced here — left as a recorded deviation, not fixed,
|
||||
since re-architecting panel content is outside this task's evidenced-defect
|
||||
scope.
|
||||
|
||||
### 4. Dark palette, bronze borders, and blue/current state
|
||||
|
||||
- Reference: anthracite/black panels, bronze/gold hairline borders, blue ring
|
||||
on the current-location node, gold ring + gold path on selected/target.
|
||||
- Render: `--ar-bg`/`--ar-panel` dark palette, `--ar-border`/
|
||||
`--ar-border-highlight` bronze/gold borders on top bar, panels, and travel
|
||||
box; `.location-node--current` renders a blue marker ring (confirmed in all
|
||||
three captures, "Aktueller Ort" label green), selected/target node renders
|
||||
gold ring + gold dashed path (confirmed, "Ausgewähltes Ziel" label gold).
|
||||
- Result: matches the style guide's colour semantics (blue = current/active
|
||||
navigation, gold = selection/important action). No fix needed.
|
||||
|
||||
### 5. Node/path legibility
|
||||
|
||||
- Reference: node names + short state label beneath each node, dashed gold
|
||||
connecting path.
|
||||
- Render: same pattern — `location-node__name` + `location-node__state`
|
||||
("Aktueller Ort" / "Ausgewähltes Ziel" / "Erreichbar"), dashed gold SVG
|
||||
path between the two nodes. Legible with sufficient text-shadow contrast
|
||||
against the background artwork at all three captured sizes.
|
||||
- Result: matches. No fix needed.
|
||||
|
||||
### 6. Travel panel placement and action prominence
|
||||
|
||||
- Reference: travel panel overlays the bottom edge of the map itself, as a
|
||||
floating box, with a full-width primary blue button.
|
||||
- Render: `.world-page__travel-panel` is a separate block directly beneath
|
||||
the map (not overlaid on top of it), centered, `min(29rem, 100%)` wide,
|
||||
with a full-width primary button (`Reise beginnen` / `Zur Verbrannte
|
||||
Straße reisen?`) using the gold-bordered, blue-tinted button style.
|
||||
- Result: placement differs (below vs. overlaid on the map) — an established
|
||||
layout choice from earlier tasks, not introduced or regressed by this
|
||||
task. Action prominence (full-width primary button, clear label, disabled
|
||||
state while travelling) matches reference intent. Not treated as a
|
||||
material mismatch requiring a redesign in this verification-only task.
|
||||
|
||||
### 7. Context-panel information density
|
||||
|
||||
- Reference: region title, recommended level, "Mögliche Begegnungen" icon
|
||||
row, description, "Mögliche Belohnungen" icon row, "Gebiet erkunden"
|
||||
button.
|
||||
- Render: "GEBIETSINFO" eyebrow, location name, selected-target note,
|
||||
artwork thumbnail, description paragraph, facts list (recommended level /
|
||||
safety / hunting availability).
|
||||
- Result: reduced density is intentional — encounters, rewards, and area
|
||||
exploration are later-gameplay systems explicitly out of scope for this
|
||||
slice (per the plan's deliberate limitations). Not a defect.
|
||||
|
||||
### 8. Responsive behaviour at all three sizes
|
||||
|
||||
- Evidence (pre-fix): measured via a Playwright DOM probe —
|
||||
`document.documentElement.scrollHeight` vs. `window.innerHeight`:
|
||||
- 1920×1080: docHeight 1098 vs. viewport 1080 (18px overflow; footer's
|
||||
bottom 18px clipped below the fold).
|
||||
- 1440×900: docHeight 997 vs. viewport 900 (97px overflow; travel button
|
||||
and footer entirely below the fold).
|
||||
- 1366×768: docHeight 909 vs. viewport 768 (141px overflow; travel button
|
||||
and footer entirely below the fold, ~half the travel panel cut off).
|
||||
- Root cause: `.world-page__scene { min-block-size: clamp(30rem, 67vh,
|
||||
44rem); }` sized the map purely off viewport height without accounting
|
||||
for the fixed chrome around it (top bar + paddings + travel panel +
|
||||
footer ≈ 395px), so the three required desktop sizes all overflowed the
|
||||
viewport and pushed the footer (and, at the two smaller sizes, the
|
||||
travel button) out of view without scrolling.
|
||||
- **Fixed** in `apps/web/src/app/features/world/world-page.component.scss`:
|
||||
changed to `min-block-size: clamp(20rem, calc(100dvh - 25rem), 44rem)`,
|
||||
which sizes the map to the remaining space after the known chrome height
|
||||
(with a small safety margin), while keeping the existing 20–44rem floor
|
||||
and ceiling.
|
||||
- Evidence (post-fix), same probe: 1920×1080 → 1080 vs. 1080 (0 overflow);
|
||||
1440×900 → 900 vs. 900 (0 overflow); 1366×768 → 768 vs. 768 (0
|
||||
overflow). Re-captured screenshots (see paths above) show the top bar,
|
||||
nav, map with both nodes, full travel panel including the primary
|
||||
button, context panel, and footer all fully visible with no clipping at
|
||||
all three sizes.
|
||||
- Result: **material mismatch found and fixed.**
|
||||
|
||||
## Above-the-fold copy diff
|
||||
|
||||
Every visible string across all three renders was checked against the
|
||||
brief's allowed-copy categories (API content, requested navigation labels,
|
||||
travel labels, restrained system/footer text):
|
||||
|
||||
| Text | Source | Category |
|
||||
|---|---|---|
|
||||
| "Aric Duskwalker", "Stufe 1", "100 / 100" | API (`/api/characters/me`) | API content |
|
||||
| "Südtor von Graufurt", "Verbrannte Straße", description paragraph, "1–1", "Sicherer Ort", "Keine Jagd" | API (`/api/world/current-location`) | API content |
|
||||
| "Verbrannte Straße", "00:00:10", "Niedrig" | API (`/api/world/current-location` connections) | API content |
|
||||
| "Karte", "Jagd", "Quests", "Inventar", "Charakter" | side nav | requested navigation labels |
|
||||
| "REISEN", "Zur … reisen?", "Ziel", "Reisezeit", "Gefahr", "Reise beginnen", "Ankunft in", "REISE LÄUFT", "Reise läuft", "Wähle einen erreichbaren Ort auf der Karte." | travel panel | travel labels |
|
||||
| "GEBIETSINFO", "Ausgewähltes Ziel: …", "Empfohlene Stufe", "Sicherheit", "Jagd", "Aktueller Ort", "Ausgewähltes Ziel", "Erreichbar" | context panel / node labels | restrained system text |
|
||||
| "Verbindung bereit", "Aschenfelder", "Ashen Realms" | footer / top bar | restrained system/footer text |
|
||||
| "Weltzustand wird geladen…", "Weltkarte wird vorbereitet.", "Erneut versuchen" | loading/empty states | restrained system text |
|
||||
| "Unable to load world state." | error fallback (`world.store.ts`) | **violation — English string in an otherwise fully German UI** |
|
||||
|
||||
**Fixed:** `apps/web/src/app/features/world/world.store.ts`,
|
||||
`toErrorMessage()` fallback changed from `'Unable to load world state.'` to
|
||||
`'Weltzustand konnte nicht geladen werden.'`, matching the German tone/case
|
||||
used everywhere else in the app (e.g. `"Weltzustand wird geladen…"`).
|
||||
Verified live: killed the API process, reloaded `/world`, confirmed the
|
||||
in-shell error box now reads "Weltzustand konnte nicht geladen werden." with
|
||||
no `window.alert()` dialog fired (Playwright `page.on('dialog', …)` listener
|
||||
recorded zero dialogs across every step of the verification pass).
|
||||
|
||||
No invented, promotional, or placeholder copy was found anywhere in the
|
||||
above-the-fold content.
|
||||
|
||||
## Summary
|
||||
|
||||
One functional/visual defect found and fixed (responsive overflow/clipping
|
||||
at all three required desktop sizes — item 8). One copy defect found and
|
||||
fixed (English fallback error string — copy diff table above). All other
|
||||
comparison points either matched the reference's visual language directly,
|
||||
or reflect deliberate, already-ruled-on scope reductions from earlier tasks
|
||||
(no currencies/social/settings/Shop, reduced context-panel density, no
|
||||
map-overlay description block, travel panel placed below rather than over
|
||||
the map) that this verification-only task did not redesign.
|
||||
Reference in New Issue
Block a user