From 5a13e9e3c652ed564497eaf8ed1881e87b74daad Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 22 Oct 2024 10:19:01 +0100 Subject: [PATCH] Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/accessibility/RovingTabIndex.tsx | 4 +- test/test-utils/utilities.ts | 3 +- .../accessibility/RovingTabIndex-test.tsx | 14 +++---- .../components/structures/RoomView-test.tsx | 30 ++++++------- .../dialogs/ConfirmRedactDialog-test.tsx | 2 +- .../views/dialogs/CreateRoomDialog-test.tsx | 2 +- .../__snapshots__/AppTile-test.tsx.snap | 4 +- .../views/emojipicker/EmojiPicker-test.tsx | 8 ++-- .../views/location/LocationShareMenu-test.tsx | 4 +- .../LocationViewDialog-test.tsx.snap | 1 - .../views/messages/MPollEndBody-test.tsx | 4 +- .../polls/pollHistory/PollHistory-test.tsx | 10 ++--- .../views/right_panel/UserInfo-test.tsx | 36 ++++++++-------- .../components/views/rooms/EventTile-test.tsx | 12 +++--- .../views/rooms/SendMessageComposer-test.tsx | 6 +-- .../settings/AddRemoveThreepids-test.tsx | 23 +++++----- .../views/settings/CrossSigningPanel-test.tsx | 2 +- .../views/settings/EventIndexPanel-test.tsx | 2 +- .../tabs/user/SessionManagerTab-test.tsx | 6 +-- .../AccountUserSettingsTab-test.tsx.snap | 8 ++-- .../SessionManagerTab-test.tsx.snap | 2 +- .../toasts/UnverifiedSessionToast-test.tsx | 3 +- .../media/requestMediaPermissions-test.tsx | 6 +-- test/unit-tests/utils/pillify-test.tsx | 42 ++++++++++--------- 24 files changed, 123 insertions(+), 111 deletions(-) diff --git a/src/accessibility/RovingTabIndex.tsx b/src/accessibility/RovingTabIndex.tsx index 2fb22e9f8f..3faa831530 100644 --- a/src/accessibility/RovingTabIndex.tsx +++ b/src/accessibility/RovingTabIndex.tsx @@ -88,11 +88,11 @@ interface UpdateAction { type Action = IAction | UpdateAction; const refSorter = (a: Ref, b: Ref): number => { - if (a === b) { + if (a === b || !a.current || !b.current) { return 0; } - const position = a.current!.compareDocumentPosition(b.current!); + const position = a.current.compareDocumentPosition(b.current); if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) { return -1; diff --git a/test/test-utils/utilities.ts b/test/test-utils/utilities.ts index 4278b73f74..c3a96a7eb7 100644 --- a/test/test-utils/utilities.ts +++ b/test/test-utils/utilities.ts @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import EventEmitter from "events"; +import { act } from "jest-matrix-react"; import { ActionPayload } from "../../src/dispatcher/payloads"; import defaultDispatcher from "../../src/dispatcher/dispatcher"; @@ -119,7 +120,7 @@ export function untilEmission( }); } -export const flushPromises = async () => await new Promise((resolve) => window.setTimeout(resolve)); +export const flushPromises = async () => await act(() => new Promise((resolve) => window.setTimeout(resolve))); // with jest's modern fake timers process.nextTick is also mocked, // flushing promises in the normal way then waits for some advancement diff --git a/test/unit-tests/accessibility/RovingTabIndex-test.tsx b/test/unit-tests/accessibility/RovingTabIndex-test.tsx index 8130167db4..229afe0405 100644 --- a/test/unit-tests/accessibility/RovingTabIndex-test.tsx +++ b/test/unit-tests/accessibility/RovingTabIndex-test.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React, { HTMLAttributes } from "react"; -import { render } from "jest-matrix-react"; +import { act, render } from "jest-matrix-react"; import userEvent from "@testing-library/user-event"; import { @@ -73,15 +73,15 @@ describe("RovingTabIndex", () => { checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]); // focus on 2nd button and test it is the only active one - container.querySelectorAll("button")[2].focus(); + act(() => container.querySelectorAll("button")[2].focus()); checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]); // focus on 1st button and test it is the only active one - container.querySelectorAll("button")[1].focus(); + act(() => container.querySelectorAll("button")[1].focus()); checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]); // check that the active button does not change even on an explicit blur event - container.querySelectorAll("button")[1].blur(); + act(() => container.querySelectorAll("button")[1].blur()); checkTabIndexes(container.querySelectorAll("button"), [-1, 0, -1]); // update the children, it should remain on the same button @@ -141,7 +141,7 @@ describe("RovingTabIndex", () => { checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]); // focus on 2nd button and test it is the only active one - container.querySelectorAll("button")[2].focus(); + act(() => container.querySelectorAll("button")[2].focus()); checkTabIndexes(container.querySelectorAll("button"), [-1, -1, 0]); }); @@ -369,7 +369,7 @@ describe("RovingTabIndex", () => { , ); - container.querySelectorAll("button")[0].focus(); + act(() => container.querySelectorAll("button")[0].focus()); checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]); await userEvent.keyboard("[ArrowDown]"); @@ -402,7 +402,7 @@ describe("RovingTabIndex", () => { , ); - container.querySelectorAll("button")[0].focus(); + act(() => container.querySelectorAll("button")[0].focus()); checkTabIndexes(container.querySelectorAll("button"), [0, -1, -1]); const button = container.querySelectorAll("button")[1]; diff --git a/test/unit-tests/components/structures/RoomView-test.tsx b/test/unit-tests/components/structures/RoomView-test.tsx index b6a0f28637..c426e0b0fd 100644 --- a/test/unit-tests/components/structures/RoomView-test.tsx +++ b/test/unit-tests/components/structures/RoomView-test.tsx @@ -22,7 +22,7 @@ import { IEvent, } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; -import { fireEvent, render, screen, RenderResult, waitForElementToBeRemoved, waitFor } from "jest-matrix-react"; +import { fireEvent, render, screen, RenderResult, waitForElementToBeRemoved, waitFor, act } from "jest-matrix-react"; import userEvent from "@testing-library/user-event"; import { @@ -214,11 +214,11 @@ describe("RoomView", () => { describe("and feature_dynamic_room_predecessors is enabled", () => { beforeEach(() => { - instance.setState({ msc3946ProcessDynamicPredecessor: true }); + act(() => instance.setState({ msc3946ProcessDynamicPredecessor: true })); }); afterEach(() => { - instance.setState({ msc3946ProcessDynamicPredecessor: false }); + act(() => instance.setState({ msc3946ProcessDynamicPredecessor: false })); }); it("should pass the setting to findPredecessor", async () => { @@ -249,15 +249,17 @@ describe("RoomView", () => { cli.isRoomEncrypted.mockReturnValue(true); // and fake an encryption event into the room to prompt it to re-check - room.addLiveEvents([ - new MatrixEvent({ - type: "m.room.encryption", - sender: cli.getUserId()!, - content: {}, - event_id: "someid", - room_id: room.roomId, - }), - ]); + await act(() => + room.addLiveEvents([ + new MatrixEvent({ + type: "m.room.encryption", + sender: cli.getUserId()!, + content: {}, + event_id: "someid", + room_id: room.roomId, + }), + ]), + ); // URL previews should now be disabled expect(roomViewInstance.state.showUrlPreview).toBe(false); @@ -267,7 +269,7 @@ describe("RoomView", () => { const roomViewInstance = await getRoomViewInstance(); const oldTimeline = roomViewInstance.state.liveTimeline; - room.getUnfilteredTimelineSet().resetLiveTimeline(); + act(() => room.getUnfilteredTimelineSet().resetLiveTimeline()); expect(roomViewInstance.state.liveTimeline).not.toEqual(oldTimeline); }); @@ -284,7 +286,7 @@ describe("RoomView", () => { await renderRoomView(); expect(VoipUserMapper.sharedInstance().getVirtualRoomForRoom).toHaveBeenCalledWith(room.roomId); - cli.emit(ClientEvent.Room, room); + act(() => cli.emit(ClientEvent.Room, room)); // called again after room event expect(VoipUserMapper.sharedInstance().getVirtualRoomForRoom).toHaveBeenCalledTimes(2); diff --git a/test/unit-tests/components/views/dialogs/ConfirmRedactDialog-test.tsx b/test/unit-tests/components/views/dialogs/ConfirmRedactDialog-test.tsx index b6c894c52b..ede37d90e4 100644 --- a/test/unit-tests/components/views/dialogs/ConfirmRedactDialog-test.tsx +++ b/test/unit-tests/components/views/dialogs/ConfirmRedactDialog-test.tsx @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { Feature, ServerSupport } from "matrix-js-sdk/src/feature"; import { MatrixClient, MatrixEvent, RelationType } from "matrix-js-sdk/src/matrix"; -import { screen } from "jest-matrix-react"; +import { act, screen } from "jest-matrix-react"; import userEvent from "@testing-library/user-event"; import { flushPromises, mkEvent, stubClient } from "../../../../test-utils"; diff --git a/test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx b/test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx index 6add6cfc74..4dfbbea30e 100644 --- a/test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx +++ b/test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { fireEvent, render, screen, within } from "jest-matrix-react"; +import { act, fireEvent, render, screen, within } from "jest-matrix-react"; import { JoinRule, MatrixError, Preset, Visibility } from "matrix-js-sdk/src/matrix"; import CreateRoomDialog from "../../../../../src/components/views/dialogs/CreateRoomDialog"; diff --git a/test/unit-tests/components/views/elements/__snapshots__/AppTile-test.tsx.snap b/test/unit-tests/components/views/elements/__snapshots__/AppTile-test.tsx.snap index 96b06a4eda..d7a912ac91 100644 --- a/test/unit-tests/components/views/elements/__snapshots__/AppTile-test.tsx.snap +++ b/test/unit-tests/components/views/elements/__snapshots__/AppTile-test.tsx.snap @@ -356,8 +356,8 @@ exports[`AppTile for a pinned widget should render permission request 1`] = ` Using this widget may share data
ref.current!.onChangeFilter("test")); expect(beforeHtml).not.toEqual(container.innerHTML); // Clear the filter and assert that the HTML matches what it was before filtering //@ts-ignore private access - ref.current!.onChangeFilter(""); + act(() => ref.current!.onChangeFilter("")); await waitFor(() => expect(beforeHtml).toEqual(container.innerHTML)); }); @@ -40,7 +40,7 @@ describe("EmojiPicker", function () { const ep = new EmojiPicker({ onChoose: (str: string) => false, onFinished: jest.fn() }); //@ts-ignore private access - ep.onChangeFilter("heart"); + act(() => ep.onChangeFilter("heart")); //@ts-ignore private access expect(ep.memoizedDataByCategory["people"][0].shortcodes[0]).toEqual("heart"); diff --git a/test/unit-tests/components/views/location/LocationShareMenu-test.tsx b/test/unit-tests/components/views/location/LocationShareMenu-test.tsx index 672580e952..84c5e91ea0 100644 --- a/test/unit-tests/components/views/location/LocationShareMenu-test.tsx +++ b/test/unit-tests/components/views/location/LocationShareMenu-test.tsx @@ -139,7 +139,7 @@ describe("", () => { const [, onGeolocateCallback] = mocked(mockGeolocate.on).mock.calls.find(([event]) => event === "geolocate")!; // set the location - onGeolocateCallback(position); + act(() => onGeolocateCallback(position)); }; const setLocationClick = () => { @@ -151,7 +151,7 @@ describe("", () => { lngLat: { lng: position.coords.longitude, lat: position.coords.latitude }, } as unknown as maplibregl.MapMouseEvent; // set the location - onMapClickCallback(event); + act(() => onMapClickCallback(event)); }; const shareTypeLabels: Record = { diff --git a/test/unit-tests/components/views/location/__snapshots__/LocationViewDialog-test.tsx.snap b/test/unit-tests/components/views/location/__snapshots__/LocationViewDialog-test.tsx.snap index d8b9d8715f..edd05cc260 100644 --- a/test/unit-tests/components/views/location/__snapshots__/LocationViewDialog-test.tsx.snap +++ b/test/unit-tests/components/views/location/__snapshots__/LocationViewDialog-test.tsx.snap @@ -23,7 +23,6 @@ exports[` renders map correctly 1`] = ` class="mx_ZoomButtons" >
", () => { const userId = "@alice:domain.org"; @@ -127,6 +128,7 @@ describe("", () => { expect(container).toMatchSnapshot(); await waitFor(() => expect(getByRole("progressbar")).toBeInTheDocument()); + await waitForElementToBeRemoved(() => getByRole("progressbar")); expect(mockClient.fetchRoomEvent).toHaveBeenCalledWith(roomId, pollStartEvent.getId()); diff --git a/test/unit-tests/components/views/polls/pollHistory/PollHistory-test.tsx b/test/unit-tests/components/views/polls/pollHistory/PollHistory-test.tsx index 96aeffb03c..7780a0b433 100644 --- a/test/unit-tests/components/views/polls/pollHistory/PollHistory-test.tsx +++ b/test/unit-tests/components/views/polls/pollHistory/PollHistory-test.tsx @@ -110,7 +110,7 @@ describe("", () => { expect(getByText("Loading polls")).toBeInTheDocument(); // flush filter creation request - await act(flushPromises); + await flushPromises(); expect(liveTimeline.getPaginationToken).toHaveBeenCalledWith(EventTimeline.BACKWARDS); expect(mockClient.paginateEventTimeline).toHaveBeenCalledWith(liveTimeline, { backwards: true }); @@ -140,7 +140,7 @@ describe("", () => { ); // flush filter creation request - await act(flushPromises); + await flushPromises(); // once per page expect(mockClient.paginateEventTimeline).toHaveBeenCalledTimes(3); @@ -175,7 +175,7 @@ describe("", () => { it("renders a no polls message when there are no active polls in the room", async () => { const { getByText } = getComponent(); - await act(flushPromises); + await flushPromises(); expect(getByText("There are no active polls in this room")).toBeTruthy(); }); @@ -199,7 +199,7 @@ describe("", () => { .mockReturnValueOnce("test-pagination-token-3"); const { getByText } = getComponent(); - await act(flushPromises); + await flushPromises(); expect(mockClient.paginateEventTimeline).toHaveBeenCalledTimes(1); @@ -212,7 +212,7 @@ describe("", () => { // load more polls button still in UI, with loader expect(getByText("Load more polls")).toMatchSnapshot(); - await act(flushPromises); + await flushPromises(); // no more spinner expect(getByText("Load more polls")).toMatchSnapshot(); diff --git a/test/unit-tests/components/views/right_panel/UserInfo-test.tsx b/test/unit-tests/components/views/right_panel/UserInfo-test.tsx index c9996d7d67..534a628d72 100644 --- a/test/unit-tests/components/views/right_panel/UserInfo-test.tsx +++ b/test/unit-tests/components/views/right_panel/UserInfo-test.tsx @@ -439,7 +439,7 @@ describe("", () => { it("renders a device list which can be expanded", async () => { renderComponent(); - await act(flushPromises); + await flushPromises(); // check the button exists with the expected text const devicesButton = screen.getByRole("button", { name: "1 session" }); @@ -459,7 +459,7 @@ describe("", () => { verificationRequest, room: mockRoom, }); - await act(flushPromises); + await flushPromises(); await waitFor(() => expect(screen.getByRole("button", { name: "Verify" })).toBeInTheDocument()); expect(container).toMatchSnapshot(); @@ -490,7 +490,7 @@ describe("", () => { mockCrypto.getUserDeviceInfo.mockResolvedValue(userDeviceMap); renderComponent({ room: mockRoom }); - await act(flushPromises); + await flushPromises(); // check the button exists with the expected text (the dehydrated device shouldn't be counted) const devicesButton = screen.getByRole("button", { name: "1 session" }); @@ -538,7 +538,7 @@ describe("", () => { } as DeviceVerificationStatus); renderComponent({ room: mockRoom }); - await act(flushPromises); + await flushPromises(); // check the button exists with the expected text (the dehydrated device shouldn't be counted) const devicesButton = screen.getByRole("button", { name: "1 verified session" }); @@ -583,7 +583,7 @@ describe("", () => { mockCrypto.getUserVerificationStatus.mockResolvedValue(new UserVerificationStatus(true, true, true)); renderComponent({ room: mockRoom }); - await act(flushPromises); + await flushPromises(); // the dehydrated device should be shown as an unverified device, which means // there should now be a button with the device id ... @@ -618,7 +618,7 @@ describe("", () => { mockCrypto.getUserDeviceInfo.mockResolvedValue(userDeviceMap); renderComponent({ room: mockRoom }); - await act(flushPromises); + await flushPromises(); // check the button exists with the expected text (the dehydrated device shouldn't be counted) const devicesButton = screen.getByRole("button", { name: "2 sessions" }); @@ -666,7 +666,7 @@ describe("", () => { it("renders unverified user info", async () => { mockCrypto.getUserVerificationStatus.mockResolvedValue(new UserVerificationStatus(false, false, false)); renderComponent({ room: mockRoom }); - await act(flushPromises); + await flushPromises(); const userHeading = screen.getByRole("heading", { name: /@user:example.com/ }); @@ -677,7 +677,7 @@ describe("", () => { it("renders verified user info", async () => { mockCrypto.getUserVerificationStatus.mockResolvedValue(new UserVerificationStatus(true, false, false)); renderComponent({ room: mockRoom }); - await act(flushPromises); + await flushPromises(); const userHeading = screen.getByRole("heading", { name: /@user:example.com/ }); @@ -768,7 +768,7 @@ describe("", () => { it("with unverified user and device, displays button without a label", async () => { renderComponent(); - await act(flushPromises); + await flushPromises(); expect(screen.getByRole("button", { name: device.displayName! })).toBeInTheDocument(); expect(screen.queryByText(/trusted/i)).not.toBeInTheDocument(); @@ -776,7 +776,7 @@ describe("", () => { it("with verified user only, displays button with a 'Not trusted' label", async () => { renderComponent({ isUserVerified: true }); - await act(flushPromises); + await flushPromises(); const button = screen.getByRole("button", { name: device.displayName }); expect(button).toHaveTextContent(`${device.displayName}Not trusted`); @@ -785,7 +785,7 @@ describe("", () => { it("with verified device only, displays no button without a label", async () => { setMockDeviceTrust(true); renderComponent(); - await act(flushPromises); + await flushPromises(); expect(screen.getByText(device.displayName!)).toBeInTheDocument(); expect(screen.queryByText(/trusted/)).not.toBeInTheDocument(); @@ -798,7 +798,7 @@ describe("", () => { mockClient.getSafeUserId.mockReturnValueOnce(defaultUserId); mockClient.getUserId.mockReturnValueOnce(defaultUserId); renderComponent(); - await act(flushPromises); + await flushPromises(); // set trust to be false for isVerified, true for isCrossSigningVerified deferred.resolve({ @@ -814,7 +814,7 @@ describe("", () => { it("with verified user and device, displays no button and a 'Trusted' label", async () => { setMockDeviceTrust(true); renderComponent({ isUserVerified: true }); - await act(flushPromises); + await flushPromises(); expect(screen.queryByRole("button")).not.toBeInTheDocument(); expect(screen.getByText(device.displayName!)).toBeInTheDocument(); @@ -824,7 +824,7 @@ describe("", () => { it("does not call verifyDevice if client.getUser returns null", async () => { mockClient.getUser.mockReturnValueOnce(null); renderComponent(); - await act(flushPromises); + await flushPromises(); const button = screen.getByRole("button", { name: device.displayName! }); expect(button).toBeInTheDocument(); @@ -839,7 +839,7 @@ describe("", () => { // even more mocking mockClient.isGuest.mockReturnValueOnce(true); renderComponent(); - await act(flushPromises); + await flushPromises(); const button = screen.getByRole("button", { name: device.displayName! }); expect(button).toBeInTheDocument(); @@ -851,7 +851,7 @@ describe("", () => { it("with display name", async () => { const { container } = renderComponent(); - await act(flushPromises); + await flushPromises(); expect(container).toMatchSnapshot(); }); @@ -859,7 +859,7 @@ describe("", () => { it("without display name", async () => { const device = { deviceId: "deviceId" } as Device; const { container } = renderComponent({ device, userId: defaultUserId }); - await act(flushPromises); + await flushPromises(); expect(container).toMatchSnapshot(); }); @@ -867,7 +867,7 @@ describe("", () => { it("ambiguous display name", async () => { const device = { deviceId: "deviceId", ambiguous: true, displayName: "my display name" }; const { container } = renderComponent({ device, userId: defaultUserId }); - await act(flushPromises); + await flushPromises(); expect(container).toMatchSnapshot(); }); diff --git a/test/unit-tests/components/views/rooms/EventTile-test.tsx b/test/unit-tests/components/views/rooms/EventTile-test.tsx index 7554c83ef0..c9280a5287 100644 --- a/test/unit-tests/components/views/rooms/EventTile-test.tsx +++ b/test/unit-tests/components/views/rooms/EventTile-test.tsx @@ -254,7 +254,7 @@ describe("EventTile", () => { } as EventEncryptionInfo); const { container } = getComponent(); - await act(flushPromises); + await flushPromises(); const eventTiles = container.getElementsByClassName("mx_EventTile"); expect(eventTiles).toHaveLength(1); @@ -279,7 +279,7 @@ describe("EventTile", () => { } as EventEncryptionInfo); const { container } = getComponent(); - await act(flushPromises); + await flushPromises(); const eventTiles = container.getElementsByClassName("mx_EventTile"); expect(eventTiles).toHaveLength(1); @@ -308,7 +308,7 @@ describe("EventTile", () => { } as EventEncryptionInfo); const { container } = getComponent(); - await act(flushPromises); + await flushPromises(); const e2eIcons = container.getElementsByClassName("mx_EventTile_e2eIcon"); expect(e2eIcons).toHaveLength(1); @@ -340,7 +340,7 @@ describe("EventTile", () => { await mxEvent.attemptDecryption(mockCrypto); const { container } = getComponent(); - await act(flushPromises); + await flushPromises(); const eventTiles = container.getElementsByClassName("mx_EventTile"); expect(eventTiles).toHaveLength(1); @@ -368,7 +368,7 @@ describe("EventTile", () => { const roomContext = getRoomContext(room, {}); const { container, rerender } = render(); - await act(flushPromises); + await flushPromises(); const eventTiles = container.getElementsByClassName("mx_EventTile"); expect(eventTiles).toHaveLength(1); @@ -419,7 +419,7 @@ describe("EventTile", () => { const roomContext = getRoomContext(room, {}); const { container, rerender } = render(); - await act(flushPromises); + await flushPromises(); const eventTiles = container.getElementsByClassName("mx_EventTile"); expect(eventTiles).toHaveLength(1); diff --git a/test/unit-tests/components/views/rooms/SendMessageComposer-test.tsx b/test/unit-tests/components/views/rooms/SendMessageComposer-test.tsx index a41c221616..0b3b69a7eb 100644 --- a/test/unit-tests/components/views/rooms/SendMessageComposer-test.tsx +++ b/test/unit-tests/components/views/rooms/SendMessageComposer-test.tsx @@ -389,7 +389,7 @@ describe("", () => { it("correctly persists state to and from localStorage", () => { const props = { replyToEvent: mockEvent }; - const { container, unmount, rerender } = getComponent(props); + let { container, unmount } = getComponent(props); addTextToComposer(container, "Test Text"); @@ -406,7 +406,7 @@ describe("", () => { }); // ensure the correct model is re-loaded - rerender(getRawComponent(props)); + ({ container, unmount } = getComponent(props)); expect(container.textContent).toBe("Test Text"); expect(spyDispatcher).toHaveBeenCalledWith({ action: "reply_to_event", @@ -417,7 +417,7 @@ describe("", () => { // now try with localStorage wiped out unmount(); localStorage.removeItem(key); - rerender(getRawComponent(props)); + ({ container } = getComponent(props)); expect(container.textContent).toBe(""); }); diff --git a/test/unit-tests/components/views/settings/AddRemoveThreepids-test.tsx b/test/unit-tests/components/views/settings/AddRemoveThreepids-test.tsx index 3b46d74435..aeec57546a 100644 --- a/test/unit-tests/components/views/settings/AddRemoveThreepids-test.tsx +++ b/test/unit-tests/components/views/settings/AddRemoveThreepids-test.tsx @@ -78,6 +78,7 @@ describe("AddRemoveThreepids", () => { />, ); + await expect(screen.findByText(EMAIL1.address)).resolves.toBeVisible(); expect(container).toMatchSnapshot(); }); @@ -92,6 +93,7 @@ describe("AddRemoveThreepids", () => { />, ); + await expect(screen.findByText(PHONE1.address)).resolves.toBeVisible(); expect(container).toMatchSnapshot(); }); @@ -106,6 +108,7 @@ describe("AddRemoveThreepids", () => { />, ); + await expect(screen.findByText("Email Address")).resolves.toBeVisible(); expect(container).toMatchSnapshot(); }); @@ -126,7 +129,7 @@ describe("AddRemoveThreepids", () => { }, ); - const input = screen.getByRole("textbox", { name: "Email Address" }); + const input = await screen.findByRole("textbox", { name: "Email Address" }); await userEvent.type(input, EMAIL1.address); const addButton = screen.getByRole("button", { name: "Add" }); await userEvent.click(addButton); @@ -165,7 +168,7 @@ describe("AddRemoveThreepids", () => { }, ); - const input = screen.getByRole("textbox", { name: "Email Address" }); + const input = await screen.findByRole("textbox", { name: "Email Address" }); await userEvent.type(input, EMAIL1.address); const addButton = screen.getByRole("button", { name: "Add" }); await userEvent.click(addButton); @@ -209,7 +212,7 @@ describe("AddRemoveThreepids", () => { }, ); - const countryDropdown = screen.getByRole("button", { name: /Country Dropdown/ }); + const countryDropdown = await screen.findByRole("button", { name: /Country Dropdown/ }); await userEvent.click(countryDropdown); const gbOption = screen.getByRole("option", { name: "🇬🇧 United Kingdom (+44)" }); await userEvent.click(gbOption); @@ -269,7 +272,7 @@ describe("AddRemoveThreepids", () => { }, ); - const removeButton = screen.getByRole("button", { name: /Remove/ }); + const removeButton = await screen.findByRole("button", { name: /Remove/ }); await userEvent.click(removeButton); expect(screen.getByText(`Remove ${EMAIL1.address}?`)).toBeVisible(); @@ -296,7 +299,7 @@ describe("AddRemoveThreepids", () => { }, ); - const removeButton = screen.getByRole("button", { name: /Remove/ }); + const removeButton = await screen.findByRole("button", { name: /Remove/ }); await userEvent.click(removeButton); expect(screen.getByText(`Remove ${EMAIL1.address}?`)).toBeVisible(); @@ -325,7 +328,7 @@ describe("AddRemoveThreepids", () => { }, ); - const removeButton = screen.getByRole("button", { name: /Remove/ }); + const removeButton = await screen.findByRole("button", { name: /Remove/ }); await userEvent.click(removeButton); expect(screen.getByText(`Remove ${PHONE1.address}?`)).toBeVisible(); @@ -356,7 +359,7 @@ describe("AddRemoveThreepids", () => { }, ); - expect(screen.getByText(EMAIL1.address)).toBeVisible(); + await expect(screen.findByText(EMAIL1.address)).resolves.toBeVisible(); const shareButton = screen.getByRole("button", { name: /Share/ }); await userEvent.click(shareButton); @@ -407,7 +410,7 @@ describe("AddRemoveThreepids", () => { }, ); - expect(screen.getByText(PHONE1.address)).toBeVisible(); + await expect(screen.findByText(PHONE1.address)).resolves.toBeVisible(); const shareButton = screen.getByRole("button", { name: /Share/ }); await userEvent.click(shareButton); @@ -451,7 +454,7 @@ describe("AddRemoveThreepids", () => { }, ); - expect(screen.getByText(EMAIL1.address)).toBeVisible(); + await expect(screen.findByText(EMAIL1.address)).resolves.toBeVisible(); const revokeButton = screen.getByRole("button", { name: /Revoke/ }); await userEvent.click(revokeButton); @@ -474,7 +477,7 @@ describe("AddRemoveThreepids", () => { }, ); - expect(screen.getByText(PHONE1.address)).toBeVisible(); + await expect(screen.findByText(PHONE1.address)).resolves.toBeVisible(); const revokeButton = screen.getByRole("button", { name: /Revoke/ }); await userEvent.click(revokeButton); diff --git a/test/unit-tests/components/views/settings/CrossSigningPanel-test.tsx b/test/unit-tests/components/views/settings/CrossSigningPanel-test.tsx index daa3570ed2..4cb610288c 100644 --- a/test/unit-tests/components/views/settings/CrossSigningPanel-test.tsx +++ b/test/unit-tests/components/views/settings/CrossSigningPanel-test.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { render, screen } from "jest-matrix-react"; +import { act, render, screen } from "jest-matrix-react"; import { Mocked, mocked } from "jest-mock"; import { MatrixClient } from "matrix-js-sdk/src/matrix"; diff --git a/test/unit-tests/components/views/settings/EventIndexPanel-test.tsx b/test/unit-tests/components/views/settings/EventIndexPanel-test.tsx index 9859cc27fa..ad48851c45 100644 --- a/test/unit-tests/components/views/settings/EventIndexPanel-test.tsx +++ b/test/unit-tests/components/views/settings/EventIndexPanel-test.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { fireEvent, render, screen, within } from "jest-matrix-react"; +import { act, fireEvent, render, screen, within } from "jest-matrix-react"; import { defer, IDeferred } from "matrix-js-sdk/src/utils"; import EventIndexPanel from "../../../../../src/components/views/settings/EventIndexPanel"; diff --git a/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx index 8f0915a830..3de1997f48 100644 --- a/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -990,7 +990,7 @@ describe("", () => { const { getByTestId, getByLabelText } = render(getComponent()); - await act(flushPromises); + await flushPromises(); // reset mock count after initial load mockClient.getDevices.mockClear(); @@ -1024,7 +1024,7 @@ describe("", () => { fireEvent.submit(getByLabelText("Password")); }); - await act(flushPromises); + await flushPromises(); // called again with auth expect(mockClient.deleteMultipleDevices).toHaveBeenCalledWith([alicesMobileDevice.device_id], { @@ -1550,7 +1550,7 @@ describe("", () => { }); const { getByTestId, container } = render(getComponent()); - await act(flushPromises); + await flushPromises(); // filter for inactive sessions await setFilter(container, DeviceSecurityVariation.Inactive); diff --git a/test/unit-tests/components/views/settings/tabs/user/__snapshots__/AccountUserSettingsTab-test.tsx.snap b/test/unit-tests/components/views/settings/tabs/user/__snapshots__/AccountUserSettingsTab-test.tsx.snap index 6c51cc41ab..5c6a8ac8ee 100644 --- a/test/unit-tests/components/views/settings/tabs/user/__snapshots__/AccountUserSettingsTab-test.tsx.snap +++ b/test/unit-tests/components/views/settings/tabs/user/__snapshots__/AccountUserSettingsTab-test.tsx.snap @@ -42,14 +42,14 @@ exports[` 3pids should display 3pid email addresses an > @@ -145,14 +145,14 @@ exports[` 3pids should display 3pid email addresses an diff --git a/test/unit-tests/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap b/test/unit-tests/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap index 2c868f92e6..bdbec2dc17 100644 --- a/test/unit-tests/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap +++ b/test/unit-tests/components/views/settings/tabs/user/__snapshots__/SessionManagerTab-test.tsx.snap @@ -370,7 +370,7 @@ exports[` goes to filtered list from security recommendatio > { }); }; - it("should render as expected", () => { + it("should render as expected", async () => { + await expect(screen.findByText("New login. Was this you?")).resolves.toBeInTheDocument(); expect(renderResult.baseElement).toMatchSnapshot(); }); diff --git a/test/unit-tests/utils/media/requestMediaPermissions-test.tsx b/test/unit-tests/utils/media/requestMediaPermissions-test.tsx index a968b51fab..0f357bb797 100644 --- a/test/unit-tests/utils/media/requestMediaPermissions-test.tsx +++ b/test/unit-tests/utils/media/requestMediaPermissions-test.tsx @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { mocked } from "jest-mock"; import { logger } from "matrix-js-sdk/src/logger"; -import { screen } from "jest-matrix-react"; +import { act, screen } from "jest-matrix-react"; import { requestMediaPermissions } from "../../../../src/utils/media/requestMediaPermissions"; import { flushPromises, useMockMediaDevices } from "../../../test-utils"; @@ -19,9 +19,9 @@ describe("requestMediaPermissions", () => { const audioStream = {} as MediaStream; const itShouldLogTheErrorAndShowTheNoMediaPermissionsModal = () => { - it("should log the error and show the »No media permissions« modal", () => { + it("should log the error and show the »No media permissions« modal", async () => { expect(logger.log).toHaveBeenCalledWith("Failed to list userMedia devices", error); - screen.getByText("No media permissions"); + await expect(screen.findByText("No media permissions")).resolves.toBeInTheDocument(); }); }; diff --git a/test/unit-tests/utils/pillify-test.tsx b/test/unit-tests/utils/pillify-test.tsx index f586eae0ff..3fc25a2192 100644 --- a/test/unit-tests/utils/pillify-test.tsx +++ b/test/unit-tests/utils/pillify-test.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { render } from "jest-matrix-react"; +import { act, render } from "jest-matrix-react"; import { MatrixEvent, ConditionKind, EventType, PushRuleActionName, Room, TweakName } from "matrix-js-sdk/src/matrix"; import { mocked } from "jest-mock"; @@ -94,7 +94,7 @@ describe("pillify", () => { it("should pillify @room", () => { const { container } = render(
@room
); const containers = new ReactRootManager(); - pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); + act(() => pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers)); expect(containers.elements).toHaveLength(1); expect(container.querySelector(".mx_Pill.mx_AtRoomPill")?.textContent).toBe("!@room"); }); @@ -103,20 +103,22 @@ describe("pillify", () => { mocked(MatrixClientPeg.safeGet().supportsIntentionalMentions).mockReturnValue(true); const { container } = render(
@room
); const containers = new ReactRootManager(); - pillifyLinks( - MatrixClientPeg.safeGet(), - [container], - new MatrixEvent({ - room_id: roomId, - type: EventType.RoomMessage, - content: { - "body": "@room", - "m.mentions": { - room: true, + act(() => + pillifyLinks( + MatrixClientPeg.safeGet(), + [container], + new MatrixEvent({ + room_id: roomId, + type: EventType.RoomMessage, + content: { + "body": "@room", + "m.mentions": { + room: true, + }, }, - }, - }), - containers, + }), + containers, + ), ); expect(containers.elements).toHaveLength(1); expect(container.querySelector(".mx_Pill.mx_AtRoomPill")?.textContent).toBe("!@room"); @@ -125,10 +127,12 @@ describe("pillify", () => { it("should not double up pillification on repeated calls", () => { const { container } = render(
@room
); const containers = new ReactRootManager(); - pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); - pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); - pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); - pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); + act(() => { + pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); + pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); + pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); + pillifyLinks(MatrixClientPeg.safeGet(), [container], event, containers); + }); expect(containers.elements).toHaveLength(1); expect(container.querySelector(".mx_Pill.mx_AtRoomPill")?.textContent).toBe("!@room"); });