From 0d682a95bdf70489a9f0e04b92b8f9383796e09a Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 9 Dec 2020 15:04:21 +0100 Subject: [PATCH] [jest] fix errors and warnings (#85291) * replace deprecated 'wait' with 'waitFor' * add required 'initialPageSize' field * fix '.getContext() is not implemented' error * wrapping code with act * replace deprecated 'wait' with 'waitFor' * fix 'state update on an unmounted component' warning --- .../dashboard_listing.test.js.snap | 1 + .../listing/dashboard_listing.test.js | 1 + .../embeddables/embeddable_renderer.test.tsx | 4 +- .../lib/embeddables/error_embeddable.test.tsx | 6 +-- .../public/request/use_request.test.ts | 5 ++- .../components/opt_in_example_flyout.tsx | 20 +++++++--- .../public/markdown_vis_controller.test.tsx | 14 +++---- .../public/vega_visualization.test.js | 2 + .../vislib/components/legend/legend.test.tsx | 9 ++++- .../edit_space/manage_space_page.test.tsx | 12 +++--- .../nav_control/nav_control_popover.test.tsx | 4 +- ...onnected_flyout_manage_drilldowns.test.tsx | 38 +++++++++---------- 12 files changed, 68 insertions(+), 48 deletions(-) diff --git a/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.js.snap b/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.js.snap index d68011d2f7fd..e817e898cca6 100644 --- a/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.js.snap +++ b/src/plugins/dashboard/public/application/listing/__snapshots__/dashboard_listing.test.js.snap @@ -492,6 +492,7 @@ exports[`renders empty page in before initial fetch to avoid flickering 1`] = ` findItems={[Function]} headingId="dashboardListingHeading" initialFilter="" + initialPageSize={10} listingLimit={1000} noItemsFragment={
diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js index 99b1ebf047d7..cc2c0a2e828c 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js @@ -62,6 +62,7 @@ test('renders empty page in before initial fetch to avoid flickering', () => { getViewUrl={() => {}} listingLimit={1000} hideWriteControls={false} + initialPageSize={10} core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} /> ); diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx index f9be9d5bfade..bcd9d31dade2 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { wait } from '@testing-library/dom'; +import { waitFor } from '@testing-library/dom'; import { render } from '@testing-library/react'; import { HelloWorldEmbeddable, @@ -47,7 +47,7 @@ describe('', () => { ); expect(getByTestId('embedSpinner')).toBeInTheDocument(); - await wait(() => !queryByTestId('embedSpinner')); // wait until spinner disappears + await waitFor(() => !queryByTestId('embedSpinner')); // wait until spinner disappears expect(getByTestId('helloWorldEmbeddable')).toBeInTheDocument(); }); }); diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx index cb14d7ed11dc..743db62ced98 100644 --- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import { wait, render } from '@testing-library/react'; +import { waitFor, render } from '@testing-library/react'; import { ErrorEmbeddable } from './error_embeddable'; import { EmbeddableRoot } from './embeddable_root'; @@ -26,7 +26,7 @@ test('ErrorEmbeddable renders an embeddable', async () => { const { getByTestId, getByText } = render(); expect(getByTestId('embeddableStackError')).toBeVisible(); - await wait(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component + await waitFor(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component expect(getByText(/some error occurred/i)).toBeVisible(); }); @@ -36,7 +36,7 @@ test('ErrorEmbeddable renders an embeddable with markdown message', async () => const { getByTestId, getByText } = render(); expect(getByTestId('embeddableStackError')).toBeVisible(); - await wait(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component + await waitFor(() => getByTestId('errorMessageMarkdown')); // wait for lazy markdown component expect(getByText(/some link/i)).toMatchInlineSnapshot(` { const { setupSuccessRequest, completeRequest, hookResult } = helpers; setupSuccessRequest(); expect(hookResult.isInitialRequest).toBe(true); - - hookResult.resendRequest(); + act(() => { + hookResult.resendRequest(); + }); await completeRequest(); expect(hookResult.isInitialRequest).toBe(false); }); diff --git a/src/plugins/telemetry_management_section/public/components/opt_in_example_flyout.tsx b/src/plugins/telemetry_management_section/public/components/opt_in_example_flyout.tsx index 402fc55eaf7c..bd78cdc931d0 100644 --- a/src/plugins/telemetry_management_section/public/components/opt_in_example_flyout.tsx +++ b/src/plugins/telemetry_management_section/public/components/opt_in_example_flyout.tsx @@ -49,6 +49,8 @@ interface State { * React component for displaying the example data associated with the Telemetry opt-in banner. */ export class OptInExampleFlyout extends React.PureComponent { + _isMounted = false; + public readonly state: State = { data: null, isLoading: true, @@ -56,14 +58,18 @@ export class OptInExampleFlyout extends React.PureComponent { }; async componentDidMount() { + this._isMounted = true; + try { const { fetchExample } = this.props; const clusters = await fetchExample(); - this.setState({ - data: Array.isArray(clusters) ? clusters : null, - isLoading: false, - hasPrivilegeToRead: true, - }); + if (this._isMounted) { + this.setState({ + data: Array.isArray(clusters) ? clusters : null, + isLoading: false, + hasPrivilegeToRead: true, + }); + } } catch (err) { this.setState({ isLoading: false, @@ -72,6 +78,10 @@ export class OptInExampleFlyout extends React.PureComponent { } } + componentWillUnmount() { + this._isMounted = false; + } + renderBody({ data, isLoading, hasPrivilegeToRead }: State) { if (isLoading) { return loadingSpinner; diff --git a/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx b/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx index 7bc8cdbd1417..e9494e086a73 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx +++ b/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { wait, render } from '@testing-library/react'; +import { waitFor, render } from '@testing-library/react'; import MarkdownVisComponent from './markdown_vis_controller'; describe('markdown vis controller', () => { @@ -36,7 +36,7 @@ describe('markdown vis controller', () => { ); - await wait(() => getByTestId('markdownBody')); + await waitFor(() => getByTestId('markdownBody')); expect(getByText('markdown')).toMatchInlineSnapshot(` { ); - await wait(() => getByTestId('markdownBody')); + await waitFor(() => getByTestId('markdownBody')); expect(getByText(/testing/i)).toMatchInlineSnapshot(`

@@ -82,7 +82,7 @@ describe('markdown vis controller', () => { ); - await wait(() => getByTestId('markdownBody')); + await waitFor(() => getByTestId('markdownBody')); expect(getByText(/initial/i)).toBeInTheDocument(); @@ -112,7 +112,7 @@ describe('markdown vis controller', () => { ); - await wait(() => getByTestId('markdownBody')); + await waitFor(() => getByTestId('markdownBody')); expect(renderComplete).toHaveBeenCalledTimes(1); }); @@ -122,7 +122,7 @@ describe('markdown vis controller', () => { ); - await wait(() => getByTestId('markdownBody')); + await waitFor(() => getByTestId('markdownBody')); expect(renderComplete).toHaveBeenCalledTimes(1); @@ -139,7 +139,7 @@ describe('markdown vis controller', () => { ); - await wait(() => getByTestId('markdownBody')); + await waitFor(() => getByTestId('markdownBody')); expect(renderComplete).toHaveBeenCalledTimes(1); diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index 8a073ca32b94..e4c4c1df202e 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -17,6 +17,8 @@ * under the License. */ +import 'jest-canvas-mock'; + import $ from 'jquery'; import 'leaflet/dist/leaflet.js'; diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx index a3fb536d0aec..7acc97404c11 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx @@ -25,6 +25,7 @@ import { EuiButtonGroup } from '@elastic/eui'; import { VisLegend, VisLegendProps } from './legend'; import { legendColors } from './models'; +import { act } from '@testing-library/react'; jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); @@ -206,7 +207,9 @@ describe('VisLegend Component', () => { const first = getLegendItems(wrapper).first(); first.simulate('click'); const filterGroup = wrapper.find(EuiButtonGroup).first(); - filterGroup.getElement().props.onChange('filterIn'); + act(() => { + filterGroup.getElement().props.onChange('filterIn'); + }); expect(fireEvent).toHaveBeenCalledWith({ name: 'filterBucket', @@ -219,7 +222,9 @@ describe('VisLegend Component', () => { const first = getLegendItems(wrapper).first(); first.simulate('click'); const filterGroup = wrapper.find(EuiButtonGroup).first(); - filterGroup.getElement().props.onChange('filterOut'); + act(() => { + filterGroup.getElement().props.onChange('filterOut'); + }); expect(fireEvent).toHaveBeenCalledWith({ name: 'filterBucket', diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx index 54960fba731d..bc26d6f13252 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx @@ -7,7 +7,7 @@ import { EuiButton, EuiCheckboxProps } from '@elastic/eui'; import { ReactWrapper } from 'enzyme'; import React from 'react'; -import { wait } from '@testing-library/react'; +import { waitFor } from '@testing-library/react'; import { mountWithIntl } from '@kbn/test/jest'; import { ConfirmAlterActiveSpaceModal } from './confirm_alter_active_space_modal'; @@ -70,7 +70,7 @@ describe('ManageSpacePage', () => { /> ); - await wait(() => { + await waitFor(() => { wrapper.update(); expect(wrapper.find('input[name="name"]')).toHaveLength(1); }); @@ -132,7 +132,7 @@ describe('ManageSpacePage', () => { /> ); - await wait(() => { + await waitFor(() => { wrapper.update(); expect(spacesManager.getSpace).toHaveBeenCalledWith('existing-space'); }); @@ -185,7 +185,7 @@ describe('ManageSpacePage', () => { /> ); - await wait(() => { + await waitFor(() => { wrapper.update(); expect(notifications.toasts.addError).toHaveBeenCalledWith(error, { title: 'Error loading available features', @@ -223,7 +223,7 @@ describe('ManageSpacePage', () => { /> ); - await wait(() => { + await waitFor(() => { wrapper.update(); expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); }); @@ -285,7 +285,7 @@ describe('ManageSpacePage', () => { /> ); - await wait(() => { + await waitFor(() => { wrapper.update(); expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); }); diff --git a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx index b08c1c834ac4..e841d3efc828 100644 --- a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx +++ b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx @@ -13,7 +13,7 @@ import { SpacesManager } from '../spaces_manager'; import { NavControlPopover } from './nav_control_popover'; import { EuiHeaderSectionItemButton } from '@elastic/eui'; import { mountWithIntl } from '@kbn/test/jest'; -import { wait } from '@testing-library/react'; +import { waitFor } from '@testing-library/react'; describe('NavControlPopover', () => { it('renders without crashing', () => { @@ -65,7 +65,7 @@ describe('NavControlPopover', () => { wrapper.find(EuiHeaderSectionItemButton).simulate('click'); // Wait for `getSpaces` promise to resolve - await wait(() => { + await waitFor(() => { wrapper.update(); expect(wrapper.find(SpaceAvatar)).toHaveLength(3); }); diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx index dab28fb03f4e..780cb05d31d8 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { fireEvent, render, wait, cleanup } from '@testing-library/react'; +import { fireEvent, render, waitFor, cleanup } from '@testing-library/react'; import { createFlyoutManageDrilldowns } from './connected_flyout_manage_drilldowns'; import { mockGetTriggerInfo, @@ -50,7 +50,7 @@ test('Allows to manage drilldowns', async () => { ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); + await waitFor(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); // no drilldowns in the list expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(0); @@ -87,7 +87,7 @@ test('Allows to manage drilldowns', async () => { expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible(); - await wait(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(1)); + await waitFor(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(1)); expect(screen.getByText(name)).toBeVisible(); const editButton = screen.getByText(/edit/i); fireEvent.click(editButton); @@ -105,14 +105,14 @@ test('Allows to manage drilldowns', async () => { fireEvent.click(screen.getByText(/save/i)); expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible(); - await wait(() => screen.getByText(newName)); + await waitFor(() => screen.getByText(newName)); // delete drilldown from edit view fireEvent.click(screen.getByText(/edit/i)); fireEvent.click(screen.getByText(/delete/i)); expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible(); - await wait(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(0)); + await waitFor(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(0)); }); test('Can delete multiple drilldowns', async () => { @@ -123,7 +123,7 @@ test('Can delete multiple drilldowns', async () => { /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); + await waitFor(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); const createDrilldown = async () => { const oldCount = screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM).length; @@ -136,7 +136,7 @@ test('Can delete multiple drilldowns', async () => { target: { value: 'https://elastic.co' }, }); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); - await wait(() => + await waitFor(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(oldCount + 1) ); }; @@ -151,7 +151,7 @@ test('Can delete multiple drilldowns', async () => { expect(screen.queryByText(/Create/i)).not.toBeInTheDocument(); fireEvent.click(screen.getByText(/Delete \(3\)/i)); - await wait(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(0)); + await waitFor(() => expect(screen.queryAllByTestId(TEST_SUBJ_DRILLDOWN_ITEM)).toHaveLength(0)); }); test('Create only mode', async () => { @@ -165,7 +165,7 @@ test('Create only mode', async () => { /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); + await waitFor(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); fireEvent.change(screen.getByLabelText(/name/i), { target: { value: 'test' }, }); @@ -175,7 +175,7 @@ test('Create only mode', async () => { }); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); - await wait(() => expect(toasts.addSuccess).toBeCalled()); + await waitFor(() => expect(toasts.addSuccess).toBeCalled()); expect(onClose).toBeCalled(); expect(await mockDynamicActionManager.state.get().events.length).toBe(1); }); @@ -189,7 +189,7 @@ test('After switching between action factories state is restored', async () => { /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); + await waitFor(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); fireEvent.change(screen.getByLabelText(/name/i), { target: { value: 'test' }, }); @@ -210,7 +210,7 @@ test('After switching between action factories state is restored', async () => { expect(screen.getByLabelText(/name/i)).toHaveValue('test'); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); - await wait(() => expect(toasts.addSuccess).toBeCalled()); + await waitFor(() => expect(toasts.addSuccess).toBeCalled()); expect(await (mockDynamicActionManager.state.get().events[0].action.config as any).url).toBe( 'https://elastic.co' ); @@ -230,7 +230,7 @@ test("Error when can't save drilldown changes", async () => { /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); + await waitFor(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); fireEvent.click(screen.getByText(/Create new/i)); fireEvent.change(screen.getByLabelText(/name/i), { target: { value: 'test' }, @@ -240,7 +240,7 @@ test("Error when can't save drilldown changes", async () => { target: { value: 'https://elastic.co' }, }); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); - await wait(() => + await waitFor(() => expect(toasts.addError).toBeCalledWith(error, { title: toastDrilldownsCRUDError }) ); }); @@ -254,7 +254,7 @@ test('Should show drilldown welcome message. Should be able to dismiss it', asyn ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); + await waitFor(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); expect(screen.getByTestId(WELCOME_MESSAGE_TEST_SUBJ)).toBeVisible(); fireEvent.click(screen.getByText(/hide/i)); @@ -268,7 +268,7 @@ test('Should show drilldown welcome message. Should be able to dismiss it', asyn /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); + await waitFor(() => expect(screen.getByText(/Manage Drilldowns/i)).toBeVisible()); expect(screen.queryByTestId(WELCOME_MESSAGE_TEST_SUBJ)).toBeNull(); }); @@ -281,7 +281,7 @@ test('Drilldown type is not shown if no supported trigger', async () => { /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); + await waitFor(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); expect(screen.queryByText(/Go to Dashboard/i)).not.toBeInTheDocument(); // dashboard action is not visible, because APPLY_FILTER_TRIGGER not supported expect(screen.getByTestId('selectedActionFactory-Url')).toBeInTheDocument(); }); @@ -295,7 +295,7 @@ test('Can pick a trigger', async () => { /> ); // wait for initial render. It is async because resolving compatible action factories is async - await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); + await waitFor(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0)); // input drilldown name const name = 'Test name'; @@ -318,6 +318,6 @@ test('Can pick a trigger', async () => { expect(createButton).toBeEnabled(); fireEvent.click(createButton); - await wait(() => expect(toasts.addSuccess).toBeCalled()); + await waitFor(() => expect(toasts.addSuccess).toBeCalled()); expect(mockDynamicActionManager.state.get().events[0].triggers).toEqual(['SELECT_RANGE_TRIGGER']); });