Repository: facebook/react
Pull request: [assert helpers] ReactDOMFloat-test

Splitting out ReactDOMFloat to it's own PR because it's huge.

Changed files:
filename: packages/react-dom/src/__tests__/ReactDOMFloat-test.js
patch: @@ -36,6 +36,7 @@ let assertLog;
 let Scheduler;
 let clientAct;
 let streamingContainer;
+let assertConsoleErrorDev;
 
 describe('ReactDOMFloat', () => {
   beforeEach(() => {
@@ -78,6 +79,7 @@ describe('ReactDOMFloat', () => {
     waitForThrow = InternalTestUtils.waitForThrow;
     assertLog = InternalTestUtils.assertLog;
     clientAct = InternalTestUtils.act;
+    assertConsoleErrorDev = InternalTestUtils.assertConsoleErrorDev;
 
     textCache = new Map();
     loadCache = new Set();
@@ -497,131 +499,166 @@ describe('ReactDOMFloat', () => {
   it('warns if you render resource-like elements above <head> or <body>', async () => {
     const root = ReactDOMClient.createRoot(document);
 
-    await expect(async () => {
-      root.render(
-        <>
-          <noscript>foo</noscript>
-          <html>
-            <body>foo</body>
-          </html>
-        </>,
-      );
-      const aggregateError = await waitForThrow();
-      expect(aggregateError.errors.length).toBe(2);
-      expect(aggregateError.errors[0].message).toContain(
-        'Invalid insertion of NOSCRIPT',
-      );
-      expect(aggregateError.errors[1].message).toContain(
-        'The node to be removed is not a child of this node',
-      );
-    }).toErrorDev(
+    root.render(
+      <>
+        <noscript>foo</noscript>
+        <html>
+          <body>foo</body>
+        </html>
+      </>,
+    );
+    let aggregateError = await waitForThrow();
+    expect(aggregateError.errors.length).toBe(2);
+    expect(aggregateError.errors[0].message).toContain(
+      'Invalid insertion of NOSCRIPT',
+    );
+    expect(aggregateError.errors[1].message).toContain(
+      'The node to be removed is not a child of this node',
+    );
+    assertConsoleErrorDev([
       [
         'Cannot render <noscript> outside the main document. Try moving it into the root <head> tag.',
-        'In HTML, <noscript> cannot be a child of <#document>.',
+        {withoutStack: true},
       ],
-      {withoutStack: 1},
+      'In HTML, <noscript> cannot be a child of <#document>.\n' +
+        'This will cause a hydration error.\n' +
+        '    in noscript (at **)',
+    ]);
+
+    root.render(
+      <html>
+        <template>foo</template>
+        <body>foo</body>
+      </html>,
     );
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render <template> outside the main document. Try moving it into the root <head> tag.\n' +
+        '    in html (at **)',
+      'In HTML, <template> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n\n' +
+        '> <html>\n' +
+        '>   <template>\n' +
+        '    ...\n' +
+        '\n' +
+        '    in template (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
+    ]);
 
-    await expect(async () => {
-      root.render(
+    root.render(
+      <html>
+        <body>foo</body>
+        <style>foo</style>
+      </html>,
+    );
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <style> outside the main document without knowing its precedence ' +
+        'and a unique href key. React can hoist and deduplicate <style> tags if you provide a ' +
+        '`precedence` prop along with an `href` prop that does not conflict with the `href` ' +
+        'values used in any other hoisted <style> or <link rel="stylesheet" ...> tags.  ' +
+        'Note that hoisting <style> tags is considered an advanced feature that most will not use directly. ' +
+        'Consider moving the <style> tag to the <head> or consider adding a `precedence="default"` ' +
+        'and `href="some unique resource identifier"`.\n' +
+        '    in html (at **)',
+      'In HTML, <style> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n\n' +
+        '> <html>\n' +
+        '    <body>\n' +
+        '>   <style>\n' +
+        '\n' +
+        '    in style (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
+    ]);
+
+    root.render(
+      <>
         <html>
-          <template>foo</template>
           <body>foo</body>
-        </html>,
-      );
-      await waitForAll([]);
-    }).toErrorDev([
-      'Cannot render <template> outside the main document. Try moving it into the root <head> tag.',
-      'In HTML, <template> cannot be a child of <html>.',
+        </html>
+        <link rel="stylesheet" href="foo" />
+      </>,
+    );
+    aggregateError = await waitForThrow();
+    expect(aggregateError.errors.length).toBe(2);
+    expect(aggregateError.errors[0].message).toContain(
+      'Invalid insertion of LINK',
+    );
+    expect(aggregateError.errors[1].message).toContain(
+      'The node to be removed is not a child of this node',
+    );
+    assertConsoleErrorDev([
+      [
+        'Cannot render a <link rel="stylesheet" /> outside the main document without knowing its precedence. ' +
+          'Consider adding precedence="default" or moving it into the root <head> tag.',
+        {withoutStack: true},
+      ],
+      'In HTML, <link> cannot be a child of <#document>.\n' +
+        'This will cause a hydration error.\n' +
+        '    in link (at **)',
     ]);
 
-    await expect(async () => {
-      root.render(
+    root.render(
+      <>
         <html>
           <body>foo</body>
-          <style>foo</style>
-        </html>,
-      );
-      await waitForAll([]);
-    }).toErrorDev([
-      'Cannot render a <style> outside the main document without knowing its precedence and a unique href key. React can hoist and deduplicate <style> tags if you provide a `precedence` prop along with an `href` prop that does not conflict with the `href` values used in any other hoisted <style> or <link rel="stylesheet" ...> tags.  Note that hoisting <style> tags is considered an advanced feature that most will not use directly. Consider moving the <style> tag to the <head> or consider adding a `precedence="default"` and `href="some unique resource identifier"`.',
-      'In HTML, <style> cannot be a child of <html>.',
+          <script href="foo" />
+        </html>
+      </>,
+    );
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a sync or defer <script> outside the main document without knowing its order. ' +
+        'Try adding async="" or moving it into the root <head> tag.\n' +
+        '    in html (at **)',
+      'In HTML, <script> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n' +
+        '\n' +
+        '> <html>\n' +
+        '    <body>\n' +
+        '>   <script href="foo">\n' +
+        '\n' +
+        '    in script (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
     ]);
 
-    await expect(async () => {
-      root.render(
-        <>
-          <html>
-            <body>foo</body>
-          </html>
-          <link rel="stylesheet" href="foo" />
-        </>,
-      );
-      const aggregateError = await waitForThrow();
-      expect(aggregateError.errors.length).toBe(2);
-      expect(aggregateError.errors[0].message).toContain(
-        'Invalid insertion of LINK',
-      );
-      expect(aggregateError.errors[1].message).toContain(
-        'The node to be removed is not a child of this node',
-      );
-    }).toErrorDev(
-      [
-        'Cannot render a <link rel="stylesheet" /> outside the main document without knowing its precedence. Consider adding precedence="default" or moving it into the root <head> tag.',
-        'In HTML, <link> cannot be a child of <#document>.',
-      ],
-      {withoutStack: 1},
+    root.render(
+      <html>
+        <script async={true} onLoad={() => {}} href="bar" />
+        <body>foo</body>
+      </html>,
     );
-
-    await expect(async () => {
-      root.render(
-        <>
-          <html>
-            <body>foo</body>
-            <script href="foo" />
-          </html>
-        </>,
-      );
-      await waitForAll([]);
-    }).toErrorDev([
-      'Cannot render a sync or defer <script> outside the main document without knowing its order. Try adding async="" or moving it into the root <head> tag.',
-      'In HTML, <script> cannot be a child of <html>.',
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <script> with onLoad or onError listeners outside the main document. ' +
+        'Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or ' +
+        'somewhere in the <body>.\n' +
+        '    in html (at **)',
     ]);
 
-    await expect(async () => {
-      root.render(
+    root.render(
+      <>
+        <link rel="foo" onLoad={() => {}} href="bar" />
         <html>
-          <script async={true} onLoad={() => {}} href="bar" />
           <body>foo</body>
-        </html>,
-      );
-      await waitForAll([]);
-    }).toErrorDev([
-      'Cannot render a <script> with onLoad or onError listeners outside the main document. Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or somewhere in the <body>.',
-    ]);
-
-    await expect(async () => {
-      root.render(
-        <>
-          <link rel="foo" onLoad={() => {}} href="bar" />
-          <html>
-            <body>foo</body>
-          </html>
-        </>,
-      );
-      const aggregateError = await waitForThrow();
-      expect(aggregateError.errors.length).toBe(2);
-      expect(aggregateError.errors[0].message).toContain(
-        'Invalid insertion of LINK',
-      );
-      expect(aggregateError.errors[1].message).toContain(
-        'The node to be removed is not a child of this node',
-      );
-    }).toErrorDev(
+        </html>
+      </>,
+    );
+    aggregateError = await waitForThrow();
+    expect(aggregateError.errors.length).toBe(2);
+    expect(aggregateError.errors[0].message).toContain(
+      'Invalid insertion of LINK',
+    );
+    expect(aggregateError.errors[1].message).toContain(
+      'The node to be removed is not a child of this node',
+    );
+    assertConsoleErrorDev(
       [
-        'Cannot render a <link> with onLoad or onError listeners outside the main document. Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or somewhere in the <body>.',
+        'Cannot render a <link> with onLoad or onError listeners outside the main document. ' +
+          'Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or ' +
+          'somewhere in the <body>.',
       ],
-      {withoutStack: 1},
+      {withoutStack: true},
     );
   });
 
@@ -2222,40 +2259,53 @@ body {
         </html>
       );
     }
-    await expect(async () => {
-      await act(() => {
-        const {pipe} = renderToPipeableStream(<App />);
-        pipe(writable);
-      });
-      expect(getMeaningfulChildren(document)).toEqual(
-        <html>
-          <head>
-            <link
-              rel="stylesheet"
-              href="foo"
-              data-precedence="default"
-              crossorigin="anonymous"
-              media="all"
-              integrity="somehash"
-              referrerpolicy="origin"
-              data-foo={'"quoted"'}
-              nonstandardattr="attr"
-              properlyformattednonstandardattr="attr"
-            />
-          </head>
-          <body>
-            <div>loading...</div>
-          </body>
-        </html>,
-      );
-    }).toErrorDev([
-      'React does not recognize the `nonStandardAttr` prop on a DOM element.' +
-        ' If you intentionally want it to appear in the DOM as a custom attribute,' +
-        ' spell it as lowercase `nonstandardattr` instead. If you accidentally passed it from a' +
-        ' parent component, remove it from the DOM element.',
-      'Invalid values for props `shouldnotincludefunctions`, `norsymbols` on <link> tag. Either remove them from' +
-        ' the element, or pass a string or number value to keep them in the DOM. For' +
-        ' details, see https://react.dev/link/attribute-behavior',
+    await act(() => {
+      const {pipe} = renderToPipeableStream(<App />);
+      pipe(writable);
+    });
+    expect(getMeaningfulChildren(document)).toEqual(
+      <html>
+        <head>
+          <link
+            rel="stylesheet"
+            href="foo"
+            data-precedence="default"
+            crossorigin="anonymous"
+            media="all"
+            integrity="somehash"
+            referrerpolicy="origin"
+            data-foo={'"quoted"'}
+            nonstandardattr="attr"
+            properlyformattednonstandardattr="attr"
+          />
+        </head>
+        <body>
+          <div>loading...</div>
+        </body>
+      </html>,
+    );
+    assertConsoleErrorDev([
+      'React does not recognize the `nonStandardAttr` prop on a DOM element. ' +
+        'If you intentionally want it to appear in the DOM as a custom attribute, ' +
+        'spell it as lowercase `nonstandardattr` instead. If you accidentally passed it from a ' +
+        'parent component, remove it from the DOM element.\n' +
+        '    in link (at **)\n' +
+        (gate('enableOwnerStacks')
+          ? ''
+          : '    in div (at **)\n' +
+            '    in body (at **)\n' +
+            '    in html (at **)\n') +
+        '    in App (at **)',
+      'Invalid values for props `shouldnotincludefunctions`, `norsymbols` on <link> tag. ' +
+        'Either remove them from the element, or pass a string or number value to keep them in the DOM. ' +
+        'For details, see https://react.dev/link/attribute-behavior \n' +
+        '    in link (at **)\n' +
+        (gate('enableOwnerStacks')
+          ? ''
+          : '    in div (at **)\n' +
+            '    in body (at **)\n' +
+            '    in html (at **)\n') +
+        '    in App (at **)',
     ]);
 
     // Now we flush the stylesheet with the boundary
@@ -2592,30 +2642,133 @@ body {
     );
   });
 
-  it('warns if you render a tag with itemProp outside <body> or <head>', async () => {
+  it('warns if you render <meta> tag with itemProp outside <body> or <head>', async () => {
     const root = ReactDOMClient.createRoot(document);
     root.render(
       <html>
         <meta itemProp="foo" />
+      </html>,
+    );
+
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <meta> outside the main document if it has an `itemProp` prop. ' +
+        '`itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. ' +
+        'If you were intending for React to hoist this <meta> remove the `itemProp` prop. ' +
+        'Otherwise, try moving this tag into the <head> or <body> of the Document.\n' +
+        '    in html (at **)',
+      'In HTML, <meta> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n' +
+        '\n' +
+        '> <html>\n' +
+        '>   <meta itemProp="foo">' +
+        '\n' +
+        '\n    in meta (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
+    ]);
+  });
+
+  it('warns if you render a <title> tag with itemProp outside <body> or <head>', async () => {
+    const root = ReactDOMClient.createRoot(document);
+    root.render(
+      <html>
         <title itemProp="foo">title</title>
+      </html>,
+    );
+
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <title> outside the main document if it has an `itemProp` prop. ' +
+        '`itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. ' +
+        'If you were intending for React to hoist this <title> remove the `itemProp` prop. ' +
+        'Otherwise, try moving this tag into the <head> or <body> of the Document.\n' +
+        '    in html (at **)',
+      'In HTML, <title> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n' +
+        '\n' +
+        '> <html>\n' +
+        '>   <title itemProp="foo">' +
+        '\n' +
+        '\n    in title (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
+    ]);
+  });
+
+  it('warns if you render a <style> tag with itemProp outside <body> or <head>', async () => {
+    const root = ReactDOMClient.createRoot(document);
+    root.render(
+      <html>
         <style itemProp="foo">style</style>
+      </html>,
+    );
+
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <style> outside the main document if it has an `itemProp` prop. ' +
+        '`itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. ' +
+        'If you were intending for React to hoist this <style> remove the `itemProp` prop. ' +
+        'Otherwise, try moving this tag into the <head> or <body> of the Document.\n' +
+        '    in html (at **)',
+      'In HTML, <style> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n' +
+        '\n' +
+        '> <html>\n' +
+        '>   <style itemProp="foo">' +
+        '\n' +
+        '\n    in style (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
+    ]);
+  });
+
+  it('warns if you render a <link> tag with itemProp outside <body> or <head>', async () => {
+    const root = ReactDOMClient.createRoot(document);
+    root.render(
+      <html>
         <link itemProp="foo" />
+      </html>,
+    );
+
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <link> outside the main document if it has an `itemProp` prop. ' +
+        '`itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. ' +
+        'If you were intending for React to hoist this <link> remove the `itemProp` prop. ' +
+        'Otherwise, try moving this tag into the <head> or <body> of the Document.\n' +
+        '    in html (at **)',
+      'In HTML, <link> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n' +
+        '\n' +
+        '> <html>\n' +
+        '>   <link itemProp="foo">\n' +
+        '\n' +
+        '    in link (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
+    ]);
+  });
+
+  it('warns if you render a <script> tag with itemProp outside <body> or <head>', async () => {
+    const root = ReactDOMClient.createRoot(document);
+    root.render(
+      <html>
         <script itemProp="foo" />
       </html>,
     );
-    await expect(async () => {
-      await waitForAll([]);
-    }).toErrorDev([
-      'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
-      'Cannot render a <title> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <title> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
-      'Cannot render a <style> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <style> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
-      'Cannot render a <link> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <link> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
-      'Cannot render a <script> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <script> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
-      'In HTML, <meta> cannot be a child of <html>',
-      'In HTML, <title> cannot be a child of <html>',
-      'In HTML, <style> cannot be a child of <html>',
-      'In HTML, <link> cannot be a child of <html>',
-      'In HTML, <script> cannot be a child of <html>',
+
+    await waitForAll([]);
+    assertConsoleErrorDev([
+      'Cannot render a <script> outside the main document if it has an `itemProp` prop. ' +
+        '`itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. ' +
+        'If you were intending for React to hoist this <script> remove the `itemProp` prop. ' +
+        'Otherwise, try moving this tag into the <head> or <body> of the Document.\n' +
+        '    in html (at **)',
+      'In HTML, <script> cannot be a child of <html>.\n' +
+        'This will cause a hydration error.\n' +
+        '\n' +
+        '> <html>\n' +
+        '>   <script itemProp="foo">\n' +
+        '\n' +
+        '    in script (at **)' +
+        (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
     ]);
   });
 
@@ -3483,12 +3636,12 @@ body {
       </html>,
     );
 
-    await expect(async () => {
-      loadStylesheets();
-    }).toErrorDev([
+    loadStylesheets();
+    assertLog(['load stylesheet: foo']);
+    await waitForAll([]);
+    assertConsoleErrorDev([
       "Hydration failed because the server rendered HTML didn't match the client.",
     ]);
-    assertLog(['load stylesheet: foo']);
 
     expect(getMeaningfulChildren(document)).toEqual(
       <html>
@@ -4705,12 +4858,17 @@ body {
       );
     }
 
-    await expect(async () => {
-      await act(() => {
-        renderToPipeableStream(<App />).pipe(writable);
-      });
-    }).toErrorDev([
-      'React encountered a hoistable style tag for the same href as a preload: "foo". When using a style tag to inline styles you should not also preload it as a stylsheet.',
+    await act(() => {
+      renderToPipeableStream(<App />).pipe(writable);
+    });
+    assertConsoleErrorDev([
+      'React encountered a hoistable style tag for the same href as a preload: "foo". ' +
+        'When using a style tag to inline styles you should not also preload it as a stylsheet.\n' +
+        '    in style (at **)\n' +
+        (gate('enableOwnerStacks')
+          ? ''
+          : '    in body (at **)\n' + '    in html (at **)\n') +
+        '    in App (at **)',
     ]);
 
     expect(getMeaningfulChildren(document)).toEqual(
@@ -5404,13 +5562,23 @@ body {
         );
       }
 
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App url="foo" />).pipe(writable);
-        });
-      }).toErrorDev([
-        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.',
-        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.',
+      await act(() => {
+        renderToPipeableStream(<App url="foo" />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, ' +
+          'but encountered something with type "object" as a second argument instead. ' +
+          'This argument is reserved for future options and is currently disallowed. ' +
+          'Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.\n' +
+          '    in App (at **)',
+        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, ' +
+          'but encountered something with type "object" as a second argument instead. ' +
+          'This argument is reserved for future options and is currently disallowed. ' +
+          'It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. ' +
+          'Browsers do not perform DNS queries using CORS and setting this attribute ' +
+          'on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just ' +
+          'a single string argument, `href`.\n' +
+          '    in App (at **)',
       ]);
 
       expect(getMeaningfulChildren(document)).toEqual(
@@ -5423,11 +5591,21 @@ body {
       );
 
       const root = ReactDOMClient.hydrateRoot(document, <App url="foo" />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev([
-        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.',
-        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.',
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, ' +
+          'but encountered something with type "object" as a second argument instead. ' +
+          'This argument is reserved for future options and is currently disallowed. ' +
+          'Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.\n' +
+          '    in App (at **)',
+        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, ' +
+          'but encountered something with type "object" as a second argument instead. ' +
+          'This argument is reserved for future options and is currently disallowed. ' +
+          'It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. ' +
+          'Browsers do not perform DNS queries using CORS and setting this attribute ' +
+          'on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just ' +
+          'a single string argument, `href`.\n' +
+          '    in App (at **)',
       ]);
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
@@ -5439,11 +5617,21 @@ body {
       );
 
       root.render(<App url="bar" />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev([
-        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.',
-        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.',
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, ' +
+          'but encountered something with type "object" as a second argument instead. ' +
+          'This argument is reserved for future options and is currently disallowed. ' +
+          'Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.\n' +
+          '    in App (at **)',
+        'ReactDOM.prefetchDNS(): Expected only one argument, `href`, ' +
+          'but encountered something with type "object" as a second argument instead. ' +
+          'This argument is reserved for future options and is currently disallowed. ' +
+          'It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. ' +
+          'Browsers do not perform DNS queries using CORS and setting this attribute ' +
+          'on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just ' +
+          'a single string argument, `href`.\n' +
+          '    in App (at **)',
       ]);
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
@@ -5587,13 +5775,15 @@ body {
         );
       }
 
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App url="foo" />).pipe(writable);
-        });
-      }).toErrorDev(
-        'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered something with type "boolean" instead. Try removing this option or passing a string value instead.',
-      );
+      await act(() => {
+        renderToPipeableStream(<App url="foo" />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) ' +
+          'to be a string but encountered something with type "boolean" instead. ' +
+          'Try removing this option or passing a string value instead.\n' +
+          '    in App (at **)',
+      ]);
 
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
@@ -5607,11 +5797,13 @@ body {
       );
 
       const root = ReactDOMClient.hydrateRoot(document, <App url="foo" />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev(
-        'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered something with type "boolean" instead. Try removing this option or passing a string value instead.',
-      );
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) ' +
+          'to be a string but encountered something with type "boolean" instead. ' +
+          'Try removing this option or passing a string value instead.\n' +
+          '    in App (at **)',
+      ]);
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
           <head>
@@ -5624,11 +5816,13 @@ body {
       );
 
       root.render(<App url="bar" />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev(
-        'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered something with type "boolean" instead. Try removing this option or passing a string value instead.',
-      );
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) ' +
+          'to be a string but encountered something with type "boolean" instead. ' +
+          'Try removing this option or passing a string value instead.\n' +
+          '    in App (at **)',
+      ]);
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
           <head>
@@ -5785,15 +5979,28 @@ body {
         return <div>foo</div>;
       }
 
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App />).pipe(writable);
-        });
-      }).toErrorDev([
-        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. The `href` argument encountered was `undefined`. The `options` argument encountered was `undefined`.',
-        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. The `href` argument encountered was an empty string. The `options` argument encountered was `undefined`.',
-        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. The `options` argument encountered was `null`.',
-        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. The `as` option encountered was `undefined`.',
+      await act(() => {
+        renderToPipeableStream(<App />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an ' +
+          '`options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. ' +
+          'The `href` argument encountered was `undefined`. ' +
+          'The `options` argument encountered was `undefined`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an ' +
+          '`options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. ' +
+          'The `href` argument encountered was an empty string. ' +
+          'The `options` argument encountered was `undefined`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an ' +
+          '`options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. ' +
+          'The `options` argument encountered was `null`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an ' +
+          '`options` object with an `as` property valid for a `<link rel="preload" as="..." />` tag. ' +
+          'The `as` option encountered was `undefined`.\n' +
+          '    in App (at **)',
       ]);
     });
 
@@ -6041,16 +6248,30 @@ body {
         ReactDOM.preloadModule('2', {as: true});
         return <div>hello</div>;
       }
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App />).pipe(writable);
-        });
-      }).toErrorDev([
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `href` argument encountered was `undefined`',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `href` argument encountered was something with type "function"',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `href` argument encountered was an empty string',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `options` argument encountered was something with type "boolean"',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `as` option encountered was something with type "boolean"',
+      await act(() => {
+        renderToPipeableStream(<App />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, ' +
+          'an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `href` argument encountered was `undefined`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, ' +
+          'an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `href` argument encountered was something with type "function".\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, ' +
+          'an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `href` argument encountered was an empty string.\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, ' +
+          'an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `options` argument encountered was something with type "boolean".\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally,' +
+          ' an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `as` option encountered was something with type "boolean".\n' +
+          '    in App (at **)',
       ]);
       expect(getMeaningfulChildren(document.body)).toEqual(
         <div id="container">
@@ -6064,14 +6285,28 @@ body {
         document.getElementById('container'),
       );
       root.render(<App />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev([
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `href` argument encountered was `undefined`',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `href` argument encountered was something with type "function"',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `href` argument encountered was an empty string',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `options` argument encountered was something with type "boolean"',
-        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. The `as` option encountered was something with type "boolean"',
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, ' +
+          'an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `href` argument encountered was `undefined`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, ' +
+          'an `options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `href` argument encountered was something with type "function".\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an ' +
+          '`options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `href` argument encountered was an empty string.\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an ' +
+          '`options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `options` argument encountered was something with type "boolean".\n' +
+          '    in App (at **)',
+        'ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an ' +
+          '`options` object with an `as` property valid for a `<link rel="modulepreload" as="..." />` tag. ' +
+          'The `as` option encountered was something with type "boolean".\n' +
+          '    in App (at **)',
       ]);
     });
   });
@@ -6340,16 +6575,27 @@ body {
         return <div>foo</div>;
       }
 
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App />).pipe(writable);
-        });
-      }).toErrorDev([
-        'ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string but encountered `undefined` instead',
-        'ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string but encountered an empty string instead',
-        'ReactDOM.preinit(): Expected the `options` argument (second) to be an object with an `as` property describing the type of resource to be preinitialized but encountered `null` instead',
-        'ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain a valid value describing the type of resource to be preinitialized but encountered `undefined` instead. Valid values for `as` are "style" and "script".',
-        'ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain a valid value describing the type of resource to be preinitialized but encountered "foo" instead. Valid values for `as` are "style" and "script".',
+      await act(() => {
+        renderToPipeableStream(<App />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string ' +
+          'but encountered `undefined` instead.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string ' +
+          'but encountered an empty string instead.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinit(): Expected the `options` argument (second) to be an object with an `as` ' +
+          'property describing the type of resource to be preinitialized but encountered `null` instead.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain ' +
+          'a valid value describing the type of resource to be preinitialized but encountered `undefined` instead. ' +
+          'Valid values for `as` are "style" and "script".\n' +
+          '    in App (at **)',
+        'ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain ' +
+          'a valid value describing the type of resource to be preinitialized but encountered "foo" instead. ' +
+          'Valid values for `as` are "style" and "script".\n' +
+          '    in App (at **)',
       ]);
     });
 
@@ -6621,12 +6867,14 @@ body {
         ReactDOM.preinitModule(prefix + 'warning', {as: 'style'});
         return <div>hello</div>;
       }
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App ssr={true} />).pipe(writable);
-        });
-      }).toErrorDev([
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `as` option encountered was "style"',
+      await act(() => {
+        renderToPipeableStream(<App ssr={true} />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `as` option encountered was "style".\n' +
+          '    in App (at **)',
       ]);
       expect(getMeaningfulChildren(document.body)).toEqual(
         <div id="container">
@@ -6649,10 +6897,12 @@ body {
       );
 
       ReactDOMClient.hydrateRoot(container, <App />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev([
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `as` option encountered was "style"',
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `as` option encountered was "style".\n' +
+          '    in App (at **)',
       ]);
       expect(getMeaningfulChildren(document)).toEqual(
         <html>
@@ -6704,16 +6954,30 @@ body {
         ReactDOM.preinitModule('2', {as: true});
         return <div>hello</div>;
       }
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(<App />).pipe(writable);
-        });
-      }).toErrorDev([
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `href` argument encountered was `undefined`',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `href` argument encountered was something with type "function"',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `href` argument encountered was an empty string',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `options` argument encountered was something with type "boolean"',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `as` option encountered was something with type "boolean"',
+      await act(() => {
+        renderToPipeableStream(<App />).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `href` argument encountered was `undefined`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `href` argument encountered was something with type "function".\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `href` argument encountered was an empty string.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `options` argument encountered was something with type "boolean".\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `as` option encountered was something with type "boolean".\n' +
+          '    in App (at **)',
       ]);
       expect(getMeaningfulChildren(document.body)).toEqual(
         <div id="container">
@@ -6725,14 +6989,28 @@ body {
         document.getElementById('container'),
       );
       root.render(<App />);
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev([
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `href` argument encountered was `undefined`',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `href` argument encountered was something with type "function"',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `href` argument encountered was an empty string',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `options` argument encountered was something with type "boolean"',
-        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property. The `as` option encountered was something with type "boolean"',
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `href` argument encountered was `undefined`.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `href` argument encountered was something with type "function".\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `href` argument encountered was an empty string.\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `options` argument encountered was something with type "boolean".\n' +
+          '    in App (at **)',
+        'ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` ' +
+          'string and, optionally, an `options` object with a valid `as` property. ' +
+          'The `as` option encountered was something with type "boolean".\n' +
+          '    in App (at **)',
       ]);
     });
   });
@@ -7454,51 +7732,106 @@ body {
     });
 
     it('warns if you provide a `precedence` prop with other props that invalidate the creation of a stylesheet resource', async () => {
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(
-            <html>
-              <body>
-                <link rel="stylesheet" precedence="default" />
-                <link rel="stylesheet" href="" precedence="default" />
-                <link
-                  rel="stylesheet"
-                  href="foo"
-                  precedence="default"
-                  onLoad={() => {}}
-                  onError={() => {}}
-                />
-                <link
-                  rel="stylesheet"
-                  href="foo"
-                  precedence="default"
-                  onLoad={() => {}}
-                />
-                <link
-                  rel="stylesheet"
-                  href="foo"
-                  precedence="default"
-                  onError={() => {}}
-                />
-                <link
-                  rel="stylesheet"
-                  href="foo"
-                  precedence="default"
-                  disabled={false}
-                />
-              </body>
-            </html>,
-          ).pipe(writable);
-        });
-      }).toErrorDev(
+      await act(() => {
+        renderToPipeableStream(
+          <html>
+            <body>
+              <link rel="stylesheet" precedence="default" />
+              <link rel="stylesheet" href="" precedence="default" />
+              <link
+                rel="stylesheet"
+                href="foo"
+                precedence="default"
+                onLoad={() => {}}
+                onError={() => {}}
+              />
+              <link
+                rel="stylesheet"
+                href="foo"
+                precedence="default"
+                onLoad={() => {}}
+              />
+              <link
+                rel="stylesheet"
+                href="foo"
+                precedence="default"
+                onError={() => {}}
+              />
+              <link
+                rel="stylesheet"
+                href="foo"
+                precedence="default"
+                disabled={false}
+              />
+            </body>
+          </html>,
+        ).pipe(writable);
+      });
+      assertConsoleErrorDev(
         [
-          'An empty string ("") was passed to the href attribute. To fix this, either do not render the element at all or pass null to href instead of an empty string.',
-          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and expected the `href` prop to be a non-empty string but ecountered `undefined` instead. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop ensure there is a non-empty string `href` prop as well, otherwise remove the `precedence` prop.',
-          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and expected the `href` prop to be a non-empty string but ecountered an empty string instead. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop ensure there is a non-empty string `href` prop as well, otherwise remove the `precedence` prop.',
-          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and `onLoad` and `onError` props. The presence of loading and error handlers indicates an intent to manage the stylesheet loading state from your from your Component code and React will not hoist or deduplicate this stylesheet. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop remove the `onLoad` and `onError` props, otherwise remove the `precedence` prop.',
-          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and `onLoad` prop. The presence of loading and error handlers indicates an intent to manage the stylesheet loading state from your from your Component code and React will not hoist or deduplicate this stylesheet. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop remove the `onLoad` prop, otherwise remove the `precedence` prop.',
-          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and `onError` prop. The presence of loading and error handlers indicates an intent to manage the stylesheet loading state from your from your Component code and React will not hoist or deduplicate this stylesheet. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop remove the `onError` prop, otherwise remove the `precedence` prop.',
-          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and a `disabled` prop. The presence of the `disabled` prop indicates an intent to manage the stylesheet active state from your from your Component code and React will not hoist or deduplicate this stylesheet. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop remove the `disabled` prop, otherwise remove the `precedence` prop.',
+          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and ' +
+            'expected the `href` prop to be a non-empty string but ecountered `undefined` instead. ' +
+            'If your intent was to have React hoist and deduplciate this stylesheet using the ' +
+            '`precedence` prop ensure there is a non-empty string `href` prop as well, ' +
+            'otherwise remove the `precedence` prop.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
+          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and ' +
+            'expected the `href` prop to be a non-empty string but ecountered an empty string instead. ' +
+            'If your intent was to have React hoist and deduplciate this stylesheet using the ' +
+            '`precedence` prop ensure there is a non-empty string `href` prop as well, ' +
+            'otherwise remove the `precedence` prop.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
+          'An empty string ("") was passed to the href attribute. ' +
+            'To fix this, either do not render the element at all or ' +
+            'pass null to href instead of an empty string.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
+          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and ' +
+            '`onLoad` and `onError` props. The presence of loading and error handlers indicates ' +
+            'an intent to manage the stylesheet loading state from your from your Component code ' +
+            'and React will not hoist or deduplicate this stylesheet. ' +
+            'If your intent was to have React hoist and deduplciate this stylesheet using the ' +
+            '`precedence` prop remove the `onLoad` and `onError` props, otherwise remove the `precedence` prop.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
+          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and ' +
+            '`onLoad` prop. The presence of loading and error handlers indicates an intent to ' +
+            'manage the stylesheet loading state from your from your Component code and ' +
+            'React will not hoist or deduplicate this stylesheet. ' +
+            'If your intent was to have React hoist and deduplciate this stylesheet using the ' +
+            '`precedence` prop remove the `onLoad` prop, otherwise remove the `precedence` prop.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
+          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and `onError` prop. ' +
+            'The presence of loading and error handlers indicates an intent to manage the stylesheet loading state ' +
+            'from your from your Component code and React will not hoist or deduplicate this stylesheet. ' +
+            'If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` ' +
+            'prop remove the `onError` prop, otherwise remove the `precedence` prop.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
+          'React encountered a `<link rel="stylesheet" .../>` with a `precedence` prop and a `disabled` prop. ' +
+            'The presence of the `disabled` prop indicates an intent to manage the stylesheet active state from ' +
+            'your from your Component code and React will not hoist or deduplicate this stylesheet. ' +
+            'If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` ' +
+            'prop remove the `disabled` prop, otherwise remove the `precedence` prop.\n' +
+            '    in link (at **)' +
+            (gate('enableOwnerStacks')
+              ? ''
+              : '\n    in body (at **)' + '\n    in html (at **)'),
         ].filter(Boolean),
       );
 
@@ -7516,10 +7849,16 @@ body {
           </body>
         </html>,
       );
-      await expect(async () => {
-        await waitForAll([]);
-      }).toErrorDev([
-        'React encountered a <link rel="stylesheet" href="foo" ... /> with a `precedence` prop that also included the `onLoad` and `onError` props. The presence of loading and error handlers indicates an intent to manage the stylesheet loading state from your from your Component code and React will not hoist or deduplicate this stylesheet. If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` prop remove the `onLoad` and `onError` props, otherwise remove the `precedence` prop.',
+      await waitForAll([]);
+      assertConsoleErrorDev([
+        'React encountered a <link rel="stylesheet" href="foo" ... /> with a `precedence` ' +
+          'prop that also included the `onLoad` and `onError` props. ' +
+          'The presence of loading and error handlers indicates an intent to manage the stylesheet ' +
+          'loading state from your from your Component code and React will not hoist or deduplicate this stylesheet. ' +
+          'If your intent was to have React hoist and deduplciate this stylesheet using the `precedence` ' +
+          'prop remove the `onLoad` and `onError` props, otherwise remove the `precedence` prop.\n' +
+          '    in body (at **)' +
+          (gate('enableOwnerStacks') ? '' : '\n    in html (at **)'),
       ]);
     });
 
@@ -8095,21 +8434,27 @@ background-color: green;
     });
 
     it('warns if you render a <style> with an href with a space on the server', async () => {
-      await expect(async () => {
-        await act(() => {
-          renderToPipeableStream(
-            <html>
-              <body>
-                <style href="foo bar" precedence="default">
-                  style
-                </style>
-              </body>
-            </html>,
-          ).pipe(writable);
-        });
-      }).toErrorDev(
-        'React expected the `href` prop for a <style> tag opting into hoisting semantics using the `precedence` prop to not have any spaces but ecountered spaces instead. using spaces in this prop will cause hydration of this style to fail on the client. The href for the <style> where this ocurred is "foo bar".',
-      );
+      await act(() => {
+        renderToPipeableStream(
+          <html>
+            <body>
+              <style href="foo bar" precedence="default">
+                style
+              </style>
+            </body>
+          </html>,
+        ).pipe(writable);
+      });
+      assertConsoleErrorDev([
+        'React expected the `href` prop for a <style> tag opting into hoisting semantics ' +
+          'using the `precedence` prop to not have any spaces but ecountered spaces instead. ' +
+          'using spaces in this prop will cause hydration of this style to fail on the client. ' +
+          'The href for the <style> where this ocurred is "foo bar".\n' +
+          '    in style (at **)' +
+          (gate('enableOwnerStacks')
+            ? ''
+            : '\n    in body (at **)' + '\n    in html (at **)'),
+      ]);
     });
   });