Fix flaky jest tests (#12486)
...and remove the code that causes them to be retried in CI. Most of these were just lack of waiting for async things to happen, mostly lazy loading components, hence whythey worked on the retry: because the code had been loaded by then.
This commit is contained in:
parent
7193d4c695
commit
374cee9080
8 changed files with 36 additions and 27 deletions
|
@ -197,7 +197,9 @@ describe("ThreadView", () => {
|
||||||
it("sets the correct thread in the room view store", async () => {
|
it("sets the correct thread in the room view store", async () => {
|
||||||
// expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBeNull();
|
// expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBeNull();
|
||||||
const { unmount } = await getComponent();
|
const { unmount } = await getComponent();
|
||||||
|
waitFor(() => {
|
||||||
expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBe(rootEvent.getId());
|
expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBe(rootEvent.getId());
|
||||||
|
});
|
||||||
|
|
||||||
unmount();
|
unmount();
|
||||||
await waitFor(() => expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBeNull());
|
await waitFor(() => expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBeNull());
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { act, render, screen } from "@testing-library/react";
|
import { act, render, screen, waitFor } from "@testing-library/react";
|
||||||
import * as maplibregl from "maplibre-gl";
|
import * as maplibregl from "maplibre-gl";
|
||||||
import { Beacon, Room, RoomMember, MatrixEvent, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
|
import { Beacon, Room, RoomMember, MatrixEvent, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
|
@ -111,14 +111,16 @@ describe("<BeaconMarker />", () => {
|
||||||
expect(screen.queryByTestId("avatar-img")).not.toBeInTheDocument();
|
expect(screen.queryByTestId("avatar-img")).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders marker when beacon has location", () => {
|
it("renders marker when beacon has location", async () => {
|
||||||
const room = setupRoom([defaultEvent]);
|
const room = setupRoom([defaultEvent]);
|
||||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
|
||||||
beacon?.addLocations([location1]);
|
beacon?.addLocations([location1]);
|
||||||
const { asFragment } = renderComponent({ beacon });
|
const { asFragment } = renderComponent({ beacon });
|
||||||
expect(asFragment()).toMatchSnapshot();
|
await waitFor(() => {
|
||||||
expect(screen.getByTestId("avatar-img")).toBeInTheDocument();
|
expect(screen.getByTestId("avatar-img")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
it("updates with new locations", () => {
|
it("updates with new locations", () => {
|
||||||
const lonLat1 = { lon: 41, lat: 51 };
|
const lonLat1 = { lon: 41, lat: 51 };
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { act, fireEvent, render, RenderResult } from "@testing-library/react";
|
import { act, fireEvent, render, RenderResult, waitFor } from "@testing-library/react";
|
||||||
import { MatrixClient, MatrixEvent, Room, RoomMember, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
|
import { MatrixClient, MatrixEvent, Room, RoomMember, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
|
||||||
import * as maplibregl from "maplibre-gl";
|
import * as maplibregl from "maplibre-gl";
|
||||||
import { mocked } from "jest-mock";
|
import { mocked } from "jest-mock";
|
||||||
|
@ -92,7 +92,7 @@ describe("<BeaconViewDialog />", () => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a map with markers", () => {
|
it("renders a map with markers", async () => {
|
||||||
const room = setupRoom([defaultEvent]);
|
const room = setupRoom([defaultEvent]);
|
||||||
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
|
||||||
beacon.addLocations([location1]);
|
beacon.addLocations([location1]);
|
||||||
|
@ -103,8 +103,10 @@ describe("<BeaconViewDialog />", () => {
|
||||||
lat: 51,
|
lat: 51,
|
||||||
});
|
});
|
||||||
// marker added
|
// marker added
|
||||||
|
await waitFor(() => {
|
||||||
expect(mockMarker.addTo).toHaveBeenCalledWith(mockMap);
|
expect(mockMarker.addTo).toHaveBeenCalledWith(mockMap);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("does not render any own beacon status when user is not live sharing", () => {
|
it("does not render any own beacon status when user is not live sharing", () => {
|
||||||
// default event belongs to alice, we are bob
|
// default event belongs to alice, we are bob
|
||||||
|
|
|
@ -130,9 +130,9 @@ describe("ForwardDialog", () => {
|
||||||
expect(container.querySelectorAll(".mx_ForwardList_entry")).toHaveLength(3);
|
expect(container.querySelectorAll(".mx_ForwardList_entry")).toHaveLength(3);
|
||||||
|
|
||||||
const searchInput = getByTestId(container, "searchbox-input");
|
const searchInput = getByTestId(container, "searchbox-input");
|
||||||
act(() => userEvent.type(searchInput, "a"));
|
await userEvent.type(searchInput, "a");
|
||||||
|
|
||||||
expect(container.querySelectorAll(".mx_ForwardList_entry")).toHaveLength(3);
|
expect(container.querySelectorAll(".mx_ForwardList_entry")).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be navigable using arrow keys", async () => {
|
it("should be navigable using arrow keys", async () => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { ComponentProps } from "react";
|
import React, { ComponentProps } from "react";
|
||||||
import { fireEvent, render } from "@testing-library/react";
|
import { fireEvent, render, waitFor } from "@testing-library/react";
|
||||||
import { LocationAssetType, ClientEvent, RoomMember, SyncState } from "matrix-js-sdk/src/matrix";
|
import { LocationAssetType, ClientEvent, RoomMember, SyncState } from "matrix-js-sdk/src/matrix";
|
||||||
import * as maplibregl from "maplibre-gl";
|
import * as maplibregl from "maplibre-gl";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
@ -90,8 +90,13 @@ describe("MLocationBody", () => {
|
||||||
jest.spyOn(logger, "error").mockRestore();
|
jest.spyOn(logger, "error").mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("displays correct fallback content without error style when map_style_url is not configured", () => {
|
it("displays correct fallback content without error style when map_style_url is not configured", async () => {
|
||||||
const component = getComponent();
|
const component = getComponent();
|
||||||
|
|
||||||
|
// The map code needs to be lazy loaded so this will take some time to appear
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(component.container.querySelector(".mx_EventTile_body")).toBeInTheDocument(),
|
||||||
|
);
|
||||||
expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot();
|
expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { render, screen } from "@testing-library/react";
|
import { render, screen, waitFor } from "@testing-library/react";
|
||||||
|
|
||||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||||
import RoomContext from "../../../../src/contexts/RoomContext";
|
import RoomContext from "../../../../src/contexts/RoomContext";
|
||||||
|
@ -82,7 +82,7 @@ describe("MessageComposerButtons", () => {
|
||||||
expect(getButtonLabels()).toEqual(["Emoji", "Attachment", "More options"]);
|
expect(getButtonLabels()).toEqual(["Emoji", "Attachment", "More options"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Renders other buttons in menu in wide mode", () => {
|
it("Renders other buttons in menu in wide mode", async () => {
|
||||||
wrapAndRender(
|
wrapAndRender(
|
||||||
<MessageComposerButtons
|
<MessageComposerButtons
|
||||||
{...mockProps}
|
{...mockProps}
|
||||||
|
@ -94,6 +94,9 @@ describe("MessageComposerButtons", () => {
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// The location code is lazy loaded, so the button will take a little while
|
||||||
|
// to appear, so we need to wait.
|
||||||
|
await waitFor(() => {
|
||||||
expect(getButtonLabels()).toEqual([
|
expect(getButtonLabels()).toEqual([
|
||||||
"Emoji",
|
"Emoji",
|
||||||
"Attachment",
|
"Attachment",
|
||||||
|
@ -101,6 +104,7 @@ describe("MessageComposerButtons", () => {
|
||||||
["Sticker", "Voice Message", "Poll", "Location"],
|
["Sticker", "Voice Message", "Poll", "Location"],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("Renders only some buttons in narrow mode", () => {
|
it("Renders only some buttons in narrow mode", () => {
|
||||||
wrapAndRender(
|
wrapAndRender(
|
||||||
|
|
|
@ -30,7 +30,7 @@ import {
|
||||||
ThreepidMedium,
|
ThreepidMedium,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import { randomString } from "matrix-js-sdk/src/randomstring";
|
import { randomString } from "matrix-js-sdk/src/randomstring";
|
||||||
import { act, fireEvent, getByTestId, render, screen, within } from "@testing-library/react";
|
import { act, fireEvent, getByTestId, render, screen, waitFor, within } from "@testing-library/react";
|
||||||
import { mocked } from "jest-mock";
|
import { mocked } from "jest-mock";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent from "@testing-library/user-event";
|
||||||
|
|
||||||
|
@ -907,6 +907,7 @@ describe("<Notifications />", () => {
|
||||||
fireEvent.click(clearNotificationEl);
|
fireEvent.click(clearNotificationEl);
|
||||||
|
|
||||||
expect(clearNotificationEl.className).toContain("mx_AccessibleButton_disabled");
|
expect(clearNotificationEl.className).toContain("mx_AccessibleButton_disabled");
|
||||||
|
await waitFor(() => expect(clearNotificationEl.className).not.toContain("mx_AccessibleButton_disabled"));
|
||||||
expect(mockClient.sendReadReceipt).toHaveBeenCalled();
|
expect(mockClient.sendReadReceipt).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,13 +37,6 @@ beforeEach(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Retry to work around our flaky app & tests
|
|
||||||
if (process.env.CI) {
|
|
||||||
jest.retryTimes(2, {
|
|
||||||
logErrorsBeforeRetry: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Very carefully enable the mocks for everything else in
|
// Very carefully enable the mocks for everything else in
|
||||||
// a specific order. We use this order to ensure we properly
|
// a specific order. We use this order to ensure we properly
|
||||||
// establish an application state that actually works.
|
// establish an application state that actually works.
|
||||||
|
|
Loading…
Reference in a new issue