diff --git a/packages/react-reconciler/src/__tests__/DebugTracing-test.internal.js b/packages/react-reconciler/src/__tests__/DebugTracing-test.internal.js index 14960c36811c..2df04c8c8854 100644 --- a/packages/react-reconciler/src/__tests__/DebugTracing-test.internal.js +++ b/packages/react-reconciler/src/__tests__/DebugTracing-test.internal.js @@ -96,6 +96,45 @@ describe('DebugTracing', () => { expect(logs).toEqual(['log: ⚛️ Example resolved']); }); + // @gate experimental && build === 'development' && enableDebugTracing + it('should log sync render with CPU suspense', () => { + function Example() { + console.log(''); + return null; + } + + function Wrapper({children}) { + console.log(''); + return children; + } + + ReactTestRenderer.create( + + + + + + + , + ); + + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000000000000000000000000000001)', + 'log: ', + 'groupEnd: ⚛️ render (0b0000000000000000000000000000001)', + ]); + + logs.splice(0); + + expect(Scheduler).toFlushUntilNextPaint([]); + + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000010000000000000000000000000)', + 'log: ', + 'groupEnd: ⚛️ render (0b0000010000000000000000000000000)', + ]); + }); + // @gate experimental && build === 'development' && enableDebugTracing it('should log concurrent render with suspense', async () => { const fakeSuspensePromise = Promise.resolve(true); @@ -130,6 +169,52 @@ describe('DebugTracing', () => { expect(logs).toEqual(['log: ⚛️ Example resolved']); }); + // @gate experimental && build === 'development' && enableDebugTracing + it('should log concurrent render with CPU suspense', () => { + function Example() { + console.log(''); + return null; + } + + function Wrapper({children}) { + console.log(''); + return children; + } + + ReactTestRenderer.create( + + + + + + + , + {unstable_isConcurrent: true}, + ); + + expect(logs).toEqual([]); + + logs.splice(0); + + expect(Scheduler).toFlushUntilNextPaint([]); + + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000000000000000000001000000000)', + 'log: ', + 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', + ]); + + logs.splice(0); + + expect(Scheduler).toFlushUntilNextPaint([]); + + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000010000000000000000000000000)', + 'log: ', + 'groupEnd: ⚛️ render (0b0000010000000000000000000000000)', + ]); + }); + // @gate experimental && build === 'development' && enableDebugTracing it('should log cascading class component updates', () => { class Example extends React.Component { @@ -191,12 +276,23 @@ describe('DebugTracing', () => { expect(Scheduler).toFlushUntilNextPaint([]); }).toErrorDev('Cannot update during an existing state transition'); - expect(logs).toEqual([ - 'group: ⚛️ render (0b0000000000000000000001000000000)', - 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', - 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', - 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', - ]); + gate(flags => { + if (flags.new) { + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000000000000000000001000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000001000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000001000000000)', + 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', + ]); + } else { + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000000000000000000001000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', + 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', + ]); + } + }); }); // @gate experimental && build === 'development' && enableDebugTracing @@ -274,12 +370,24 @@ describe('DebugTracing', () => { {unstable_isConcurrent: true}, ); }); - expect(logs).toEqual([ - 'group: ⚛️ render (0b0000000000000000000001000000000)', - 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', - 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', // debugRenderPhaseSideEffectsForStrictMode - 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', - ]); + + gate(flags => { + if (flags.new) { + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000000000000000000001000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000001000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000001000000000)', // debugRenderPhaseSideEffectsForStrictMode + 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', + ]); + } else { + expect(logs).toEqual([ + 'group: ⚛️ render (0b0000000000000000000001000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', + 'log: ⚛️ Example updated state (0b0000000000000000000010000000000)', // debugRenderPhaseSideEffectsForStrictMode + 'groupEnd: ⚛️ render (0b0000000000000000000001000000000)', + ]); + } + }); }); // @gate experimental && build === 'development' && enableDebugTracing diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index aa3cf1a64a84..881a0e61010d 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -25,7 +25,7 @@ export const enableEagerRootListeners = !__VARIANT__; // It logs information to the console about React scheduling, rendering, and commit phases. // // NOTE: This feature will only work in DEV mode; all callsights are wrapped with __DEV__. -export const enableDebugTracing = false; +export const enableDebugTracing = __EXPERIMENTAL__; // This only has an effect in the new reconciler. But also, the new reconciler // is only enabled when __VARIANT__ is true. So this is set to the opposite of