@@ -2729,6 +2729,91 @@ describe('Profiler', () => {
2729
2729
onInteractionScheduledWorkCompleted . mock . calls [ 1 ] [ 0 ] ,
2730
2730
) . toMatchInteraction ( highPriUpdateInteraction ) ;
2731
2731
} ) ;
2732
+
2733
+ it ( 'does not trace Promises flagged with __reactDoNotTraceInteractions' , async ( ) => {
2734
+ loadModulesForTracing ( { useNoopRenderer : true } ) ;
2735
+
2736
+ const interaction = {
2737
+ id : 0 ,
2738
+ name : 'initial render' ,
2739
+ timestamp : Scheduler . unstable_now ( ) ,
2740
+ } ;
2741
+
2742
+ AsyncText = ( { ms, text} ) => {
2743
+ try {
2744
+ TextResource . read ( [ text , ms ] ) ;
2745
+ Scheduler . unstable_yieldValue ( `AsyncText [${ text } ]` ) ;
2746
+ return text ;
2747
+ } catch ( promise ) {
2748
+ promise . __reactDoNotTraceInteractions = true ;
2749
+
2750
+ if ( typeof promise . then === 'function' ) {
2751
+ Scheduler . unstable_yieldValue ( `Suspend [${ text } ]` ) ;
2752
+ } else {
2753
+ Scheduler . unstable_yieldValue ( `Error [${ text } ]` ) ;
2754
+ }
2755
+ throw promise ;
2756
+ }
2757
+ } ;
2758
+
2759
+ const onRender = jest . fn ( ) ;
2760
+ SchedulerTracing . unstable_trace (
2761
+ interaction . name ,
2762
+ Scheduler . unstable_now ( ) ,
2763
+ ( ) => {
2764
+ ReactNoop . render (
2765
+ < React . Profiler id = "test-profiler" onRender = { onRender } >
2766
+ < React . Suspense fallback = { < Text text = "Loading..." /> } >
2767
+ < AsyncText text = "Async" ms = { 20000 } />
2768
+ </ React . Suspense >
2769
+ < Text text = "Sync" />
2770
+ </ React . Profiler > ,
2771
+ ) ;
2772
+ } ,
2773
+ ) ;
2774
+
2775
+ expect ( onInteractionTraced ) . toHaveBeenCalledTimes ( 1 ) ;
2776
+ expect ( onInteractionTraced ) . toHaveBeenLastNotifiedOfInteraction (
2777
+ interaction ,
2778
+ ) ;
2779
+ expect ( onInteractionScheduledWorkCompleted ) . not . toHaveBeenCalled ( ) ;
2780
+ expect ( getWorkForReactThreads ( onWorkStarted ) ) . toHaveLength ( 0 ) ;
2781
+ expect ( getWorkForReactThreads ( onWorkStopped ) ) . toHaveLength ( 0 ) ;
2782
+
2783
+ expect ( Scheduler ) . toFlushAndYield ( [
2784
+ 'Suspend [Async]' ,
2785
+ 'Text [Loading...]' ,
2786
+ 'Text [Sync]' ,
2787
+ ] ) ;
2788
+ // Should have committed the placeholder.
2789
+ expect ( ReactNoop . getChildrenAsJSX ( ) ) . toEqual ( 'Loading...Sync' ) ;
2790
+ expect ( onRender ) . toHaveBeenCalledTimes ( 1 ) ;
2791
+
2792
+ let call = onRender . mock . calls [ 0 ] ;
2793
+ expect ( call [ 0 ] ) . toEqual ( 'test-profiler' ) ;
2794
+ expect ( call [ 6 ] ) . toMatchInteractions (
2795
+ ReactFeatureFlags . enableSchedulerTracing ? [ interaction ] : [ ] ,
2796
+ ) ;
2797
+
2798
+ // The interaction is now complete.
2799
+ expect ( onInteractionTraced ) . toHaveBeenCalledTimes ( 1 ) ;
2800
+ expect ( onInteractionScheduledWorkCompleted ) . toHaveBeenCalledTimes ( 1 ) ;
2801
+ expect (
2802
+ onInteractionScheduledWorkCompleted ,
2803
+ ) . toHaveBeenLastNotifiedOfInteraction ( interaction ) ;
2804
+
2805
+ // Once the promise resolves, we render the suspended view
2806
+ await awaitableAdvanceTimers ( 20000 ) ;
2807
+ expect ( Scheduler ) . toHaveYielded ( [ 'Promise resolved [Async]' ] ) ;
2808
+ expect ( Scheduler ) . toFlushAndYield ( [ 'AsyncText [Async]' ] ) ;
2809
+ expect ( ReactNoop . getChildrenAsJSX ( ) ) . toEqual ( 'AsyncSync' ) ;
2810
+ expect ( onRender ) . toHaveBeenCalledTimes ( 2 ) ;
2811
+
2812
+ // No interactions should be associated with this update.
2813
+ call = onRender . mock . calls [ 1 ] ;
2814
+ expect ( call [ 0 ] ) . toEqual ( 'test-profiler' ) ;
2815
+ expect ( call [ 6 ] ) . toMatchInteractions ( [ ] ) ;
2816
+ } ) ;
2732
2817
} ) ;
2733
2818
} ) ;
2734
2819
} ) ;
0 commit comments