[1m[30m[46m RUN [49m[39m[22m [36mv4.1.9 [39m[90m/workspace/niko/agent-platform/frontend[39m [2mCoverage enabled with [22m[33mv8[39m (node:361) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:352) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:341) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:335) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:394) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:381) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:382) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:354) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:353) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:334) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:388) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22mcreateCoordinator[2m > [22mreturns an object with useCoordinator[32m 24[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22minitial state: reconnecting → connected[2m > [22mstarts in reconnecting and transitions to connected on onopen[32m 207[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — inactive state (no crud)[2m > [22mactiveCrud is null when routeContext has no crud[32m 236[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — inactive state (no crud)[2m > [22mactiveCrud is null when routeContext.crud is undefined[32m 53[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22mresolveEndpointTemplate[2m > [22mreplaces a single token in the template[32m 48[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22mresolveEndpointTemplate[2m > [22mreplaces multiple tokens and removes used params[32m 3[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22mresolveEndpointTemplate[2m > [22mreturns url unchanged when no tokens exist[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22mresolveEndpointTemplate[2m > [22mthrows when a token is missing from params[32m 5[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22mresolveEndpointTemplate[2m > [22mthrows when one of multiple tokens is missing[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22mcreateEntityHooks[2m > [22mreturns EntityHooks with required shape[32m 3[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mconnection lost after 5 onerrors[2m > [22msets connectionState:lost after 5 consecutive failures[32m 38[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mreconnecting state on 1–4 onerrors[2m > [22mstays in reconnecting after 4 consecutive onerrors[32m 54[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2W/coordinator.test.ts[2m > [22m[2museCoordinator — inactive state (no crud)[2m > [22m[2msubmit is callable even when inactive (no-op) [22m[39mAn update to TestComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to TestComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to TestComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — inactive state (no crud)[2m > [22mfieldPolicy is empty when inactive[32m 50[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — inactive state (no crud)[2m > [22mformModel is defaults when inactive[32m 33[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — inactive state (no crud)[2m > [22mbridge starts clean when inactive[32m 32[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22mMount -> refCount=1 -> staleTime Infinity[2m > [22museEntityList sees staleTime Infinity when refCount > 0[32m 274[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mreconnect() resets failureCount and state[2m > [22mreconnect() moves from lost back to reconnecting and resets backoff[32m 62[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mheartbeat timeout triggers lost state[2m > [22mtransitions to lost after 30s without heartbeat[32m 55[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/ReconnectRefresh.test.tsx[2m > [22mReconnectRefresh[2m > [22mDoD-3: initial mount does NOT invalidate[2m > [22mfirst onopen does not call invalidateQueries[32m 293[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/ReconnectRefresh.test.tsx[2m > [22mReconnectRefresh[2m > [22mDoD-4/DoD-5: 1 onerror + onopen triggers invalidate after wasEverConnected[2m > [22minvalidates on reconnect onopen after an onerror on the established connection[32m 35[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/ReconnectRefresh.test.tsx[2m > [22mReconnectRefresh[2m > [22mDoD-4: 4+ onerrors during initial mount + onopen = NO invalidate[2m > [22mno invalidate when errors happen before first successful connection[32m 43[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22mreturns ListResult shape with hasMore and totalEstimate when API responds with data array[32m 280[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — inactive state (no crud)[2m > [22msubmit is callable even when inactive (no-op)[32m 58[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — owner isolation[2m > [22mactiveCrud is null when routeContext.crud.owner != config.owner[32m 10[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — owner isolation[2m > [22mactiveCrud is populated when owner matches[32m 14[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — owner isolation[2m > [22mactiveCrud includes prefix when provided[32m 10[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — owner isolation[2m > [22mowner isolation works for edit mode[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — add flow[2m > [22mformModel initialized with defaults[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — add flow[2m > [22mfieldPolicy uses add mode[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — add flow[2m > [22mactiveCrud has mode add[32m 18[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22mUnmount -> refCount=0 -> staleTime 120_000[2m > [22mafter unmount, refCount drops to 0 and staleTime falls back to sseMode value[32m 125[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/ReconnectRefresh.test.tsx[2m > [22mReconnectRefresh[2m > [22mDoD-5: flag cycle[2m > [22mcycles: onerror→onopen(invalidate)→onerror→onopen(invalidate)→onopen(no invalidate)[32m 35[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/ReconnectRefresh.test.tsx[2m > [22mReconnectRefresh[2m > [22mDoD-6: manual reconnect in lost state triggers invalidate[2m > [22mreconnect from lost state triggers invalidate when flag is true[32m 49[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/ReconnectRefresh.test.tsx[2m > [22mReconnectRefresh[2m > [22mDoD-7: zombie callback — unmount prevents invalidate[2m > [22mdoes not invalidate when onopen fires after unmount[32m 25[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mheartbeat timeout triggers lost state[2m > [22mheartbeat timeout → reconnecting with backoff[32m 58[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mheartbeat timeout triggers lost state[2m > [22mheartbeat events prevent lost state (35s with heartbeat at 20s does NOT trigger lost)[32m 39[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22m60s lost auto-retry[2m > [22mretries after 60s in lost state and schedules next retry on failure[32m 19[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22munmount cancels timers[2m > [22mcancels lostRetryTimeout and closes EventSource on unmount in lost state[32m 16[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — add flow[2m > [22msubmit calls mutation.create with toCreate(formModel)[32m 36[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — add flow[2m > [22mbridge.pending is true after submit[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — add flow[2m > [22msubmit uses the latest formModel via setFormModel[32m 28[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — edit flow[2m > [22mformModel populated from entity detail[32m 14[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — edit flow[2m > [22mfieldPolicy uses edit mode[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — edit flow[2m > [22mactiveCrud has mode edit[32m 9[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — edit flow[2m > [22msubmit calls mutation.update with id and toUpdate(formModel)[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22mfilters out pending deleted entities[32m 90[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22mTwo components, same queryKey -> refCount=2[2m > [22mboth subscriptions contribute to refCount, both become 0 only after both unmount[32m 113[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mper-subscription heartbeat isolation[2m > [22mtwo hook instances do not share heartbeat state[32m 17[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mPhase 3 fix: clearLostRetry() on every open() — no duplicate 60s timers[2m > [22mafter 60s lost retry fires, open() clears the stale timer and starts fresh backoff cycle[32m 25[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mPhase 3 fix: onopen resets heartbeat timestamp to prevent premature timeout[2m > [22monopen resets heartbeat timestamp so heartbeat does not trigger within 10s of reconnect[32m 14[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mPhase 3 fix: pendingTimeouts cleared on lost — stale reconnecting timers do not override lost[2m > [22mafter 5 rapid onerrors trigger lost, stale backoff timers do NOT fire and override lost state[32m 13[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mPhase 3 fix: clearLostRetry() in reconnecting path — stale lost timer does not override reconnecting[2m > [22mreconnect() clears stale lost timer and stays connected past the 60s window[32m 13[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2W/coordinator.test.ts[2m > [22m[2museCoordinator failure path[2m > [22m[2msubmit does not throw when called without active crud [22m[39mAn update to TestComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to TestComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to TestComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — edit flow[2m > [22mdetail not yet loaded shows formModel as defaults[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator lifecycle transitions[2m > [22mhandles transition from add → inactive → edit cleanly[32m 25[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator lifecycle transitions[2m > [22mcloseIntent resets on mode change[32m 14[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator failure path[2m > [22mfailure is null initially[32m 10[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator failure path[2m > [22mbridge dirty stays true when pending resets (failure simulation)[32m 11[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator failure path[2m > [22msubmit does not throw when called without active crud[32m 21[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22muses defaultListQuery when no params provided[32m 96[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22mresolves endpoint template with params and strips used tokens[32m 38[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22mTwo components, different queryKey[2m > [22mdifferent filters get independent refCounts[32m 77[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22mRace condition: refCount 0->1 cancels ongoing refetch[2m > [22mcalls cancelQueries when refCount transitions 0->1 mid-refetch[32m 85[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator failure path[2m > [22mactiveCrud remains populated after submit (branch not closed)[32m 21[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator failure path[2m > [22mfailure is null after submit when no sync error occurs[32m 35[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator failure path[2m > [22mfailure is set when mutation resolves with isError=true[32m 34[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator closeIntent[2m > [22mcloseIntent is null initially[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22muses staleTime 0 when queryMode is live[32m 83[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22muses default staleTime when queryMode is cache[32m 74[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseConnectionState.test.tsx[2m > [22mSseConnectionState — state machine[2m > [22mDoD-4: backoff survives re-render (normalizedRef fix)[2m > [22mfailureCount persists across re-renders and retry fires on schedule[32m 24[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22msseMode + refCount combinations[2m > [22msseMode true, refCount 0 -> staleTime 120_000[32m 98[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator closeIntent[2m > [22mcancel() sets closeIntent to cancel[32m 19[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator updateField and setFormModel[2m > [22msetFormModel updates snapshot.formModel[32m 10[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator updateField and setFormModel[2m > [22mupdateField updates a single field and marks dirty[32m 11[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator updateField and setFormModel[2m > [22mupdateField preserves other fields[32m 16[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator snapshot type contract (compile-time)[2m > [22msnapshot has all required CoordinatorSnapshot fields[32m 37[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator snapshot type contract (compile-time)[2m > [22mresult exposes updateField, setFormModel, cancel[32m 19[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22mreturns hasMore true from API meta[32m 83[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mdeleteState is null on collection route[32m 21[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mdeleteState is null on collection route even with crud[32m 16[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mdeleteState is non-null on detail route[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mrequestDelete sets showConfirm to true[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mrequestDelete clears previous delete errors[32m 24[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22msseMode + refCount combinations[2m > [22msseMode true, refCount > 0 -> staleTime Infinity[32m 138[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22mhandles totalEstimate -1 as unknown count[32m 81[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityList[2m > [22mfalls back safely when API meta is missing[32m 79[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mcancelDelete sets showConfirm to false[32m 27[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mcancelDelete does not call mutation.remove[32m 26[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mconfirmDelete calls mutation.remove with routeContext.id[32m 30[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mconfirmDelete closes showConfirm and clears delete error before calling remove[32m 24[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22msseMode + refCount combinations[2m > [22msseMode false/undef, refCount 0 -> staleTime undefined (global default)[32m 83[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22msseMode + refCount combinations[2m > [22msseMode false/undef, refCount > 0 -> staleTime Infinity[32m 91[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityDetail[2m > [22mreturns DetailResult shape on successful fetch[32m 66[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museEntityDetail[2m > [22mis skipped when id is empty[32m 10[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mreturns MutationHandle shape with isPending and callable methods[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mupdate receives id as first argument and sends Idempotency-Key header[32m 30[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mconfirmDelete is a no-op on collection route[32m 27[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mdeleteState.isPending is false when delete not requested[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mdeleteState.isPending reflects mutation.isPending during active delete[32m 14[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mdeleteState.isPending becomes false after delete completes[32m 29[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mextracts error message from response.data.error[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mfalls back to error.message when response.data is absent[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22museEntityDetail refCount-aware staleTime[2m > [22mdetail query sees staleTime Infinity when subscription is active for same entity[32m 85[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mupdate does not trigger cache invalidation[32m 16[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mcreate triggers cache invalidation with Idempotency-Key header[32m 21[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mcreate resolves endpoint template in mutationFn[32m 66[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22museEntityDetail refCount-aware staleTime[2m > [22mdetail query sees staleTime undefined when no subscription[32m 100[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mfalls back to String(err) when response.data.error and message are both missing[32m 29[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mcreate resolves endpoint template using createPathParams from contract[32m 22[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mcreate with pipelines-like contract uses context to build URL /projects/{id}/pipelines[32m 19[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mcreate resolves template from context when body lacks the token field[32m 34[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22mfalls back to default string when error is null[32m 126[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22msuccessful delete clears error state[32m 45[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — delete state machine[2m > [22merror remains null after successful delete (was null before)[32m 19[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mcreate isolates context between rapid successive calls (no ref race)[32m 69[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22moffline create adds to outbox without calling API[32m 23[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22moffline update adds to outbox without calling API[32m 42[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/RefCountIntegration.test.tsx[2m > [22mRefCount Integration[2m > [22mPer-queryKey isolation (DoD-7)[2m > [22mtwo different queryKeys do not share refCount[32m 21[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — entitySelectData resolution[2m > [22mentitySelectData is empty when no entitySelectSources configured[32m 25[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — entitySelectData resolution[2m > [22mresolves entity-select options from L1 useEntityList[32m 25[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinator.test.ts[2m > [22museCoordinator — entitySelectData resolution[2m > [22muses default idField and nameField when not specified[32m 71[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22moffline remove adds to pendingDeleteMap, cache, and outbox without API call[32m 58[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mremove does not trigger cache invalidation[32m 26[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mremove onSuccess performs deterministic cache cleanup across all same-path entries[32m 18[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22mremove onSuccess cache cleanup removes entity from detail cache entry[32m 26[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museMutation[2m > [22misPending reflects combined mutation state[32m 38[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museSubscription[2m > [22mshape smoke[2m > [22mreturns SubscriptionHandle with correct shape[32m 20[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museSubscription[2m > [22mconnection-lost after 5 failures[2m > [22msets connectionState:lost after 5 consecutive failures[32m 27[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museSubscription[2m > [22mreconnect resets the state[2m > [22mreconnect is callable and triggers a new connection attempt[32m 23[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityHooks.test.tsx[2m > [22museSubscription[2m > [22mSSE deleted cleanup[2m > [22mremoves pendingDelete entry on entity.deleted event[32m 50[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22m[2mListSurface[2m > [22m[2mrendering states[2m > [22m[2mrenders loading state when isLoading is true [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrendering states[2m > [22mrenders loading state when isLoading is true[32m 267[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrendering states[2m > [22mrenders error state when error is present[32m 17[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrendering states[2m > [22mrenders empty state when data is empty[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrendering states[2m > [22mrenders data table when data is present[33m 321[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrendering states[2m > [22mrenders column headers from config[32m 120[2mms[22m[39m [90mstderr[2m | src/shared/components/CrudReadCard.test.tsx[2m > [22m[2mCrudReadCard[2m > [22m[2m1. loading shows skeleton header + skeleton card, no buttons rendered [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mrenders add button when createTarget is set[32m 96[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mrenders custom add button label from config.createLabel[32m 86[2mms[22m[39m [90mstderr[2m | src/layers/L2R/slots/DataTable.test.tsx[2m > [22m[2mDataTable slot[2m > [22m[2mrow identity[2m > [22m[2muses resolveIdOf result for row key and data-testid [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mrenders default add button label when createLabel is not set[32m 84[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrow identity[2m > [22muses resolveIdOf result for row key and data-testid[33m 405[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrow identity[2m > [22mfalls back to row.id when resolveIdOf returns null[32m 105[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mcalls navigate with createTarget when add button clicked[32m 123[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m1. loading shows skeleton header + skeleton card, no buttons rendered[33m 313[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrow identity[2m > [22mfalls back to empty string when no id field and resolveIdOf returns null[32m 121[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m2. error shows "Failed to load" + Retry[33m 474[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mSSE[2m > [22mshows connection-lost banner with reconnect when SSE enabled and connection lost[32m 196[2mms[22m[39m [90mstderr[2m | src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22m[2mDetailSurface[2m > [22m[2mrendering states[2m > [22m[2mrenders loading state when isLoading is true [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mrow click calls navigate with rowTarget and row id[32m 257[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mdoes not render add button when createTarget is not set (no fallback)[32m 72[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mrendering states[2m > [22mrenders loading state when isLoading is true[33m 655[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mSSE[2m > [22mshows data table alongside SSE connection-lost banner (preserving cached data)[32m 108[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m3. 404 shows "not found" + "Back to list"[32m 128[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22madd button is not clickable when createTarget is not set[32m 300[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mrow click uses derived default when rowTarget is not set[32m 67[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mSSE[2m > [22mreconnect button calls sse.reconnect[32m 170[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mcancel[2m > [22m[2mnavigates to cancelTarget when Cancel is clicked [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mcancel[2m > [22m[2mnavigates to cancelTarget when Cancel is clicked [22m[39mAn update to Crud inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mSSE[2m > [22mrenders table normally when SSE enabled and connection is live[32m 154[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m4. default renders title, actions, field grid[32m 258[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mcancel[2m > [22m[2mnavigates to cancelTarget when Cancel is clicked [22m[39mAn update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mSSE[2m > [22mrenders table normally when SSE is not enabled[32m 123[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mwiring[2m > [22mrow click uses rowTargetOverride when provided[32m 66[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22msets default sort in URL on initial hydration[32m 57[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22mshows sort indicator on active sort column[32m 28[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22mshows error state[32m 130[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22mshows loading state[32m 28[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22mshows empty state when no data and not loading[32m 52[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22mcycles sort on header click: none -> asc -> desc -> none[32m 264[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22mswitches to new column asc when different column is clicked[32m 61[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22msorts data by active sort field asc[32m 57[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22msorts data by active sort field desc[32m 62[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22mplaces null/undefined values last in asc sort[32m 115[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22msorts numbers numerically[32m 28[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22msorts strings case-insensitively[32m 40[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders nothing when activeCrud is null[33m 507[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m5. edit onClick is called[33m 649[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mrendering states[2m > [22mrenders error state when error is present[32m 51[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mrendering states[2m > [22mrenders empty state when entity is null[32m 55[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22msort[2m > [22mdoes not render sort indicator on non-sortable columns[32m 44[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22moverrides[2m > [22mrenders custom loading fragment from overrides[32m 22[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22moverrides[2m > [22mrenders custom empty fragment from overrides[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22moverrides[2m > [22mrenders custom error fragment from overrides[32m 9[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22moverrides[2m > [22mwraps content in layoutWrapper from overrides[32m 31[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22mshows filter-empty state when data is empty and filters are active[33m 356[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22mfilter-empty state shows clear filters button[32m 47[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mcancel[2m > [22mnavigates to cancelTarget when Cancel is clicked[33m 1517[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22moverrides[2m > [22muses label overrides for column headers[32m 32[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22moverrides[2m > [22mhides columns specified in overrides[32m 41[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22mshows regular empty when no filters are active and data empty[32m 45[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mstates[2m > [22merror takes priority over loading[32m 39[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mfilter-empty state[2m > [22mshows filter-empty when hasActiveFilters is true and data is empty[32m 67[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mfilter-empty state[2m > [22mshows regular empty when hasActiveFilters is false and data empty[32m 22[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mfilter-empty state[2m > [22mshows clear filters button in filter-empty state when onClearFilters provided[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mfilter-empty state[2m > [22mdoes not show filter-empty when data is not empty[32m 22[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrender contract[2m > [22mcalls render for each cell[32m 26[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders add mode title by default[33m 1473[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22madd button[2m > [22mrenders add button in header when createTarget is set[32m 144[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrender contract[2m > [22mrenders ReactNode from render function[32m 83[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrender contract[2m > [22mrender receives full row object[32m 20[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrender contract[2m > [22mrenders default plain text when render is omitted[32m 30[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrender contract[2m > [22msupports mixed columns: some with render, some without[32m 25[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mrendering states[2m > [22mrenders detail content via CrudReadCard with fields from readGrouping[33m 890[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mcancel[2m > [22mnavigates to cancelTarget via closeIntent cancel[33m 605[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m6. delete opens ConfirmDialog[33m 577[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22madd button[2m > [22mdoes not render add button when createTarget is not set (no fallback)[32m 224[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mrendering states[2m > [22mrenders field values correctly via MetadataCard[33m 548[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders edit mode title[33m 404[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrow click[2m > [22mnavigates via rowTargetOverride on click when override is set[32m 225[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/ListSurface.test.tsx[2m > [22mListSurface[2m > [22mrender contract[2m > [22mrender is optional — ColumnConfig is valid without render[32m 23[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrow click[2m > [22mrowTargetOverride takes precedence over rowTarget[32m 107[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders form fields based on fieldPolicy[33m 335[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mrendering states[2m > [22muses default grouping when readGrouping is not set[32m 111[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrow click[2m > [22mnavigates to derived default pathname/id when no rowTarget and no override[32m 111[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mdoes not render fields with visible: false[32m 200[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mfilters slot[2m > [22mrenders filtersSlot when provided alongside data[32m 163[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mfilters slot[2m > [22mdoes not render filters-slot when filtersSlot is not provided[32m 72[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mcancel[2m > [22m[2mfalls back to onCancel callback [22m[39mAn update to Crud inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mcancel[2m > [22mnavigates with :id replaced in edit mode cancel[33m 510[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders disabled input for fields with editable: false[32m 183[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mcancel[2m > [22m[2mfalls back to onCancel callback [22m[39mAn update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mwiring[2m > [22mrenders edit button when edit target is set[32m 291[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mrenders pagination controls with prev/next buttons[32m 33[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mdisables prev button when offset is 0[32m 26[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22menables prev button when offset > 0[32m 41[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mwiring[2m > [22mcalls navigate with edit target when edit button clicked[33m 323[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders modal with dialog role for accessibility[32m 134[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m7. delete confirm calls onClick[33m 936[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mdisables next button when hasMore is false[32m 34[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mdisables next button when hasMore is undefined and data length < pageSize (fallback)[32m 66[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m8. delete disabled is muted[32m 220[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22m9. extra renders before Edit[32m 75[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mcancel[2m > [22mfalls back to onCancel callback[33m 683[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22menables next button when hasMore is true[32m 170[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22menables next button when hasMore is true even with less data than pageSize[32m 40[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mwiring[2m > [22mdoes not render edit button when actionTargets.edit is not set[32m 166[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mrendering[2m > [22mrenders Save and Cancel buttons in modal footer[32m 245[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mreads offset from URL search params[32m 75[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22muses fixedParams.limit as pageSize when provided[32m 51[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mwiring[2m > [22medit button navigates to configured target when actionTargets.edit is set[32m 223[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mdefaults pageSize to 25 when no fixedParams.limit[32m 64[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mshows totalEstimate in pagination display when >= 0[32m 63[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m10. renders external delete button when deleteState is provided[32m 28[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m11. external delete button click calls requestDelete[32m 82[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mpending state[2m > [22mdisables fieldset and modal buttons when pending[32m 261[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mwiring[2m > [22mrenders edit button when actionTargets.edit is present[32m 151[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22moverrides[2m > [22mrenders custom loading fragment[32m 12[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22moverrides[2m > [22mrenders custom empty fragment[32m 15[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22moverrides[2m > [22mrenders custom error fragment[32m 13[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22moverrides[2m > [22mwraps in layoutWrapper from overrides[32m 38[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22msuccess[2m > [22mnavigates to successTarget with id replaced from mutation result (add)[33m 344[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mhides "of" in pagination display when totalEstimate is -1[32m 65[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mhides "of" in pagination display when totalEstimate is undefined[32m 27[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mfalls back to total for pagination display when totalEstimate is missing but total is set[32m 60[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mpending state[2m > [22mpending makes fields read-only via isEditable check[32m 186[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22msuccess[2m > [22mnavigates using route param id in edit mode[33m 387[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2msuccess[2m > [22m[2mfalls back to onSuccess callback [22m[39mAn update to Crud inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mresets offset when sort changes[32m 81[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2msuccess[2m > [22m[2mfalls back to onSuccess callback [22m[39mAn update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfailure and loading states[2m > [22mrenders failure message and retry button[32m 234[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mpagination[2m > [22mresets offset when filter changes[32m 294[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22msort + filter param merge[2m > [22mincludes stripped filter params and excludes prefixed internal keys[32m 33[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mrenders delete button when actionTargets.delete=true and deleteState is present[32m 59[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdoes not render delete button when actionTargets.delete is not set[32m 23[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdoes not render delete button when deleteState is null[32m 17[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdelete button click calls deleteState.requestDelete[32m 30[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m12. shows confirm dialog when showConfirm is true[32m 256[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22msuccess[2m > [22mfalls back to onSuccess callback[33m 332[2mms[22m[39m (node:443) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfailure and loading states[2m > [22mretry button calls failure.retry[32m 253[2mms[22m[39m (node:429) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfailure and loading states[2m > [22mrenders loading state when pending[33m 355[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22msort + filter param merge[2m > [22mdoes not break fixedParams[32m 33[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22msuccess[2m > [22mfalls back to cancelTarget when successTarget has :id but mutation returns no id[32m 229[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mrenders confirm-delete-dialog when deleteState.showConfirm is true[33m 517[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdoes not render confirm-delete-dialog when showConfirm is false[32m 40[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mcloseIntent[2m > [22mcalls onSuccess when closeIntent is success[32m 202[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m13. confirm button calls confirmDelete[33m 687[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mextra[2m > [22mrenders extra Button in header bar[33m 598[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mextra[2m > [22mDOM order: extra container before Add button within header flex[32m 38[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mextra[2m > [22mundefined does not break[32m 39[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mcloseIntent[2m > [22mcalls onClose when closeIntent is cancel[32m 154[2mms[22m[39m (node:422) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mmutation tracking[2m > [22m[2mdoes not navigate before coordinator emits closeIntent [22m[39mAn update to Crud inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22msuccess[2m > [22mfalls back to entityPath when successTarget has :id, mutation returns no id, and no cancelTarget[33m 442[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m14. cancel button calls cancelDelete[33m 602[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mmutation tracking[2m > [22m[2mdoes not navigate before coordinator emits closeIntent [22m[39mAn update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m15. confirm button disabled when isPending[32m 221[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m16. renders deleteError when provided[32m 28[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mextra[2m > [22monClick callback is invoked when button clicked[32m 165[2mms[22m[39m (node:436) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mcancel button calls deleteState.cancelDelete[33m 438[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22muser interactions[2m > [22mSave button triggers snapshot.submit[32m 208[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mmutation tracking[2m > [22m[2mstays on page when failure is present [22m[39mAn update to Crud inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mmutation tracking[2m > [22mdoes not navigate before coordinator emits closeIntent[33m 490[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mextra[2m > [22mfragment with multiple buttons renders all[33m 334[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22muser interactions[2m > [22mupdateField is called when input value changes[32m 295[2mms[22m[39m [90mstderr[2m | src/layers/__tests__/L2R/Crud.test.tsx[2m > [22m[2mCrud slot — route handoff[2m > [22m[2mmutation tracking[2m > [22m[2mstays on page when failure is present [22m[39mAn update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to FocusScope inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to Presence inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act An update to DismissableLayer inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22msort toggle[2m > [22mcycles sort: none -> asc -> desc -> none[32m 196[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrefresh button[2m > [22mrefresh button visible when SSE not enabled[32m 38[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrefresh button[2m > [22mrefresh button visible when SSE is enabled[32m 32[2mms[22m[39m [32m✓[39m src/layers/__tests__/config-contracts.test.ts[2m > [22mconfig contracts — CrudConfig minimum requirements[2m > [22mevery CrudConfig has entityPath[32m 40[2mms[22m[39m [32m✓[39m src/layers/__tests__/config-contracts.test.ts[2m > [22mconfig contracts — CrudConfig minimum requirements[2m > [22mevery CrudConfig has fieldSet with at least one field[32m 7[2mms[22m[39m [32m✓[39m src/layers/__tests__/config-contracts.test.ts[2m > [22mconfig contracts — CrudConfig minimum requirements[2m > [22mall collection-page configs have both successTarget and cancelTarget[32m 5[2mms[22m[39m [32m✓[39m src/layers/__tests__/config-contracts.test.ts[2m > [22mconfig contracts — CrudConfig minimum requirements[2m > [22mall detail-page configs have both successTarget and cancelTarget[32m 6[2mms[22m[39m [32m✓[39m src/layers/__tests__/config-contracts.test.ts[2m > [22mconfig contracts — CrudConfig minimum requirements[2m > [22mall entity-select fields have corresponding entitySelectSources[32m 6[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mconfirm button calls deleteState.confirmDelete[33m 658[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22mexternal deleteState integration[2m > [22m17. no internal DeleteButton when deleteState is provided[32m 73[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22moverrides[2m > [22m18. renders custom error fragment via overrides[32m 20[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22moverrides[2m > [22m19. renders custom loading fragment via overrides[32m 14[2mms[22m[39m [32m✓[39m src/shared/components/CrudReadCard.test.tsx[2m > [22mCrudReadCard[2m > [22moverrides[2m > [22m20. renders custom empty fragment via overrides[32m 27[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mconfirm button is disabled when isPending is true[32m 282[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mrenders delete-error when deleteState.error is not null[32m 22[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdoes not render delete-error when error is null[32m 24[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mmutation tracking[2m > [22mstays on page when failure is present[33m 347[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mcalls onDeleteSuccess when delete transitions from pending to done without error[32m 54[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdoes not call onDeleteSuccess when pending transition has error[32m 38[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mdoes not call onDeleteSuccess while still pending[32m 18[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22muser interactions[2m > [22mdirty guard[2m > [22mcalls cancel directly when dirty=false on Cancel click[32m 198[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mDetailSurface — delete UI contract[2m > [22mcalls onDeleteSuccess at most once during repeated pending→done cycles[32m 38[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mfield formatters[2m > [22mapplies formatter for fields with formatter defined[32m 24[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mfield formatters[2m > [22mapplies ReactNode formatter[32m 30[2mms[22m[39m [32m✓[39m src/layers/L2R/slots/DataTable.test.tsx[2m > [22mDataTable slot[2m > [22mrefresh button[2m > [22mrefresh button calls refetch[32m 52[2mms[22m[39m (node:453) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mdefault navigation (without successTarget / onSuccess)[2m > [22mnavigates to detail page on success when no successTarget or onSuccess (add mode)[33m 317[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m1. opens EventSource on mount: connecting → connected[33m 328[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m2. closes EventSource on unmount[32m 16[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m3. entity.created → onEvent({ type: "created", data })[32m 46[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m4. entity.updated → onEvent({ type: "updated", data })[32m 12[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mfield formatters[2m > [22mfalls back to String() when no formatter for field[32m 68[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mfield formatters[2m > [22mpasses entity as second argument to formatter[32m 24[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m5. exponential backoff: 1s → 2s → 4s[32m 31[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m6. 5 consecutive failures → connection-lost + onConnectionLost[32m 28[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m7. successful reconnect resets backoff to 1s[32m 42[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mextra[2m > [22mforwards extra buttons to CrudReadCard when provided[32m 199[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m8. reconnect() manually reopens EventSource[32m 36[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m9. heartbeat (: heartbeat) does not trigger onEvent[32m 27[2mms[22m[39m [32m✓[39m src/shared/hooks/useSSE.test.ts[2m > [22museSSE[2m > [22m10. url change closes old EventSource and opens new one[32m 29[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/Crud.test.tsx[2m > [22mCrud slot — route handoff[2m > [22mdefault navigation (without successTarget / onSuccess)[2m > [22mnavigates back in history on cancel without cancelTarget or onCancel[32m 278[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mextra[2m > [22mextra buttons render before Edit button in CrudReadCard[32m 153[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22muser interactions[2m > [22mdirty guard[2m > [22mopens DiscardDialog when dirty=true on Cancel click[33m 354[2mms[22m[39m [32m✓[39m src/layers/L2R/surfaces/DetailSurface.test.tsx[2m > [22mDetailSurface[2m > [22mextra[2m > [22mrenders multiple extra buttons via fragment[32m 148[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22muser interactions[2m > [22mdirty guard[2m > [22mDiscard in modal DiscardDialog calls cancel[33m 694[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinatorFK.test.tsx[2m > [22mcoordinator FK refresh (§7 DoD-3)[2m > [22mcalls refetchQueries when activeCrud is truthy[32m 150[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinatorFK.test.tsx[2m > [22mcoordinator FK refresh (§7 DoD-3)[2m > [22mcalls refetchQueries for each entitySelectSource with cancelRefetch: false[32m 18[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinatorFK.test.tsx[2m > [22mcoordinator FK refresh (§7 DoD-3)[2m > [22mdoes NOT call refetchQueries when activeCrud is null (no modal)[32m 21[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinatorFK.test.tsx[2m > [22mcoordinator FK refresh (§7 DoD-3)[2m > [22mdoes NOT call refetchQueries when entitySelectSources is empty[32m 23[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/coordinatorFK.test.tsx[2m > [22mcoordinator FK refresh (§7 DoD-3)[2m > [22mdoes NOT call refetchQueries when crud owner does not match[32m 12[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22muser interactions[2m > [22mdirty guard[2m > [22mKeep Editing in modal DiscardDialog does not call cancel[33m 833[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22moverrides[2m > [22mrenders custom title label[32m 204[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22moverrides[2m > [22mrenders custom error fragment[32m 258[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22moverrides[2m > [22mrenders custom loading fragment[32m 177[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22moverrides[2m > [22mrenders fields in custom order[32m 140[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders text input by default[32m 82[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders text input for type text[32m 127[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders textarea for type textarea[32m 226[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar[2m > [22mrenders filter legends for all filter types[33m 478[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders password input for type password[32m 151[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22mresolveContract[2m > [22mresolves repositories contract[32m 11[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22mresolveContract[2m > [22mresolves projects contract[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22mresolveContract[2m > [22mresolves runs contract[32m 1[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22mresolveContract[2m > [22mresolves pipelines contract[32m 1[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22mresolveContract[2m > [22mreturns the same contract as the static registry[32m 4[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar[2m > [22mdoes not render clear button when no active filters[32m 103[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityList[2m > [22mreturns a ListResult-like shape for repositories[32m 263[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityList[2m > [22mreturns a ListResult-like shape for projects[32m 40[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders checkbox for type checkbox[32m 130[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar[2m > [22mrenders clear button when at least one filter is active[32m 122[2mms[22m[39m (node:462) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityList[2m > [22mreturns a ListResult-like shape for runs[32m 79[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityList[2m > [22mreturns a ListResult-like shape for pipelines[32m 58[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders entity-select for type entity-select[32m 259[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityList[2m > [22mpasses params through to the query[32m 154[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityDetail[2m > [22mreturns a DetailResult-like shape[32m 76[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museEntityDetail[2m > [22mworks for runs with run_id-based entities[32m 97[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museMutation[2m > [22mreturns a MutationHandle-like shape[32m 63[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museMutation[2m > [22mworks for all entity paths[32m 32[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museSubscription[2m > [22mreturns a SubscriptionHandle-like shape[32m 49[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/entityResolver.test.tsx[2m > [22mentityResolver[2m > [22museSubscription[2m > [22mworks for all entity paths[32m 60[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mfield types[2m > [22mrenders kv-editor for type kv-editor[32m 187[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar[2m > [22mcalls onClear when clear button is clicked[33m 1053[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — multi-select[2m > [22mrenders all options[32m 99[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — multi-select[2m > [22mcalls onChange when an option is clicked[32m 148[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — multi-select[2m > [22mtoggles option off when already active[32m 124[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mdefault rendering without targets[2m > [22mrenders form and buttons with default snapshot (no closeIntent)[33m 646[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — multi-select[2m > [22mcalls onChange with undefined when last option deselected[32m 152[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22museBlocker dirty guard[2m > [22mshows DiscardDialog when blocker state is blocked and proceed is called on confirm[33m 523[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — multi-select[2m > [22msets aria-label on option buttons[32m 84[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — select[2m > [22mrenders all options plus "All" default[32m 64[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22museBlocker dirty guard[2m > [22mdoes not show DiscardDialog when blocker is unblocked (dirty=false)[32m 153[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22museBlocker dirty guard[2m > [22mKeep Editing in blocker DiscardDialog calls blocker.reset[33m 330[2mms[22m[39m (node:470) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — select[2m > [22mcalls onChange with selected value[33m 431[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — select[2m > [22mcalls onChange with undefined when "All" is selected[33m 388[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mcheckbox field value[2m > [22mcalls updateField with boolean checked value, not string value[32m 290[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — select[2m > [22mpreselects the current value[32m 71[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — date-range[2m > [22mrenders preset options[32m 44[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/CrudSurface.test.tsx[2m > [22mCrudSurface[2m > [22mbackdrop click[2m > [22mbackdrop click does not close the modal[33m 314[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseRealConnection.integration.test.tsx[2m > [22mSseRealConnection — real EventSource + MSW SSE handler[2m > [22mconnects via MSW and receives SSE events into query cache[33m 591[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — date-range[2m > [22mcalls onChange when a preset is clicked[32m 274[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — date-range[2m > [22mcalls onChange with undefined when active preset is clicked again[32m 105[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — integration[2m > [22mclear button appears when any filter type has a value[32m 164[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/FilterBar.test.tsx[2m > [22mFilterBar — integration[2m > [22mcombines multiple active filters[32m 85[2mms[22m[39m (node:483) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:499) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:491) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L1/SseRealConnection.integration.test.tsx[2m > [22mSseRealConnection — real EventSource + MSW SSE handler[2m > [22mon connection loss transitions to reconnecting and recovers on new connection[33m 1378[2mms[22m[39m [90mstderr[2m | src/shared/hooks/useFilterState.test.tsx[2m > [22m[2museFilterState[2m > [22m[2m1. prefix prepends prefix to URL params [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m1. prefix prepends prefix to URL params[32m 170[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m2. setFilter merges, does not replace other params[32m 44[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m3. clearFilters removes filters, preserves sort defaults in memory[32m 24[2mms[22m[39m (node:477) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L1/SseRealConnection.integration.test.tsx[2m > [22mSseRealConnection — real EventSource + MSW SSE handler[2m > [22mwith fake timers — backoff, lost, reconnect, heartbeat[2m > [22m5 connection failures via 500 responses → lost state[33m 373[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m4. setSort cycles: asc → desc → none (returns to default)[32m 48[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22msetSort with explicit order[32m 107[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m5. clearFilters does NOT write sort defaults to URL[32m 42[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m6. multiple prefixes do not collide[32m 92[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m7. arrays serialized as pipe-delimited[32m 36[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22m8. undefined removes param entirely[32m 21[2mms[22m[39m [32m✓[39m src/shared/hooks/useFilterState.test.tsx[2m > [22museFilterState[2m > [22mgetFilter returns current value for key[32m 10[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/SseRealConnection.integration.test.tsx[2m > [22mSseRealConnection — real EventSource + MSW SSE handler[2m > [22mwith fake timers — backoff, lost, reconnect, heartbeat[2m > [22mreconnect() from lost state transitions to connected[33m 531[2mms[22m[39m [2m[90m↓[39m[22m src/layers/__tests__/L1/SseRealConnection.integration.test.tsx[2m > [22mSseRealConnection — real EventSource + MSW SSE handler[2m > [22mwith fake timers — backoff, lost, reconnect, heartbeat[2m > [22mheartbeat checker triggers lost at 30s — skipped: eventsource uses setTimeout internally for stream reader; fake timers freeze open streams [2m[90m↓[39m[22m src/layers/__tests__/L1/SseRealConnection.integration.test.tsx[2m > [22mSseRealConnection — real EventSource + MSW SSE handler[2m > [22mwith fake timers — backoff, lost, reconnect, heartbeat[2m > [22mheartbeat event resets timestamp — skipped: same eventsource + fake timers incompatibility as above [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mreturns an object with all BehaviorContract functions[32m 30[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mdefaults() returns an object[32m 3[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mpopulate(entity) returns a copy[32m 6[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mtoCreate(form) returns a partial copy[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mtoUpdate(form) returns a partial copy[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mfieldPolicy(mode) returns an empty FieldPolicy[32m 4[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateDefaultBehaviorContract[2m > [22mpopulated entity does not mutate original[32m 4[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mreturns empty policy when no fieldBehavior config[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mapplies visible constraint for add mode[32m 9[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mapplies visibility constraint for edit mode[32m 6[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mapplies editable constraint per mode[32m 8[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mapplies both visible and editable together[32m 33[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22msplits policy by mode independently[32m 7[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mhandles unknown fields gracefully[32m 16[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2W/behaviorContract.test.ts[2m > [22mcreateFieldPolicyFromConfig[2m > [22mreturns FieldPolicy that satisfies the type contract[32m 11[2mms[22m[39m (node:505) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:516) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mreturns runs without filter[33m 367[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mfilters by created_after (30 days)[32m 31[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mfilters by created_after (24 hours)[32m 31[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mhandles invalid created_after gracefully[32m 26[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mhandles today shorthand gracefully[32m 26[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mfilters by project_id[32m 159[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22mfilters by multiple project_ids[32m 24[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22msorts by tokens desc[32m 79[2mms[22m[39m [32m✓[39m src/msw/__tests__/runs-handler.test.ts[2m > [22mruns MSW handler[2m > [22msorts by tokens asc[32m 38[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22maddPendingDelete + getPendingDeletes[2m > [22madds an id to the set for an entityPath[32m 15[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22maddPendingDelete + getPendingDeletes[2m > [22madds multiple ids to the same entityPath[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22maddPendingDelete + getPendingDeletes[2m > [22mhandles multiple entityPaths independently[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mremovePendingDelete[2m > [22mremoves a specific id[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mremovePendingDelete[2m > [22mis a no-op when id does not exist[32m 14[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mremovePendingDelete[2m > [22mis a no-op when entityPath has no entries[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22misMarkedDeleted[2m > [22mreturns true for a marked id[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22misMarkedDeleted[2m > [22mreturns false for an unmarked id[32m 1[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22misMarkedDeleted[2m > [22mreturns false for unknown entityPath[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mpopulatePendingDeletes[2m > [22mpopulates from an array of entries[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mpopulatePendingDeletes[2m > [22mdeduplicates when same id appears twice[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mgetAllPendingDeleteEntries[2m > [22mreturns empty array when map is empty[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mgetAllPendingDeleteEntries[2m > [22mreturns all entries as flat array[32m 8[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mpurgePendingDeletes[2m > [22mreturns and removes all ids for an entityPath[32m 5[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mpurgePendingDeletes[2m > [22mreturns empty set for unknown entityPath[32m 2[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mpendingDeleteMap[2m > [22mpurgePendingDeletes[2m > [22mdoes not affect other entityPaths[32m 1[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mnormalizeFilters[2m > [22mremoves undefined values[32m 7[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mnormalizeFilters[2m > [22mremoves empty string values[32m 7[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mnormalizeFilters[2m > [22msorts keys alphabetically[32m 45[2mms[22m[39m [32m✓[39m src/layers/__tests__/L1/mutationQueue.test.ts[2m > [22mnormalizeFilters[2m > [22mreturns empty object for all-empty filters[32m 1[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/AgeCheckIndicator.test.tsx[2m > [22mAgeCheckIndicator[2m > [22mrenders children when refCount > 0 (SSE view)[33m 414[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/AgeCheckIndicator.test.tsx[2m > [22mAgeCheckIndicator[2m > [22mrenders children when refCount === 0 and data is fresh[32m 18[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/AgeCheckIndicator.test.tsx[2m > [22mAgeCheckIndicator[2m > [22mrenders skeleton + message + refresh button when refCount === 0 and data is stale[33m 401[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/AgeCheckIndicator.test.tsx[2m > [22mAgeCheckIndicator[2m > [22mrefresh button calls invalidateQueries when no onRefresh provided[32m 133[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/AgeCheckIndicator.test.tsx[2m > [22mAgeCheckIndicator[2m > [22mrefresh button calls onRefresh when provided[32m 78[2mms[22m[39m (node:526) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [90mstderr[2m | src/layers/__tests__/L2R/EntityDetail.test.tsx[2m > [22m[2mEntityDetail — delete navigation[2m > [22m[2mnavigates to entityPath on delete success without custom onDeleteSuccess [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. (node:534) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/layers/__tests__/L2R/EntityDetail.test.tsx[2m > [22mEntityDetail — delete navigation[2m > [22mnavigates to entityPath on delete success without custom onDeleteSuccess[33m 1589[2mms[22m[39m [32m✓[39m src/layers/__tests__/L2R/EntityDetail.test.tsx[2m > [22mEntityDetail — delete navigation[2m > [22mcalls custom onDeleteSuccess and does not default navigate[32m 141[2mms[22m[39m (node:550) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:541) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:557) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:558) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [90mstderr[2m | src/features/bot-accounts/BotAccountsListTab.test.tsx[2m > [22m[2mBotAccountsListTab[2m > [22m[2mrenders DataTable with mock bot account names [22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition. ⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath. (node:572) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) [32m✓[39m src/features/bot-accounts/BotAccountsListTab.test.tsx[2m > [22mBotAccountsListTab[2m > [22mrenders DataTable with mock bot account names[33m 2035[2mms[22m[39m [31m×[39m src/features/bot-accounts/BotAccountsListTab.test.tsx[2m > [22mBotAccountsListTab[2m > [22mdisplays Name, Description, Created, Used By columns[33m 302[2mms[22m[39m [31m → Unable to find an element with the text: Used By. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. Ignored nodes: comments, script, style [36m
[31m [36m| [31m [36m[31m [0mName[0m [36m[31m [36m[31m [36m | [31m [36m[31m [36m[31m [0mDescription[0m [36m[31m [36m | [31m [36m[31m [36m[31m [0mCreated[0m [36m[31m [36m | [31m [36m||
|---|---|---|---|---|
| [22mBotAccountsListTab[2m > [22mname links do NOT contain ?tab=accounts[32m 193[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/BotAccountsListTab.test.tsx[2m > [22mBotAccountsListTab[2m > [22mshows create button with label "+ New Bot Account"[32m 129[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/BotAccountsListTab.test.tsx[2m > [22mBotAccountsListTab[2m > [22mcreateTarget leads to /repositories/bot-accounts/add[32m 230[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/BotAccountsListTab.test.tsx[2m > [22mBotAccountsListTab[2m > [22mrenders Crud component[32m 73[2mms[22m[39m
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2mreturns ageMs for data that is N ms old
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2misStale === true when ageMs > AGE_THRESHOLD
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2misStale === false when ageMs <= AGE_THRESHOLD
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2mupdates when cache subscription fires
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2mupdates when cache subscription fires
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2mupdates when cache subscription fires
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
An update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[32m✓[39m src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22museDataAge[2m > [22mreturns ageMs for data that is N ms old[32m 141[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22museDataAge[2m > [22misStale === true when ageMs > AGE_THRESHOLD[32m 21[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22museDataAge[2m > [22misStale === false when ageMs <= AGE_THRESHOLD[32m 28[2mms[22m[39m
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mwindow online event updates isOnline
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mpendingCount matches getOutboxEntries length
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mlastSynced is null when cache is empty
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22m[2museDataAge[2m > [22m[2mupdates on minute tick (fakeTimers)
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mlastSynced reflects max dataUpdatedAt
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mlastSynced reflects max dataUpdatedAt
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22misOnline === false when navigator.onLine is false[32m 141[2mms[22m[39m
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22misOnline === true by default[32m 10[2mms[22m[39m
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22mwindow online event updates isOnline[32m 33[2mms[22m[39m
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22mpendingCount matches getOutboxEntries length[32m 10[2mms[22m[39m
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22mlastSynced is null when cache is empty[32m 10[2mms[22m[39m
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mqueryClient.invalidateQueries updates lastSynced
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
An update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[90mstderr[2m | src/lib/__tests__/useOfflineState.test.tsx[2m > [22m[2museOfflineState[2m > [22m[2mqueryClient.invalidateQueries updates lastSynced
[22m[39mAn update to TestComponent inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mremoves inactive queries older than retention threshold[32m 69[2mms[22m[39m
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mdoes not remove queries under retention threshold accounting for interval delay[32m 10[2mms[22m[39m
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22mlastSynced reflects max dataUpdatedAt[32m 25[2mms[22m[39m
[32m✓[39m src/lib/__tests__/useOfflineState.test.tsx[2m > [22museOfflineState[2m > [22mqueryClient.invalidateQueries updates lastSynced[32m 9[2mms[22m[39m
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mdoes not remove active queries with observers[32m 159[2mms[22m[39m
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mremoves only exact matching query keys[32m 21[2mms[22m[39m
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mskips eviction entirely when offline[32m 5[2mms[22m[39m
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mreturns a cleanup function that stops the interval[32m 4[2mms[22m[39m
[32m✓[39m src/lib/__tests__/queryCacheEviction.test.tsx[2m > [22mstartCacheEviction[2m > [22mevicts only queries older than threshold across multiple entity paths[32m 7[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22museDataAge[2m > [22mupdates when cache subscription fires[32m 44[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/useDataAge.test.tsx[2m > [22museDataAge[2m > [22mupdates on minute tick (fakeTimers)[32m 31[2mms[22m[39m
(node:581) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[90mstderr[2m | src/features/repositories/RepositoriesPage.test.tsx[2m > [22m[2mRepositoriesPage layout[2m > [22m[2mrenders Tabs component with Repositories and Bot Accounts
[22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition.
⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath.
[90mstderr[2m | src/features/bot-accounts/BotAccountDetailPage.test.tsx[2m > [22m[2mBotAccountDetailPage[2m > [22m[2mrenders account name in the page title
[22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition.
⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath.
[32m✓[39m src/features/bot-accounts/BotAccountDetailPage.test.tsx[2m > [22mBotAccountDetailPage[2m > [22mrenders account name in the page title[33m 1373[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mrenders Tabs component with Repositories and Bot Accounts[33m 1199[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m1. open=false renders nothing[33m 338[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mactive tab is determined from URL pathname, not React state[32m 161[2mms[22m[39m
(node:590) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mbot-accounts tab is active when URL contains /bot-accounts[32m 295[2mms[22m[39m
(node:597) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m2. open=true renders title, children, footer[33m 1330[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mclicking Repositories tab navigates to /repositories/repos[32m 226[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/BotAccountDetailPage.test.tsx[2m > [22mBotAccountDetailPage[2m > [22mrenders edit dialog with "Edit Bot Account" title when edit route activated[33m 622[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m3. Backdrop click does not close dialog[33m 519[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mclicking Bot Accounts tab navigates to /repositories/bot-accounts[33m 446[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mdoes NOT render DataTable directly (only via Outlet)[32m 259[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m4. Cancel pristine calls onClose[33m 360[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/BotAccountDetailPage.test.tsx[2m > [22mBotAccountDetailPage[2m > [22mbreadcrumb Bot Accounts link does NOT contain ?tab=accounts[33m 596[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesPage.test.tsx[2m > [22mRepositoriesPage layout[2m > [22mdoes NOT render Crud directly (only via child routes)[32m 92[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/BotAccountDetailPage.test.tsx[2m > [22mBotAccountDetailPage[2m > [22mbreadcrumb Repositories link points to /repositories/repos[33m 418[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m5. Cancel dirty opens DiscardDialog[33m 917[2mms[22m[39m
[90mstderr[2m | src/features/repositories/RepositoriesList.test.tsx[2m > [22m[2mRepositoriesList[2m > [22m[2mrenders DataTable with columns
[22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition.
⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath.
[32m✓[39m src/lib/__tests__/mutationOutbox.test.ts[2m > [22mreplayOutbox[2m > [22mtriggers refetchQueries({ stale: true }) after successful drain[32m 35[2mms[22m[39m
[32m✓[39m src/lib/__tests__/mutationOutbox.test.ts[2m > [22mreplayOutbox[2m > [22mdoes NOT call refetchQueries({ stale: true }) when failed > 0[32m 5[2mms[22m[39m
[32m✓[39m src/lib/__tests__/mutationOutbox.test.ts[2m > [22mreplayOutbox[2m > [22mrefetchQueries is called after delete replay drain[32m 5[2mms[22m[39m
[32m✓[39m src/lib/__tests__/mutationOutbox.test.ts[2m > [22mreplayOutbox[2m > [22mskips refetchQueries when outbox is empty[32m 2[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesList.test.tsx[2m > [22mRepositoriesList[2m > [22mrenders DataTable with columns[33m 844[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesList.test.tsx[2m > [22mRepositoriesList[2m > [22mrenders Crud component[33m 406[2mms[22m[39m
[90mstderr[2m | src/features/auth/CallbackPage.test.tsx[2m > [22m[2mCallbackPage[2m > [22m[2mnavigates to dashboard when session fetch succeeds
[22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition.
⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath.
(node:606) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/features/auth/CallbackPage.test.tsx[2m > [22mCallbackPage[2m > [22mnavigates to dashboard when session fetch succeeds[33m 1124[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesList.test.tsx[2m > [22mRepositoriesList[2m > [22mcreate button label is "+ New Repository"[33m 438[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mshows loading state[33m 1417[2mms[22m[39m
[32m✓[39m src/features/auth/CallbackPage.test.tsx[2m > [22mCallbackPage[2m > [22msets auth store with session data when fetch succeeds[32m 111[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m6. Discard → onClose, Keep → dialog stays[33m 1554[2mms[22m[39m
[32m✓[39m src/features/auth/CallbackPage.test.tsx[2m > [22mCallbackPage[2m > [22mnavigates to returnUrl when set in sessionStorage[32m 176[2mms[22m[39m
[32m✓[39m src/features/auth/CallbackPage.test.tsx[2m > [22mCallbackPage[2m > [22mshows error when session fetch fails[32m 67[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mshows empty state[32m 251[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mshows error state[32m 85[2mms[22m[39m
[32m✓[39m src/features/repositories/RepositoriesList.test.tsx[2m > [22mRepositoriesList[2m > [22mrenders data table with repository rows[33m 364[2mms[22m[39m
[32m✓[39m src/features/auth/CallbackPage.test.tsx[2m > [22mCallbackPage[2m > [22mshows redirecting message and redirects to login on error[32m 47[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m7. ESC dirty opens DiscardDialog[33m 395[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m8. ESC pristine calls onClose[33m 392[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22msupports single select[33m 654[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m9. Save calls onSave[33m 350[2mms[22m[39m
(node:626) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m10. isPending disables Save + Cancel and shows spinner[32m 199[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22msupports multi select[33m 590[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mdisplays placeholder when value is undefined[32m 40[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mrenders readOnly single mode as text[32m 27[2mms[22m[39m
(node:619) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:613) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mrenders readOnly multi mode as comma-separated labels[32m 59[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mrenders raw value in readOnly when no match[32m 42[2mms[22m[39m
[32m✓[39m src/shared/components/CrudModal.test.tsx[2m > [22mCrudModal[2m > [22m11. cancelLabel prop overrides the cancel button text[32m 178[2mms[22m[39m
[32m✓[39m src/shared/components/EntitySelect.test.tsx[2m > [22mEntitySelect[2m > [22mdisables the trigger when disabled prop is true[32m 74[2mms[22m[39m
[90mstderr[2m | src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22m[2mCrudRoute[2m > [22m[2msets route context on mount with id (detail page)
[22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition.
⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath.
[32m✓[39m src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22mCrudRoute[2m > [22msets route context on mount with id (detail page)[32m 253[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22mCrudRoute[2m > [22msets route context on mount without id (collection page)[32m 38[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22mCrudRoute[2m > [22msets route context with prefix when provided[32m 38[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22mCrudRoute[2m > [22mcleans up (sets null) on unmount[32m 16[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22mCrudRoute[2m > [22mdoes not re-set context on re-render with same props[32m 24[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/routes/CrudRoute.test.tsx[2m > [22mCrudRoute[2m > [22mre-sets context when id changes[32m 102[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22mstarts with dirty=false and pending=false[32m 192[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22msetDirty(true) sets dirty=true on bridge[32m 17[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22msetDirty(false) sets dirty=false on bridge[32m 10[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22msetPending(true) sets pending=true on bridge[32m 18[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22msetPending(false) sets pending=false on bridge[32m 25[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22mmarkDirty() sets dirty=true[32m 14[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22mreset() clears both dirty and pending[32m 29[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22msupports dirty → pending transition (submit start)[32m 9[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22msupports pending → not pending transition while dirty stays (failure case)[32m 30[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2W/formBridge.test.ts[2m > [22museFormBridge[2m > [22mbridge object reflects current state[32m 14[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mreturns a function when edit target is present[32m 44[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22mincrementRefCount[2m > [22mincreases count and notifies subscribed listener[32m 17[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22mdecrementRefCount[2m > [22mdecreases count and notifies subscribed listener[32m 3[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22mdecrementRefCount[2m > [22mremoves key when count reaches 0[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22mdecrementRefCount[2m > [22mreturns 0 when decrementing a non-existent key[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22msubscribeRefCount[2m > [22mreturns an unsubscribe function that stops notifications[32m 21[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22mkey isolation[2m > [22mnotifies only the subscribed key, not other keys[32m 11[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L1/RefCountStore.test.ts[2m > [22mrefCountStore[2m > [22mrefCountKey[2m > [22mproduces idempotent keys for same entityPath and params[32m 7[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mcalls navigate with edit target and replaced id[32m 14[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mfalls back to pathname + /edit when actionTargets is undefined[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mfalls back to pathname + /edit when actionTargets.edit is undefined[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mfalls back to pathname + /edit when actionTargets.edit is missing[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mcalls navigate with the replaced id correctly[32m 1[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mexplicit edit target takes precedence over derived default[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22mderives default from the provided pathname[32m 1[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultEditNav.test.ts[2m > [22mcreateDefaultEditNavHandler[2m > [22meditTargetOverride takes precedence over actionTargets.edit[32m 2[2mms[22m[39m
(node:638) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:645) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mreturns a function that accepts an id[32m 28[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mcalls navigate with rowTarget where :id is replaced[32m 21[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mreplaces :id with the provided id string[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mfalls back to pathname + /:id when rowTarget is undefined[32m 10[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mdoes not throw when rowTarget is undefined (derived default used)[32m 11[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mreplaces all occurrences of :id in the target[32m 7[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mleaves target unchanged if :id not present[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mexplicit rowTarget takes precedence over derived default[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultRowNav.test.ts[2m > [22mcreateDefaultRowNavHandler[2m > [22mderives default from the provided pathname[32m 7[2mms[22m[39m
(node:661) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:654) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m1. isDirty=false → blocker ei estä[32m 201[2mms[22m[39m
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m2. isDirty=true → blocker estää (isBlocked=true)[32m 9[2mms[22m[39m
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m3. submitted=true → blocker ei estä vaikka isDirty[32m 8[2mms[22m[39m
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m4. confirmNavigation → blocker.proceed() → nav jatkuu[32m 10[2mms[22m[39m
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m5. cancelNavigation → blocker.reset() → formi jää[32m 9[2mms[22m[39m
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m6. beforeunload estetään kun isDirty && !submitted[32m 10[2mms[22m[39m
[32m✓[39m src/shared/hooks/useDirtyGuard.test.ts[2m > [22museDirtyGuard[2m > [22m7. beforeunload EI estetä kun submitted[32m 7[2mms[22m[39m
(node:667) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:678) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:684) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:692) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22misOnline[2m > [22mreturns navigator.onLine value[32m 96[2mms[22m[39m
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22misOnline[2m > [22mreturns true when navigator is undefined (SSR safety)[32m 2[2mms[22m[39m
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22msubscribe[2m > [22mregisters listener that is called on online event[32m 18[2mms[22m[39m
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22msubscribe[2m > [22mregisters listener that is called on offline event[32m 13[2mms[22m[39m
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22msubscribe[2m > [22mcalls all active listeners on event[32m 14[2mms[22m[39m
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22msubscribe[2m > [22munsub prevents further calls[32m 14[2mms[22m[39m
[32m✓[39m src/lib/__tests__/onlineDetector.test.ts[2m > [22mOnlineDetector[2m > [22mgetOnlineDetector singleton[2m > [22mreturns the same instance on every call[32m 2[2mms[22m[39m
(node:700) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mdefaults[2m > [22mhas healthy status by default[32m 74[2mms[22m[39m
(node:708) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mdefaults[2m > [22mhas null responseTime by default[32m 12[2mms[22m[39m
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mdefaults[2m > [22mhas null lastChecked by default[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mdefaults[2m > [22mhas null apiVersion by default[32m 1[2mms[22m[39m
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mfetchHealth[2m > [22msets healthy status on success[32m 10[2mms[22m[39m
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mfetchHealth[2m > [22msets degraded status when services report issues[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/healthStore.test.ts[2m > [22mhealthStore[2m > [22mfetchHealth[2m > [22msets unhealthy status on network error[32m 39[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22mshows loading skeleton[33m 860[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22mshows error state with retry button[33m 637[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22mrenders labels and values in grid[32m 92[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22mrenders field with spanFull as col-span-full[32m 42[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22mshows em dash for empty value[32m 47[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22muses render callback over value[32m 37[2mms[22m[39m
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22madds a blank row on [+ Add row] click[33m 924[2mms[22m[39m
[32m✓[39m src/features/auth/authStore.test.ts[2m > [22mauthStore[2m > [22mstarts unauthenticated[32m 36[2mms[22m[39m
[32m✓[39m src/features/auth/authStore.test.ts[2m > [22mauthStore[2m > [22msetAuth sets authenticated state with TTL fields[32m 29[2mms[22m[39m
[32m✓[39m src/shared/components/MetadataCard.test.tsx[2m > [22mMetadataCard[2m > [22mrenders children instead of default layout[32m 35[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22mdefaults[2m > [22mhas sidebar open by default[32m 13[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22mdefaults[2m > [22mhas dark theme by default[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22mtoggleSidebar[2m > [22mcloses sidebar when open[32m 5[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22mtoggleSidebar[2m > [22mopens sidebar when closed[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22msetSidebarOpen[2m > [22msets sidebar to false[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22msetSidebarOpen[2m > [22msets sidebar to true[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22msetTheme[2m > [22msets theme to light[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22msetTheme[2m > [22msets theme to high-contrast[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22msetTheme[2m > [22msets theme to dark[32m 2[2mms[22m[39m
[32m✓[39m src/layouts/uiStore.test.ts[2m > [22muiStore[2m > [22mresetSession[2m > [22mrestores defaults[32m 2[2mms[22m[39m
(node:709) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/features/auth/authStore.test.ts[2m > [22mauthStore[2m > [22mclearAuth clears all auth state including TTL fields[32m 7[2mms[22m[39m
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22mremoves a row and emits without it[32m 251[2mms[22m[39m
[90mstderr[2m | src/features/auth/LoginPage.test.tsx[2m > [22m[2mLoginPage[2m > [22m[2mshows login heading, description and button
[22m[39m⚠️ React Router Future Flag Warning: React Router will begin wrapping state updates in `React.startTransition` in v7. You can use the `v7_startTransition` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_starttransition.
⚠️ React Router Future Flag Warning: Relative route resolution within Splat routes is changing in v7. You can use the `v7_relativeSplatPath` future flag to opt-in early. For more information, see https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath.
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22mshows duplicate key error but still emits onChange[33m 376[2mms[22m[39m
[32m✓[39m src/features/auth/LoginPage.test.tsx[2m > [22mLoginPage[2m > [22mshows login heading, description and button[33m 899[2mms[22m[39m
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22msanitizes empty keys from payload[32m 137[2mms[22m[39m
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22mrenders readOnly mode as static key: value lines[32m 56[2mms[22m[39m
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22mshows empty state text when value is undefined in readOnly[32m 8[2mms[22m[39m
[32m✓[39m src/shared/components/KeyValueEditor.test.tsx[2m > [22mKeyValueEditor[2m > [22mshows skeleton when isLoading[32m 17[2mms[22m[39m
[32m✓[39m src/features/auth/LoginPage.test.tsx[2m > [22mLoginPage[2m > [22mshows session expired message when expired query param is set[32m 268[2mms[22m[39m
[32m✓[39m src/features/auth/LoginPage.test.tsx[2m > [22mLoginPage[2m > [22mdoes not show expired message without expired param[32m 50[2mms[22m[39m
[32m✓[39m src/features/auth/LoginPage.test.tsx[2m > [22mLoginPage[2m > [22mshows error toast when error query param is set[32m 48[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultAddNav.test.ts[2m > [22mcreateDefaultAddNavHandler[2m > [22mreturns a function[32m 22[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultAddNav.test.ts[2m > [22mcreateDefaultAddNavHandler[2m > [22mcalls navigate with createTarget when invoked[32m 23[2mms[22m[39m
[32m✓[39m src/features/auth/LoginPage.test.tsx[2m > [22mLoginPage[2m > [22mredirects to dashboard when already authenticated[32m 101[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultAddNav.test.ts[2m > [22mcreateDefaultAddNavHandler[2m > [22mthrows when invoked without createTarget (no fallback allowed)[32m 23[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultAddNav.test.ts[2m > [22mcreateDefaultAddNavHandler[2m > [22mcalls navigate with the exact createTarget string when set[32m 2[2mms[22m[39m
[32m✓[39m src/layers/__tests__/L2R/defaultAddNav.test.ts[2m > [22mcreateDefaultAddNavHandler[2m > [22mempty-string createTarget is treated as missing (throws)[32m 7[2mms[22m[39m
[32m✓[39m src/features/auth/LoginPage.test.tsx[2m > [22mLoginPage[2m > [22mperforms mock login in dev mode and navigates to dashboard[33m 496[2mms[22m[39m
(node:726) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/DiscardDialog.test.tsx[2m > [22mDiscardDialog[2m > [22mdoes not render when closed[33m 461[2mms[22m[39m
(node:733) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/DiscardDialog.test.tsx[2m > [22mDiscardDialog[2m > [22mrenders with default title and description[33m 1356[2mms[22m[39m
[32m✓[39m src/shared/components/DiscardDialog.test.tsx[2m > [22mDiscardDialog[2m > [22mcalls onDiscard when Discard button clicked[33m 1023[2mms[22m[39m
[32m✓[39m src/shared/components/Page.test.tsx[2m > [22mPageHeader[2m > [22mrenders title[32m 237[2mms[22m[39m
[32m✓[39m src/shared/components/DiscardDialog.test.tsx[2m > [22mDiscardDialog[2m > [22mcalls onKeepEditing when Keep Editing button clicked[33m 331[2mms[22m[39m
[32m✓[39m src/shared/components/DiscardDialog.test.tsx[2m > [22mDiscardDialog[2m > [22mrenders custom title and description[32m 188[2mms[22m[39m
(node:742) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/Page.test.tsx[2m > [22mPageHeader[2m > [22mrenders breadcrumbs[32m 93[2mms[22m[39m
[32m✓[39m src/shared/components/DiscardDialog.test.tsx[2m > [22mDiscardDialog[2m > [22mcalls onKeepEditing on dialog dismiss (ESC)[33m 401[2mms[22m[39m
[32m✓[39m src/shared/components/Page.test.tsx[2m > [22mPageHeader[2m > [22mrenders actions slot[33m 855[2mms[22m[39m
[32m✓[39m src/shared/components/Page.test.tsx[2m > [22mPage[2m > [22mrenders children[32m 49[2mms[22m[39m
[32m✓[39m src/shared/components/Page.test.tsx[2m > [22mPage[2m > [22mpasses className to root div[32m 16[2mms[22m[39m
[32m✓[39m src/shared/components/Page.test.tsx[2m > [22mPage[2m > [22mrenders header slot[32m 45[2mms[22m[39m
(node:749) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/features/bot-accounts/botAccountsCrudConfig.test.ts[2m > [22mbotAccountsCrudConfig[2m > [22mfieldSet validations[2m > [22mname requires 3-100 characters[32m 14[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/botAccountsCrudConfig.test.ts[2m > [22mbotAccountsCrudConfig[2m > [22mfieldSet validations[2m > [22mdescription allows max 5000 characters[32m 2[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/botAccountsCrudConfig.test.ts[2m > [22mbotAccountsCrudConfig[2m > [22mfieldSet validations[2m > [22mtoken_encrypted has description hint[32m 3[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/botAccountsCrudConfig.test.ts[2m > [22mbotAccountsCrudConfig[2m > [22mfieldTypes[2m > [22mdescription is textarea[32m 2[2mms[22m[39m
[32m✓[39m src/features/bot-accounts/botAccountsCrudConfig.test.ts[2m > [22mbotAccountsCrudConfig[2m > [22mfieldTypes[2m > [22mtoken_encrypted is password[32m 1[2mms[22m[39m
(node:769) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/layers/__tests__/architecture-contracts.test.ts[2m > [22marchitecture contracts[2m > [22mtype-level assertions are verified by npm run typecheck:arch[32m 37[2mms[22m[39m
(node:764) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:757) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:779) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/ConfirmDialog.test.tsx[2m > [22mConfirmDialog[2m > [22mrenders with title and message[33m 1379[2mms[22m[39m
(node:795) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:789) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/ConfirmDialog.test.tsx[2m > [22mConfirmDialog[2m > [22mcalls onConfirm when confirm button is clicked[33m 486[2mms[22m[39m
[32m✓[39m src/shared/components/DurationDisplay.test.tsx[2m > [22mDurationDisplay[2m > [22mrenders 0ms as "0s"[32m 288[2mms[22m[39m
[32m✓[39m src/shared/components/DurationDisplay.test.tsx[2m > [22mDurationDisplay[2m > [22mrenders 5000ms as "5s"[32m 43[2mms[22m[39m
[32m✓[39m src/shared/components/ConfirmDialog.test.tsx[2m > [22mConfirmDialog[2m > [22mcalls onCancel when cancel button is clicked[33m 467[2mms[22m[39m
[32m✓[39m src/shared/components/ConfirmDialog.test.tsx[2m > [22mConfirmDialog[2m > [22mdoes not render when closed[32m 18[2mms[22m[39m
[32m✓[39m src/shared/components/DurationDisplay.test.tsx[2m > [22mDurationDisplay[2m > [22mrenders 65000ms as "1m 5s"[32m 38[2mms[22m[39m
[32m✓[39m src/shared/components/DurationDisplay.test.tsx[2m > [22mDurationDisplay[2m > [22mrenders 3661000ms as "1h 1m"[32m 38[2mms[22m[39m
[32m✓[39m src/shared/components/DurationDisplay.test.tsx[2m > [22mDurationDisplay[2m > [22mrenders 3723000ms as "1h 2m"[32m 22[2mms[22m[39m
[32m✓[39m src/shared/components/DurationDisplay.test.tsx[2m > [22mDurationDisplay[2m > [22mrenders null as "—"[32m 14[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders 0 as "0"[33m 308[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders 500 as "500"[32m 16[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders 1500 as "1.5K"[32m 13[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders 890123 as "890.1K"[32m 12[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders 1234567 as "1.2M"[32m 12[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders 999500 as "999.5K"[32m 14[2mms[22m[39m
[32m✓[39m src/shared/components/TokenDisplay.test.tsx[2m > [22mTokenDisplay[2m > [22mrenders with label when provided[32m 12[2mms[22m[39m
[32m✓[39m src/shared/components/RunPhaseIcon.test.tsx[2m > [22mRunPhaseIcon[2m > [22mrenders pending with correct label[32m 180[2mms[22m[39m
[32m✓[39m src/shared/components/RunPhaseIcon.test.tsx[2m > [22mRunPhaseIcon[2m > [22mrenders running with correct label[32m 31[2mms[22m[39m
[32m✓[39m src/shared/components/Breadcrumb.test.tsx[2m > [22mBreadcrumb[2m > [22mrenders items with separators[33m 452[2mms[22m[39m
[32m✓[39m src/shared/components/RunPhaseIcon.test.tsx[2m > [22mRunPhaseIcon[2m > [22mrenders succeeded with correct label[32m 52[2mms[22m[39m
[32m✓[39m src/shared/components/RunPhaseIcon.test.tsx[2m > [22mRunPhaseIcon[2m > [22mrenders failed with correct label[32m 39[2mms[22m[39m
[32m✓[39m src/shared/components/Breadcrumb.test.tsx[2m > [22mBreadcrumb[2m > [22mrenders links for items with href[33m 509[2mms[22m[39m
[32m✓[39m src/shared/components/Breadcrumb.test.tsx[2m > [22mBreadcrumb[2m > [22mrenders last item as plain text[32m 40[2mms[22m[39m
[32m✓[39m src/shared/components/StatsCard.test.tsx[2m > [22mStatsCard[2m > [22mrenders label and value[32m 281[2mms[22m[39m
[32m✓[39m src/shared/components/StatsCard.test.tsx[2m > [22mStatsCard[2m > [22mrenders large values with abbreviation[32m 28[2mms[22m[39m
[32m✓[39m src/shared/components/StatsCard.test.tsx[2m > [22mStatsCard[2m > [22mrenders accent color border[32m 39[2mms[22m[39m
(node:807) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:806) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided.
(Use `node --trace-warnings ...` to show where the warning was created)
[32m✓[39m src/shared/components/SourceBadge.test.tsx[2m > [22mSourceBadge[2m > [22mrenders manual badge[32m 277[2mms[22m[39m
[32m✓[39m src/shared/components/SourceBadge.test.tsx[2m > [22mSourceBadge[2m > [22mrenders webhook badge[32m 14[2mms[22m[39m
[32m✓[39m src/shared/components/SourceBadge.test.tsx[2m > [22mSourceBadge[2m > [22mrenders schedule badge[32m 44[2mms[22m[39m
[32m✓[39m src/shared/components/SourceBadge.test.tsx[2m > [22mSourceBadge[2m > [22mrenders api badge[32m 23[2mms[22m[39m
[90mstderr[2m | src/shared/components/ErrorBoundary.test.tsx[2m > [22m[2mErrorBoundary[2m > [22m[2mrenders fallback on error
[22m[39mError: kaboom
at Bomb [90m(/workspace/niko/agent-platform/frontend/[39msrc/shared/components/ErrorBoundary.test.tsx:6:9[90m)[39m
at Object.react_stack_bottom_frame (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:25904:20)
at renderWithHooks (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:7662:22)
at updateFunctionComponent (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:10166:19)
at beginWork (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:11778:18)
at runWithFiberInDEV (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:874:13)
at performUnitOfWork (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:17641:22)
at workLoopSync (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:17469:41)
at renderRootSync (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:17450:11)
at performWorkOnRoot (/workspace/node_modules/[4mreact-dom[24m/cjs/react-dom-client.development.js:16583:35) {
[stack]: [36m[Getter/Setter][39m,
[message]: [32m'kaboom'[39m
}
The above error occurred in the [39m
[36m [39m
[36m [39m
[36m [39m
[36m[39m
[36m [39m
[36m[39m
[36m[39m
[36m [39m
[36m[39m
[36m[39m
[36m [39m
[36m
|