Use require() to implement script src in tests (#26717)
We currently use rollup to make an adhoc bundle from the file system when we're testing an import of an external file. This doesn't follow all the interception rules that we use in jest and in our actual builds. This switches to just using jest require() to load these. This means that they effectively have to load into the global document so this only works with global document tests which is all we have now anyway.
Sebastian Markbåge committed
Apr 25, 2023 at 09:12 UTC
64d6be71224c4241ba8f9d80747d53c0fd6224e7
4 files changed
+24
-71
packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+5
-1
@@ -64,7 +64,11 @@ describe('ReactDOMFizzServer', () => {
64
});
65
streamingContainer = null;
66
global.window = jsdom.window;
67
- global.document = jsdom.window.document;
67
+ global.document = global.window.document;
68
+ global.navigator = global.window.navigator;
69
+ global.Node = global.window.Node;
70
+ global.addEventListener = global.window.addEventListener;
71
+ global.MutationObserver = global.window.MutationObserver;
72
container = document.getElementById('container');
73
74
Scheduler = require('scheduler');
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+6
-2
@@ -59,7 +59,11 @@ describe('ReactDOMFloat', () => {
59
});
60
streamingContainer = null;
61
global.window = jsdom.window;
62
- global.document = jsdom.window.document;
62
+ global.document = global.window.document;
63
+ global.navigator = global.window.navigator;
64
+ global.Node = global.window.Node;
65
+ global.addEventListener = global.window.addEventListener;
66
+ global.MutationObserver = global.window.MutationObserver;
67
container = document.getElementById('container');
68
69
React = require('react');
@@ -95,7 +99,7 @@ describe('ReactDOMFloat', () => {
99
renderOptions = {};
100
if (gate(flags => flags.enableFizzExternalRuntime)) {
101
renderOptions.unstable_externalRuntimeSrc =
98
- 'react-dom-bindings/src/server/ReactDOMServerExternalRuntime.js';
102
+ 'react-dom/unstable_server-external-runtime';
103
}
104
});
105
packages/react-dom/src/test-utils/FizzTestUtils.js
+11
-68
@@ -8,68 +8,6 @@
8
*/
9
'use strict';
10
11
-import * as tmp from 'tmp';
12
-import * as fs from 'fs';
13
-import replace from '@rollup/plugin-replace';
14
-import resolve from '@rollup/plugin-node-resolve';
15
-import {rollup} from 'rollup';
16
-import path from 'path';
17
-
18
-const rollupCache: Map<string, string | null> = new Map();
19
-
20
-// Utility function to read and bundle a standalone browser script
21
-async function getRollupResult(scriptSrc: string): Promise<string | null> {
22
- const cachedResult = rollupCache.get(scriptSrc);
23
- if (cachedResult !== undefined) {
24
- return cachedResult;
25
- }
26
- let tmpFile;
27
- try {
28
- tmpFile = tmp.fileSync();
29
- const rollupConfig = {
30
- input: require.resolve(scriptSrc),
31
- onwarn: console.warn,
32
- plugins: [
33
- replace({__DEV__: 'true', preventAssignment: true}),
34
- resolve({
35
- rootDir: path.join(__dirname, '..', '..', '..'),
36
- }),
37
- ],
38
- output: {
39
- externalLiveBindings: false,
40
- freeze: false,
41
- interop: false,
42
- esModule: false,
43
- },
44
- };
45
- const outputConfig = {
46
- file: tmpFile.name,
47
- format: 'iife',
48
- };
49
- const bundle = await rollup(rollupConfig);
50
- await bundle.write(outputConfig);
51
- const bundleBuffer = Buffer.alloc(4096);
52
- let bundleStr = '';
53
- while (true) {
54
- // $FlowFixMe[incompatible-call]
55
- const bytes = fs.readSync(tmpFile.fd, bundleBuffer);
56
- if (bytes <= 0) {
57
- break;
58
- }
59
- bundleStr += bundleBuffer.slice(0, bytes).toString();
60
- }
61
- rollupCache.set(scriptSrc, bundleStr);
62
- return bundleStr;
63
- } catch (e) {
64
- rollupCache.set(scriptSrc, null);
65
- return null;
66
- } finally {
67
- if (tmpFile) {
68
- tmpFile.removeCallback();
69
- }
70
- }
71
-}
72
-
11
async function insertNodesAndExecuteScripts(
12
source: Document | Element,
13
target: Node,
@@ -150,12 +88,17 @@ async function executeScript(script: Element) {
88
const parent = script.parentNode;
89
const scriptSrc = script.getAttribute('src');
90
if (scriptSrc) {
153
- const rollupOutput = await getRollupResult(scriptSrc);
154
- if (rollupOutput) {
155
- const transientScript = ownerDocument.createElement('script');
156
- transientScript.textContent = rollupOutput;
157
- parent.appendChild(transientScript);
158
- parent.removeChild(transientScript);
91
+ if (document !== ownerDocument) {
92
+ throw new Error(
93
+ 'You must set the current document to the global document to use script src in tests',
94
+ );
95
+ }
96
+ try {
97
+ // $FlowFixMe
98
+ require(scriptSrc);
99
+ } catch (x) {
100
+ const event = new window.ErrorEvent('error', {error: x});
101
+ window.dispatchEvent(event);
102
}
103
} else {
104
const newScript = ownerDocument.createElement('script');
scripts/jest/ReactDOMServerIntegrationEnvironment.js
+2
@@ -16,6 +16,8 @@ class ReactDOMServerIntegrationEnvironment extends NodeEnvironment {
16
this.global.document = this.global.window.document;
17
this.global.navigator = this.global.window.navigator;
18
this.global.Node = this.global.window.Node;
19
+ this.global.addEventListener = this.global.window.addEventListener;
20
+ this.global.MutationObserver = this.global.window.MutationObserver;
21
}
22
23
async setup() {