ci: fix e2e-docker and playwright-e2e workflows#204
Conversation
…ressing session storage issues in results page
…nt with results page navbar
… can be loaded to the react state of the vehicles to be exported through the save point
…mported via the save point
Stabilize setRoutes via a routes ref so it no longer breaks memoization for every callback that depends on it, document why optimizeResults is intentionally left in sessionStorage for useSyncExternalStore, dedupe the new-session handler in welcome/page.tsx, and extract the geocode cache-hit check into a testable helper with a regression test for the imported-address (null state) case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…proved layout and error indication
…s to results page without stored route
…desktop to prevent hidden DOM's from being picked up by the playwright CI check
…te responses for excessive and negative deliveries
…ize tests The legacy sync /api/v1/deliveries/optimize endpoint is disabled by default everywhere (dev, prod, and the e2e stack env all set DELIVERYOPTIMIZER_ENABLE_SYNC_OPTIMIZE=0), so the previous rewrite of these 3 scripts 404'd against it. Point them at POST /api/v1/optimization-jobs instead, which is always registered and shares the same ParseAndValidateOptimizeRequest validation contract. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OptimizeValidQueryReturnsSummary only asserted HTTP 202 + job_id on submission, so it could pass even if the async worker never completed the job or the result payload regressed. Poll the job status to succeeded and assert the result contains status/summary/routes/ unassigned, matching what the test's name promises.
|
Great work — the CI fixes are clearly motivated and well-executed, and the test rewrites are a genuine upgrade (they now actually test what the test names promise). A few things to flag before merging:
The new version expands the class list into an explicit string, which means it no longer tracks changes to Module-level mutable cache in let cachedRouteLoadKey = "";
let cachedRouteLoadResult: RouteLoadResult = EMPTY_ROUTE_LOAD_RESULT;The pattern is correct for Empty state vs. non-empty state in The non-empty path now uses
e2e_init "$1" "$2" "$3" "$4"
python3_bin="$5"Just want to confirm: Everything else looks solid — the |
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Thank you Mark for your feedback! I have addressed the issues you mentioned. I refactored the stepper error token so it shares the same base layout as the normal stepper, added a comment explaining the module-level useSyncExternalStore cache, aligned the desktop empty address-list path with the responsive list tokens, and clarified in the E2E script that e2e_init takes the shared Docker stack args while Python is handled separately for JSON parsing. |
|
Thanks for the follow-up commits — the
useEffect(() => {
setDraftRoutes(null);
}, [routeLoadResult]);
The export const ADDRESS_ROW_STEPPER_CONTAINER_NARROW_ERROR =
`${ADDRESS_ROW_STEPPER_CONTAINER_NARROW} border-[var(--edit-error-border)]`;
Lines 22–33 list every field explicitly. A new field on |
Summary
Fixes both CI workflows that exercise the full Docker stack (
e2e-docker.yml) and the browser-driven flow (playwright-e2e.yml), neither of which had ever completed successfully. Both are now verified green end-to-end via realworkflow_dispatchruns, not just local inspection.Depends on #193 (
feat/session-storage) — that PR must merge first. This branch was cut fromfeat/session-storageand only contains the CI-fix commits on top of it; this description intentionally omitsfeat/session-storage's own changes.Motivation
e2e-docker.ymldied at the CMake configure step on every run (missing PostgreSQL dev headers for Drogon's Postgres feature), so the full Docker E2E suite had literally never executed past configure.playwright-e2e.ymlfailed on alocator.filltimeout because the edit page rendered the same address card twice (desktop + mobile), both always mounted and only CSS-hidden, which confused Playwright's strict-mode locator matching. Fixing the infra surfaced more pre-existing, previously-unexercised bugs once each workflow could finally run far enough to hit them, including a test that only verified an optimize job was accepted rather than that it actually completed and returned a real result.Changes
Infrastructure
libpq-devto thee2e-docker.ymlapt package cache so Drogon's Postgres support configures correctly.Frontend
AddressCardmapping inAddressSection.tsxso only one set of address rows is ever mounted, eliminating the hidden-DOM collision that broke Playwright's locator.optimize-flow.spec.ts) to theasideelement, since the same always-mounted-both-mounted pattern exists between the desktopSidebarand mobileResultsBottomSheet, both of which render identical "N routes with M total stops" text.formStyles.v2.ts.Backend tests
e2e-dockerAPI scripts (optimize_valid_query_returns_summary,optimize_rejects_negative_deliveries,optimize_rejects_excessive_deliveries), which targeted aGET /optimize?deliveries=N&vehicles=Nshape that no longer exists. They now POST real JSON payloads againstPOST /api/v1/optimization-jobs(the always-registered async API) and assert the current validation contract (400+{"field": "jobs[0].demand"}/{"field": "jobs"},202+job_id).tests/CMakeLists.txtto register the rewritten "valid query" script as a Python-assisted test, since it now needs to parse JSON out of the response.optimize_valid_query_returns_summary_e2e_test.shinitially only asserted202+job_idon submission, which would stay green even if the async worker never completed the job or the result payload regressed. It now polls/api/v1/optimization-jobs/{id}tosucceededand asserts the result containsstatus/summary/routes/unassigned, matching what the test's name promises.Validation
gh workflow run "E2E Docker (weekly + manual)" --repo Gill87/b2deliveryoptimizer --ref ci/fix-checks— 100% tests passed, 0 failed out of 8 (1 disabled smoke test skipped as expected), re-run after the polling fix to confirmOptimizeValidQueryReturnsSummarystill passes end-to-endgh workflow run "Playwright E2E (weekly + manual)" --repo Gill87/b2deliveryoptimizer --ref ci/fix-checks— 1 passedCI workflows
e2e-docker.ymlConfigure/Build steps pass for the first time (previously failed every run at CMake configure)playwright-e2e.ymlclears the original edit-pagelocator.filltimeout and the newly-discovered results-page locator collisionOptimizeValidQueryReturnsSummaryexercises the full submit → poll → result path (12.3s runtime, not an instant submit-only pass)Both workflows are
workflow_dispatch/schedule-only by design (not wired topull_request), so they were validated by dispatching real runs against this branch on the fork rather than viapr-checks.Risk
The 3 rewritten e2e-docker scripts now depend on the always-on
/api/v1/optimization-jobsAPI and Postgres-backed job store being healthy in the stack; if that store becomes misconfigured these tests will fail at submission (503) rather than validation, which is an acceptable and already-covered failure mode (seeOptimizationJobValidPayloadReturnsRoutingResponse). The Playwright locator scoping toasideis coupled to the current Sidebar/ResultsBottomSheet markup — if either component's root tag changes, the locator will need to be revisited.OptimizeValidQueryReturnsSummarynow duplicates most ofOptimizationJobValidPayloadReturnsRoutingResponse's submit/poll/result mechanics; that overlap is intentional so each test can fail independently and point at what actually broke, rather than collapsing coverage into one test.Rollout and Recovery
No runtime/deploy changes — this is CI and test-only. Both workflows remain
workflow_dispatch/schedule-triggered, so a bad merge only affects the weekly scheduled run or manual dispatches, notpull_requestchecks. Revert is a plaingit revertof the relevant commits if either workflow regresses.