Skip to content

Commit

Permalink
refactor(frontend): migrate 6 tests from Enzyme to RTL (apache#30151)
Browse files Browse the repository at this point in the history
Signed-off-by: hainenber <[email protected]>
Co-authored-by: JUST.in DO IT <[email protected]>
  • Loading branch information
hainenber and justinpark authored Sep 13, 2024
1 parent bdf29cb commit e909465
Show file tree
Hide file tree
Showing 11 changed files with 461 additions and 256 deletions.
145 changes: 127 additions & 18 deletions superset-frontend/package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,28 @@
* under the License.
*/

import { shallow } from 'enzyme';
import '@testing-library/jest-dom';
import { TooltipFrame } from '@superset-ui/core';
import { render, screen } from '@testing-library/react';

describe('TooltipFrame', () => {
it('sets className', () => {
const wrapper = shallow(
const { container } = render(
<TooltipFrame className="test-class">
<span>Hi!</span>
</TooltipFrame>,
);
expect(wrapper.hasClass('test-class')).toEqual(true);
expect(screen.getByText('Hi!')).toBeInTheDocument();
expect(container.querySelector('.test-class')).toBeInTheDocument();
});

it('renders', () => {
const wrapper = shallow(
const { container } = render(
<TooltipFrame>
<span>Hi!</span>
</TooltipFrame>,
);
const span = wrapper.find('span');
expect(span).toHaveLength(1);
expect(span.text()).toEqual('Hi!');
expect(container.querySelectorAll('span')).toHaveLength(1);
expect(container.querySelector('span')).toHaveTextContent('Hi!');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,53 @@
* under the License.
*/

import { shallow } from 'enzyme';
import '@testing-library/jest-dom';
import { screen, render } from '@testing-library/react';
import { TooltipTable } from '@superset-ui/core';
import { CSSProperties } from 'react';

describe('TooltipTable', () => {
it('sets className', () => {
const wrapper = shallow(<TooltipTable className="test-class" />);
expect(wrapper.render().hasClass('test-class')).toEqual(true);
const { container } = render(<TooltipTable className="test-class" />);
expect(container.querySelector('[class="test-class"]')).toBeInTheDocument();
});

it('renders empty table', () => {
const wrapper = shallow(<TooltipTable />);
expect(wrapper.find('tbody')).toHaveLength(1);
expect(wrapper.find('tr')).toHaveLength(0);
const { container } = render(<TooltipTable />);
expect(container.querySelector('tbody')).toBeInTheDocument();
expect(container.querySelector('tr')).not.toBeInTheDocument();
});

it('renders table with content', () => {
const wrapper = shallow(
<TooltipTable
data={[
{
key: 'Cersei',
keyColumn: 'Cersei',
keyStyle: { padding: '10' },
valueColumn: 2,
valueStyle: { textAlign: 'right' },
},
{
key: 'Jaime',
keyColumn: 'Jaime',
keyStyle: { padding: '10' },
valueColumn: 1,
valueStyle: { textAlign: 'right' },
},
{
key: 'Tyrion',
keyStyle: { padding: '10' },
valueColumn: 2,
},
]}
/>,
);
expect(wrapper.find('tbody')).toHaveLength(1);
expect(wrapper.find('tr')).toHaveLength(3);
expect(wrapper.find('tr > td').first().text()).toEqual('Cersei');
it('renders table with content', async () => {
const data = [
{
key: 'Cersei',
keyColumn: 'Cersei',
keyStyle: { padding: '10' },
valueColumn: 2,
valueStyle: { textAlign: 'right' } as CSSProperties,
},
{
key: 'Jaime',
keyColumn: 'Jaime',
keyStyle: { padding: '10' },
valueColumn: 1,
valueStyle: { textAlign: 'right' } as CSSProperties,
},
{
key: 'Tyrion',
keyStyle: { padding: '10' },
valueColumn: 2,
},
];

render(<TooltipTable data={data} />);

for await (const { key, valueColumn } of data) {
const keyCell = await screen.findByText(key);
const valueCell = keyCell?.nextSibling as HTMLElement;
expect(keyCell).toBeInTheDocument();
expect(valueCell?.textContent).toEqual(String(valueColumn));
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
"peerDependencies": {
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"enzyme": "*",
"react": "^16.13.1"
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^12.1.5",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"publishConfig": {
"access": "public"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
import { shallow } from 'enzyme';

import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import '@testing-library/jest-dom';
import { screen, render, fireEvent, act } from '@testing-library/react';
import { ThemeProvider, supersetTheme } from '@superset-ui/core';
import OptionDescription from '../src/OptionDescription';

const defaultProps = {
Expand All @@ -28,20 +28,41 @@ const defaultProps = {
},
};

describe('OptionDescription', () => {
let wrapper;
let props;
beforeEach(() => {
jest.useFakeTimers();
});

afterEach(() => {
jest.useRealTimers();
});

describe('OptionDescription', () => {
beforeEach(() => {
props = { option: { ...defaultProps.option } };
wrapper = shallow(<OptionDescription {...props} />);
const props = { option: { ...defaultProps.option } };
render(
<ThemeProvider theme={supersetTheme}>
<OptionDescription {...props} />
</ThemeProvider>,
);
});

it('renders an InfoTooltipWithTrigger', () => {
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(1);
const tooltipTrigger = screen.getByLabelText('Show info tooltip');
expect(tooltipTrigger).toBeInTheDocument();

// Perform delayed mouse hovering so tooltip could pop out
fireEvent.mouseOver(tooltipTrigger);
act(() => jest.runAllTimers());
fireEvent.mouseOut(tooltipTrigger);

const tooltip = screen.getByRole('tooltip');
expect(tooltip).toBeInTheDocument();
expect(tooltip).toHaveTextContent('Description for some option');
});

it('renders a span with the label', () => {
expect(wrapper.find('.option-label').text()).toBe('Some option');
expect(
screen.getByText('Some option', { selector: 'span' }),
).toBeInTheDocument();
});
});
1 change: 0 additions & 1 deletion superset-frontend/plugins/plugin-chart-table/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"dependencies": {
"@react-icons/all-files": "^4.1.0",
"@types/d3-array": "^2.9.0",
"@types/enzyme": "^3.10.18",
"@types/react-table": "^7.7.20",
"classnames": "^2.5.1",
"d3-array": "^2.4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
import { CommonWrapper } from 'enzyme';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import { ThemeProvider, supersetTheme } from '@superset-ui/core';
import TableChart from '../src/TableChart';
import transformProps from '../src/transformProps';
import DateWithFormatter from '../src/utils/DateWithFormatter';
import testData from './testData';
import { mount, ProviderWrapper } from './enzyme';
import { ProviderWrapper } from './testHelpers';

describe('plugin-chart-table', () => {
describe('transformProps', () => {
Expand Down Expand Up @@ -178,39 +178,42 @@ describe('plugin-chart-table', () => {
});

describe('TableChart', () => {
let wrap: CommonWrapper; // the ReactDataTable wrapper
let tree: Cheerio;

it('render basic data', () => {
wrap = mount(
<TableChart {...transformProps(testData.basic)} sticky={false} />,
render(
<ThemeProvider theme={supersetTheme}>
<TableChart {...transformProps(testData.basic)} sticky={false} />,
</ThemeProvider>,
);

tree = wrap.render(); // returns a CheerioWrapper with jQuery-like API
const cells = tree.find('td');
const firstDataRow = screen.getAllByRole('rowgroup')[1];
const cells = firstDataRow.querySelectorAll('td');
expect(cells).toHaveLength(12);
expect(cells.eq(0).text()).toEqual('2020-01-01 12:34:56');
expect(cells.eq(1).text()).toEqual('Michael');
expect(cells[0]).toHaveTextContent('2020-01-01 12:34:56');
expect(cells[1]).toHaveTextContent('Michael');
// number is not in `metrics` list, so it should output raw value
// (in real world Superset, this would mean the column is used in GROUP BY)
expect(cells.eq(2).text()).toEqual('2467063');
expect(cells[2]).toHaveTextContent('2467063');
// should not render column with `.` in name as `undefined`
expect(cells.eq(3).text()).toEqual('foo');
expect(cells.eq(6).text()).toEqual('2467');
expect(cells.eq(8).text()).toEqual('N/A');
expect(cells[3]).toHaveTextContent('foo');
expect(cells[6]).toHaveTextContent('2467');
expect(cells[8]).toHaveTextContent('N/A');
});

it('render advanced data', () => {
wrap = mount(
<TableChart {...transformProps(testData.advanced)} sticky={false} />,
render(
<ThemeProvider theme={supersetTheme}>
<TableChart {...transformProps(testData.advanced)} sticky={false} />,
</ThemeProvider>,
);
tree = wrap.render();
// should successful rerender with new props
const cells = tree.find('td');
expect(tree.find('th').eq(1).text()).toEqual('Sum of Num');
expect(cells.eq(0).text()).toEqual('Michael');
expect(cells.eq(2).text()).toEqual('12.346%');
expect(cells.eq(4).text()).toEqual('2.47k');
const secondColumnHeader = screen.getByText('Sum of Num');
expect(secondColumnHeader).toBeInTheDocument();
expect(secondColumnHeader?.getAttribute('data-column-name')).toEqual('1');

const firstDataRow = screen.getAllByRole('rowgroup')[1];
const cells = firstDataRow.querySelectorAll('td');
expect(cells[0]).toHaveTextContent('Michael');
expect(cells[2]).toHaveTextContent('12.346%');
expect(cells[4]).toHaveTextContent('2.47k');
});

it('render advanced data with currencies', () => {
Expand Down Expand Up @@ -318,9 +321,12 @@ describe('plugin-chart-table', () => {
});

it('render empty data', () => {
wrap.setProps({ ...transformProps(testData.empty), sticky: false });
tree = wrap.render();
expect(tree.text()).toContain('No records found');
render(
<ThemeProvider theme={supersetTheme}>
<TableChart {...transformProps(testData.empty)} sticky={false} />,
</ThemeProvider>,
);
expect(screen.getByText('No records found')).toBeInTheDocument();
});

it('render color with column color formatter', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ReactElement } from 'react';
import { shallow as enzymeShallow, mount as enzymeMount } from 'enzyme';
import {
EmotionCacheProvider,
createEmotionCache,
Expand All @@ -29,12 +27,6 @@ const emotionCache = createEmotionCache({
key: 'test',
});

type optionsType = {
wrappingComponentProps?: any;
wrappingComponent?: ReactElement;
context?: any;
};

export function ProviderWrapper(props: any) {
const { children, theme = supersetTheme } = props;
return (
Expand All @@ -43,25 +35,3 @@ export function ProviderWrapper(props: any) {
</EmotionCacheProvider>
);
}

export function mount(component: ReactElement, options: optionsType = {}) {
return enzymeMount(component, {
...options,
wrappingComponent: ProviderWrapper,
wrappingComponentProps: {
theme: supersetTheme,
...options?.wrappingComponentProps,
},
});
}

export function shallow(component: ReactElement, options: optionsType = {}) {
return enzymeShallow(component, {
...options,
wrappingComponent: ProviderWrapper,
wrappingComponentProps: {
theme: supersetTheme,
...options?.wrappingComponentProps,
},
}).dive();
}
Loading

0 comments on commit e909465

Please sign in to comment.