@@ -1003,4 +1003,74 @@ describe('ReactDOMServerPartialHydration', () => {
10031003 let div = container . getElementsByTagName ( 'div' ) [ 0 ] ;
10041004 expect ( ref . current ) . toBe ( div ) ;
10051005 } ) ;
1006+
1007+ it ( 'warns when a sibling before the dehydrated boundary has inner text mismatch' , async ( ) => {
1008+ let suspend = false ;
1009+ let resolve ;
1010+ let promise = new Promise ( resolvePromise => ( resolve = resolvePromise ) ) ;
1011+
1012+ function Child ( { text} ) {
1013+ if ( suspend ) {
1014+ throw promise ;
1015+ } else {
1016+ return 'Second ' + text ;
1017+ }
1018+ }
1019+
1020+ function Sibling ( { text} ) {
1021+ return < div > First { text } </ div > ;
1022+ }
1023+
1024+ function App ( { text} ) {
1025+ return (
1026+ < div >
1027+ < Sibling text = { text } />
1028+ < Suspense fallback = "Loading..." >
1029+ < span >
1030+ < Child text = { text } />
1031+ </ span >
1032+ </ Suspense >
1033+ </ div >
1034+ ) ;
1035+ }
1036+
1037+ suspend = false ;
1038+ let finalHTML = ReactDOMServer . renderToString ( < App text = { 'server text' } /> ) ;
1039+ let container = document . createElement ( 'div' ) ;
1040+ container . innerHTML = finalHTML ;
1041+
1042+ // On the client we don't have all data yet but we want to start
1043+ // hydrating anyway.
1044+ suspend = true ;
1045+
1046+ expect ( ( ) => {
1047+ act ( ( ) => {
1048+ ReactDOM . hydrate ( < App text = { 'client text' } /> , container ) ;
1049+ } ) ;
1050+ } ) . toWarnDev (
1051+ 'Text content did not match. ' +
1052+ 'Server: "server text" ' +
1053+ 'Client: "client text"\n' +
1054+ ' in div (at **)\n' +
1055+ ' in Sibling (at **)\n' +
1056+ ' in div (at **)\n' +
1057+ ' in App (at **)' ,
1058+ ) ;
1059+
1060+ expect ( container . firstChild . firstChild . tagName ) . toBe ( 'DIV' ) ;
1061+ expect ( container . firstChild . firstChild . textContent ) . toBe (
1062+ 'First client text' ,
1063+ ) ;
1064+
1065+ // Resolving the promise should continue hydration
1066+ suspend = false ;
1067+ resolve ( ) ;
1068+ await promise ;
1069+ Scheduler . flushAll ( ) ;
1070+ jest . runAllTimers ( ) ;
1071+
1072+ let span = container . getElementsByTagName ( 'span' ) [ 0 ] ;
1073+ expect ( span . textContent ) . toBe ( 'Second client text' ) ;
1074+ expect ( container . textContent ) . toBe ( 'First client textSecond client text' ) ;
1075+ } ) ;
10061076} ) ;
0 commit comments