v0.18.0 — ISS-010 relocate empty planes + bigger airport markers + popup options #20
@@ -9,6 +9,7 @@
|
||||
- Tests: e2e — new `e2e/relocation.spec.ts` (serial mode, SCALE=1000, self-heal fly-home in afterEach like actions.spec.ts): market-row test ensures plane-starter grounded at the hub via API, picks it + the nearest non-hub airport (shortest leg) and asserts `/api/state` shows `flying` with that destIcao after clicking Relocate; popup test clicks the isolated LFRS marker (projected-center pattern from map.spec.ts), asserts the select lists "ATR 72-600 — EDDF" and the button is disabled until a plane is picked, then relocates via the popup. Marker-size regression gate = the existing map.spec.ts click tests keep passing
|
||||
- Verified: `tsc --noEmit` clean; unit suite green locally (no lib/ changes — flyPlane's zero-package case already covered by actions.test.ts); e2e not run locally by design — CI verifies against an isolated stack
|
||||
- **Fix (CI run #50): POPUP_AIRPORT scoping in the popup relocation e2e.** The LFRS marker click passed `POPUP_AIRPORT` into a `page.evaluate(() => …)` callback that runs in the BROWSER, where Node-scope constants don't exist — deterministic `ReferenceError: POPUP_AIRPORT is not defined` (relocation.spec.ts popup test, both attempts of run #50). The constant is now passed as an evaluate argument (`page.evaluate(({lon, lat}) => …, POPUP_AIRPORT)`); the other evaluate in the file only touches browser globals and needed no change. Test-only — no app code touched
|
||||
- **Fix (CI run #51): strict-mode locator in the popup relocation e2e.** `expect(planeSel.locator('option')).toContainText(…)` resolved to BOTH options (placeholder + plane) → strict mode violation (relocation.spec.ts popup test, both attempts of run #51; the app rendered correctly). The assertion now targets `option[value="plane-starter"]` specifically with `toHaveText`. Test-only — no app code touched
|
||||
|
||||
## v0.17.0 — 2026-09-19 14:49
|
||||
- **Bottom-right toasts for action errors (ISS-008).** Error messages like "insufficient funds: a ATR 72-600 costs 200000, you have 62721" now appear as toasts in the bottom-right corner — new `lib/useToasts.ts` hook (`useToasts() → {toasts, push(kind, msg), dismiss(id)}`, auto-dismiss after ~5 s, queue capped at 4 dropping the oldest; pure core `pushToast` unit-tested) and new `components/Toasts.tsx` `<ToastStack>` (fixed container `.toasts`, items `[data-testid="toast"]` with class `toast toast-error|toast-info` + a × dismiss button). Wired into BOTH error paths: `RightPane.runAction`'s catch now calls the shell's `onError` in addition to keeping the inline `[data-testid="right-error"]` pane error, and `LeftPane.applySimControls`'s catch (previously console.error-only) reports "Failed to update time controls (…)" through the same callback. The shell (`app/page.tsx`) owns the hook and renders the stack; CSS in `app/globals.css`
|
||||
|
||||
@@ -168,7 +168,9 @@ test('airport popup offers Relocate options for grounded planes', async ({ page
|
||||
// The Relocate row: a select of grounded planes + the button (disabled until one is picked).
|
||||
const planeSel = page.getByTestId('airport-popup-plane');
|
||||
await expect(planeSel).toBeVisible();
|
||||
await expect(planeSel.locator('option')).toContainText(/ATR 72-600 — EDDF/);
|
||||
// Target THE PLANE OPTION specifically — locator('option') also matches the placeholder and
|
||||
// trips strict mode (CI run #51).
|
||||
await expect(planeSel.locator('option[value="plane-starter"]')).toHaveText(/ATR 72-600 — EDDF/);
|
||||
const goBtn = page.getByTestId('airport-popup-relocate');
|
||||
await expect(goBtn).toBeDisabled(); // placeholder selected
|
||||
|
||||
|
||||
Reference in New Issue
Block a user