diff --git a/package.json b/package.json
index fb428f35c04b9..440ed35fa6fc7 100644
--- a/package.json
+++ b/package.json
@@ -109,7 +109,7 @@
"scripts": {
"build": "node ./scripts/rollup/build.js",
"build-combined": "node ./scripts/rollup/build-all-release-channels.js",
- "build-for-devtools": "cross-env RELEASE_CHANNEL=experimental yarn build react/index,react/jsx,react-dom,react-is,react-debug-tools,scheduler,react-test-renderer,react-refresh --type=NODE && cp -r ./build/node_modules build/oss-experimental/",
+ "build-for-devtools": "cross-env RELEASE_CHANNEL=experimental yarn build react/index,react/jsx,react-dom/index,react-dom/test,react-is,react-debug-tools,scheduler,react-test-renderer,react-refresh --type=NODE && cp -r ./build/node_modules build/oss-experimental/",
"build-for-devtools-dev": "yarn build-for-devtools --type=NODE_DEV",
"build-for-devtools-prod": "yarn build-for-devtools --type=NODE_PROD",
"linc": "node ./scripts/tasks/linc.js",
diff --git a/packages/react-devtools-inline/webpack.config.js b/packages/react-devtools-inline/webpack.config.js
index ab7bcb8be3650..07f23f8ef34ea 100644
--- a/packages/react-devtools-inline/webpack.config.js
+++ b/packages/react-devtools-inline/webpack.config.js
@@ -33,6 +33,14 @@ const babelOptions = {
),
};
+const builtModulesDir = resolve(
+ __dirname,
+ '..',
+ '..',
+ 'build',
+ 'oss-experimental',
+);
+
module.exports = {
mode: __DEV__ ? 'development' : 'production',
devtool: __DEV__ ? 'eval-cheap-source-map' : 'source-map',
@@ -49,12 +57,10 @@ module.exports = {
libraryTarget: 'commonjs2',
},
externals: {
- react: 'react',
- // TODO: Once this package is published, remove the external
- // 'react-debug-tools': 'react-debug-tools',
- 'react-dom': 'react-dom',
- 'react-is': 'react-is',
- scheduler: 'scheduler',
+ react: resolve(builtModulesDir, 'react'),
+ 'react-dom': resolve(builtModulesDir, 'react-dom/unstable_testing'),
+ 'react-is': resolve(builtModulesDir, 'react-is'),
+ scheduler: resolve(builtModulesDir, 'scheduler'),
},
node: {
// source-maps package has a dependency on 'fs'
diff --git a/packages/react-devtools-shell/webpack.config.js b/packages/react-devtools-shell/webpack.config.js
index cc846954e901b..fb3df7240fb3e 100644
--- a/packages/react-devtools-shell/webpack.config.js
+++ b/packages/react-devtools-shell/webpack.config.js
@@ -55,7 +55,7 @@ const config = {
react: resolve(builtModulesDir, 'react'),
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
'react-devtools-feature-flags': resolveFeatureFlags('shell'),
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
+ 'react-dom': resolve(builtModulesDir, 'react-dom/unstable_testing'),
'react-is': resolve(builtModulesDir, 'react-is'),
scheduler: resolve(builtModulesDir, 'scheduler'),
},
diff --git a/packages/react-dom/npm/testing.js b/packages/react-dom/npm/unstable_testing.js
similarity index 100%
rename from packages/react-dom/npm/testing.js
rename to packages/react-dom/npm/unstable_testing.js
diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json
index f7918bcc83846..c60f4950dd6ca 100644
--- a/packages/react-dom/package.json
+++ b/packages/react-dom/package.json
@@ -34,6 +34,7 @@
"server.browser.js",
"server.node.js",
"test-utils.js",
+ "unstable_testing.js",
"cjs/",
"umd/"
],
diff --git a/packages/react-dom/src/__tests__/ReactDOMTestSelectors-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMTestSelectors-test.internal.js
index e9b0cc6ea0e5b..29cf7a9870ec1 100644
--- a/packages/react-dom/src/__tests__/ReactDOMTestSelectors-test.internal.js
+++ b/packages/react-dom/src/__tests__/ReactDOMTestSelectors-test.internal.js
@@ -56,7 +56,7 @@ describe('ReactDOMTestSelectors', () => {
});
describe('findAllNodes', () => {
- // @gate www
+ // @gate www || experimental
it('should support searching from the document root', () => {
function Example() {
return (
@@ -76,7 +76,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should support searching from the container', () => {
function Example() {
return (
@@ -96,7 +96,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should support searching from a previous match if the match had a data-testname', () => {
function Outer() {
return (
@@ -127,7 +127,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('inner');
});
- // @gate www
+ // @gate www || experimental
it('should not support searching from a previous match if the match did not have a data-testname', () => {
function Outer() {
return (
@@ -157,7 +157,7 @@ describe('ReactDOMTestSelectors', () => {
);
});
- // @gate www
+ // @gate www || experimental
it('should support an multiple component types in the selector array', () => {
function Outer() {
return (
@@ -211,7 +211,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match3');
});
- // @gate www
+ // @gate www || experimental
it('should find multiple matches', () => {
function Example1() {
return (
@@ -249,7 +249,7 @@ describe('ReactDOMTestSelectors', () => {
]);
});
- // @gate www
+ // @gate www || experimental
it('should ignore nested matches', () => {
function Example() {
return (
@@ -269,7 +269,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toEqual('match1');
});
- // @gate www
+ // @gate www || experimental
it('should enforce the specific order of selectors', () => {
function Outer() {
return (
@@ -294,7 +294,7 @@ describe('ReactDOMTestSelectors', () => {
).toHaveLength(0);
});
- // @gate www
+ // @gate www || experimental
it('should not search within hidden subtrees', () => {
const ref1 = React.createRef(null);
const ref2 = React.createRef(null);
@@ -324,7 +324,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0]).toBe(ref2.current);
});
- // @gate www
+ // @gate www || experimental
it('should support filtering by display text', () => {
function Example() {
return (
@@ -347,7 +347,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should support filtering by explicit accessibiliy role', () => {
function Example() {
return (
@@ -372,7 +372,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should support filtering by explicit secondary accessibiliy role', () => {
const ref = React.createRef();
@@ -397,7 +397,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0]).toBe(ref.current);
});
- // @gate www
+ // @gate www || experimental
it('should support filtering by implicit accessibiliy role', () => {
function Example() {
return (
@@ -420,7 +420,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should support filtering by implicit accessibiliy role with attributes qualifications', () => {
function Example() {
return (
@@ -443,7 +443,7 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should support searching ahead with the has() selector', () => {
function Example() {
return (
@@ -479,14 +479,14 @@ describe('ReactDOMTestSelectors', () => {
expect(matches[0].id).toBe('match');
});
- // @gate www
+ // @gate www || experimental
it('should throw if no container can be found', () => {
expect(() => findAllNodes(document.body, [])).toThrow(
'Could not find React container within specified host subtree.',
);
});
- // @gate www
+ // @gate www || experimental
it('should throw if an invalid host root is specified', () => {
const ref = React.createRef();
function Example() {
@@ -502,7 +502,7 @@ describe('ReactDOMTestSelectors', () => {
});
describe('getFindAllNodesFailureDescription', () => {
- // @gate www
+ // @gate www || experimental
it('should describe findAllNodes failures caused by the component type selector', () => {
function Outer() {
return ;
@@ -532,7 +532,7 @@ No matching component was found for:
);
});
- // @gate www
+ // @gate www || experimental
it('should return null if findAllNodes was able to find a match', () => {
function Example() {
return (
@@ -568,7 +568,7 @@ No matching component was found for:
};
}
- // @gate www
+ // @gate www || experimental
it('should return a single rect for a component that returns a single root host element', () => {
const ref = React.createRef();
@@ -602,7 +602,7 @@ No matching component was found for:
});
});
- // @gate www
+ // @gate www || experimental
it('should return a multiple rects for multiple matches', () => {
const outerRef = React.createRef();
const innerRef = React.createRef();
@@ -652,7 +652,7 @@ No matching component was found for:
});
});
- // @gate www
+ // @gate www || experimental
it('should return a multiple rects for single match that returns a fragment', () => {
const refA = React.createRef();
const refB = React.createRef();
@@ -702,7 +702,7 @@ No matching component was found for:
});
});
- // @gate www
+ // @gate www || experimental
it('should merge overlapping rects', () => {
const refA = React.createRef();
const refB = React.createRef();
@@ -757,7 +757,7 @@ No matching component was found for:
});
});
- // @gate www
+ // @gate www || experimental
it('should merge some types of adjacent rects (if they are the same in one dimension)', () => {
const refA = React.createRef();
const refB = React.createRef();
@@ -857,7 +857,7 @@ No matching component was found for:
});
});
- // @gate www
+ // @gate www || experimental
it('should not search within hidden subtrees', () => {
const refA = React.createRef();
const refB = React.createRef();
@@ -914,7 +914,7 @@ No matching component was found for:
});
describe('focusWithin', () => {
- // @gate www
+ // @gate www || experimental
it('should return false if the specified component path has no matches', () => {
function Example() {
return ;
@@ -935,7 +935,7 @@ No matching component was found for:
expect(didFocus).toBe(false);
});
- // @gate www
+ // @gate www || experimental
it('should return false if there are no focusable elements within the matched subtree', () => {
function Example() {
return ;
@@ -953,7 +953,7 @@ No matching component was found for:
expect(didFocus).toBe(false);
});
- // @gate www
+ // @gate www || experimental
it('should return false if the only focusable elements are disabled', () => {
function Example() {
return (
@@ -971,7 +971,7 @@ No matching component was found for:
expect(didFocus).toBe(false);
});
- // @gate www
+ // @gate www || experimental
it('should return false if the only focusable elements are hidden', () => {
function Example() {
return ;
@@ -985,7 +985,7 @@ No matching component was found for:
expect(didFocus).toBe(false);
});
- // @gate www
+ // @gate www || experimental
it('should successfully focus the first focusable element within the tree', () => {
const secondRef = React.createRef(null);
@@ -1040,7 +1040,7 @@ No matching component was found for:
expect(handleThirdFocus).not.toHaveBeenCalled();
});
- // @gate www
+ // @gate www || experimental
it('should successfully focus the first focusable element even if application logic interferes', () => {
const ref = React.createRef(null);
@@ -1070,7 +1070,7 @@ No matching component was found for:
expect(handleFocus).toHaveBeenCalledTimes(1);
});
- // @gate www
+ // @gate www || experimental
it('should not focus within hidden subtrees', () => {
const secondRef = React.createRef(null);
@@ -1194,7 +1194,7 @@ No matching component was found for:
window.IntersectionObserver = IntersectionObserver;
});
- // @gate www
+ // @gate www || experimental
it('should notify a listener when the underlying instance intersection changes', () => {
const ref = React.createRef(null);
@@ -1231,7 +1231,7 @@ No matching component was found for:
expect(handleVisibilityChange).toHaveBeenCalledWith([{rect, ratio: 0.5}]);
});
- // @gate www
+ // @gate www || experimental
it('should notify a listener of multiple targets when the underlying instance intersection changes', () => {
const ref1 = React.createRef(null);
const ref2 = React.createRef(null);
@@ -1308,7 +1308,7 @@ No matching component was found for:
]);
});
- // @gate www
+ // @gate www || experimental
it('should stop listening when its disconnected', () => {
const ref = React.createRef(null);
@@ -1343,7 +1343,7 @@ No matching component was found for:
});
// This test reuires gating because it relies on the __DEV__ only commit hook to work.
- // @gate www && __DEV__
+ // @gate www || experimental && __DEV__
it('should update which targets its listening to after a commit', () => {
const ref1 = React.createRef(null);
const ref2 = React.createRef(null);
@@ -1422,7 +1422,7 @@ No matching component was found for:
]);
});
- // @gate www
+ // @gate www || experimental
it('should not observe components within hidden subtrees', () => {
const ref1 = React.createRef(null);
const ref2 = React.createRef(null);
diff --git a/packages/react-dom/testing.experimental.js b/packages/react-dom/testing.experimental.js
index f994d83fa7d22..8b0b366705e93 100644
--- a/packages/react-dom/testing.experimental.js
+++ b/packages/react-dom/testing.experimental.js
@@ -8,3 +8,15 @@
*/
export * from './index.experimental.js';
+export {
+ createComponentSelector,
+ createHasPseudoClassSelector,
+ createRoleSelector,
+ createTestNameSelector,
+ createTextSelector,
+ getFindAllNodesFailureDescription,
+ findAllNodes,
+ findBoundingRects,
+ focusWithin,
+ observeVisibleRects,
+} from 'react-reconciler/src/ReactFiberReconciler';
diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js
index 264127fc197ef..3e9233f9c8f87 100644
--- a/packages/shared/forks/ReactFeatureFlags.testing.js
+++ b/packages/shared/forks/ReactFeatureFlags.testing.js
@@ -23,7 +23,7 @@ export const enableUpdaterTracking = false;
export const enableSuspenseServerRenderer = false;
export const enableSelectiveHydration = false;
export const enableLazyElements = false;
-export const enableCache = false;
+export const enableCache = __EXPERIMENTAL__;
export const disableJavaScriptURLs = false;
export const disableInputAttributeSyncing = false;
export const enableSchedulerDebugging = false;
diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js
index 8b12e8550e365..02f0c68f6baab 100644
--- a/scripts/rollup/bundles.js
+++ b/scripts/rollup/bundles.js
@@ -249,7 +249,7 @@ const bundles = [
/******* React DOM - www - Testing *******/
{
moduleType: RENDERER,
- bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],
+ bundleTypes: [FB_WWW_DEV, FB_WWW_PROD, NODE_DEV, NODE_PROD],
entry: 'react-dom/testing',
global: 'ReactDOMTesting',
minifyWithProdErrorCodes: true,