This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new db70c7912c chore(fe): migrate 4 Enzyme-based tests to RTL (#31634)
db70c7912c is described below

commit db70c7912c21b39dbf9df01d5c60577e9539518f
Author: Đỗ Trọng Hải <[email protected]>
AuthorDate: Tue Feb 11 23:01:59 2025 +0700

    chore(fe): migrate 4 Enzyme-based tests to RTL (#31634)
    
    Signed-off-by: hainenber <[email protected]>
---
 .../chart-composition/legend/WithLegend.test.tsx   | 54 +++++++++++-----------
 .../test/chart/components/reactify.test.tsx        | 24 ++++++----
 .../src/features/home/EmptyState.test.tsx          | 27 +++++------
 ...nLogList.test.jsx => ExecutionLogList.test.tsx} | 49 +++++++-------------
 4 files changed, 72 insertions(+), 82 deletions(-)

diff --git 
a/superset-frontend/packages/superset-ui-core/test/chart-composition/legend/WithLegend.test.tsx
 
b/superset-frontend/packages/superset-ui-core/test/chart-composition/legend/WithLegend.test.tsx
index 9d660a28ad..f4d5ab8e29 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/chart-composition/legend/WithLegend.test.tsx
+++ 
b/superset-frontend/packages/superset-ui-core/test/chart-composition/legend/WithLegend.test.tsx
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-import { mount, shallow } from 'enzyme';
 import { triggerResizeObserver } from 'resize-observer-polyfill';
 import { promiseTimeout, WithLegend } from '@superset-ui/core';
+import { render } from '@testing-library/react';
 
 let renderChart = jest.fn();
 let renderLegend = jest.fn();
@@ -32,18 +32,18 @@ describe.skip('WithLegend', () => {
   });
 
   it('sets className', () => {
-    const wrapper = shallow(
+    const { container } = render(
       <WithLegend
         className="test-class"
         renderChart={renderChart}
         renderLegend={renderLegend}
       />,
     );
-    expect(wrapper.hasClass('test-class')).toEqual(true);
+    expect(container.querySelectorAll('.test-class')).toHaveLength(1);
   });
 
   it('renders when renderLegend is not set', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         width={500}
@@ -56,13 +56,13 @@ describe.skip('WithLegend', () => {
     // Have to delay more than debounceTime (1ms)
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(0);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(0);
     }, 100);
   });
 
   it('renders', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         width={500}
@@ -77,13 +77,13 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 
   it('renders without width or height', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         renderChart={renderChart}
@@ -96,13 +96,13 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 
   it('renders legend on the left', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         position="left"
@@ -116,13 +116,13 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 
   it('renders legend on the right', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         position="right"
@@ -136,13 +136,13 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 
   it('renders legend on the top', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         position="top"
@@ -156,13 +156,13 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 
   it('renders legend on the bottom', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         position="bottom"
@@ -176,13 +176,13 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 
   it('renders legend with justifyContent set', () => {
-    const wrapper = mount(
+    const { container } = render(
       <WithLegend
         debounceTime={1}
         position="right"
@@ -197,8 +197,8 @@ describe.skip('WithLegend', () => {
     return promiseTimeout(() => {
       expect(renderChart).toHaveBeenCalledTimes(1);
       expect(renderLegend).toHaveBeenCalledTimes(1);
-      expect(wrapper.render().find('div.chart')).toHaveLength(1);
-      expect(wrapper.render().find('div.legend')).toHaveLength(1);
+      expect(container.querySelectorAll('div.chart')).toHaveLength(1);
+      expect(container.querySelectorAll('div.legend')).toHaveLength(1);
     }, 100);
   });
 });
diff --git 
a/superset-frontend/packages/superset-ui-core/test/chart/components/reactify.test.tsx
 
b/superset-frontend/packages/superset-ui-core/test/chart/components/reactify.test.tsx
index db74801bac..1d00b372c5 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/chart/components/reactify.test.tsx
+++ 
b/superset-frontend/packages/superset-ui-core/test/chart/components/reactify.test.tsx
@@ -17,10 +17,11 @@
  * under the License.
  */
 
+import '@testing-library/jest-dom';
 import PropTypes from 'prop-types';
 import { PureComponent } from 'react';
-import { mount } from 'enzyme';
 import { reactify } from '@superset-ui/core';
+import { render, screen } from '@testing-library/react';
 import { RenderFuncType } from '../../../src/chart/components/reactify';
 
 describe('reactify(renderFn)', () => {
@@ -78,14 +79,18 @@ describe('reactify(renderFn)', () => {
 
   it('returns a React component class', () =>
     new Promise(done => {
-      const wrapper = mount(<TestComponent />);
+      render(<TestComponent />);
 
       expect(renderFn).toHaveBeenCalledTimes(1);
-      expect(wrapper.html()).toEqual('<div id="test"><b>abc</b></div>');
+      expect(screen.getByText('abc')).toBeInTheDocument();
+      expect(screen.getByText('abc').parentNode).toHaveAttribute('id', 'test');
       setTimeout(() => {
         expect(renderFn).toHaveBeenCalledTimes(2);
-        expect(wrapper.html()).toEqual('<div id="test"><b>def</b></div>');
-        wrapper.unmount();
+        expect(screen.getByText('def')).toBeInTheDocument();
+        expect(screen.getByText('def').parentNode).toHaveAttribute(
+          'id',
+          'test',
+        );
         done(undefined);
       }, 20);
     }));
@@ -119,8 +124,9 @@ describe('reactify(renderFn)', () => {
   describe('defaultProps', () => {
     it('has defaultProps if renderFn.defaultProps is defined', () => {
       expect(TheChart.defaultProps).toBe(renderFn.defaultProps);
-      const wrapper = mount(<TheChart id="test" />);
-      expect(wrapper.html()).toEqual('<div id="test"><b>ghi</b></div>');
+      render(<TheChart id="test" />);
+      expect(screen.getByText('ghi')).toBeInTheDocument();
+      expect(screen.getByText('ghi').parentNode).toHaveAttribute('id', 'test');
     });
     it('does not have defaultProps if renderFn.defaultProps is not defined', 
() => {
       const AnotherChart = reactify(() => {});
@@ -136,9 +142,9 @@ describe('reactify(renderFn)', () => {
   });
   it('calls willUnmount hook when it is provided', () =>
     new Promise(done => {
-      const wrapper = mount(<AnotherTestComponent />);
+      const { unmount } = render(<AnotherTestComponent />);
       setTimeout(() => {
-        wrapper.unmount();
+        unmount();
         expect(willUnmountCb).toHaveBeenCalledTimes(1);
         done(undefined);
       }, 20);
diff --git a/superset-frontend/src/features/home/EmptyState.test.tsx 
b/superset-frontend/src/features/home/EmptyState.test.tsx
index 0be86559dc..a43fac1fe8 100644
--- a/superset-frontend/src/features/home/EmptyState.test.tsx
+++ b/superset-frontend/src/features/home/EmptyState.test.tsx
@@ -16,8 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { styledMount as mount } from 'spec/helpers/theming';
 import { TableTab } from 'src/views/CRUD/types';
+import { render, screen } from 'spec/helpers/testing-library';
 import EmptyState, { EmptyStateProps } from './EmptyState';
 import { WelcomeTable } from './types';
 
@@ -65,29 +65,30 @@ describe('EmptyState', () => {
 
   variants.forEach(variant => {
     it(`renders an ${variant.tab} ${variant.tableName} empty state`, () => {
-      const wrapper = mount(<EmptyState {...variant} />);
-      expect(wrapper).toExist();
+      const { container } = render(<EmptyState {...variant} />);
 
       // Select the first description node
-      const textContainer = wrapper.find('.ant-empty-description').at(0);
-      expect(textContainer.text()).toEqual('Nothing here yet');
-      expect(wrapper.find('button')).toHaveLength(1);
+      expect(
+        container.querySelector('.ant-empty-description'),
+      ).toHaveTextContent('Nothing here yet');
+      expect(screen.getAllByRole('button')).toHaveLength(1);
     });
   });
 
   recents.forEach(recent => {
     it(`renders a ${recent.tab} ${recent.tableName} empty state`, () => {
-      const wrapper = mount(<EmptyState {...recent} />);
-      expect(wrapper).toExist();
+      const { container } = render(<EmptyState {...recent} />);
 
       // Select the first description node
-      const textContainer = wrapper.find('.ant-empty-description').at(0);
+      // Check the correct text is displayed
+      expect(
+        container.querySelector('.ant-empty-description'),
+      ).toHaveTextContent('Nothing here yet');
 
       // Validate the image
-      expect(wrapper.find('.ant-empty-image').children()).toHaveLength(1);
-
-      // Check the correct text is displayed
-      expect(textContainer.text()).toContain(`Nothing here yet`);
+      expect(
+        container.querySelector('.ant-empty-image')?.children,
+      ).toHaveLength(1);
     });
   });
 });
diff --git 
a/superset-frontend/src/pages/ExecutionLogList/ExecutionLogList.test.jsx 
b/superset-frontend/src/pages/ExecutionLogList/ExecutionLogList.test.tsx
similarity index 69%
rename from 
superset-frontend/src/pages/ExecutionLogList/ExecutionLogList.test.jsx
rename to superset-frontend/src/pages/ExecutionLogList/ExecutionLogList.test.tsx
index 1318b3625e..5c32371431 100644
--- a/superset-frontend/src/pages/ExecutionLogList/ExecutionLogList.test.jsx
+++ b/superset-frontend/src/pages/ExecutionLogList/ExecutionLogList.test.tsx
@@ -17,24 +17,15 @@
  * under the License.
  */
 import fetchMock from 'fetch-mock';
-import { Provider } from 'react-redux';
-import configureStore from 'redux-mock-store';
-import thunk from 'redux-thunk';
-import { styledMount as mount } from 'spec/helpers/theming';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import ListView from 'src/components/ListView';
 import ExecutionLog from 'src/pages/ExecutionLogList';
-
-// store needed for withToasts(ExecutionLog)
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
+import { render, screen } from 'spec/helpers/testing-library';
 
 const executionLogsEndpoint = 'glob:*/api/v1/report/*/log*';
 const reportEndpoint = 'glob:*/api/v1/report/*';
 
 fetchMock.delete(executionLogsEndpoint, {});
 
-const mockannotations = [...new Array(3)].map((_, i) => ({
+const mockAnnotations = [...new Array(3)].map((_, i) => ({
   end_dttm: new Date().toISOString,
   error_message: `report ${i} error message`,
   id: i,
@@ -47,7 +38,7 @@ const mockannotations = [...new Array(3)].map((_, i) => ({
 
 fetchMock.get(executionLogsEndpoint, {
   ids: [2, 0, 1],
-  result: mockannotations,
+  result: mockAnnotations,
   count: 3,
 });
 
@@ -61,30 +52,22 @@ jest.mock('react-router-dom', () => ({
   useParams: () => ({ alertId: '1' }),
 }));
 
-async function mountAndWait(props) {
-  const mounted = mount(
-    <Provider store={store}>
-      <ExecutionLog {...props} />
-    </Provider>,
-  );
-  await waitForComponentToPaint(mounted);
-
-  return mounted;
-}
-
-describe('ExecutionLog', () => {
-  let wrapper;
-
-  beforeAll(async () => {
-    wrapper = await mountAndWait();
+const renderAndWait = (props = {}) =>
+  render(<ExecutionLog {...props} />, {
+    useRedux: true,
+    useQueryParams: true,
+    useRouter: true,
   });
 
-  it('renders', () => {
-    expect(wrapper.find(ExecutionLog)).toExist();
-  });
+describe('ExecutionLog', () => {
+  beforeAll(() => renderAndWait());
 
-  it('renders a ListView', () => {
-    expect(wrapper.find(ListView)).toExist();
+  it('renders with a ListView', () => {
+    expect(screen.getByText('Back to all')).toHaveAttribute(
+      'href',
+      '/alert/list/',
+    );
+    expect(screen.getByTestId('execution-log-list-view')).toBeVisible();
   });
 
   it('fetches report/alert', () => {

Reply via email to