Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test] Run React 18 integration tests with new createRoot API #26672

Merged
merged 46 commits into from
Jul 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a524c0d
Install testing-library packages supporting concurrent features
eps1lon Jun 8, 2021
a6d4090
REVERT LATER use-react-dist-tag next
eps1lon Jun 8, 2021
49fbdb0
mock scheduler for test:unit
eps1lon Jun 9, 2021
42b9140
Only mock with react@next
eps1lon Jun 9, 2021
fd3e1d4
Allow using legacy roots
eps1lon Jun 9, 2021
6fe1d1b
Opt out of strictmode for React 18 specifically
eps1lon Jun 9, 2021
624d20c
Start enabling legacy roots where incompatible with React 18
eps1lon Jun 9, 2021
417f531
[TrapFocus] Capture nodeToRestore via relatedTarget
eps1lon Jun 11, 2021
6c5e504
Fix tests related to double console calls
eps1lon Jun 11, 2021
5caa4f5
fix treeitem focus by using await (#580)
siriwatknp Jun 16, 2021
beb80e6
[test] fix focus and strict effects related (#582)
siriwatknp Jun 18, 2021
a9f2044
make sure this is about flushing microtasks (and the updates schedule…
eps1lon Jun 18, 2021
b04e375
Merge remote-tracking branch 'upstream/next' into test/concurrent-react
eps1lon Jun 18, 2021
27ff353
Fix useForkRef test
eps1lon Jun 18, 2021
5eeba13
Fix TrapFocus tests
eps1lon Jun 18, 2021
2337ed1
Fix tooltip tests
eps1lon Jun 18, 2021
8e77964
fix Modal test
eps1lon Jun 18, 2021
6c1e442
Merge branch 'next' into test/concurrent-react
eps1lon Jun 20, 2021
54f8140
Link to react wg thread for more context
eps1lon Jun 20, 2021
3c5b6e1
Document interface of `strictEffects` not its implementation
eps1lon Jun 20, 2021
19a04df
[Popper] Re-appear when leaving Offscreen
eps1lon Jun 20, 2021
e88448f
Merge branch 'next' into test/concurrent-react
eps1lon Jun 21, 2021
9d5daa2
Merge remote-tracking branch 'upstream/next' into test/concurrent-react
eps1lon Jun 28, 2021
35ff90e
WIP bump react
eps1lon Jun 28, 2021
833b35f
Merge branch 'next' into test/concurrent-react
eps1lon Jun 29, 2021
307da42
FOR NEXT [test] Act on clock ticks
eps1lon Jun 29, 2021
f33eb96
Bump testing-library
eps1lon Jun 29, 2021
b6034d9
git-diff hygene
eps1lon Jun 29, 2021
419b3fc
Fix more tests related to errors in effects
eps1lon Jun 29, 2021
4ef0d95
Fix tests failing due to double `onEnter` in StrictEffects
eps1lon Jun 29, 2021
6e36be2
f testing library
eps1lon Jun 29, 2021
4108353
f clock act
eps1lon Jun 29, 2021
5a7c37b
enable missing act warnings
eps1lon Jun 30, 2021
24fc564
f hygene
eps1lon Jun 30, 2021
5d6a7e2
No longer require react_dist_tag env to be set
eps1lon Jun 30, 2021
a8a746d
Automatically install rtl version with concurrent rendering support
eps1lon Jun 30, 2021
4a4e4fd
proptypes
eps1lon Jul 1, 2021
0ffaaa9
Bump React
eps1lon Jul 1, 2021
f18bfba
FOR NEXT fix more missing act actions
eps1lon Jul 1, 2021
6ec8094
fix useMediaQuery test
eps1lon Jul 1, 2021
1b22e32
Revert some unnecessary act()
eps1lon Jul 1, 2021
399f5af
Revert Popper runtime change
eps1lon Jul 1, 2021
d378610
Merge remote-tracking branch 'upstream/next' into test/concurrent-react
eps1lon Jul 1, 2021
d4f7b9f
Revert "REVERT LATER use-react-dist-tag next"
eps1lon Jul 1, 2021
debacd4
ignore type issues due to using different forks
eps1lon Jul 1, 2021
89e4735
Merge remote-tracking branch 'upstream/next' into test/concurrent-react
eps1lon Jul 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ describe('<DesktopDatePicker />', () => {
TransitionComponent={FakeTransitionComponent}
renderInput={(params) => <TextField {...params} />}
/>,
// TODO: React18Compat
{ legacyRoot: true },
);

act(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ describe('<DesktopDateTimePicker />', () => {
onChange={() => {}}
renderInput={(params) => <TextField autoFocus {...params} />}
/>,
// TODO: React18Compat
{ legacyRoot: true },
);

userEvent.mousePress(screen.getByLabelText(/choose date/i));
Expand Down
18 changes: 9 additions & 9 deletions packages/material-ui-lab/src/TreeItem/TreeItem.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,8 @@ describe('<TreeItem />', () => {

act(() => {
screen.getByRole('tree').focus();
fireEvent.keyDown(screen.getByRole('tree'), { key: 'ArrowLeft' });
});
fireEvent.keyDown(screen.getByRole('tree'), { key: 'ArrowLeft' });

expect(firstItem).to.have.attribute('aria-expanded', 'false');
expect(screen.getByTestId('one')).toHaveVirtualFocus();
Expand Down Expand Up @@ -1099,8 +1099,8 @@ describe('<TreeItem />', () => {

act(() => {
getByRole('tree').focus();
fireEvent.keyDown(getByRole('tree'), { key: ' ' });
});
fireEvent.keyDown(getByRole('tree'), { key: ' ' });

expect(getByTestId('one')).not.to.have.attribute('aria-selected');
});
Expand Down Expand Up @@ -1440,16 +1440,16 @@ describe('<TreeItem />', () => {
</TreeView>,
);

fireEvent.click(getByText('five'));
fireEvent.click(getByText('five'));
// Focus node five
act(() => {
fireEvent.click(getByText('five'));
fireEvent.click(getByText('five'));
getByRole('tree').focus();
fireEvent.keyDown(getByRole('tree'), {
key: 'End',
shiftKey: true,
ctrlKey: true,
});
});
fireEvent.keyDown(getByRole('tree'), {
key: 'End',
shiftKey: true,
ctrlKey: true,
});

expect(queryAllByRole('treeitem', { selected: true })).to.have.length(0);
Expand Down
2 changes: 2 additions & 0 deletions packages/material-ui-lab/src/TreeView/TreeView.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ describe('<TreeView />', () => {

act(() => {
getByRole('tree').focus();
});
act(() => {
getByRole('tree').blur();
});

Expand Down
5 changes: 4 additions & 1 deletion packages/material-ui-lab/src/internal/pickers/test-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ export function createPickerRender({
);
}

return (node: React.ReactElement) => clientRender(node, { wrapper: Wrapper });
return (
node: React.ReactElement,
options?: Omit<import('test/utils').RenderOptions, 'wrapper'>,
) => clientRender(node, { ...options, wrapper: Wrapper });
}

export const queryByMuiTest = queryHelpers.queryByAttribute.bind(null, 'data-mui-test');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { expect } from 'chai';
import { createClientRender } from 'test/utils';
import { createClientRender, RenderCounter } from 'test/utils';
import useTheme from '../useTheme';
import ThemeProvider from './ThemeProvider';

Expand Down Expand Up @@ -49,24 +49,20 @@ describe('ThemeProvider', () => {
});

it('should memoize the merged output', () => {
const themes = [];

const ref = React.createRef();
const getRenderCountRef = React.createRef();
const text = () => ref.current.textContent;
function Test() {
const theme = useTheme();
React.useEffect(() => {
themes.push(theme);
});

return (
<span ref={ref}>
{theme.foo}
{theme.bar}
</span>
<RenderCounter ref={getRenderCountRef}>
<span ref={ref}>
{theme.foo}
{theme.bar}
</span>
</RenderCounter>
);
}
const MemoTest = React.memo(Test);

const outerTheme = { bar: 'bar' };
const innerTheme = { foo: 'foo' };
Expand All @@ -75,7 +71,7 @@ describe('ThemeProvider', () => {
return (
<ThemeProvider theme={outerTheme}>
<ThemeProvider theme={innerTheme}>
<MemoTest />
<Test />
</ThemeProvider>
</ThemeProvider>
);
Expand All @@ -85,7 +81,7 @@ describe('ThemeProvider', () => {
expect(text()).to.equal('foobar');
setProps({});
expect(text()).to.equal('foobar');
expect(themes).to.have.length(1);
expect(getRenderCountRef.current()).to.equal(2);
});

describe('warnings', () => {
Expand Down
6 changes: 5 additions & 1 deletion packages/material-ui-unstyled/src/Portal/Portal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,13 @@ describe('<Portal />', () => {

function Test(props) {
const { container } = props;
const containerRef = React.useRef();

React.useEffect(() => {
updateFunction();
if (containerRef.current !== container) {
updateFunction();
}
containerRef.current = container;
}, [container]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ describe('<TrapFocus />', () => {
initialFocus = document.createElement('button');
initialFocus.tabIndex = 0;
document.body.appendChild(initialFocus);
initialFocus.focus();
act(() => {
initialFocus.focus();
});
});

afterEach(() => {
Expand All @@ -29,11 +31,15 @@ describe('<TrapFocus />', () => {
<input autoFocus data-testid="auto-focus" />
</div>
</TrapFocus>,
// TODO: https://github.com/reactwg/react-18/discussions/18#discussioncomment-893076
{ strictEffects: false },
);

expect(getByTestId('auto-focus')).toHaveFocus();

initialFocus.focus();
act(() => {
initialFocus.focus();
});
expect(getByTestId('root')).toHaveFocus();
});

Expand All @@ -44,11 +50,15 @@ describe('<TrapFocus />', () => {
<input autoFocus data-testid="auto-focus" />
</div>
</TrapFocus>,
// TODO: https://github.com/reactwg/react-18/discussions/18#discussioncomment-893076s
{ strictEffects: false },
);

expect(getByTestId('auto-focus')).toHaveFocus();

initialFocus.focus();
act(() => {
initialFocus.focus();
});

expect(initialFocus).toHaveFocus();
});
Expand Down Expand Up @@ -112,7 +122,9 @@ describe('<TrapFocus />', () => {
}
const { setProps } = render(<Test />);
const portaledTextbox = screen.getByTestId('portal-input');
portaledTextbox.focus();
act(() => {
portaledTextbox.focus();
});

// sanity check
expect(portaledTextbox).toHaveFocus();
Expand Down Expand Up @@ -178,7 +190,11 @@ describe('<TrapFocus />', () => {
</div>
);
}
const { setProps } = render(<Test />);
const { setProps } = render(<Test />, {
// Strict Effects interferes with the premise of the test.
// It would trigger a focus restore (i.e. a blur event)
strictEffects: false,
});

// same behavior, just referential equality changes
setProps({ isEnabled: () => true });
Expand All @@ -201,12 +217,16 @@ describe('<TrapFocus />', () => {
const { setProps, getByRole } = render(<Test />);
expect(screen.getByTestId('root')).toHaveFocus();

getByRole('textbox').focus();
act(() => {
getByRole('textbox').focus();
});
expect(getByRole('textbox')).not.toHaveFocus();

setProps({ isEnabled: () => false });

getByRole('textbox').focus();
act(() => {
getByRole('textbox').focus();
});
expect(getByRole('textbox')).toHaveFocus();
});

Expand Down Expand Up @@ -293,7 +313,9 @@ describe('<TrapFocus />', () => {
const { setProps } = render(<WithRemovableElement />);

expect(screen.getByTestId('root')).toHaveFocus();
screen.getByTestId('hide-button').focus();
act(() => {
screen.getByTestId('hide-button').focus();
});
expect(screen.getByTestId('hide-button')).toHaveFocus();

setProps({ hideButton: true });
Expand All @@ -313,10 +335,14 @@ describe('<TrapFocus />', () => {
</div>,
);

clock.tick(500); // trigger an interval call
act(() => {
clock.tick(500); // trigger an interval call
});
expect(initialFocus).toHaveFocus();

getByRole('textbox').focus(); // trigger a focus event
act(() => {
getByRole('textbox').focus();
});
expect(getByRole('textbox')).toHaveFocus();
});

Expand All @@ -334,15 +360,21 @@ describe('<TrapFocus />', () => {

expect(initialFocus).toHaveFocus();

screen.getByTestId('outside-input').focus();
act(() => {
screen.getByTestId('outside-input').focus();
});
expect(screen.getByTestId('outside-input')).toHaveFocus();

// the trap activates
screen.getByTestId('focus-input').focus();
act(() => {
screen.getByTestId('focus-input').focus();
});
expect(screen.getByTestId('focus-input')).toHaveFocus();

// the trap prevent to escape
screen.getByTestId('outside-input').focus();
act(() => {
screen.getByTestId('outside-input').focus();
});
expect(screen.getByTestId('root')).toHaveFocus();
});

Expand All @@ -361,11 +393,15 @@ describe('<TrapFocus />', () => {
const { setProps } = render(<Test />);

// set the expected focus restore location
screen.getByTestId('outside-input').focus();
act(() => {
screen.getByTestId('outside-input').focus();
});
expect(screen.getByTestId('outside-input')).toHaveFocus();

// the trap activates
screen.getByTestId('root').focus();
act(() => {
screen.getByTestId('root').focus();
});
expect(screen.getByTestId('root')).toHaveFocus();

// restore the focus to the first element before triggering the trap
Expand Down
11 changes: 8 additions & 3 deletions packages/material-ui-utils/src/useIsFocusVisible.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { expect } from 'chai';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
act,
createClientRender,
focusVisible,
simulatePointerDevice,
Expand Down Expand Up @@ -48,7 +49,7 @@ const SimpleButton = React.forwardRef(function SimpleButton(props, ref) {
);
});

describe('focus-visible polyfill', () => {
describe('useIsFocusVisible', () => {
const render = createClientRender();

before(() => {
Expand Down Expand Up @@ -99,15 +100,19 @@ describe('focus-visible polyfill', () => {

expect(button.classList.contains('focus-visible')).to.equal(false);

button.focus();
act(() => {
button.focus();
});

if (programmaticFocusTriggersFocusVisible()) {
expect(button).to.have.class('focus-visible');
} else {
expect(button).not.to.have.class('focus-visible');
}

button.blur();
act(() => {
button.blur();
});
focusVisible(button);

expect(button.classList.contains('focus-visible')).to.equal(true);
Expand Down
3 changes: 2 additions & 1 deletion packages/material-ui/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ function checkHighlightIs(listbox, expected) {
}

describe('<Autocomplete />', () => {
const render = createClientRender();
// TODO: React18Compat
const render = createClientRender({ legacyRoot: true });

describeConformanceV5(
<Autocomplete options={[]} renderInput={(params) => <TextField {...params} />} />,
Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui/src/Breadcrumbs/Breadcrumbs.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { expect } from 'chai';
import { describeConformanceV5, act, createClientRender, screen } from 'test/utils';
import { act, describeConformanceV5, createClientRender, screen } from 'test/utils';
import Breadcrumbs, { breadcrumbsClasses as classes } from '@material-ui/core/Breadcrumbs';

describe('<Breadcrumbs />', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui/src/Button/Button.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,8 @@ describe('<Button />', () => {
);
const button = getByRole('button');

fireEvent.keyDown(document.body, { key: 'TAB' });
act(() => {
fireEvent.keyDown(document.body, { key: 'TAB' });
button.focus();
});

Expand Down
Loading