diff --git a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js index fe2d4e008f949..ae4812afa8ec2 100644 --- a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js +++ b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js @@ -16,6 +16,7 @@ let act; let getCacheForType; let useState; let Suspense; +let Offscreen; let startTransition; let caches; @@ -34,6 +35,7 @@ describe('ReactInteractionTracing', () => { useState = React.useState; startTransition = React.startTransition; Suspense = React.Suspense; + Offscreen = React.unstable_Offscreen; getCacheForType = React.unstable_getCacheForType; @@ -1362,4 +1364,74 @@ describe('ReactInteractionTracing', () => { ]); }); }); + + // @gate enableTransitionTracing + it('offscreen trees should not stop transition from completing', async () => { + const transitionCallbacks = { + onTransitionStart: (name, startTime) => { + Scheduler.unstable_yieldValue( + `onTransitionStart(${name}, ${startTime})`, + ); + }, + onTransitionComplete: (name, startTime, endTime) => { + Scheduler.unstable_yieldValue( + `onTransitionComplete(${name}, ${startTime}, ${endTime})`, + ); + }, + onMarkerComplete: (transitioName, markerName, startTime, endTime) => { + Scheduler.unstable_yieldValue( + `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`, + ); + }, + }; + + function App() { + return ( + + }> + + + + }> + + + + + ); + } + + const root = ReactNoop.createRoot({ + unstable_transitionCallbacks: transitionCallbacks, + }); + await act(() => { + startTransition(() => root.render(), {name: 'transition'}); + ReactNoop.expire(1000); + advanceTimers(1000); + }); + expect(Scheduler).toHaveYielded([ + 'Suspend [Text]', + 'Loading...', + 'Suspend [Hidden Text]', + 'Hidden Loading...', + 'onTransitionStart(transition, 0)', + ]); + + await act(() => { + resolveText('Text'); + ReactNoop.expire(1000); + advanceTimers(1000); + }); + expect(Scheduler).toHaveYielded([ + 'Text', + 'onMarkerComplete(transition, marker, 0, 2000)', + 'onTransitionComplete(transition, 0, 2000)', + ]); + + await act(() => { + resolveText('Hidden Text'); + ReactNoop.expire(1000); + advanceTimers(1000); + }); + expect(Scheduler).toHaveYielded(['Hidden Text']); + }); });