diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js index c4fe7d337dd..8c9beb18544 100644 --- a/packages/react-devtools-shared/src/__tests__/store-test.js +++ b/packages/react-devtools-shared/src/__tests__/store-test.js @@ -7,7 +7,12 @@ * @flow */ +import semver from 'semver'; + import {getVersionedRenderImplementation} from './utils'; +import {ReactVersion} from '../../../../ReactVersions'; + +const ReactVersionTestingAgainst = process.env.REACT_VERSION || ReactVersion; describe('Store', () => { let React; @@ -3143,8 +3148,9 @@ describe('Store', () => { expect(store).toMatchInlineSnapshot(``); }); - // @reactVersion >= 17.0 - it('should track suspended by in filtered fallback', async () => { + // Can't suspend the root in React 17. + // @reactVersion >= 18.0 + it('should track suspended-by in filtered fallback suspending the root', async () => { function IgnoreMe({promise}) { return readValue(promise); } @@ -3196,6 +3202,91 @@ describe('Store', () => { `); }); + // @reactVersion >= 17.0 + it('should track suspended-by in filtered fallback', async () => { + function IgnoreMe({promise}) { + return readValue(promise); + } + + function Component({promise}) { + if (promise) { + return readValue(promise); + } + return null; + } + + await actAsync( + async () => + (store.componentFilters = [createDisplayNameFilter('^IgnoreMe', true)]), + ); + + let resolveFallback; + const fallbackPromise = new Promise(resolve => { + resolveFallback = resolve; + }); + let resolveContent; + const contentPromise = new Promise(resolve => { + resolveContent = resolve; + }); + + await actAsync(() => + render( + } + name="root"> + }> + + + , + ), + ); + + if (semver.lt(ReactVersionTestingAgainst, '18.0.0')) { + // React 17 commits partial trees hidden which causes the "main" + // Suspense boundary to be included. + // React 18 and upwards excluded partial tree entirely. + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + + [suspense-root] rects={null} + + + `); + } else { + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + + [suspense-root] rects={null} + + `); + } + + await actAsync(() => resolveFallback('loading')); + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + + [suspense-root] rects={null} + + + `); + + await actAsync(() => resolveContent('content')); + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + ▾ + + [suspense-root] rects={null} + + + `); + }); + // @reactVersion >= 19 it('should keep suspended boundaries in the Suspense tree but not hidden Activity', async () => { const Activity = React.Activity || React.unstable_Activity;