diff --git a/src/components/views/beacon/ShareLatestLocation.tsx b/src/components/views/beacon/ShareLatestLocation.tsx index 09c179f6d6..be8bc6f977 100644 --- a/src/components/views/beacon/ShareLatestLocation.tsx +++ b/src/components/views/beacon/ShareLatestLocation.tsx @@ -47,7 +47,7 @@ const ShareLatestLocation: React.FC = ({ latestLocationState }) => { return <> ', () => { beacon: new Beacon(aliceBeaconEvent), }; - const getComponent = (props = {}) => - mount(, { - wrappingComponent: MatrixClientContext.Provider, - wrappingComponentProps: { value: mockClient }, - }); + const getComponent = (props = {}) => render( + + ); const setupRoomWithBeacons = (beaconInfoEvents: MatrixEvent[], locationEvents?: MatrixEvent[]): Beacon[] => { const beacons = makeRoomWithBeacons(roomId, mockClient, beaconInfoEvents, locationEvents); @@ -104,71 +100,72 @@ describe('', () => { { isLive: false }, ); const [beacon] = setupRoomWithBeacons([notLiveBeacon]); - const component = getComponent({ beacon }); - expect(component.html()).toBeNull(); + const { container } = getComponent({ beacon }); + expect(container.innerHTML).toBeFalsy(); }); it('renders null when beacon has no location', () => { const [beacon] = setupRoomWithBeacons([aliceBeaconEvent]); - const component = getComponent({ beacon }); - expect(component.html()).toBeNull(); + const { container } = getComponent({ beacon }); + expect(container.innerHTML).toBeFalsy(); }); describe('when a beacon is live and has locations', () => { it('renders beacon info', () => { const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); - const component = getComponent({ beacon }); - expect(component.html()).toMatchSnapshot(); + const { asFragment } = getComponent({ beacon }); + expect(asFragment()).toMatchSnapshot(); }); describe('non-self beacons', () => { it('uses beacon description as beacon name', () => { const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); - const component = getComponent({ beacon }); - expect(component.find('BeaconStatus').props().label).toEqual("Alice's car"); + const { container } = getComponent({ beacon }); + expect(container.querySelector('.mx_BeaconStatus_label')).toHaveTextContent("Alice's car"); }); it('uses beacon owner mxid as beacon name for a beacon without description', () => { const [beacon] = setupRoomWithBeacons([pinBeaconWithoutDescription], [aliceLocation1]); - const component = getComponent({ beacon }); - expect(component.find('BeaconStatus').props().label).toEqual(aliceId); + const { container } = getComponent({ beacon }); + expect(container.querySelector('.mx_BeaconStatus_label')).toHaveTextContent(aliceId); }); it('renders location icon', () => { const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); - const component = getComponent({ beacon }); - expect(component.find('StyledLiveBeaconIcon').length).toBeTruthy(); + const { container } = getComponent({ beacon }); + expect(container.querySelector('.mx_StyledLiveBeaconIcon')).toBeTruthy(); }); }); describe('self locations', () => { it('renders beacon owner avatar', () => { const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation1]); - const component = getComponent({ beacon }); - expect(component.find('MemberAvatar').length).toBeTruthy(); + const { container } = getComponent({ beacon }); + expect(container.querySelector('.mx_BaseAvatar')).toBeTruthy(); }); it('uses beacon owner name as beacon name', () => { const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation1]); - const component = getComponent({ beacon }); - expect(component.find('BeaconStatus').props().label).toEqual('Alice'); + const { container } = getComponent({ beacon }); + expect(container.querySelector('.mx_BeaconStatus_label')).toHaveTextContent("Alice"); }); }); describe('on location updates', () => { it('updates last updated time on location updated', () => { const [beacon] = setupRoomWithBeacons([aliceBeaconEvent], [aliceLocation2]); - const component = getComponent({ beacon }); + const { container } = getComponent({ beacon }); - expect(component.find('.mx_BeaconListItem_lastUpdated').text()).toEqual('Updated 9 minutes ago'); + expect(container.querySelector('.mx_BeaconListItem_lastUpdated')) + .toHaveTextContent('Updated 9 minutes ago'); // update to a newer location act(() => { beacon.addLocations([aliceLocation1]); - component.setProps({}); }); - expect(component.find('.mx_BeaconListItem_lastUpdated').text()).toEqual('Updated a few seconds ago'); + expect(container.querySelector('.mx_BeaconListItem_lastUpdated')) + .toHaveTextContent('Updated a few seconds ago'); }); }); @@ -176,23 +173,19 @@ describe('', () => { it('does not call onClick handler when clicking share button', () => { const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const onClick = jest.fn(); - const component = getComponent({ beacon, onClick }); + const { getByTestId } = getComponent({ beacon, onClick }); - act(() => { - findByTestId(component, 'open-location-in-osm').at(0).simulate('click'); - }); + fireEvent.click(getByTestId('open-location-in-osm')); expect(onClick).not.toHaveBeenCalled(); }); it('calls onClick handler when clicking outside of share buttons', () => { const [beacon] = setupRoomWithBeacons([alicePinBeaconEvent], [aliceLocation1]); const onClick = jest.fn(); - const component = getComponent({ beacon, onClick }); + const { container } = getComponent({ beacon, onClick }); - act(() => { - // click the beacon name - component.find('.mx_BeaconStatus_description').simulate('click'); - }); + // click the beacon name + fireEvent.click(container.querySelector(".mx_BeaconStatus_description")); expect(onClick).toHaveBeenCalled(); }); }); diff --git a/test/components/views/beacon/LeftPanelLiveShareWarning-test.tsx b/test/components/views/beacon/LeftPanelLiveShareWarning-test.tsx index 0369fa5cc1..b8ab33b044 100644 --- a/test/components/views/beacon/LeftPanelLiveShareWarning-test.tsx +++ b/test/components/views/beacon/LeftPanelLiveShareWarning-test.tsx @@ -16,8 +16,7 @@ limitations under the License. import React from 'react'; import { mocked } from 'jest-mock'; -// eslint-disable-next-line deprecate/import -import { mount } from 'enzyme'; +import { fireEvent, render } from "@testing-library/react"; import { act } from 'react-dom/test-utils'; import { Beacon, BeaconIdentifier } from 'matrix-js-sdk/src/matrix'; @@ -48,9 +47,7 @@ jest.mock('../../../../src/stores/OwnBeaconStore', () => { ); describe('', () => { - const defaultProps = {}; - const getComponent = (props = {}) => - mount(); + const getComponent = (props = {}) => render(); const roomId1 = '!room1:server'; const roomId2 = '!room2:server'; @@ -85,8 +82,8 @@ describe('', () => { )); it('renders nothing when user has no live beacons', () => { - const component = getComponent(); - expect(component.html()).toBe(null); + const { container } = getComponent(); + expect(container.innerHTML).toBeFalsy(); }); describe('when user has live location monitor', () => { @@ -110,17 +107,15 @@ describe('', () => { }); it('renders correctly when not minimized', () => { - const component = getComponent(); - expect(component).toMatchSnapshot(); + const { asFragment } = getComponent(); + expect(asFragment()).toMatchSnapshot(); }); it('goes to room of latest beacon when clicked', () => { - const component = getComponent(); + const { container } = getComponent(); const dispatchSpy = jest.spyOn(dispatcher, 'dispatch'); - act(() => { - component.simulate('click'); - }); + fireEvent.click(container.querySelector("[role=button]")); expect(dispatchSpy).toHaveBeenCalledWith({ action: Action.ViewRoom, @@ -134,28 +129,26 @@ describe('', () => { }); it('renders correctly when minimized', () => { - const component = getComponent({ isMinimized: true }); - expect(component).toMatchSnapshot(); + const { asFragment } = getComponent({ isMinimized: true }); + expect(asFragment()).toMatchSnapshot(); }); it('renders location publish error', () => { mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue( [beacon1.identifier], ); - const component = getComponent(); - expect(component).toMatchSnapshot(); + const { asFragment } = getComponent(); + expect(asFragment()).toMatchSnapshot(); }); it('goes to room of latest beacon with location publish error when clicked', () => { mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue( [beacon1.identifier], ); - const component = getComponent(); + const { container } = getComponent(); const dispatchSpy = jest.spyOn(dispatcher, 'dispatch'); - act(() => { - component.simulate('click'); - }); + fireEvent.click(container.querySelector("[role=button]")); expect(dispatchSpy).toHaveBeenCalledWith({ action: Action.ViewRoom, @@ -172,9 +165,9 @@ describe('', () => { mocked(OwnBeaconStore.instance).getLiveBeaconIdsWithLocationPublishError.mockReturnValue( [beacon1.identifier], ); - const component = getComponent(); + const { container, rerender } = getComponent(); // error mode - expect(component.find('.mx_LeftPanelLiveShareWarning').at(0).text()).toEqual( + expect(container.querySelector('.mx_LeftPanelLiveShareWarning').textContent).toEqual( 'An error occurred whilst sharing your live location', ); @@ -183,18 +176,18 @@ describe('', () => { OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.LocationPublishError, 'abc'); }); - component.setProps({}); + rerender(); // default mode - expect(component.find('.mx_LeftPanelLiveShareWarning').at(0).text()).toEqual( + expect(container.querySelector('.mx_LeftPanelLiveShareWarning').textContent).toEqual( 'You are sharing your live location', ); }); it('removes itself when user stops having live beacons', async () => { - const component = getComponent({ isMinimized: true }); + const { container, rerender } = getComponent({ isMinimized: true }); // started out rendered - expect(component.html()).toBeTruthy(); + expect(container.innerHTML).toBeTruthy(); act(() => { mocked(OwnBeaconStore.instance).isMonitoringLiveLocation = false; @@ -202,9 +195,9 @@ describe('', () => { }); await flushPromises(); - component.setProps({}); + rerender(); - expect(component.html()).toBe(null); + expect(container.innerHTML).toBeFalsy(); }); it('refreshes beacon liveness monitors when pagevisibilty changes to visible', () => { @@ -228,21 +221,21 @@ describe('', () => { describe('stopping errors', () => { it('renders stopping error', () => { OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); - const component = getComponent(); - expect(component.text()).toEqual('An error occurred while stopping your live location'); + const { container } = getComponent(); + expect(container.textContent).toEqual('An error occurred while stopping your live location'); }); it('starts rendering stopping error on beaconUpdateError emit', () => { - const component = getComponent(); + const { container } = getComponent(); // no error - expect(component.text()).toEqual('You are sharing your live location'); + expect(container.textContent).toEqual('You are sharing your live location'); act(() => { OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); OwnBeaconStore.instance.emit(OwnBeaconStoreEvent.BeaconUpdateError, beacon2.identifier, true); }); - expect(component.text()).toEqual('An error occurred while stopping your live location'); + expect(container.textContent).toEqual('An error occurred while stopping your live location'); }); it('renders stopping error when beacons have stopping and location errors', () => { @@ -250,8 +243,8 @@ describe('', () => { [beacon1.identifier], ); OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); - const component = getComponent(); - expect(component.text()).toEqual('An error occurred while stopping your live location'); + const { container } = getComponent(); + expect(container.textContent).toEqual('An error occurred while stopping your live location'); }); it('goes to room of latest beacon with stopping error when clicked', () => { @@ -259,12 +252,10 @@ describe('', () => { [beacon1.identifier], ); OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error')); - const component = getComponent(); + const { container } = getComponent(); const dispatchSpy = jest.spyOn(dispatcher, 'dispatch'); - act(() => { - component.simulate('click'); - }); + fireEvent.click(container.querySelector("[role=button]")); expect(dispatchSpy).toHaveBeenCalledWith({ action: Action.ViewRoom, diff --git a/test/components/views/beacon/ShareLatestLocation-test.tsx b/test/components/views/beacon/ShareLatestLocation-test.tsx index 767c712042..1712d7d57c 100644 --- a/test/components/views/beacon/ShareLatestLocation-test.tsx +++ b/test/components/views/beacon/ShareLatestLocation-test.tsx @@ -15,9 +15,7 @@ limitations under the License. */ import React from 'react'; -// eslint-disable-next-line deprecate/import -import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; +import { fireEvent, render } from "@testing-library/react"; import ShareLatestLocation from '../../../../src/components/views/beacon/ShareLatestLocation'; import { copyPlaintext } from '../../../../src/utils/strings'; @@ -34,26 +32,23 @@ describe('', () => { timestamp: 123, }, }; - const getComponent = (props = {}) => - mount(); + const getComponent = (props = {}) => render(); beforeEach(() => { jest.clearAllMocks(); }); it('renders null when no location', () => { - const component = getComponent({ latestLocationState: undefined }); - expect(component.html()).toBeNull(); + const { container } = getComponent({ latestLocationState: undefined }); + expect(container.innerHTML).toBeFalsy(); }); it('renders share buttons when there is a location', async () => { - const component = getComponent(); - expect(component).toMatchSnapshot(); + const { container, asFragment } = getComponent(); + expect(asFragment()).toMatchSnapshot(); - await act(async () => { - component.find('.mx_CopyableText_copyButton').at(0).simulate('click'); - await flushPromises(); - }); + fireEvent.click(container.querySelector('.mx_CopyableText_copyButton')); + await flushPromises(); expect(copyPlaintext).toHaveBeenCalledWith('51,42'); }); diff --git a/test/components/views/beacon/StyledLiveBeaconIcon-test.tsx b/test/components/views/beacon/StyledLiveBeaconIcon-test.tsx index d6be878a25..e04289c7db 100644 --- a/test/components/views/beacon/StyledLiveBeaconIcon-test.tsx +++ b/test/components/views/beacon/StyledLiveBeaconIcon-test.tsx @@ -15,18 +15,16 @@ limitations under the License. */ import React from 'react'; -// eslint-disable-next-line deprecate/import -import { mount } from 'enzyme'; +import { render } from "@testing-library/react"; import StyledLiveBeaconIcon from '../../../../src/components/views/beacon/StyledLiveBeaconIcon'; describe('', () => { const defaultProps = {}; - const getComponent = (props = {}) => - mount(); + const getComponent = (props = {}) => render(); it('renders', () => { - const component = getComponent(); - expect(component).toBeTruthy(); + const { asFragment } = getComponent(); + expect(asFragment()).toMatchSnapshot(); }); }); diff --git a/test/components/views/beacon/__snapshots__/BeaconListItem-test.tsx.snap b/test/components/views/beacon/__snapshots__/BeaconListItem-test.tsx.snap index 9ddc5dd44c..dd1d607dd4 100644 --- a/test/components/views/beacon/__snapshots__/BeaconListItem-test.tsx.snap +++ b/test/components/views/beacon/__snapshots__/BeaconListItem-test.tsx.snap @@ -1,3 +1,68 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` when a beacon is live and has locations renders beacon info 1`] = `"
  • Updated a few seconds ago
  • "`; +exports[` when a beacon is live and has locations renders beacon info 1`] = ` + +
  • +
    +
    +
    +
    + + Alice's car + + + Live until 16:04 + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + + Updated a few seconds ago + +
    +
  • +
    +`; diff --git a/test/components/views/beacon/__snapshots__/DialogSidebar-test.tsx.snap b/test/components/views/beacon/__snapshots__/DialogSidebar-test.tsx.snap index a92079d2c8..22199fbc91 100644 --- a/test/components/views/beacon/__snapshots__/DialogSidebar-test.tsx.snap +++ b/test/components/views/beacon/__snapshots__/DialogSidebar-test.tsx.snap @@ -75,7 +75,7 @@ exports[` renders sidebar correctly with beacons 1`] = ` tabindex="0" > when user has live location monitor renders correctly when minimized 1`] = ` - - +
    -
    -
    - - + height="10" + /> +
    + `; exports[` when user has live location monitor renders correctly when not minimized 1`] = ` - - +
    -
    - You are sharing your live location -
    - - + You are sharing your live location +
    + `; exports[` when user has live location monitor renders location publish error 1`] = ` - - +
    -
    - An error occurred whilst sharing your live location -
    - - + An error occurred whilst sharing your live location +
    + `; diff --git a/test/components/views/beacon/__snapshots__/ShareLatestLocation-test.tsx.snap b/test/components/views/beacon/__snapshots__/ShareLatestLocation-test.tsx.snap index 5f55d3103d..1162786e30 100644 --- a/test/components/views/beacon/__snapshots__/ShareLatestLocation-test.tsx.snap +++ b/test/components/views/beacon/__snapshots__/ShareLatestLocation-test.tsx.snap @@ -1,79 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` renders share buttons when there is a location 1`] = ` - - +
    + +
    + +
    +
    - -
    - -
    - - -
    - - -
    - - -
    - - + aria-label="Copy" + class="mx_AccessibleButton mx_CopyableText_copyButton" + role="button" + tabindex="0" + /> +
    + `; diff --git a/test/components/views/beacon/__snapshots__/StyledLiveBeaconIcon-test.tsx.snap b/test/components/views/beacon/__snapshots__/StyledLiveBeaconIcon-test.tsx.snap new file mode 100644 index 0000000000..e1e2bf1faa --- /dev/null +++ b/test/components/views/beacon/__snapshots__/StyledLiveBeaconIcon-test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders 1`] = ` + +
    + +`; diff --git a/test/components/views/elements/StyledRadioGroup-test.tsx b/test/components/views/elements/StyledRadioGroup-test.tsx index 3fa5dd9c53..8868b741bd 100644 --- a/test/components/views/elements/StyledRadioGroup-test.tsx +++ b/test/components/views/elements/StyledRadioGroup-test.tsx @@ -15,9 +15,7 @@ limitations under the License. */ import React from 'react'; -// eslint-disable-next-line deprecate/import -import { mount } from 'enzyme'; -import { act } from "react-dom/test-utils"; +import { fireEvent, render } from "@testing-library/react"; import StyledRadioGroup from "../../../../src/components/views/elements/StyledRadioGroup"; @@ -44,16 +42,16 @@ describe('', () => { definitions: defaultDefinitions, onChange: jest.fn(), }; - const getComponent = (props = {}) => mount(); + const getComponent = (props = {}) => render(); - const getInputByValue = (component, value) => component.find(`input[value="${value}"]`); - const getCheckedInput = component => component.find('input[checked=true]'); + const getInputByValue = (component, value) => component.container.querySelector(`input[value="${value}"]`); + const getCheckedInput = component => component.container.querySelector('input[checked]'); it('renders radios correctly when no value is provided', () => { const component = getComponent(); - expect(component).toMatchSnapshot(); - expect(getCheckedInput(component).length).toBeFalsy(); + expect(component.asFragment()).toMatchSnapshot(); + expect(getCheckedInput(component)).toBeFalsy(); }); it('selects correct button when value is provided', () => { @@ -61,7 +59,7 @@ describe('', () => { value: optionC.value, }); - expect(getCheckedInput(component).at(0).props().value).toEqual(optionC.value); + expect(getCheckedInput(component).value).toEqual(optionC.value); }); it('selects correct buttons when definitions have checked prop', () => { @@ -74,10 +72,10 @@ describe('', () => { value: optionC.value, definitions, }); - expect(getInputByValue(component, optionA.value).props().checked).toBeTruthy(); - expect(getInputByValue(component, optionB.value).props().checked).toBeFalsy(); + expect(getInputByValue(component, optionA.value)).toBeChecked(); + expect(getInputByValue(component, optionB.value)).not.toBeChecked(); // optionC.checked = false overrides value matching - expect(getInputByValue(component, optionC.value).props().checked).toBeFalsy(); + expect(getInputByValue(component, optionC.value)).not.toBeChecked(); }); it('disables individual buttons based on definition.disabled', () => { @@ -87,16 +85,16 @@ describe('', () => { { ...optionC, disabled: true }, ]; const component = getComponent({ definitions }); - expect(getInputByValue(component, optionA.value).props().disabled).toBeFalsy(); - expect(getInputByValue(component, optionB.value).props().disabled).toBeTruthy(); - expect(getInputByValue(component, optionC.value).props().disabled).toBeTruthy(); + expect(getInputByValue(component, optionA.value)).not.toBeDisabled(); + expect(getInputByValue(component, optionB.value)).toBeDisabled(); + expect(getInputByValue(component, optionC.value)).toBeDisabled(); }); it('disables all buttons with disabled prop', () => { const component = getComponent({ disabled: true }); - expect(getInputByValue(component, optionA.value).props().disabled).toBeTruthy(); - expect(getInputByValue(component, optionB.value).props().disabled).toBeTruthy(); - expect(getInputByValue(component, optionC.value).props().disabled).toBeTruthy(); + expect(getInputByValue(component, optionA.value)).toBeDisabled(); + expect(getInputByValue(component, optionB.value)).toBeDisabled(); + expect(getInputByValue(component, optionC.value)).toBeDisabled(); }); it('calls onChange on click', () => { @@ -106,9 +104,7 @@ describe('', () => { onChange, }); - act(() => { - getInputByValue(component, optionB.value).simulate('change'); - }); + fireEvent.click(getInputByValue(component, optionB.value)); expect(onChange).toHaveBeenCalledWith(optionB.value); }); diff --git a/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap b/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap index 423c006a72..cb3c3374fd 100644 --- a/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap +++ b/test/components/views/elements/__snapshots__/StyledRadioGroup-test.tsx.snap @@ -1,152 +1,83 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` renders radios correctly when no value is provided 1`] = ` - - Anteater label - , - "value": "Anteater", - }, - Object { - "label": - Badger label - , - "value": "Badger", - }, - Object { - "description": - Canary description - , - "label": - Canary label - , - "value": "Canary", - }, - ] - } - name="test" - onChange={[MockFunction]} -> - +