Skip to content

Commit 2ecc448

Browse files
renovate[bot]renovate-botdanez
authored
chore(deps): update dependency @testing-library/user-event to v14 (#454)
Co-authored-by: Renovate Bot <[email protected]> Co-authored-by: Daniel Tschinder <[email protected]>
1 parent d14708f commit 2ecc448

File tree

8 files changed

+277
-222
lines changed

8 files changed

+277
-222
lines changed

.babelrc.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
const target = process.env.BABEL_TARGET;
44
const output = process.env.BABEL_OUTPUT;
5+
const env = process.env.NODE_ENV;
56
const modules = output == null ? false : output;
67

8+
const targets = env === 'test' ? { node: 'current' } : undefined;
9+
710
const options = {
8-
presets: [['@babel/env', { loose: true, modules }], '@babel/react'],
11+
presets: [['@babel/env', { loose: true, modules, targets }], '@babel/react'],
912
plugins: [],
1013
};
1114

@@ -14,7 +17,7 @@ if (target === 'examples') {
1417
'transform-react-remove-prop-types',
1518
{ removeImport: true },
1619
]);
17-
} else {
20+
} else if (env !== 'test') {
1821
options.plugins.push(['transform-react-remove-prop-types', { mode: 'wrap' }]);
1922
}
2023

.vscode/launch.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Attach to Process",
9+
"type": "node",
10+
"request": "attach",
11+
"port": 9229
12+
}
13+
]
14+
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"@testing-library/dom": "8.12.0",
5858
"@testing-library/jest-dom": "5.16.3",
5959
"@testing-library/react": "13.0.0",
60-
"@testing-library/user-event": "13.5.0",
60+
"@testing-library/user-event": "14.0.2",
6161
"babel-jest": "27.5.1",
6262
"babel-loader": "8.2.4",
6363
"babel-plugin-transform-react-remove-prop-types": "0.4.24",

src/components/UncontrolledTabs.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -266,15 +266,24 @@ const UncontrolledTabs = (props) => {
266266
let preventDefault = false;
267267
let useSelectedIndex = false;
268268

269-
if (e.keyCode === 32 /* space */ || e.keyCode === 13 /* enter */) {
269+
if (
270+
e.code === 'Space' ||
271+
e.keyCode === 32 /* space */ ||
272+
e.code === 'Enter' ||
273+
e.keyCode === 13 /* enter */
274+
) {
270275
preventDefault = true;
271276
useSelectedIndex = false;
272277
handleClick(e);
273278
}
274279

280+
// keyCode is deprecated and only used here for IE
281+
275282
if (
283+
e.code === 'ArrowLeft' ||
276284
e.keyCode === 37 /* arrow left */ ||
277-
(!disableUpDownKeys && e.keyCode === 38) /* arrow up */
285+
(!disableUpDownKeys &&
286+
(e.keyCode === 38 || e.code === 'ArrowUp')) /* arrow up */
278287
) {
279288
// Select next tab to the left, validate if up arrow is not disabled
280289
if (direction === 'rtl') {
@@ -285,8 +294,10 @@ const UncontrolledTabs = (props) => {
285294
preventDefault = true;
286295
useSelectedIndex = true;
287296
} else if (
297+
e.code === 'ArrowRight' ||
288298
e.keyCode === 39 /* arrow right */ ||
289-
(!disableUpDownKeys && e.keyCode === 40) /* arrow down */
299+
(!disableUpDownKeys &&
300+
(e.keyCode === 40 || e.code === 'ArrowDown')) /* arrow down */
290301
) {
291302
// Select next tab to the right, validate if down arrow is not disabled
292303
if (direction === 'rtl') {
@@ -296,12 +307,12 @@ const UncontrolledTabs = (props) => {
296307
}
297308
preventDefault = true;
298309
useSelectedIndex = true;
299-
} else if (e.keyCode === 35) {
310+
} else if (e.keyCode === 35 || e.code === 'End') {
300311
// Select last tab (End key)
301312
index = getLastTab();
302313
preventDefault = true;
303314
useSelectedIndex = true;
304-
} else if (e.keyCode === 36) {
315+
} else if (e.keyCode === 36 || e.code === 'Home') {
305316
// Select first tab (Home key)
306317
index = getFirstTab();
307318
preventDefault = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import React from 'react';
2+
import { render } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
4+
import Tab from '../Tab';
5+
import TabList from '../TabList';
6+
import TabPanel from '../TabPanel';
7+
import Tabs from '../Tabs';
8+
import { reset as resetIdCounter } from '../../helpers/uuid';
9+
10+
describe('<Tabs />', () => {
11+
let consoleErrorMock;
12+
13+
function assertPropTypeWarning(message, nth = 1) {
14+
expect(consoleErrorMock).toHaveBeenNthCalledWith(
15+
nth,
16+
expect.anything(),
17+
expect.anything(),
18+
expect.stringMatching(message),
19+
expect.anything(),
20+
);
21+
}
22+
23+
beforeEach(() => {
24+
resetIdCounter();
25+
consoleErrorMock = jest.spyOn(console, 'error').mockImplementation();
26+
});
27+
28+
afterEach(() => {
29+
consoleErrorMock.mockRestore();
30+
});
31+
32+
describe('errors', () => {
33+
test('should result with warning when tabs/panels are imbalanced and it should ignore non tab children', () => {
34+
render(
35+
<Tabs>
36+
<TabList>
37+
<Tab>Foo</Tab>
38+
<div>+</div>
39+
</TabList>
40+
41+
<TabPanel>Hello Foo</TabPanel>
42+
<TabPanel>Hello Bar</TabPanel>
43+
</Tabs>,
44+
);
45+
46+
assertPropTypeWarning(
47+
"There should be an equal number of 'Tab' and 'TabPanel' in `Tabs`. Received 1 'Tab' and 2 'TabPanel'.",
48+
1,
49+
);
50+
assertPropTypeWarning(
51+
"There should be an equal number of 'Tab' and 'TabPanel' in `UncontrolledTabs`. Received 1 'Tab' and 2 'TabPanel'.",
52+
2,
53+
);
54+
});
55+
56+
test('should result with warning when multiple tablist components exist', () => {
57+
render(
58+
<Tabs>
59+
<TabList>
60+
<Tab>Foo</Tab>
61+
</TabList>
62+
<TabList>
63+
<Tab>Foo</Tab>
64+
</TabList>
65+
<TabPanel />
66+
<TabPanel />
67+
</Tabs>,
68+
);
69+
70+
assertPropTypeWarning(
71+
"Found multiple 'TabList' components inside 'Tabs'. Only one is allowed.",
72+
);
73+
});
74+
75+
test('should result with warning when tab outside of tablist', () => {
76+
render(
77+
<Tabs>
78+
<TabList>
79+
<Tab>Foo</Tab>
80+
</TabList>
81+
<Tab>Foo</Tab>
82+
<TabPanel />
83+
<TabPanel />
84+
</Tabs>,
85+
);
86+
87+
assertPropTypeWarning(
88+
"Found a 'Tab' component outside of the 'TabList' component. 'Tab' components have to be inside the 'TabList' component.",
89+
);
90+
});
91+
92+
test('should result with warning when defaultIndex and selectedIndex set', () => {
93+
render(
94+
<Tabs selectedIndex={1} defaultIndex={1} onSelect={() => {}}>
95+
<TabList>
96+
<Tab>Foo</Tab>
97+
</TabList>
98+
<TabPanel>Foo</TabPanel>
99+
</Tabs>,
100+
);
101+
102+
assertPropTypeWarning(
103+
'The prop `selectedIndex` cannot be used together with `defaultIndex` in `Tabs`.\nEither remove `selectedIndex` to let `Tabs` handle the selected tab internally or remove `defaultIndex` to handle it yourself.',
104+
);
105+
});
106+
107+
test('should throw when mode of component changes', () => {
108+
const onSelect = () => {};
109+
const { rerender } = render(
110+
<Tabs defaultIndex={1} onSelect={onSelect}>
111+
<TabList>
112+
<Tab>Foo</Tab>
113+
<Tab>Foo2</Tab>
114+
</TabList>
115+
<TabPanel>Foo</TabPanel>
116+
<TabPanel>Foo2</TabPanel>
117+
</Tabs>,
118+
);
119+
120+
const consoleLogMock = jest.spyOn(console, 'log').mockImplementation();
121+
try {
122+
rerender(
123+
<Tabs selectedIndex={0} onSelect={onSelect}>
124+
<TabList>
125+
<Tab>Foo</Tab>
126+
<Tab>Foo2</Tab>
127+
</TabList>
128+
<TabPanel>Foo</TabPanel>
129+
<TabPanel>Foo2</TabPanel>
130+
</Tabs>,
131+
);
132+
} catch (e) {
133+
expect(e.message).toContain(
134+
'Switching between controlled mode (by using `selectedIndex`) and uncontrolled mode is not supported in `Tabs`.',
135+
);
136+
} finally {
137+
consoleLogMock.mockRestore();
138+
}
139+
});
140+
141+
test('should result with warning when tabs/panels are imbalanced', () => {
142+
render(
143+
<Tabs>
144+
<TabList>
145+
<Tab>Foo</Tab>
146+
</TabList>
147+
</Tabs>,
148+
);
149+
150+
assertPropTypeWarning(
151+
"There should be an equal number of 'Tab' and 'TabPanel' in `Tabs`. Received 1 'Tab' and 0 'TabPanel'.",
152+
1,
153+
);
154+
assertPropTypeWarning(
155+
"There should be an equal number of 'Tab' and 'TabPanel' in `UncontrolledTabs`. Received 1 'Tab' and 0 'TabPanel'.",
156+
2,
157+
);
158+
});
159+
160+
test('should result with warning when onSelect missing when selectedIndex set', () => {
161+
render(
162+
<Tabs selectedIndex={1}>
163+
<TabList>
164+
<Tab>Foo</Tab>
165+
</TabList>
166+
<TabPanel>Foo</TabPanel>
167+
</Tabs>,
168+
);
169+
170+
assertPropTypeWarning(
171+
'The prop `onSelect` is marked as required in `Tabs`, but its value is `undefined` or `null`.\n`onSelect` is required when `selectedIndex` is also set. Not doing so will make the tabs not do anything, as `selectedIndex` indicates that you want to handle the selected tab yourself.\nIf you only want to set the inital tab replace `selectedIndex` with `defaultIndex`.',
172+
);
173+
});
174+
});
175+
});

0 commit comments

Comments
 (0)