Skip to content

Commit 6d2d483

Browse files
author
Constance
authored
[Emotion] Fix/regression test tooltip-related css props (#6253)
* [setup] Add missing tooltip helper type defs * Update `shouldRenderCustomStyles` with a `renderCallback` option - for components (primarily tooltip) that only render the component conditionally - nb: snapshot changed because the preceding test removes a className from `body` * Add EuiIconTip regression test * Add EuiKeyPad regression tests + update `waitForEuiToolTipVisible` to not throw for tooltips with along delay * Add EuiSuperUpdateButton tooltip regression tests * Fix EuiSuperDatePicker ignoring the`className` prop * changelog
1 parent b3327d7 commit 6d2d483

13 files changed

+123
-15
lines changed

src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.tsx.snap

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ exports[`EuiSuperDatePicker is rendered 1`] = `
88
>
99
<EuiFlexItem>
1010
<EuiFormControlLayout
11-
className="euiSuperDatePicker"
11+
className="euiSuperDatePicker testClass1 testClass2"
12+
data-test-subj="test subject string"
1213
isDisabled={false}
1314
prepend={
1415
<EuiQuickSelectPopover

src/components/date_picker/super_date_picker/super_date_picker.test.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import React from 'react';
1010
import { mount, shallow, ReactWrapper } from 'enzyme';
11+
import { requiredProps } from '../../../test';
12+
import { shouldRenderCustomStyles } from '../../../test/internal';
1113

1214
import {
1315
EuiSuperDatePicker,
@@ -30,9 +32,17 @@ const shallowAndDive = (component: React.ReactElement) =>
3032
shallow(component).dive().dive();
3133

3234
describe('EuiSuperDatePicker', () => {
35+
shouldRenderCustomStyles(<EuiSuperDatePicker onTimeChange={noop} />, {
36+
skipStyles: true,
37+
});
38+
shouldRenderCustomStyles(<EuiSuperDatePicker onTimeChange={noop} />, {
39+
childProps: ['updateButtonProps'],
40+
skipParentTest: true,
41+
});
42+
3343
test('is rendered', () => {
3444
const component = shallowAndDive(
35-
<EuiSuperDatePicker onTimeChange={noop} />
45+
<EuiSuperDatePicker onTimeChange={noop} {...requiredProps} />
3646
);
3747

3848
expect(component).toMatchSnapshot();

src/components/date_picker/super_date_picker/super_date_picker.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ export class EuiSuperDatePickerInternal extends Component<
541541
width: _width,
542542
isQuickSelectOnly,
543543
compressed,
544+
className,
544545
} = this.props;
545546

546547
// Force reduction in width if showing quick select only
@@ -600,13 +601,14 @@ export class EuiSuperDatePickerInternal extends Component<
600601
compressed={compressed}
601602
isDisabled={isDisabled}
602603
data-test-subj={dataTestSubj}
604+
className={className}
603605
/>
604606
</EuiFlexItem>
605607
) : (
606608
<>
607609
<EuiFlexItem>
608610
<EuiFormControlLayout
609-
className="euiSuperDatePicker"
611+
className={classNames('euiSuperDatePicker', className)}
610612
compressed={compressed}
611613
isDisabled={isDisabled}
612614
prepend={quickSelect}

src/components/date_picker/super_date_picker/super_update_button.test.tsx

+22
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,35 @@
88

99
import React from 'react';
1010
import { shallow, mount } from 'enzyme';
11+
import { fireEvent } from '@testing-library/react';
12+
import { waitForEuiToolTipVisible } from '../../../test/rtl';
13+
import { shouldRenderCustomStyles } from '../../../test/internal';
1114

1215
import { EuiSuperUpdateButton } from './super_update_button';
1316
import { EuiButton, EuiButtonProps } from '../../button';
1417

1518
const noop = () => {};
1619

1720
describe('EuiSuperUpdateButton', () => {
21+
shouldRenderCustomStyles(<EuiSuperUpdateButton onClick={noop} />);
22+
shouldRenderCustomStyles(
23+
<EuiSuperUpdateButton
24+
onClick={noop}
25+
data-test-subj="trigger"
26+
showTooltip
27+
needsUpdate
28+
toolTipProps={{ children: <>Test</>, delay: 'regular', position: 'top' }} // React throws a `Failed prop type` error without this
29+
/>,
30+
{
31+
childProps: ['toolTipProps'],
32+
skipParentTest: true,
33+
renderCallback: async ({ getByTestSubject }) => {
34+
fireEvent.mouseOver(getByTestSubject('trigger'));
35+
await waitForEuiToolTipVisible();
36+
},
37+
}
38+
);
39+
1840
test('is rendered', () => {
1941
const component = shallow(<EuiSuperUpdateButton onClick={noop} />);
2042

src/components/key_pad_menu/key_pad_menu.test.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,17 @@
99
import React from 'react';
1010
import { render } from 'enzyme';
1111
import { requiredProps } from '../../test/required_props';
12+
import { shouldRenderCustomStyles } from '../../test/internal';
1213

1314
import { EuiKeyPadMenu } from './key_pad_menu';
1415

1516
describe('EuiKeyPadMenu', () => {
17+
shouldRenderCustomStyles(<EuiKeyPadMenu />);
18+
shouldRenderCustomStyles(<EuiKeyPadMenu checkable={{ legend: 'test' }} />, {
19+
childProps: ['checkable.legendProps'],
20+
skipParentTest: true,
21+
});
22+
1623
test('is rendered', () => {
1724
const component = render(<EuiKeyPadMenu {...requiredProps} />);
1825

src/components/key_pad_menu/key_pad_menu_item.test.tsx

+24
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,35 @@
88

99
import React from 'react';
1010
import { render, shallow } from 'enzyme';
11+
import { fireEvent } from '@testing-library/react';
12+
import { waitForEuiToolTipVisible } from '../../test/rtl';
1113
import { requiredProps } from '../../test';
14+
import { shouldRenderCustomStyles } from '../../test/internal';
1215

1316
import { EuiKeyPadMenuItem } from './key_pad_menu_item';
1417

1518
describe('EuiKeyPadMenuItem', () => {
19+
shouldRenderCustomStyles(
20+
<EuiKeyPadMenuItem label="test">Test</EuiKeyPadMenuItem>
21+
);
22+
shouldRenderCustomStyles(
23+
<EuiKeyPadMenuItem
24+
label="test"
25+
betaBadgeLabel="Beta"
26+
data-test-subj="trigger"
27+
>
28+
Test
29+
</EuiKeyPadMenuItem>,
30+
{
31+
skipParentTest: true,
32+
childProps: ['betaBadgeTooltipProps'],
33+
renderCallback: async ({ getByTestSubject }) => {
34+
fireEvent.mouseOver(getByTestSubject('trigger'));
35+
await waitForEuiToolTipVisible();
36+
},
37+
}
38+
);
39+
1640
test('is rendered', () => {
1741
const component = render(
1842
<EuiKeyPadMenuItem label="Label" {...requiredProps}>

src/components/tool_tip/__snapshots__/tool_tip.test.tsx.snap

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ exports[`EuiToolTip display prop renders block 1`] = `
3030
`;
3131

3232
exports[`EuiToolTip is rendered 1`] = `
33-
<body>
33+
<body
34+
class=""
35+
>
3436
<div>
3537
<span
3638
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"

src/components/tool_tip/icon_tip.test.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,25 @@
88

99
import React from 'react';
1010
import { render } from 'enzyme';
11+
import { fireEvent } from '@testing-library/react';
12+
import { waitForEuiToolTipVisible } from '../../test/rtl';
1113
import { requiredProps } from '../../test';
14+
import { shouldRenderCustomStyles } from '../../test/internal';
1215

1316
import { EuiIconTip } from './icon_tip';
1417

1518
describe('EuiIconTip', () => {
19+
shouldRenderCustomStyles(
20+
<EuiIconTip content="test" iconProps={{ 'data-test-subj': 'trigger' }} />,
21+
{
22+
childProps: ['iconProps'],
23+
renderCallback: async ({ getByTestSubject }) => {
24+
fireEvent.mouseOver(getByTestSubject('trigger'));
25+
await waitForEuiToolTipVisible();
26+
},
27+
}
28+
);
29+
1630
test('is rendered', () => {
1731
const component = render(
1832
<EuiIconTip title="title" id="id" content="content" {...requiredProps} />

src/components/tool_tip/tool_tip.test.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,24 @@ import {
1515
waitForEuiToolTipHidden,
1616
} from '../../test/rtl';
1717
import { requiredProps, findTestSubject } from '../../test';
18+
import { shouldRenderCustomStyles } from '../../test/internal';
1819

1920
import { EuiToolTip } from './tool_tip';
2021

2122
describe('EuiToolTip', () => {
23+
shouldRenderCustomStyles(
24+
<EuiToolTip content="test">
25+
<button data-test-subj="trigger" />
26+
</EuiToolTip>,
27+
{
28+
childProps: ['anchorProps'],
29+
renderCallback: async ({ getByTestSubject }) => {
30+
fireEvent.mouseOver(getByTestSubject('trigger'));
31+
await waitForEuiToolTipVisible();
32+
},
33+
}
34+
);
35+
2236
it('is rendered', () => {
2337
const { baseElement } = render(
2438
<EuiToolTip title="title" id="id" content="content" {...requiredProps}>

src/test/internal/render_custom_styles.tsx

+10-7
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*/
88

99
import React, { ReactElement } from 'react';
10-
import { render } from '@testing-library/react';
1110
import { css } from '@emotion/react';
1211
import { get, set } from 'lodash';
12+
import { render } from '../rtl';
1313

1414
export const customStyles = {
1515
className: 'hello',
@@ -59,6 +59,7 @@ export const shouldRenderCustomStyles = (
5959
childProps?: string[];
6060
skipStyles?: boolean;
6161
skipParentTest?: boolean;
62+
renderCallback?: (result: ReturnType<typeof render>) => void;
6263
} = {}
6364
) => {
6465
const testCases = options.skipStyles
@@ -71,25 +72,27 @@ export const shouldRenderCustomStyles = (
7172
// Some tests run separate child props tests with different settings & don't need
7273
// to run the base parent test multiple times. If so, allow skipping this test
7374
if (!(options.skipParentTest === true && options.childProps)) {
74-
it(`should render custom ${testCases}`, () => {
75-
const { baseElement } = render(
75+
it(`should render custom ${testCases}`, async () => {
76+
const result = render(
7677
<div>{React.cloneElement(component, testProps)}</div>
7778
);
78-
assertOutputStyles(baseElement, options);
79+
await options.renderCallback?.(result);
80+
assertOutputStyles(result.baseElement, options);
7981
});
8082
}
8183

8284
if (options.childProps) {
8385
options.childProps.forEach((childProps) => {
84-
it(`should render custom ${testCases} on ${childProps}`, () => {
86+
it(`should render custom ${testCases} on ${childProps}`, async () => {
8587
const mergedChildProps = set({ ...component.props }, childProps, {
8688
...get(component.props, childProps),
8789
...testProps,
8890
});
89-
const { baseElement } = render(
91+
const result = render(
9092
<div>{React.cloneElement(component, mergedChildProps)}</div>
9193
);
92-
assertOutputStyles(baseElement, options);
94+
await options.renderCallback?.(result);
95+
assertOutputStyles(result.baseElement, options);
9396
});
9497
});
9598
}

src/test/rtl/component_helpers.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55
*/
66
export declare const waitForEuiPopoverOpen: () => Promise<void>;
77
export declare const waitForEuiPopoverClose: () => Promise<void>;
8+
9+
export declare const waitForEuiToolTipVisible: () => Promise<void>;
10+
export declare const waitForEuiToolTipHidden: () => Promise<void>;

src/test/rtl/component_helpers.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@ export const waitForEuiPopoverClose = async () =>
3030
* Ensure the EuiToolTip being tested is open and visible before continuing
3131
*/
3232
export const waitForEuiToolTipVisible = async () =>
33-
await waitFor(() => {
34-
const tooltip = document.querySelector('.euiToolTipPopover');
35-
expect(tooltip).toBeVisible();
36-
});
33+
await waitFor(
34+
() => {
35+
const tooltip = document.querySelector('.euiToolTipPopover');
36+
expect(tooltip).toBeVisible();
37+
},
38+
{ timeout: 1500 } // Account for long delay on tooltips
39+
);
3740

3841
export const waitForEuiToolTipHidden = async () =>
3942
await waitFor(() => {

upcoming_changelogs/6253.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
**Bug fixes**
2+
3+
- Fixed `EuiSuperDatePicker` not correctly merging passed `className`s

0 commit comments

Comments
 (0)