Two-plane load fix + e2e coverage (ISS-055, v0.31.0)
CI / build + unit + e2e (pull_request) Failing after 8m13s

- LoadControls preselects the first eligible plane so Load is one-click with N planes
- LeftPane queue testids scoped by plane id (queue-leg/cancel/add[-dest]-{plane.id})
  — unscoped ids duplicated in the DOM with two on-board blocks
- new POST /api/test/add-cash hook (FLIGHT_TEST_HOOKS=1, default €1M) so e2e can
  afford a second plane; returns the full state snapshot
- new serial spec e2e/two-planes.spec.ts: load, parallel fly + ISS-057 slow/resume,
  refuel, relocate, per-plane queues with auto-chain, sell (6 tests)
- e2e/queue.spec.ts locators updated to the scoped testids
This commit is contained in:
2026-09-20 21:26:16 +00:00
parent 57cc6705f2
commit 1e3992f872
7 changed files with 663 additions and 14 deletions
+6 -4
View File
@@ -49,8 +49,9 @@ export function loadEligiblePlanes(state: StateSnapshot, pkg: PackageState): Pla
// Load controls for one open package: a single Load button when exactly one plane
// is eligible (it acts on that plane directly), a small plane picker + Load when
// several are, and a disabled button with the reason otherwise. Each row owns its
// selection in local state and defaults to the "Select a plane…" placeholder —
// never preselecting — so rows stay visibly independent (v0.10.1 pattern).
// selection in local state; ISS-055 (v0.31.0): the multi-plane path PRESELECTS the
// first eligible plane so Load is one-click out of the box (matching the single-plane
// UX) while the picker still allows choosing a different plane.
function LoadControls({
pkg,
eligible,
@@ -63,8 +64,9 @@ function LoadControls({
onLoad: (planeId: string) => void;
}) {
const [selectedId, setSelectedId] = useState<string | null>(null);
// The user's pick while it stays eligible, else nothing (placeholder).
const effective = eligible.find((p) => p.id === selectedId) ?? null;
// ISS-055 (v0.31.0): the user's pick while it stays eligible, else the FIRST eligible plane —
// Load is enabled and one-click whenever ≥1 plane qualifies; the picker still allows a different pick.
const effective = eligible.find((p) => p.id === selectedId) ?? eligible[0] ?? null;
if (eligible.length === 1) {
return (