From 9a8e8549d750102ebbc4091765a1ad55b75792b0 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Fri, 3 Oct 2025 12:43:02 -0400 Subject: [PATCH] [nocommit] test transition trancing for backgrounded transitions --- .../__tests__/ReactTransitionTracing-test.js | 92 +++++++++++++++++++ .../react/index.experimental.development.js | 1 + packages/shared/ReactFeatureFlags.js | 2 +- 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js index 42d3ee57a6130..24ea5f34a1f5e 100644 --- a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js +++ b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js @@ -2030,6 +2030,98 @@ describe('ReactInteractionTracing', () => { }); }); + // @gate enableTransitionTracing + it('background transitions report in progress boundaries and final markers', async () => { + const transitionCallbacks = { + onTransitionStart: (name, startTime) => { + Scheduler.log(`onTransitionStart(${name}, ${startTime})`); + }, + onTransitionProgress: (name, startTime, endTime, pending) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.log( + `onTransitionProgress(${name}, ${startTime}, ${endTime}, [${suspenseNames}])`, + ); + }, + onTransitionComplete: (name, startTime, endTime) => { + Scheduler.log( + `onTransitionComplete(${name}, ${startTime}, ${endTime})`, + ); + }, + onMarkerProgress: ( + transitionName, + markerName, + startTime, + currentTime, + pending, + ) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.log( + `onMarkerProgress(${transitionName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`, + ); + }, + onMarkerIncomplete: ( + transitionName, + markerName, + startTime, + deletions, + ) => { + Scheduler.log( + `onMarkerIncomplete(${transitionName}, ${markerName}, ${startTime}, [${stringifyDeletions( + deletions, + )}])`, + ); + }, + onMarkerComplete: (transitionName, markerName, startTime, endTime) => { + Scheduler.log( + `onMarkerComplete(${transitionName}, ${markerName}, ${startTime}, ${endTime})`, + ); + }, + }; + + function App({text}) { + return ( + + + + + + + ); + } + + const root = ReactNoop.createRoot({ + unstable_transitionCallbacks: transitionCallbacks, + }); + + await act(async () => { + root.render(); + ReactNoop.expire(1000); + await advanceTimers(1000); + }); + + assertLog(['Suspend [One]', 'Suspend [One]']); + await act(async () => { + startTransition(() => root.render(), { + name: 'transition', + }); + }); + + assertLog([ + 'Suspend [Two]', + 'Suspend [Two]', + 'onTransitionStart(transition, 1000)', + 'onTransitionComplete(transition, 1000, 1000)', + ]); + + await act(async () => { + ReactNoop.expire(2000); + await advanceTimers(2000); + await resolveText('Two'); + }); + + assertLog(['Two']); + }); + // @gate enableTransitionTracing it('marker incomplete gets called properly if child suspense marker is not part of it', async () => { const transitionCallbacks = { diff --git a/packages/react/index.experimental.development.js b/packages/react/index.experimental.development.js index 211f1c5dfb419..ccfcc2b659c22 100644 --- a/packages/react/index.experimental.development.js +++ b/packages/react/index.experimental.development.js @@ -37,6 +37,7 @@ export { unstable_startGestureTransition, unstable_addTransitionType, unstable_useCacheRefresh, + unstable_TracingMarker, useId, useCallback, useContext, diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index a37adfea434a3..db3d7fe99afd5 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -105,7 +105,7 @@ export const enableDefaultTransitionIndicator = __EXPERIMENTAL__; */ export const enableObjectFiber: boolean = false; -export const enableTransitionTracing: boolean = false; +export const enableTransitionTracing: boolean = true; // FB-only usage. The new API has different semantics. export const enableLegacyHidden: boolean = false;