diff --git a/fixtures/ssr/server/render.js b/fixtures/ssr/server/render.js
index a4fe698858ab1..e20b9a35dc502 100644
--- a/fixtures/ssr/server/render.js
+++ b/fixtures/ssr/server/render.js
@@ -1,5 +1,6 @@
import React from 'react';
import {renderToPipeableStream} from 'react-dom/server';
+import {Writable} from 'stream';
import App from '../src/components/App';
@@ -14,11 +15,41 @@ if (process.env.NODE_ENV === 'development') {
assets = require('../build/asset-manifest.json');
}
+class ThrottledWritable extends Writable {
+ constructor(destination) {
+ super();
+ this.destination = destination;
+ this.delay = 150;
+ }
+
+ _write(chunk, encoding, callback) {
+ let o = 0;
+ const write = () => {
+ this.destination.write(chunk.slice(o, o + 100), encoding, x => {
+ o += 100;
+ if (o < chunk.length) {
+ setTimeout(write, this.delay);
+ } else {
+ callback(x);
+ }
+ });
+ };
+ setTimeout(write, this.delay);
+ }
+
+ _final(callback) {
+ setTimeout(() => {
+ this.destination.end(callback);
+ }, this.delay);
+ }
+}
+
export default function render(url, res) {
res.socket.on('error', error => {
// Log fatal errors
console.error('Fatal', error);
});
+ console.log('hello');
let didError = false;
const {pipe, abort} = renderToPipeableStream(, {
bootstrapScripts: [assets['main.js']],
@@ -26,7 +57,10 @@ export default function render(url, res) {
// If something errored before we started streaming, we set the error code appropriately.
res.statusCode = didError ? 500 : 200;
res.setHeader('Content-type', 'text/html');
- pipe(res);
+ // To test the actual chunks taking time to load over the network, we throttle
+ // the stream a bit.
+ const throttledResponse = new ThrottledWritable(res);
+ pipe(throttledResponse);
},
onShellError(x) {
// Something errored before we could complete the shell so we emit an alternative shell.
diff --git a/fixtures/ssr/src/components/Chrome.js b/fixtures/ssr/src/components/Chrome.js
index 5cf81a877f7e3..984c726a02652 100644
--- a/fixtures/ssr/src/components/Chrome.js
+++ b/fixtures/ssr/src/components/Chrome.js
@@ -37,6 +37,7 @@ export default class Chrome extends Component {
+
This should appear in the first paint.
');
const startScriptSrc = stringToPrecomputedChunk('');
+const scriptNonce = stringToPrecomputedChunk(' nonce="');
+const scriptIntegirty = stringToPrecomputedChunk(' integrity="');
+const scriptCrossOrigin = stringToPrecomputedChunk(' crossorigin="');
+const endAsyncScript = stringToPrecomputedChunk(' async="">');
/**
* This escaping function is designed to work with with inline scripts where the entire
@@ -367,7 +368,7 @@ export function createRenderState(
nonce === undefined
? startInlineScript
: stringToPrecomputedChunk(
- '',
+ '' +
+ '',
);
});
@@ -4189,7 +4190,7 @@ describe('ReactDOMFizzServer', () => {
renderOptions.unstable_externalRuntimeSrc,
).map(n => n.outerHTML),
).toEqual([
- '',
+ '',
'',
'',
'',
@@ -4276,7 +4277,7 @@ describe('ReactDOMFizzServer', () => {
renderOptions.unstable_externalRuntimeSrc,
).map(n => n.outerHTML),
).toEqual([
- '',
+ '',
'',
'',
'',
@@ -4512,7 +4513,7 @@ describe('ReactDOMFizzServer', () => {
// the html should be as-is
expect(document.documentElement.innerHTML).toEqual(
- 'hello world!
',
+ 'hello world!
',
);
});
@@ -6492,7 +6493,7 @@ describe('ReactDOMFizzServer', () => {
});
expect(document.documentElement.outerHTML).toEqual(
- '',
+ '',
);
});
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js
index 4022f227a8abe..f5b01d2462403 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js
@@ -85,7 +85,7 @@ describe('ReactDOMFizzServerBrowser', () => {
);
const result = await readResult(stream);
expect(result).toMatchInlineSnapshot(
- `"hello world"`,
+ `"hello world"`,
);
});
@@ -99,7 +99,7 @@ describe('ReactDOMFizzServerBrowser', () => {
);
const result = await readResult(stream);
expect(result).toMatchInlineSnapshot(
- `"hello world
"`,
+ `"hello world
"`,
);
});
@@ -529,7 +529,7 @@ describe('ReactDOMFizzServerBrowser', () => {
const result = await readResult(stream);
expect(result).toEqual(
- 'foobar',
+ 'foobar',
);
});
@@ -547,7 +547,7 @@ describe('ReactDOMFizzServerBrowser', () => {
expect(result).toMatchInlineSnapshot(
// TODO: remove interpolation because it prevents snapshot updates.
// eslint-disable-next-line jest/no-interpolation-in-snapshots
- `"hello world
"`,
+ `"hello world
"`,
);
});
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerEdge-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerEdge-test.js
index c442f1813836c..1eefe1a4082e6 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServerEdge-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerEdge-test.js
@@ -72,7 +72,7 @@ describe('ReactDOMFizzServerEdge', () => {
});
expect(result).toMatchInlineSnapshot(
- `"hello"`,
+ `"hello"`,
);
});
});
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js
index e97b4a29a7497..2704c243eba48 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js
@@ -79,7 +79,7 @@ describe('ReactDOMFizzServerNode', () => {
});
// with Float, we emit empty heads if they are elided when rendering
expect(output.result).toMatchInlineSnapshot(
- `"hello world"`,
+ `"hello world"`,
);
});
@@ -97,7 +97,7 @@ describe('ReactDOMFizzServerNode', () => {
pipe(writable);
});
expect(output.result).toMatchInlineSnapshot(
- `"hello world
"`,
+ `"hello world
"`,
);
});
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js
index 96e6538cd2196..de6e21b557a1d 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzStatic-test.js
@@ -106,7 +106,10 @@ describe('ReactDOMFizzStatic', () => {
node.tagName !== 'TEMPLATE' &&
node.tagName !== 'template' &&
!node.hasAttribute('hidden') &&
- !node.hasAttribute('aria-hidden')
+ !node.hasAttribute('aria-hidden') &&
+ // Ignore the render blocking expect
+ (node.getAttribute('rel') !== 'expect' ||
+ node.getAttribute('blocking') !== 'render')
) {
const props = {};
const attributes = node.attributes;
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js
index f973a5ed4d6e0..7eecb16cf82f6 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js
@@ -187,7 +187,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
);
const prelude = await readContent(result.prelude);
expect(prelude).toMatchInlineSnapshot(
- `"hello world"`,
+ `"hello world"`,
);
});
@@ -201,7 +201,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
);
const prelude = await readContent(result.prelude);
expect(prelude).toMatchInlineSnapshot(
- `"hello world
"`,
+ `"hello world
"`,
);
});
@@ -1428,7 +1428,8 @@ describe('ReactDOMFizzStaticBrowser', () => {
expect(await readContent(content)).toBe(
'' +
'' +
- 'Hello',
+ '' +
+ 'Hello