diff --git a/compiler/apps/playground/components/Editor/ConfigEditor.tsx b/compiler/apps/playground/components/Editor/ConfigEditor.tsx index 5f904960bacbe..162d82591cb00 100644 --- a/compiler/apps/playground/components/Editor/ConfigEditor.tsx +++ b/compiler/apps/playground/components/Editor/ConfigEditor.tsx @@ -6,6 +6,7 @@ */ import MonacoEditor, {loader, type Monaco} from '@monaco-editor/react'; +import {PluginOptions} from 'babel-plugin-react-compiler'; import type {editor} from 'monaco-editor'; import * as monaco from 'monaco-editor'; import React, {useState} from 'react'; @@ -13,30 +14,33 @@ import {Resizable} from 're-resizable'; import {useStore, useStoreDispatch} from '../StoreContext'; import {monacoOptions} from './monacoOptions'; import {IconChevron} from '../Icons/IconChevron'; +import prettyFormat from 'pretty-format'; // @ts-expect-error - webpack asset/source loader handles .d.ts files as strings import compilerTypeDefs from 'babel-plugin-react-compiler/dist/index.d.ts'; loader.config({monaco}); -export default function ConfigEditor(): React.ReactElement { +export default function ConfigEditor({ + appliedOptions, +}: { + appliedOptions: PluginOptions | null; +}): React.ReactElement { const [isExpanded, setIsExpanded] = useState(false); - return ( -
- {isExpanded ? ( - - ) : ( - - )} -
+ return isExpanded ? ( + + ) : ( + ); } function ExpandedEditor({ onToggle, + appliedOptions, }: { onToggle: (expanded: boolean) => void; + appliedOptions: PluginOptions | null; }): React.ReactElement { const store = useStore(); const dispatchStore = useStoreDispatch(); @@ -81,22 +85,22 @@ function ExpandedEditor({ } }; + const formattedAppliedOptions = appliedOptions + ? prettyFormat(appliedOptions, { + printFunctionName: false, + printBasicPrototype: false, + }) + : 'Invalid configs'; + return ( -
-
-

- Config Overrides -

-
+ defaultSize={{width: 350}} + enable={{right: true, bottom: false}}> +
onToggle(false)} style={{ @@ -106,30 +110,60 @@ function ExpandedEditor({ borderTopLeftRadius: 0, borderBottomLeftRadius: 0, }}> - + +
+ +
+
+

+ Config Overrides +

+
+
+ +
-
- + +
+
+

+ Applied Configs +

+
+
+ +
@@ -143,10 +177,10 @@ function CollapsedEditor({ }): React.ReactElement { return (
+ className="w-4 !h-[calc(100vh_-_3.5rem)]" + style={{position: 'relative'}}>
onToggle(true)} style={{ @@ -156,7 +190,7 @@ function CollapsedEditor({ borderTopLeftRadius: 0, borderBottomLeftRadius: 0, }}> - +
); diff --git a/compiler/apps/playground/components/Editor/EditorImpl.tsx b/compiler/apps/playground/components/Editor/EditorImpl.tsx index a90447c96b50a..8b75ce6ac5eb5 100644 --- a/compiler/apps/playground/components/Editor/EditorImpl.tsx +++ b/compiler/apps/playground/components/Editor/EditorImpl.tsx @@ -201,7 +201,7 @@ function compile( source: string, mode: 'compiler' | 'linter', configOverrides: string, -): [CompilerOutput, 'flow' | 'typescript'] { +): [CompilerOutput, 'flow' | 'typescript', PluginOptions | null] { const results = new Map>(); const error = new CompilerError(); const otherErrors: Array = []; @@ -279,7 +279,7 @@ function compile( ...baseOpts, logger: { debugLogIRs: logIR, - logEvent: (_filename: string | null, event: LoggerEvent) => { + logEvent: (_filename: string | null, event: LoggerEvent): void => { if (event.kind === 'CompileError') { otherErrors.push(event.detail); } @@ -315,11 +315,12 @@ function compile( otherErrors.forEach(e => error.details.push(e)); } if (error.hasErrors()) { - return [{kind: 'err', results, error}, language]; + return [{kind: 'err', results, error}, language, baseOpts]; } return [ {kind: 'ok', results, transformOutput, errors: error.details}, language, + baseOpts, ]; } @@ -328,7 +329,7 @@ export default function Editor(): JSX.Element { const deferredStore = useDeferredValue(store); const dispatchStore = useStoreDispatch(); const {enqueueSnackbar} = useSnackbar(); - const [compilerOutput, language] = useMemo( + const [compilerOutput, language, appliedOptions] = useMemo( () => compile(deferredStore.source, 'compiler', deferredStore.config), [deferredStore.source, deferredStore.config], ); @@ -379,7 +380,7 @@ export default function Editor(): JSX.Element { <>
- +
diff --git a/compiler/apps/playground/components/TabbedWindow.tsx b/compiler/apps/playground/components/TabbedWindow.tsx index 49ff76543bb5c..1751bd87e26c2 100644 --- a/compiler/apps/playground/components/TabbedWindow.tsx +++ b/compiler/apps/playground/components/TabbedWindow.tsx @@ -33,7 +33,7 @@ export default function TabbedWindow({ key={tab} onClick={() => onTabChange(tab)} className={clsx( - 'active:scale-95 transition-transform text-center outline-none py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full capitalize whitespace-nowrap text-sm', + 'active:scale-95 transition-transform py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full text-sm', !isActive && 'hover:bg-primary/5', isActive && 'bg-highlight text-link', )}> diff --git a/compiler/apps/playground/lib/defaultStore.ts b/compiler/apps/playground/lib/defaultStore.ts index 17a80094a6628..bb33c1b76c539 100644 --- a/compiler/apps/playground/lib/defaultStore.ts +++ b/compiler/apps/playground/lib/defaultStore.ts @@ -17,9 +17,7 @@ export const defaultConfig = `\ import type { PluginOptions } from 'babel-plugin-react-compiler/dist'; ({ - environment: { - enableResetCacheOnSourceFileChanges: false - } + //compilationMode: "all" } satisfies Partial);`; export const defaultStore: Store = { diff --git a/packages/react-devtools-extensions/src/main/fetchFileWithCaching.js b/packages/react-devtools-extensions/src/main/fetchFileWithCaching.js index 97bf1fe35bcbe..15028e99094e1 100644 --- a/packages/react-devtools-extensions/src/main/fetchFileWithCaching.js +++ b/packages/react-devtools-extensions/src/main/fetchFileWithCaching.js @@ -82,7 +82,7 @@ const fetchFromPage = async (url, resolve, reject) => { debugLog('[main] fetchFromPage()', url); function onPortMessage({payload, source}) { - if (source === 'react-devtools-background') { + if (source === 'react-devtools-background' && payload?.url === url) { switch (payload?.type) { case 'fetch-file-with-cache-complete': chrome.runtime.onMessage.removeListener(onPortMessage); diff --git a/packages/react-devtools-inline/__tests__/__e2e__/components.test.js b/packages/react-devtools-inline/__tests__/__e2e__/components.test.js index ae451d29587b0..3d187c3ddabae 100644 --- a/packages/react-devtools-inline/__tests__/__e2e__/components.test.js +++ b/packages/react-devtools-inline/__tests__/__e2e__/components.test.js @@ -93,7 +93,9 @@ test.describe('Components', () => { const name = isEditable.name ? existingNameElements[0].value - : existingNameElements[0].innerText; + : existingNameElements[0].innerText + // remove trailing colon + .slice(0, -1); const value = isEditable.value ? existingValueElements[0].value : existingValueElements[0].innerText; diff --git a/packages/react-devtools-shared/src/__tests__/__serializers__/storeSerializer.js b/packages/react-devtools-shared/src/__tests__/__serializers__/storeSerializer.js index ea5a402bdc235..9c13799214dd3 100644 --- a/packages/react-devtools-shared/src/__tests__/__serializers__/storeSerializer.js +++ b/packages/react-devtools-shared/src/__tests__/__serializers__/storeSerializer.js @@ -12,8 +12,8 @@ export function test(maybeStore) { } // print() is part of Jest's serializer API -export function print(store, serialize, indent) { - return printStore(store); +export function print(store, serialize, indent, includeSuspense = true) { + return printStore(store, false, null, includeSuspense); } // Used for Jest snapshot testing. diff --git a/packages/react-devtools-shared/src/__tests__/profilingCache-test.js b/packages/react-devtools-shared/src/__tests__/profilingCache-test.js index d16062c69f488..0d26d7107cb6d 100644 --- a/packages/react-devtools-shared/src/__tests__/profilingCache-test.js +++ b/packages/react-devtools-shared/src/__tests__/profilingCache-test.js @@ -724,34 +724,69 @@ describe('ProfilingCache', () => { const rootID = store.roots[0]; const commitData = store.profilerStore.getDataForRoot(rootID).commitData; expect(commitData).toHaveLength(2); - expect(commitData[0].fiberActualDurations).toMatchInlineSnapshot(` - Map { - 1 => 15, - 2 => 15, - 3 => 5, - 4 => 2, - } - `); - expect(commitData[0].fiberSelfDurations).toMatchInlineSnapshot(` - Map { - 1 => 0, - 2 => 10, - 3 => 3, - 4 => 2, - } - `); - expect(commitData[1].fiberActualDurations).toMatchInlineSnapshot(` - Map { - 5 => 3, - 3 => 3, - } - `); - expect(commitData[1].fiberSelfDurations).toMatchInlineSnapshot(` - Map { - 5 => 3, - 3 => 0, - } - `); + + const isLegacySuspense = React.version.startsWith('17'); + if (isLegacySuspense) { + expect(commitData[0].fiberActualDurations).toMatchInlineSnapshot(` + Map { + 1 => 15, + 2 => 15, + 3 => 5, + 4 => 3, + 5 => 2, + } + `); + expect(commitData[0].fiberSelfDurations).toMatchInlineSnapshot(` + Map { + 1 => 0, + 2 => 10, + 3 => 3, + 4 => 3, + 5 => 2, + } + `); + expect(commitData[1].fiberActualDurations).toMatchInlineSnapshot(` + Map { + 6 => 3, + 3 => 3, + } + `); + expect(commitData[1].fiberSelfDurations).toMatchInlineSnapshot(` + Map { + 6 => 3, + 3 => 0, + } + `); + } else { + expect(commitData[0].fiberActualDurations).toMatchInlineSnapshot(` + Map { + 1 => 15, + 2 => 15, + 3 => 5, + 4 => 2, + } + `); + expect(commitData[0].fiberSelfDurations).toMatchInlineSnapshot(` + Map { + 1 => 0, + 2 => 10, + 3 => 3, + 4 => 2, + } + `); + expect(commitData[1].fiberActualDurations).toMatchInlineSnapshot(` + Map { + 5 => 3, + 3 => 3, + } + `); + expect(commitData[1].fiberSelfDurations).toMatchInlineSnapshot(` + Map { + 5 => 3, + 3 => 0, + } + `); + } }); // @reactVersion >= 16.9 @@ -866,6 +901,7 @@ describe('ProfilingCache', () => { "hocDisplayNames": null, "id": 1, "key": null, + "stack": null, "type": 11, }, ], @@ -908,6 +944,7 @@ describe('ProfilingCache', () => { "hocDisplayNames": null, "id": 1, "key": null, + "stack": null, "type": 11, }, ], diff --git a/packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js b/packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js index 73df17071bac2..176056cf10e63 100644 --- a/packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js +++ b/packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js @@ -15,10 +15,12 @@ import { } from './utils'; describe('commit tree', () => { - let React; + let React = require('react'); let Scheduler; let store: Store; let utils; + const isLegacySuspense = + React.version.startsWith('16') || React.version.startsWith('17'); beforeEach(() => { utils = require('./utils'); @@ -184,17 +186,32 @@ describe('commit tree', () => { utils.act(() => store.profilerStore.startProfiling()); utils.act(() => legacyRender()); await Promise.resolve(); - expect(store).toMatchInlineSnapshot(` - [root] - ▾ - - `); + if (isLegacySuspense) { + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + ▾ + + [suspense-root] rects={null} + + `); + } else { + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + + [suspense-root] rects={null} + + `); + } utils.act(() => legacyRender()); expect(store).toMatchInlineSnapshot(` [root] ▾ + [suspense-root] rects={null} + `); utils.act(() => legacyRender()); expect(store).toMatchInlineSnapshot(` @@ -214,7 +231,13 @@ describe('commit tree', () => { ); } - expect(commitTrees[0].nodes.size).toBe(3); // + + + expect(commitTrees[0].nodes.size).toBe( + isLegacySuspense + ? // + + + + 4 + : // + + + 3, + ); expect(commitTrees[1].nodes.size).toBe(4); // + + + expect(commitTrees[2].nodes.size).toBe(2); // + }); @@ -268,11 +291,24 @@ describe('commit tree', () => { it('should support Lazy components that are unmounted before resolving (legacy render)', async () => { utils.act(() => store.profilerStore.startProfiling()); utils.act(() => legacyRender()); - expect(store).toMatchInlineSnapshot(` - [root] - ▾ - - `); + if (isLegacySuspense) { + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + ▾ + + [suspense-root] rects={null} + + `); + } else { + expect(store).toMatchInlineSnapshot(` + [root] + ▾ + + [suspense-root] rects={null} + + `); + } utils.act(() => legacyRender()); expect(store).toMatchInlineSnapshot(` [root] @@ -291,7 +327,13 @@ describe('commit tree', () => { ); } - expect(commitTrees[0].nodes.size).toBe(3); // + + + expect(commitTrees[0].nodes.size).toBe( + isLegacySuspense + ? // + + + + 4 + : // + + + 3, + ); expect(commitTrees[1].nodes.size).toBe(2); // + }); diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js index 88144b4aa1c13..a2024be3d2e5e 100644 --- a/packages/react-devtools-shared/src/__tests__/store-test.js +++ b/packages/react-devtools-shared/src/__tests__/store-test.js @@ -24,6 +24,35 @@ describe('Store', () => { let store; let withErrorsOrWarningsIgnored; + function readValue(promise) { + if (typeof React.use === 'function') { + return React.use(promise); + } + + // Support for React < 19.0 + switch (promise.status) { + case 'fulfilled': + return promise.value; + case 'rejected': + throw promise.reason; + case 'pending': + throw promise; + default: + promise.status = 'pending'; + promise.then( + value => { + promise.status = 'fulfilled'; + promise.value = value; + }, + reason => { + promise.status = 'rejected'; + promise.reason = reason; + }, + ); + throw promise; + } + } + beforeAll(() => { // JSDDOM doesn't implement getClientRects so we're just faking one for testing purposes Element.prototype.getClientRects = function (this: Element) { @@ -107,11 +136,7 @@ describe('Store', () => { let Dynamic = null; const Owner = () => { Dynamic = ; - if (React.use) { - React.use(promise); - } else { - throw promise; - } + readValue(promise); }; const Parent = () => { return Dynamic; @@ -462,12 +487,9 @@ describe('Store', () => { // @reactVersion >= 18.0 it('should display Suspense nodes properly in various states', async () => { const Loading = () =>
Loading...
; + const never = new Promise(() => {}); const SuspendingComponent = () => { - if (React.use) { - React.use(new Promise(() => {})); - } else { - throw new Promise(() => {}); - } + readValue(never); }; const Component = () => { return
Hello
; @@ -514,12 +536,9 @@ describe('Store', () => { it('should support nested Suspense nodes', async () => { const Component = () => null; const Loading = () =>
Loading...
; + const never = new Promise(() => {}); const Never = () => { - if (React.use) { - React.use(new Promise(() => {})); - } else { - throw new Promise(() => {}); - } + readValue(never); }; const Wrapper = ({ @@ -1019,12 +1038,9 @@ describe('Store', () => { it('should display a partially rendered SuspenseList', async () => { const Loading = () =>
Loading...
; + const never = new Promise(() => {}); const SuspendingComponent = () => { - if (React.use) { - React.use(new Promise(() => {})); - } else { - throw new Promise(() => {}); - } + readValue(never); }; const Component = () => { return
Hello
; @@ -1379,12 +1395,9 @@ describe('Store', () => { // @reactVersion >= 18.0 it('should display Suspense nodes properly in various states', async () => { const Loading = () =>
Loading...
; + const never = new Promise(() => {}); const SuspendingComponent = () => { - if (React.use) { - React.use(new Promise(() => {})); - } else { - throw new Promise(() => {}); - } + readValue(never); }; const Component = () => { return
Hello
; @@ -2081,6 +2094,8 @@ describe('Store', () => { [root] ▾ + [suspense-root] rects={null} + `); // Render again to unmount it before it finishes loading @@ -2826,7 +2841,7 @@ describe('Store', () => { function Component({children, promise}) { if (promise) { - React.use(promise); + readValue(promise); } return
{children}
; } @@ -2901,7 +2916,7 @@ describe('Store', () => { function Component({children, promise}) { if (promise) { - React.use(promise); + readValue(promise); } return
{children}
; } diff --git a/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js b/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js index 89076ea63daa3..b5cf97a4730a3 100644 --- a/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js +++ b/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js @@ -134,7 +134,7 @@ describe('Store component filters', () => { `); }); - // @reactVersion >= 16.0 + // @reactVersion >= 16.6 it('should filter Suspense', async () => { const Suspense = React.Suspense; await actAsync(async () => diff --git a/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js b/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js index 759ce79590371..db93c280cdf42 100644 --- a/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js +++ b/packages/react-devtools-shared/src/__tests__/storeStressSync-test.js @@ -16,6 +16,35 @@ describe('StoreStress (Legacy Mode)', () => { let store; let print; + function readValue(promise) { + if (typeof React.use === 'function') { + return React.use(promise); + } + + // Support for React < 19.0 + switch (promise.status) { + case 'fulfilled': + return promise.value; + case 'rejected': + throw promise.reason; + case 'pending': + throw promise; + default: + promise.status = 'pending'; + promise.then( + value => { + promise.status = 'fulfilled'; + promise.value = value; + }, + reason => { + promise.status = 'rejected'; + promise.reason = reason; + }, + ); + throw promise; + } + } + beforeEach(() => { bridge = global.bridge; store = global.store; @@ -415,118 +444,116 @@ describe('StoreStress (Legacy Mode)', () => { a, ]; + // Excluding Suspense tree here due to different measurement semantics for fallbacks const stepsSnapshot = [ ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ` - [root] + "[root] ▾ - + " `, ]; + const never = new Promise(() => {}); const Never = () => { - if (React.use) { - React.use(new Promise(() => {})); - } else { - throw new Promise(() => {}); - } + readValue(never); }; const Root = ({children}) => { @@ -549,8 +576,10 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // We snapshot each step once so it doesn't regress. - expect(store).toMatchInlineSnapshot(stepsSnapshot[i]); - snapshots.push(print(store)); + expect(print(store, undefined, undefined, false)).toMatchInlineSnapshot( + stepsSnapshot[i], + ); + snapshots.push(print(store, undefined, undefined, false)); act(() => unmount()); expect(print(store)).toBe(''); } @@ -572,7 +601,7 @@ describe('StoreStress (Legacy Mode)', () => { , ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); act(() => unmount()); expect(print(store)).toBe(''); } @@ -592,7 +621,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => render( @@ -604,7 +633,7 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Verify the successful transition to steps[j]. - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => render( @@ -615,7 +644,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Clean up after every iteration. act(() => unmount()); expect(print(store)).toBe(''); @@ -641,7 +670,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => render( @@ -657,7 +686,7 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Verify the successful transition to steps[j]. - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => render( @@ -672,7 +701,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Clean up after every iteration. act(() => unmount()); expect(print(store)).toBe(''); @@ -694,7 +723,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => render( @@ -710,7 +739,7 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Verify the successful transition to steps[j]. - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => render( @@ -721,7 +750,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Clean up after every iteration. act(() => unmount()); expect(print(store)).toBe(''); @@ -747,7 +776,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Re-render with steps[j]. act(() => render( @@ -759,7 +788,7 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Verify the successful transition to steps[j]. - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Check that we can transition back again. act(() => render( @@ -774,7 +803,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Clean up after every iteration. act(() => unmount()); expect(print(store)).toBe(''); @@ -803,7 +832,7 @@ describe('StoreStress (Legacy Mode)', () => { const suspenseID = store.getElementIDAtIndex(2); // Force fallback. - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); act(() => { bridge.send('overrideSuspense', { id: suspenseID, @@ -811,7 +840,7 @@ describe('StoreStress (Legacy Mode)', () => { forceFallback: true, }); }); - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Stop forcing fallback. act(() => { @@ -821,7 +850,7 @@ describe('StoreStress (Legacy Mode)', () => { forceFallback: false, }); }); - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Trigger actual fallback. act(() => @@ -837,7 +866,7 @@ describe('StoreStress (Legacy Mode)', () => {
, ), ); - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Force fallback while we're in fallback mode. act(() => { @@ -848,7 +877,7 @@ describe('StoreStress (Legacy Mode)', () => { }); }); // Keep seeing fallback content. - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Switch to primary mode. act(() => @@ -861,7 +890,7 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Fallback is still forced though. - expect(print(store)).toEqual(snapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[j]); // Stop forcing fallback. This reverts to primary content. act(() => { @@ -872,7 +901,7 @@ describe('StoreStress (Legacy Mode)', () => { }); }); // Now we see primary content. - expect(print(store)).toEqual(snapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual(snapshots[i]); // Clean up after every iteration. act(() => unmount()); @@ -921,6 +950,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -931,6 +962,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -943,6 +976,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -955,6 +990,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -966,6 +1003,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -977,6 +1016,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -988,6 +1029,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -999,6 +1042,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1009,6 +1054,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1018,6 +1065,8 @@ describe('StoreStress (Legacy Mode)', () => { ▾ + [suspense-root] rects={[]} + `, ` [root] @@ -1028,6 +1077,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1038,6 +1089,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ]; @@ -1049,6 +1102,8 @@ describe('StoreStress (Legacy Mode)', () => { ▾ + [suspense-root] rects={[]} + `, ` [root] @@ -1057,6 +1112,8 @@ describe('StoreStress (Legacy Mode)', () => { ▾ + [suspense-root] rects={[]} + `, ` [root] @@ -1067,6 +1124,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1077,6 +1136,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1086,6 +1147,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1095,6 +1158,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1104,6 +1169,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1113,6 +1180,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1121,6 +1190,8 @@ describe('StoreStress (Legacy Mode)', () => { ▾ + [suspense-root] rects={[]} + `, ` [root] @@ -1128,6 +1199,8 @@ describe('StoreStress (Legacy Mode)', () => { + [suspense-root] rects={[]} + `, ` [root] @@ -1136,6 +1209,8 @@ describe('StoreStress (Legacy Mode)', () => { ▾ + [suspense-root] rects={[]} + `, ` [root] @@ -1144,15 +1219,14 @@ describe('StoreStress (Legacy Mode)', () => { ▾ + [suspense-root] rects={[]} + `, ]; + const never = new Promise(() => {}); const Never = () => { - if (React.use) { - React.use(new Promise(() => {})); - } else { - throw new Promise(() => {}); - } + readValue(never); }; const MaybeSuspend = ({children, suspend}) => { @@ -1224,7 +1298,7 @@ describe('StoreStress (Legacy Mode)', () => { ); // We snapshot each step once so it doesn't regress. expect(store).toMatchInlineSnapshot(stepsSnapshotTwo[i]); - fallbackSnapshots.push(print(store)); + fallbackSnapshots.push(print(store, undefined, undefined, false)); act(() => unmount()); expect(print(store)).toBe(''); } @@ -1302,7 +1376,9 @@ describe('StoreStress (Legacy Mode)', () => { , ), ); - expect(print(store)).toEqual(fallbackSnapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[i], + ); // Re-render with steps[j]. act(() => render( @@ -1321,7 +1397,9 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Verify the successful transition to steps[j]. - expect(print(store)).toEqual(fallbackSnapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[j], + ); // Check that we can transition back again. act(() => render( @@ -1339,7 +1417,9 @@ describe('StoreStress (Legacy Mode)', () => { , ), ); - expect(print(store)).toEqual(fallbackSnapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[i], + ); // Clean up after every iteration. act(() => unmount()); expect(print(store)).toBe(''); @@ -1377,7 +1457,9 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Verify the successful transition to steps[j]. - expect(print(store)).toEqual(fallbackSnapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[j], + ); // Check that we can transition back again. act(() => render( @@ -1414,7 +1496,9 @@ describe('StoreStress (Legacy Mode)', () => { , ), ); - expect(print(store)).toEqual(fallbackSnapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[i], + ); // Re-render with steps[j]. act(() => render( @@ -1441,7 +1525,9 @@ describe('StoreStress (Legacy Mode)', () => { , ), ); - expect(print(store)).toEqual(fallbackSnapshots[i]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[i], + ); // Clean up after every iteration. act(() => unmount()); expect(print(store)).toBe(''); @@ -1480,7 +1566,9 @@ describe('StoreStress (Legacy Mode)', () => { forceFallback: true, }); }); - expect(print(store)).toEqual(fallbackSnapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[j], + ); // Stop forcing fallback. act(() => { @@ -1504,7 +1592,9 @@ describe('StoreStress (Legacy Mode)', () => { , ), ); - expect(print(store)).toEqual(fallbackSnapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[j], + ); // Force fallback while we're in fallback mode. act(() => { @@ -1515,7 +1605,9 @@ describe('StoreStress (Legacy Mode)', () => { }); }); // Keep seeing fallback content. - expect(print(store)).toEqual(fallbackSnapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[j], + ); // Switch to primary mode. act(() => @@ -1530,7 +1622,9 @@ describe('StoreStress (Legacy Mode)', () => { ), ); // Fallback is still forced though. - expect(print(store)).toEqual(fallbackSnapshots[j]); + expect(print(store, undefined, undefined, false)).toEqual( + fallbackSnapshots[j], + ); // Stop forcing fallback. This reverts to primary content. act(() => { diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js index 5561bc5f5383c..3d7e98eab97da 100644 --- a/scripts/jest/preprocessor.js +++ b/scripts/jest/preprocessor.js @@ -80,7 +80,19 @@ module.exports = { // This is only for React DevTools tests with React 16.x // `react/jsx-dev-runtime` and `react/jsx-runtime` are included in the package starting from v17 - if (semver.gte(ReactVersionTestingAgainst, '17.0.0')) { + // Technically 16.14 and 15.7 have the new runtime but we're not testing those versions. + if ( + semver.gte(ReactVersionTestingAgainst, '15.0.0') && + semver.lt(ReactVersionTestingAgainst, '17.0.0') + ) { + plugins.push( + [ + require.resolve('@babel/plugin-transform-react-jsx'), + {runtime: 'classic'}, + ], + require.resolve('@babel/plugin-transform-react-jsx-source') + ); + } else { plugins.push([ process.env.NODE_ENV === 'development' ? require.resolve('@babel/plugin-transform-react-jsx-development') @@ -89,11 +101,6 @@ module.exports = { // would be React.createElement. {runtime: 'automatic'}, ]); - } else { - plugins.push( - require.resolve('@babel/plugin-transform-react-jsx'), - require.resolve('@babel/plugin-transform-react-jsx-source') - ); } plugins.push(pathToTransformLazyJSXImport);