19
let assertConsoleErrorDev;
20
let assertLog;
21
let root;
22
+let JSDOM;
23
24
describe('ReactDOMFiber', () => {
25
let container;
26
27
beforeEach(() => {
28
jest.resetModules();
29
+
30
+ // JSDOM needs to be setup with a TextEncoder and TextDecoder when used standalone
31
+ // https://github.com/jsdom/jsdom/issues/2524
32
+ (() => {
33
+ const {TextEncoder, TextDecoder} = require('util');
34
+ global.TextEncoder = TextEncoder;
35
+ global.TextDecoder = TextDecoder;
36
+ JSDOM = require('jsdom').JSDOM;
37
+ })();
38
+
39
React = require('react');
40
ReactDOM = require('react-dom');
41
PropTypes = require('prop-types');
1283
});
1284
expect(didCallOnChange).toBe(true);
1285
});
1286
+
1287
+ it('should restore selection in the correct window', async () => {
1288
+ // creating new JSDOM instance to get a second window as window.open is not implemented
1289
+ // https://github.com/jsdom/jsdom/blob/c53efc81e75f38a0558fbf3ed75d30b78b4c4898/lib/jsdom/browser/Window.js#L987
1290
+ const {window: newWindow} = new JSDOM('');
1291
+ // creating a new container since the default cleanup expects the existing container to be in the document
1292
+ const newContainer = newWindow.document.createElement('div');
1293
+ newWindow.document.body.appendChild(newContainer);
1294
+ root = ReactDOMClient.createRoot(newContainer);
1295
+
1296
+ const Test = () => {
1297
+ const [reverse, setReverse] = React.useState(false);
1298
+ const [items] = React.useState(() => ['a', 'b', 'c']);
1299
+ const onClick = () => {
1300
+ setReverse(true);
1301
+ };
1302
+
1303
+ // shuffle the items so that the react commit needs to restore focus
1304
+ // to the correct element after commit
1305
+ const itemsToRender = reverse ? items.reverse() : items;
1306
+
1307
+ return (
1308
+ <div>
1309
+ {itemsToRender.map(item => (
1310
+ <button onClick={onClick} key={item} id={item}>
1311
+ {item}
1312
+ </button>
1313
+ ))}
1314
+ </div>
1315
+ );
1316
+ };
1317
+
1318
+ await act(() => {
1319
+ root.render(<Test />);
1320
+ });
1321
+
1322
+ newWindow.document.getElementById('a').focus();
1323
+ await act(() => {
1324
+ newWindow.document.getElementById('a').click();
1325
+ });
1326
+
1327
+ expect(newWindow.document.activeElement).not.toBe(newWindow.document.body);
1328
+ expect(newWindow.document.activeElement.innerHTML).toBe('a');
1329
+ });
1330
});