Add test selectors to experimental build (#22760)
This change adds a new "react-dom/unstable_testing" entry point but I believe its contents will exactly match "react-dom/index" for the stable build. (The experimental build will have the added new selector APIs.)
Brian Vaughn committed
Nov 16, 2021 at 16:27 UTC
aa19d569b22ae447be18e768c97600656c080993
9 files changed
+66
-47
package.json
+1
-1
@@ -109,7 +109,7 @@
109
"scripts": {
110
"build": "node ./scripts/rollup/build.js",
111
"build-combined": "node ./scripts/rollup/build-all-release-channels.js",
112
- "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/",
112
+ "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/",
113
"build-for-devtools-dev": "yarn build-for-devtools --type=NODE_DEV",
114
"build-for-devtools-prod": "yarn build-for-devtools --type=NODE_PROD",
115
"linc": "node ./scripts/tasks/linc.js",
packages/react-devtools-inline/webpack.config.js
+12
-6
@@ -33,6 +33,14 @@ const babelOptions = {
33
),
34
};
35
36
+const builtModulesDir = resolve(
37
+ __dirname,
38
+ '..',
39
+ '..',
40
+ 'build',
41
+ 'oss-experimental',
42
+);
43
+
44
module.exports = {
45
mode: __DEV__ ? 'development' : 'production',
46
devtool: __DEV__ ? 'eval-cheap-source-map' : 'source-map',
@@ -49,12 +57,10 @@ module.exports = {
57
libraryTarget: 'commonjs2',
58
},
59
externals: {
52
- react: 'react',
53
- // TODO: Once this package is published, remove the external
54
- // 'react-debug-tools': 'react-debug-tools',
55
- 'react-dom': 'react-dom',
56
- 'react-is': 'react-is',
57
- scheduler: 'scheduler',
60
+ react: resolve(builtModulesDir, 'react'),
61
+ 'react-dom': resolve(builtModulesDir, 'react-dom/unstable_testing'),
62
+ 'react-is': resolve(builtModulesDir, 'react-is'),
63
+ scheduler: resolve(builtModulesDir, 'scheduler'),
64
},
65
node: {
66
// source-maps package has a dependency on 'fs'
packages/react-devtools-shell/webpack.config.js
+1
-1
@@ -55,7 +55,7 @@ const config = {
55
react: resolve(builtModulesDir, 'react'),
56
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
57
'react-devtools-feature-flags': resolveFeatureFlags('shell'),
58
- 'react-dom': resolve(builtModulesDir, 'react-dom'),
58
+ 'react-dom': resolve(builtModulesDir, 'react-dom/unstable_testing'),
59
'react-is': resolve(builtModulesDir, 'react-is'),
60
scheduler: resolve(builtModulesDir, 'scheduler'),
61
},
packages/react-dom/npm/unstable_testing.js
renamed
packages/react-dom/package.json
+1
@@ -34,6 +34,7 @@
34
"server.browser.js",
35
"server.node.js",
36
"test-utils.js",
37
+ "unstable_testing.js",
38
"cjs/",
39
"umd/"
40
],
packages/react-dom/src/__tests__/ReactDOMTestSelectors-test.internal.js
+37
-37
@@ -56,7 +56,7 @@ describe('ReactDOMTestSelectors', () => {
56
});
57
58
describe('findAllNodes', () => {
59
- // @gate www
59
+ // @gate www || experimental
60
it('should support searching from the document root', () => {
61
function Example() {
62
return (
@@ -76,7 +76,7 @@ describe('ReactDOMTestSelectors', () => {
76
expect(matches[0].id).toBe('match');
77
});
78
79
- // @gate www
79
+ // @gate www || experimental
80
it('should support searching from the container', () => {
81
function Example() {
82
return (
@@ -96,7 +96,7 @@ describe('ReactDOMTestSelectors', () => {
96
expect(matches[0].id).toBe('match');
97
});
98
99
- // @gate www
99
+ // @gate www || experimental
100
it('should support searching from a previous match if the match had a data-testname', () => {
101
function Outer() {
102
return (
@@ -127,7 +127,7 @@ describe('ReactDOMTestSelectors', () => {
127
expect(matches[0].id).toBe('inner');
128
});
129
130
- // @gate www
130
+ // @gate www || experimental
131
it('should not support searching from a previous match if the match did not have a data-testname', () => {
132
function Outer() {
133
return (
@@ -157,7 +157,7 @@ describe('ReactDOMTestSelectors', () => {
157
);
158
});
159
160
- // @gate www
160
+ // @gate www || experimental
161
it('should support an multiple component types in the selector array', () => {
162
function Outer() {
163
return (
@@ -211,7 +211,7 @@ describe('ReactDOMTestSelectors', () => {
211
expect(matches[0].id).toBe('match3');
212
});
213
214
- // @gate www
214
+ // @gate www || experimental
215
it('should find multiple matches', () => {
216
function Example1() {
217
return (
@@ -249,7 +249,7 @@ describe('ReactDOMTestSelectors', () => {
249
]);
250
});
251
252
- // @gate www
252
+ // @gate www || experimental
253
it('should ignore nested matches', () => {
254
function Example() {
255
return (
@@ -269,7 +269,7 @@ describe('ReactDOMTestSelectors', () => {
269
expect(matches[0].id).toEqual('match1');
270
});
271
272
- // @gate www
272
+ // @gate www || experimental
273
it('should enforce the specific order of selectors', () => {
274
function Outer() {
275
return (
@@ -294,7 +294,7 @@ describe('ReactDOMTestSelectors', () => {
294
).toHaveLength(0);
295
});
296
297
- // @gate www
297
+ // @gate www || experimental
298
it('should not search within hidden subtrees', () => {
299
const ref1 = React.createRef(null);
300
const ref2 = React.createRef(null);
@@ -324,7 +324,7 @@ describe('ReactDOMTestSelectors', () => {
324
expect(matches[0]).toBe(ref2.current);
325
});
326
327
- // @gate www
327
+ // @gate www || experimental
328
it('should support filtering by display text', () => {
329
function Example() {
330
return (
@@ -347,7 +347,7 @@ describe('ReactDOMTestSelectors', () => {
347
expect(matches[0].id).toBe('match');
348
});
349
350
- // @gate www
350
+ // @gate www || experimental
351
it('should support filtering by explicit accessibiliy role', () => {
352
function Example() {
353
return (
@@ -372,7 +372,7 @@ describe('ReactDOMTestSelectors', () => {
372
expect(matches[0].id).toBe('match');
373
});
374
375
- // @gate www
375
+ // @gate www || experimental
376
it('should support filtering by explicit secondary accessibiliy role', () => {
377
const ref = React.createRef();
378
@@ -397,7 +397,7 @@ describe('ReactDOMTestSelectors', () => {
397
expect(matches[0]).toBe(ref.current);
398
});
399
400
- // @gate www
400
+ // @gate www || experimental
401
it('should support filtering by implicit accessibiliy role', () => {
402
function Example() {
403
return (
@@ -420,7 +420,7 @@ describe('ReactDOMTestSelectors', () => {
420
expect(matches[0].id).toBe('match');
421
});
422
423
- // @gate www
423
+ // @gate www || experimental
424
it('should support filtering by implicit accessibiliy role with attributes qualifications', () => {
425
function Example() {
426
return (
@@ -443,7 +443,7 @@ describe('ReactDOMTestSelectors', () => {
443
expect(matches[0].id).toBe('match');
444
});
445
446
- // @gate www
446
+ // @gate www || experimental
447
it('should support searching ahead with the has() selector', () => {
448
function Example() {
449
return (
@@ -479,14 +479,14 @@ describe('ReactDOMTestSelectors', () => {
479
expect(matches[0].id).toBe('match');
480
});
481
482
- // @gate www
482
+ // @gate www || experimental
483
it('should throw if no container can be found', () => {
484
expect(() => findAllNodes(document.body, [])).toThrow(
485
'Could not find React container within specified host subtree.',
486
);
487
});
488
489
- // @gate www
489
+ // @gate www || experimental
490
it('should throw if an invalid host root is specified', () => {
491
const ref = React.createRef();
492
function Example() {
@@ -502,7 +502,7 @@ describe('ReactDOMTestSelectors', () => {
502
});
503
504
describe('getFindAllNodesFailureDescription', () => {
505
- // @gate www
505
+ // @gate www || experimental
506
it('should describe findAllNodes failures caused by the component type selector', () => {
507
function Outer() {
508
return <Middle />;
@@ -532,7 +532,7 @@ No matching component was found for:
532
);
533
});
534
535
- // @gate www
535
+ // @gate www || experimental
536
it('should return null if findAllNodes was able to find a match', () => {
537
function Example() {
538
return (
@@ -568,7 +568,7 @@ No matching component was found for:
568
};
569
}
570
571
- // @gate www
571
+ // @gate www || experimental
572
it('should return a single rect for a component that returns a single root host element', () => {
573
const ref = React.createRef();
574
@@ -602,7 +602,7 @@ No matching component was found for:
602
});
603
});
604
605
- // @gate www
605
+ // @gate www || experimental
606
it('should return a multiple rects for multiple matches', () => {
607
const outerRef = React.createRef();
608
const innerRef = React.createRef();
@@ -652,7 +652,7 @@ No matching component was found for:
652
});
653
});
654
655
- // @gate www
655
+ // @gate www || experimental
656
it('should return a multiple rects for single match that returns a fragment', () => {
657
const refA = React.createRef();
658
const refB = React.createRef();
@@ -702,7 +702,7 @@ No matching component was found for:
702
});
703
});
704
705
- // @gate www
705
+ // @gate www || experimental
706
it('should merge overlapping rects', () => {
707
const refA = React.createRef();
708
const refB = React.createRef();
@@ -757,7 +757,7 @@ No matching component was found for:
757
});
758
});
759
760
- // @gate www
760
+ // @gate www || experimental
761
it('should merge some types of adjacent rects (if they are the same in one dimension)', () => {
762
const refA = React.createRef();
763
const refB = React.createRef();
@@ -857,7 +857,7 @@ No matching component was found for:
857
});
858
});
859
860
- // @gate www
860
+ // @gate www || experimental
861
it('should not search within hidden subtrees', () => {
862
const refA = React.createRef();
863
const refB = React.createRef();
@@ -914,7 +914,7 @@ No matching component was found for:
914
});
915
916
describe('focusWithin', () => {
917
- // @gate www
917
+ // @gate www || experimental
918
it('should return false if the specified component path has no matches', () => {
919
function Example() {
920
return <Child />;
@@ -935,7 +935,7 @@ No matching component was found for:
935
expect(didFocus).toBe(false);
936
});
937
938
- // @gate www
938
+ // @gate www || experimental
939
it('should return false if there are no focusable elements within the matched subtree', () => {
940
function Example() {
941
return <Child />;
@@ -953,7 +953,7 @@ No matching component was found for:
953
expect(didFocus).toBe(false);
954
});
955
956
- // @gate www
956
+ // @gate www || experimental
957
it('should return false if the only focusable elements are disabled', () => {
958
function Example() {
959
return (
@@ -971,7 +971,7 @@ No matching component was found for:
971
expect(didFocus).toBe(false);
972
});
973
974
- // @gate www
974
+ // @gate www || experimental
975
it('should return false if the only focusable elements are hidden', () => {
976
function Example() {
977
return <button hidden={true}>not clickable</button>;
@@ -985,7 +985,7 @@ No matching component was found for:
985
expect(didFocus).toBe(false);
986
});
987
988
- // @gate www
988
+ // @gate www || experimental
989
it('should successfully focus the first focusable element within the tree', () => {
990
const secondRef = React.createRef(null);
991
@@ -1040,7 +1040,7 @@ No matching component was found for:
1040
expect(handleThirdFocus).not.toHaveBeenCalled();
1041
});
1042
1043
- // @gate www
1043
+ // @gate www || experimental
1044
it('should successfully focus the first focusable element even if application logic interferes', () => {
1045
const ref = React.createRef(null);
1046
@@ -1070,7 +1070,7 @@ No matching component was found for:
1070
expect(handleFocus).toHaveBeenCalledTimes(1);
1071
});
1072
1073
- // @gate www
1073
+ // @gate www || experimental
1074
it('should not focus within hidden subtrees', () => {
1075
const secondRef = React.createRef(null);
1076
@@ -1194,7 +1194,7 @@ No matching component was found for:
1194
window.IntersectionObserver = IntersectionObserver;
1195
});
1196
1197
- // @gate www
1197
+ // @gate www || experimental
1198
it('should notify a listener when the underlying instance intersection changes', () => {
1199
const ref = React.createRef(null);
1200
@@ -1231,7 +1231,7 @@ No matching component was found for:
1231
expect(handleVisibilityChange).toHaveBeenCalledWith([{rect, ratio: 0.5}]);
1232
});
1233
1234
- // @gate www
1234
+ // @gate www || experimental
1235
it('should notify a listener of multiple targets when the underlying instance intersection changes', () => {
1236
const ref1 = React.createRef(null);
1237
const ref2 = React.createRef(null);
@@ -1308,7 +1308,7 @@ No matching component was found for:
1308
]);
1309
});
1310
1311
- // @gate www
1311
+ // @gate www || experimental
1312
it('should stop listening when its disconnected', () => {
1313
const ref = React.createRef(null);
1314
@@ -1343,7 +1343,7 @@ No matching component was found for:
1343
});
1344
1345
// This test reuires gating because it relies on the __DEV__ only commit hook to work.
1346
- // @gate www && __DEV__
1346
+ // @gate www || experimental && __DEV__
1347
it('should update which targets its listening to after a commit', () => {
1348
const ref1 = React.createRef(null);
1349
const ref2 = React.createRef(null);
@@ -1422,7 +1422,7 @@ No matching component was found for:
1422
]);
1423
});
1424
1425
- // @gate www
1425
+ // @gate www || experimental
1426
it('should not observe components within hidden subtrees', () => {
1427
const ref1 = React.createRef(null);
1428
const ref2 = React.createRef(null);
packages/react-dom/testing.experimental.js
+12
@@ -8,3 +8,15 @@
8
*/
9
10
export * from './index.experimental.js';
11
+export {
12
+ createComponentSelector,
13
+ createHasPseudoClassSelector,
14
+ createRoleSelector,
15
+ createTestNameSelector,
16
+ createTextSelector,
17
+ getFindAllNodesFailureDescription,
18
+ findAllNodes,
19
+ findBoundingRects,
20
+ focusWithin,
21
+ observeVisibleRects,
22
+} from 'react-reconciler/src/ReactFiberReconciler';
packages/shared/forks/ReactFeatureFlags.testing.js
+1
-1
@@ -23,7 +23,7 @@ export const enableUpdaterTracking = false;
23
export const enableSuspenseServerRenderer = false;
24
export const enableSelectiveHydration = false;
25
export const enableLazyElements = false;
26
-export const enableCache = false;
26
+export const enableCache = __EXPERIMENTAL__;
27
export const disableJavaScriptURLs = false;
28
export const disableInputAttributeSyncing = false;
29
export const enableSchedulerDebugging = false;
scripts/rollup/bundles.js
+1
-1
@@ -249,7 +249,7 @@ const bundles = [
249
/******* React DOM - www - Testing *******/
250
{
251
moduleType: RENDERER,
252
- bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],
252
+ bundleTypes: [FB_WWW_DEV, FB_WWW_PROD, NODE_DEV, NODE_PROD],
253
entry: 'react-dom/testing',
254
global: 'ReactDOMTesting',
255
minifyWithProdErrorCodes: true,