1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-08-07 21:23:00 +03:00
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2024-08-01 17:01:42 +01:00
parent 07670a75ce
commit 8d7f0aa3cc
17 changed files with 257 additions and 298 deletions

View File

@@ -16,7 +16,7 @@ limitations under the License.
import React from "react"; import React from "react";
import { mocked } from "jest-mock"; import { mocked } from "jest-mock";
import { act, render, RenderResult, screen, waitFor } from "@testing-library/react"; import { act, render, RenderResult, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { MatrixClient, createClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient, createClient } from "matrix-js-sdk/src/matrix";

View File

@@ -38,9 +38,7 @@ exports[`<DialogSidebar /> renders sidebar correctly with beacons 1`] = `
data-type="round" data-type="round"
role="presentation" role="presentation"
style="--cpd-avatar-size: 32px;" style="--cpd-avatar-size: 32px;"
> />
</span>
<div <div
class="mx_BeaconListItem_info" class="mx_BeaconListItem_info"
> >

View File

@@ -16,7 +16,7 @@ limitations under the License.
import React, { ComponentProps } from "react"; import React, { ComponentProps } from "react";
import { SecretStorage, MatrixClient } from "matrix-js-sdk/src/matrix"; import { SecretStorage, MatrixClient } from "matrix-js-sdk/src/matrix";
import { act, fireEvent, render, screen } from "@testing-library/react"; import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { Mocked } from "jest-mock"; import { Mocked } from "jest-mock";
@@ -129,11 +129,13 @@ describe("AccessSecretStorageDialog", () => {
expect(screen.getByPlaceholderText("Security Phrase")).toHaveValue(securityKey); expect(screen.getByPlaceholderText("Security Phrase")).toHaveValue(securityKey);
await submitDialog(); await submitDialog();
await waitFor(() =>
expect( expect(
screen.getByText( screen.getByText(
"👎 Unable to access secret storage. Please verify that you entered the correct Security Phrase.", "👎 Unable to access secret storage. Please verify that you entered the correct Security Phrase.",
), ),
).toBeInTheDocument(); ).toBeInTheDocument(),
);
expect(screen.getByPlaceholderText("Security Phrase")).toHaveFocus(); expect(screen.getByPlaceholderText("Security Phrase")).toHaveFocus();
}); });

View File

@@ -27,7 +27,7 @@ import {
} from "matrix-js-sdk/src/matrix"; } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types"; import { KnownMembership } from "matrix-js-sdk/src/types";
import sanitizeHtml from "sanitize-html"; import sanitizeHtml from "sanitize-html";
import { fireEvent, render, screen } from "@testing-library/react"; import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import SpotlightDialog from "../../../../src/components/views/dialogs/spotlight/SpotlightDialog"; import SpotlightDialog from "../../../../src/components/views/dialogs/spotlight/SpotlightDialog";
import { Filter } from "../../../../src/components/views/dialogs/spotlight/Filter"; import { Filter } from "../../../../src/components/views/dialogs/spotlight/Filter";
@@ -201,11 +201,13 @@ describe("Spotlight Dialog", () => {
expect(filterChip).toBeInTheDocument(); expect(filterChip).toBeInTheDocument();
expect(filterChip.innerHTML).toContain("Public rooms"); expect(filterChip.innerHTML).toContain("Public rooms");
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBe(1); expect(options.length).toBe(1);
expect(options[0].innerHTML).toContain(testPublicRoom.name); expect(options[0].innerHTML).toContain(testPublicRoom.name);
}); });
});
it("with people filter", async () => { it("with people filter", async () => {
render( render(
@@ -223,12 +225,14 @@ describe("Spotlight Dialog", () => {
expect(filterChip).toBeInTheDocument(); expect(filterChip).toBeInTheDocument();
expect(filterChip.innerHTML).toContain("People"); expect(filterChip.innerHTML).toContain("People");
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(1); expect(options.length).toBeGreaterThanOrEqual(1);
expect(options[0]!.innerHTML).toContain(testPerson.display_name); expect(options[0]!.innerHTML).toContain(testPerson.display_name);
}); });
}); });
});
describe("when MSC3946 dynamic room predecessors is enabled", () => { describe("when MSC3946 dynamic room predecessors is enabled", () => {
beforeEach(() => { beforeEach(() => {
@@ -269,10 +273,12 @@ describe("Spotlight Dialog", () => {
expect(filterChip).toBeInTheDocument(); expect(filterChip).toBeInTheDocument();
expect(filterChip.innerHTML).toContain("Public rooms"); expect(filterChip.innerHTML).toContain("Public rooms");
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBe(1); expect(options.length).toBe(1);
expect(options[0]!.innerHTML).toContain(testPublicRoom.name); expect(options[0]!.innerHTML).toContain(testPublicRoom.name);
});
// assert that getVisibleRooms is called without MSC3946 dynamic room predecessors // assert that getVisibleRooms is called without MSC3946 dynamic room predecessors
expect(mockedClient.getVisibleRooms).toHaveBeenCalledWith(false); expect(mockedClient.getVisibleRooms).toHaveBeenCalledWith(false);
@@ -292,12 +298,14 @@ describe("Spotlight Dialog", () => {
expect(filterChip).toBeInTheDocument(); expect(filterChip).toBeInTheDocument();
expect(filterChip.innerHTML).toContain("People"); expect(filterChip.innerHTML).toContain("People");
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(1); expect(options.length).toBeGreaterThanOrEqual(1);
expect(options[0]!.innerHTML).toContain(testPerson.display_name); expect(options[0]!.innerHTML).toContain(testPerson.display_name);
}); });
}); });
});
describe("should allow clearing filter manually", () => { describe("should allow clearing filter manually", () => {
it("with public room filter", async () => { it("with public room filter", async () => {
@@ -380,12 +388,14 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(2); expect(options.length).toBeGreaterThanOrEqual(2);
expect(options[0]).toHaveTextContent("User Alpha"); expect(options[0]).toHaveTextContent("User Alpha");
expect(options[1]).toHaveTextContent("User Beta"); expect(options[1]).toHaveTextContent("User Beta");
}); });
});
it("should not filter out users sent by the server even if a local suggestion gets filtered out", async () => { it("should not filter out users sent by the server even if a local suggestion gets filtered out", async () => {
const member = new RoomMember(testRoom.roomId, testPerson.user_id); const member = new RoomMember(testRoom.roomId, testPerson.user_id);
@@ -405,12 +415,14 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(2); expect(options.length).toBeGreaterThanOrEqual(2);
expect(options[0]).toHaveTextContent(testPerson.display_name!); expect(options[0]).toHaveTextContent(testPerson.display_name!);
expect(options[1]).toHaveTextContent("User Beta"); expect(options[1]).toHaveTextContent("User Beta");
}); });
});
it("show non-matching query members with DMs if they are present in the server search results", async () => { it("show non-matching query members with DMs if they are present in the server search results", async () => {
mocked(mockedClient.searchUserDirectory).mockResolvedValue({ mocked(mockedClient.searchUserDirectory).mockResolvedValue({
@@ -427,12 +439,14 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(2); expect(options.length).toBeGreaterThanOrEqual(2);
expect(options[0]).toHaveTextContent(testDMUserId); expect(options[0]).toHaveTextContent(testDMUserId);
expect(options[1]).toHaveTextContent("Bob Wonder"); expect(options[1]).toHaveTextContent("Bob Wonder");
}); });
});
it("don't sort the order of users sent by the server", async () => { it("don't sort the order of users sent by the server", async () => {
const serverList = [ const serverList = [
@@ -449,12 +463,14 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(2); expect(options.length).toBeGreaterThanOrEqual(2);
expect(options[0]).toHaveTextContent("User Beta"); expect(options[0]).toHaveTextContent("User Beta");
expect(options[1]).toHaveTextContent("User Alpha"); expect(options[1]).toHaveTextContent("User Alpha");
}); });
});
it("should start a DM when clicking a person", async () => { it("should start a DM when clicking a person", async () => {
render( render(
@@ -468,13 +484,14 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
const options = document.querySelectorAll("li.mx_SpotlightDialog_option"); const options = document.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBeGreaterThanOrEqual(1); expect(options.length).toBeGreaterThanOrEqual(1);
expect(options[0]!.innerHTML).toContain(testPerson.display_name); expect(options[0]!.innerHTML).toContain(testPerson.display_name);
fireEvent.click(options[0]!); fireEvent.click(options[0]!);
expect(startDmOnFirstMessage).toHaveBeenCalledWith(mockedClient, [new DirectoryMember(testPerson)]); expect(startDmOnFirstMessage).toHaveBeenCalledWith(mockedClient, [new DirectoryMember(testPerson)]);
}); });
});
it("should pass via of the server being explored when joining room from directory", async () => { it("should pass via of the server being explored when joining room from directory", async () => {
SdkConfig.put({ SdkConfig.put({
@@ -489,6 +506,7 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
const content = document.querySelector("#mx_SpotlightDialog_content")!; const content = document.querySelector("#mx_SpotlightDialog_content")!;
const options = content.querySelectorAll("li.mx_SpotlightDialog_option"); const options = content.querySelectorAll("li.mx_SpotlightDialog_option");
expect(options.length).toBe(1); expect(options.length).toBe(1);
@@ -504,6 +522,7 @@ describe("Spotlight Dialog", () => {
}), }),
); );
}); });
});
describe("nsfw public rooms filter", () => { describe("nsfw public rooms filter", () => {
const nsfwNameRoom: IPublicRoomsChunkRoom = { const nsfwNameRoom: IPublicRoomsChunkRoom = {
@@ -549,10 +568,12 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument(); expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
expect(screen.queryByText(nsfwTopicRoom.name!)).not.toBeInTheDocument(); expect(screen.queryByText(nsfwTopicRoom.name!)).not.toBeInTheDocument();
expect(screen.queryByText(nsfwTopicRoom.name!)).not.toBeInTheDocument(); expect(screen.queryByText(nsfwTopicRoom.name!)).not.toBeInTheDocument();
}); });
});
it("displays rooms with nsfw keywords in results when showNsfwPublicRooms is truthy", async () => { it("displays rooms with nsfw keywords in results when showNsfwPublicRooms is truthy", async () => {
SettingsStore.setValue("SpotlightSearch.showNsfwPublicRooms", null, SettingLevel.DEVICE, true); SettingsStore.setValue("SpotlightSearch.showNsfwPublicRooms", null, SettingLevel.DEVICE, true);
@@ -562,11 +583,13 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
await waitFor(() => {
expect(screen.getByText(nsfwTopicRoom.name!)).toBeInTheDocument(); expect(screen.getByText(nsfwTopicRoom.name!)).toBeInTheDocument();
expect(screen.getByText(nsfwNameRoom.name!)).toBeInTheDocument(); expect(screen.getByText(nsfwNameRoom.name!)).toBeInTheDocument();
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument(); expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
}); });
}); });
});
it("should show error if /publicRooms API failed", async () => { it("should show error if /publicRooms API failed", async () => {
mocked(mockedClient.publicRooms).mockRejectedValue(new ConnectionError("Failed to fetch")); mocked(mockedClient.publicRooms).mockRejectedValue(new ConnectionError("Failed to fetch"));
@@ -575,7 +598,7 @@ describe("Spotlight Dialog", () => {
jest.advanceTimersByTime(200); jest.advanceTimersByTime(200);
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
expect(screen.getByText("Failed to query public rooms")).toBeInTheDocument(); await waitFor(() => expect(screen.getByText("Failed to query public rooms")).toBeInTheDocument());
}); });
describe("knock rooms", () => { describe("knock rooms", () => {

View File

@@ -57,14 +57,9 @@ jest.mock("../../../../src/settings/SettingsStore", () => ({
settingIsOveriddenAtConfigLevel: jest.fn(), settingIsOveriddenAtConfigLevel: jest.fn(),
})); }));
jest.mock("../../../../src/SdkConfig", () => ({
get: jest.fn(),
}));
describe("<UserSettingsDialog />", () => { describe("<UserSettingsDialog />", () => {
const userId = "@alice:server.org"; const userId = "@alice:server.org";
const mockSettingsStore = mocked(SettingsStore); const mockSettingsStore = mocked(SettingsStore);
const mockSdkConfig = mocked(SdkConfig);
let mockClient!: MockedObject<MatrixClient>; let mockClient!: MockedObject<MatrixClient>;
let sdkContext: SdkContextClass; let sdkContext: SdkContextClass;
@@ -89,7 +84,8 @@ describe("<UserSettingsDialog />", () => {
mockSettingsStore.getValue.mockReturnValue(false); mockSettingsStore.getValue.mockReturnValue(false);
mockSettingsStore.getValueAt.mockReturnValue(false); mockSettingsStore.getValueAt.mockReturnValue(false);
mockSettingsStore.getFeatureSettingNames.mockReturnValue([]); mockSettingsStore.getFeatureSettingNames.mockReturnValue([]);
mockSdkConfig.get.mockReturnValue({ brand: "Test" }); SdkConfig.reset();
SdkConfig.put({ brand: "Test" });
}); });
const getActiveTabLabel = (container: Element) => const getActiveTabLabel = (container: Element) =>
@@ -115,6 +111,9 @@ describe("<UserSettingsDialog />", () => {
}); });
it("renders tabs correctly", () => { it("renders tabs correctly", () => {
SdkConfig.add({
show_labs_settings: true,
});
const { container } = render(getComponent()); const { container } = render(getComponent());
expect(container.querySelectorAll(".mx_TabbedView_tabLabel")).toMatchSnapshot(); expect(container.querySelectorAll(".mx_TabbedView_tabLabel")).toMatchSnapshot();
}); });
@@ -181,7 +180,7 @@ describe("<UserSettingsDialog />", () => {
expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent("Settings: Voice & Video"); expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent("Settings: Voice & Video");
}); });
it("renders with secutity tab selected", () => { it("renders with security tab selected", () => {
const { container } = render(getComponent({ initialTabId: UserTab.Security })); const { container } = render(getComponent({ initialTabId: UserTab.Security }));
expect(getActiveTabLabel(container)).toEqual("Security & Privacy"); expect(getActiveTabLabel(container)).toEqual("Security & Privacy");
@@ -189,18 +188,8 @@ describe("<UserSettingsDialog />", () => {
}); });
it("renders with labs tab selected", () => { it("renders with labs tab selected", () => {
// @ts-ignore I give up trying to get the types right here SdkConfig.add({
// why do we have functions that return different things depending on what they're passed? show_labs_settings: true,
mockSdkConfig.get.mockImplementation((x) => {
const mockConfig = { show_labs_settings: true, brand: "Test" };
switch (x) {
case "show_labs_settings":
case "brand":
// @ts-ignore
return mockConfig[x];
default:
return mockConfig;
}
}); });
const { container } = render(getComponent({ initialTabId: UserTab.Labs })); const { container } = render(getComponent({ initialTabId: UserTab.Labs }));
@@ -223,8 +212,9 @@ describe("<UserSettingsDialog />", () => {
}); });
it("renders labs tab when show_labs_settings is enabled in config", () => { it("renders labs tab when show_labs_settings is enabled in config", () => {
// @ts-ignore simplified test stub SdkConfig.add({
mockSdkConfig.get.mockImplementation((configName) => configName === "show_labs_settings"); show_labs_settings: true,
});
const { getByTestId } = render(getComponent()); const { getByTestId } = render(getComponent());
expect(getByTestId(`settings-tab-${UserTab.Labs}`)).toBeTruthy(); expect(getByTestId(`settings-tab-${UserTab.Labs}`)).toBeTruthy();
}); });

View File

@@ -211,7 +211,7 @@ describe("<MImageBody/>", () => {
it("should generate a thumbnail if one isn't included for animated media", async () => { it("should generate a thumbnail if one isn't included for animated media", async () => {
Object.defineProperty(global.Image.prototype, "src", { Object.defineProperty(global.Image.prototype, "src", {
set(src) { set(src) {
window.setTimeout(() => this.onload()); window.setTimeout(() => this.onload?.());
}, },
}); });
Object.defineProperty(global.Image.prototype, "height", { Object.defineProperty(global.Image.prototype, "height", {

View File

@@ -375,6 +375,7 @@ describe("RoomHeader", () => {
jest.spyOn(CallStore.instance, "getCall").mockReturnValue({ jest.spyOn(CallStore.instance, "getCall").mockReturnValue({
widget, widget,
on: () => {}, on: () => {},
off: () => {},
} as unknown as Call); } as unknown as Call);
jest.spyOn(WidgetStore.instance, "getApps").mockReturnValue([widget]); jest.spyOn(WidgetStore.instance, "getApps").mockReturnValue([widget]);
const { container } = render(<RoomHeader room={room} />, getWrapper()); const { container } = render(<RoomHeader room={room} />, getWrapper());
@@ -393,6 +394,7 @@ describe("RoomHeader", () => {
jest.spyOn(CallStore.instance, "getCall").mockReturnValue({ jest.spyOn(CallStore.instance, "getCall").mockReturnValue({
widget, widget,
on: () => {}, on: () => {},
off: () => {},
} as unknown as Call); } as unknown as Call);
jest.spyOn(WidgetStore.instance, "getApps").mockReturnValue([widget]); jest.spyOn(WidgetStore.instance, "getApps").mockReturnValue([widget]);

View File

@@ -17,7 +17,7 @@ limitations under the License.
import React from "react"; import React from "react";
import { MockedObject } from "jest-mock"; import { MockedObject } from "jest-mock";
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import { fireEvent, render, screen } from "@testing-library/react"; import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { VideoRoomChatButton } from "../../../../../src/components/views/rooms/RoomHeader/VideoRoomChatButton"; import { VideoRoomChatButton } from "../../../../../src/components/views/rooms/RoomHeader/VideoRoomChatButton";
import { SDKContext, SdkContextClass } from "../../../../../src/contexts/SDKContext"; import { SDKContext, SdkContextClass } from "../../../../../src/contexts/SDKContext";
@@ -94,7 +94,7 @@ describe("<VideoRoomChatButton />", () => {
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeTruthy(); expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeTruthy();
}); });
it("adds unread marker when room notification state changes to unread", () => { it("adds unread marker when room notification state changes to unread", async () => {
const room = makeRoom(); const room = makeRoom();
// start in read state // start in read state
const notificationState = mockRoomNotificationState(room, NotificationLevel.None); const notificationState = mockRoomNotificationState(room, NotificationLevel.None);
@@ -108,10 +108,10 @@ describe("<VideoRoomChatButton />", () => {
notificationState.emit(NotificationStateEvents.Update); notificationState.emit(NotificationStateEvents.Update);
// unread marker // unread marker
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeTruthy(); await waitFor(() => expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeTruthy());
}); });
it("clears unread marker when room notification state changes to read", () => { it("clears unread marker when room notification state changes to read", async () => {
const room = makeRoom(); const room = makeRoom();
// start in unread state // start in unread state
const notificationState = mockRoomNotificationState(room, NotificationLevel.Highlight); const notificationState = mockRoomNotificationState(room, NotificationLevel.Highlight);
@@ -125,6 +125,6 @@ describe("<VideoRoomChatButton />", () => {
notificationState.emit(NotificationStateEvents.Update); notificationState.emit(NotificationStateEvents.Update);
// unread marker cleared // unread marker cleared
expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeFalsy(); await waitFor(() => expect(screen.getByLabelText("Chat").hasAttribute("data-indicator")).toBeFalsy());
}); });
}); });

View File

@@ -30,7 +30,16 @@ 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, waitFor, within } from "@testing-library/react"; import {
act,
fireEvent,
getByTestId,
render,
screen,
waitFor,
waitForElementToBeRemoved,
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";
@@ -244,7 +253,7 @@ describe("<Notifications />", () => {
// get component, wait for async data and force a render // get component, wait for async data and force a render
const getComponentAndWait = async () => { const getComponentAndWait = async () => {
const component = getComponent(); const component = getComponent();
await flushPromises(); await waitForElementToBeRemoved(() => component.queryAllByRole("progressbar"));
return component; return component;
}; };

View File

@@ -39,7 +39,6 @@ exports[`<SecureBackupPanel /> handles error fetching backup 1`] = `
</th> </th>
<td> <td>
not found locally not found locally
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -75,20 +74,15 @@ exports[`<SecureBackupPanel /> suggests connecting session to key backup when ba
Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key. Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.
</div> </div>
<div <div
class="mx_SettingsSubsection_text" class="mx_Spinner"
> >
<span>
This session is
<b>
not backing up your keys
</b>
, but you do have an existing backup you can restore from and add to going forward.
</span>
</div>
<div <div
class="mx_SettingsSubsection_text" aria-label="Loading…"
> class="mx_Spinner_icon"
Connect this session to key backup before signing out to avoid losing any keys that may only be on this session. data-testid="spinner"
role="progressbar"
style="width: 32px; height: 32px;"
/>
</div> </div>
<details> <details>
<summary <summary
@@ -117,7 +111,6 @@ exports[`<SecureBackupPanel /> suggests connecting session to key backup when ba
</th> </th>
<td> <td>
not found locally not found locally
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -140,54 +133,7 @@ exports[`<SecureBackupPanel /> suggests connecting session to key backup when ba
not ready not ready
</td> </td>
</tr> </tr>
<tr>
<th
scope="row"
>
Latest backup version on server:
</th>
<td>
1
(
Algorithm:
<code>
test
</code>
)
</td>
</tr>
<tr>
<th
scope="row"
>
Active backup version:
</th>
<td>
None
</td>
</tr>
</table> </table>
<div />
</details> </details>
<div
class="mx_SecureBackupPanel_buttonRow"
>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline"
role="button"
tabindex="0"
>
Connect this session to Key Backup
</div>
<div
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger_outline"
role="button"
tabindex="0"
>
Delete Backup
</div>
</div>
</div> </div>
`; `;

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/ */
import React from "react"; import React from "react";
import { fireEvent, render, RenderResult } from "@testing-library/react"; import { fireEvent, render, RenderResult, waitFor } from "@testing-library/react";
import { DeviceDetailHeading } from "../../../../../src/components/views/settings/devices/DeviceDetailHeading"; import { DeviceDetailHeading } from "../../../../../src/components/views/settings/devices/DeviceDetailHeading";
import { flushPromisesWithFakeTimers } from "../../../../test-utils"; import { flushPromisesWithFakeTimers } from "../../../../test-utils";
@@ -118,7 +118,7 @@ describe("<DeviceDetailHeading />", () => {
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
// read mode displayed // read mode displayed
expect(getByTestId("device-detail-heading")).toBeTruthy(); await waitFor(() => expect(getByTestId("device-detail-heading")).toBeTruthy());
}); });
it("displays error when device name fails to save", async () => { it("displays error when device name fails to save", async () => {
@@ -136,7 +136,7 @@ describe("<DeviceDetailHeading />", () => {
await flushPromisesWithFakeTimers(); await flushPromisesWithFakeTimers();
// error message displayed // error message displayed
expect(queryByText("Failed to set session name")).toBeTruthy(); await waitFor(() => expect(queryByText("Failed to set session name")).toBeTruthy());
// spinner removed // spinner removed
expect(container.getElementsByClassName("mx_Spinner").length).toBeFalsy(); expect(container.getElementsByClassName("mx_Spinner").length).toBeFalsy();

View File

@@ -120,8 +120,7 @@ describe("<FilteredDeviceList />", () => {
}); });
describe("filtering", () => { describe("filtering", () => {
const setFilter = async (container: HTMLElement, option: DeviceSecurityVariation | string) => const setFilter = async (container: HTMLElement, option: DeviceSecurityVariation | string) => {
await act(async () => {
const dropdown = container.querySelector('[aria-label="Filter devices"]'); const dropdown = container.querySelector('[aria-label="Filter devices"]');
fireEvent.click(dropdown as Element); fireEvent.click(dropdown as Element);
@@ -129,7 +128,7 @@ describe("<FilteredDeviceList />", () => {
await flushPromises(); await flushPromises();
fireEvent.click(container.querySelector(`#device-list-filter__${option}`) as Element); fireEvent.click(container.querySelector(`#device-list-filter__${option}`) as Element);
}); };
it("does not display filter description when filter is falsy", () => { it("does not display filter description when filter is falsy", () => {
const { container } = render(getComponent({ filter: undefined })); const { container } = render(getComponent({ filter: undefined }));

View File

@@ -42,14 +42,14 @@ exports[`<GeneralUserSettingsTab /> 3pids should display 3pid email addresses an
> >
<input <input
autocomplete="email" autocomplete="email"
id="mx_Field_27" id="mx_Field_9"
label="Email Address" label="Email Address"
placeholder="Email Address" placeholder="Email Address"
type="text" type="text"
value="" value=""
/> />
<label <label
for="mx_Field_27" for="mx_Field_9"
> >
Email Address Email Address
</label> </label>
@@ -150,14 +150,14 @@ exports[`<GeneralUserSettingsTab /> 3pids should display 3pid email addresses an
</span> </span>
<input <input
autocomplete="tel-national" autocomplete="tel-national"
id="mx_Field_28" id="mx_Field_10"
label="Phone Number" label="Phone Number"
placeholder="Phone Number" placeholder="Phone Number"
type="text" type="text"
value="" value=""
/> />
<label <label
for="mx_Field_28" for="mx_Field_10"
> >
Phone Number Phone Number
</label> </label>

View File

@@ -2,7 +2,7 @@
exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] = ` exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] = `
<div <div
aria-labelledby="radix-16" aria-labelledby="radix-:r2f:"
aria-orientation="vertical" aria-orientation="vertical"
class="_menu_1x5h1_17" class="_menu_1x5h1_17"
data-align="start" data-align="start"
@@ -11,14 +11,14 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
data-side="top" data-side="top"
data-state="open" data-state="open"
dir="ltr" dir="ltr"
id="radix-17" id="radix-:r2g:"
role="menu" role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;" style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1" tabindex="-1"
> >
<h3 <h3
class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83" class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83"
id=":r6:" id=":r2l:"
> >
Threads activity Threads activity
</h3> </h3>
@@ -145,14 +145,14 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
class="mx_ThreadsActivityCentre_container" class="mx_ThreadsActivityCentre_container"
> >
<button <button
aria-controls="radix-3" aria-controls="radix-:r15:"
aria-disabled="false" aria-disabled="false"
aria-expanded="true" aria-expanded="true"
aria-haspopup="menu" aria-haspopup="menu"
aria-label="Threads" aria-label="Threads"
class="_icon-button_bh2qc_17 mx_ThreadsActivityCentreButton" class="_icon-button_bh2qc_17 mx_ThreadsActivityCentreButton"
data-state="open" data-state="open"
id="radix-2" id="radix-:r14:"
role="button" role="button"
style="--cpd-icon-button-size: 32px;" style="--cpd-icon-button-size: 32px;"
tabindex="0" tabindex="0"
@@ -175,7 +175,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
style="position: fixed; left: 0px; top: 0px; transform: translate(0px, -8px); min-width: max-content; --radix-popper-available-width: 0px; --radix-popper-available-height: -8px; --radix-popper-anchor-width: 0px; --radix-popper-anchor-height: 0px; --radix-popper-transform-origin: 0% 0px;" style="position: fixed; left: 0px; top: 0px; transform: translate(0px, -8px); min-width: max-content; --radix-popper-available-width: 0px; --radix-popper-available-height: -8px; --radix-popper-anchor-width: 0px; --radix-popper-anchor-height: 0px; --radix-popper-transform-origin: 0% 0px;"
> >
<div <div
aria-labelledby="radix-2" aria-labelledby="radix-:r14:"
aria-orientation="vertical" aria-orientation="vertical"
class="_menu_1x5h1_17" class="_menu_1x5h1_17"
data-align="start" data-align="start"
@@ -184,14 +184,14 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
data-side="top" data-side="top"
data-state="open" data-state="open"
dir="ltr" dir="ltr"
id="radix-3" id="radix-:r15:"
role="menu" role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;" style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1" tabindex="-1"
> >
<h3 <h3
class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83" class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83"
id=":r1:" id=":r1a:"
> >
Threads activity Threads activity
</h3> </h3>
@@ -218,7 +218,7 @@ exports[`ThreadsActivityCentre should close the release announcement when the TA
exports[`ThreadsActivityCentre should match snapshot when empty 1`] = ` exports[`ThreadsActivityCentre should match snapshot when empty 1`] = `
<div <div
aria-labelledby="radix-22" aria-labelledby="radix-:r2v:"
aria-orientation="vertical" aria-orientation="vertical"
class="_menu_1x5h1_17" class="_menu_1x5h1_17"
data-align="start" data-align="start"
@@ -227,14 +227,14 @@ exports[`ThreadsActivityCentre should match snapshot when empty 1`] = `
data-side="top" data-side="top"
data-state="open" data-state="open"
dir="ltr" dir="ltr"
id="radix-23" id="radix-:r30:"
role="menu" role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;" style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1" tabindex="-1"
> >
<h3 <h3
class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83" class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83"
id=":r8:" id=":r35:"
> >
Threads activity Threads activity
</h3> </h3>
@@ -252,7 +252,7 @@ exports[`ThreadsActivityCentre should match snapshot when empty 1`] = `
exports[`ThreadsActivityCentre should order the room with the same notification level by most recent 1`] = ` exports[`ThreadsActivityCentre should order the room with the same notification level by most recent 1`] = `
<div <div
aria-labelledby="radix-24" aria-labelledby="radix-:r36:"
aria-orientation="vertical" aria-orientation="vertical"
class="_menu_1x5h1_17" class="_menu_1x5h1_17"
data-align="start" data-align="start"
@@ -261,14 +261,14 @@ exports[`ThreadsActivityCentre should order the room with the same notification
data-side="top" data-side="top"
data-state="open" data-state="open"
dir="ltr" dir="ltr"
id="radix-25" id="radix-:r37:"
role="menu" role="menu"
style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;" style="outline: none; --radix-dropdown-menu-content-transform-origin: var(--radix-popper-transform-origin); --radix-dropdown-menu-content-available-width: var(--radix-popper-available-width); --radix-dropdown-menu-content-available-height: var(--radix-popper-available-height); --radix-dropdown-menu-trigger-width: var(--radix-popper-anchor-width); --radix-dropdown-menu-trigger-height: var(--radix-popper-anchor-height); pointer-events: auto;"
tabindex="-1" tabindex="-1"
> >
<h3 <h3
class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83" class="_typography_yh5dq_162 _font-body-sm-semibold_yh5dq_45 _title_1x5h1_83"
id=":r9:" id=":r3c:"
> >
Threads activity Threads activity
</h3> </h3>
@@ -432,8 +432,8 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
class="mx_ThreadsActivityCentre_container" class="mx_ThreadsActivityCentre_container"
> >
<button <button
aria-controls=":r6:" aria-controls=":r8:"
aria-describedby=":r6:" aria-describedby=":r8:"
aria-expanded="true" aria-expanded="true"
aria-haspopup="dialog" aria-haspopup="dialog"
aria-label="Threads" aria-label="Threads"
@@ -459,7 +459,7 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
tabindex="0" tabindex="0"
/> />
<span <span
aria-owns=":r12:" aria-owns=":re:"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;" style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: fixed; white-space: nowrap; width: 1px; top: 0px; left: 0px;"
/> />
<span <span
@@ -473,7 +473,7 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
</div> </div>
<div <div
data-floating-ui-portal="" data-floating-ui-portal=""
id=":r12:" id=":re:"
> >
<span <span
data-floating-ui-focus-guard="" data-floating-ui-focus-guard=""
@@ -484,10 +484,10 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
tabindex="0" tabindex="0"
/> />
<div <div
aria-describedby=":r5:" aria-describedby=":r7:"
aria-labelledby=":r4:" aria-labelledby=":r6:"
class="_content_1oa1y_17" class="_content_1oa1y_17"
id=":r6:" id=":r8:"
role="dialog" role="dialog"
style="position: absolute; left: 0px; top: 0px; transform: translate(0px, 0px);" style="position: absolute; left: 0px; top: 0px; transform: translate(0px, 0px);"
tabindex="-1" tabindex="-1"
@@ -505,7 +505,7 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
stroke="none" stroke="none"
/> />
<clippath <clippath
id=":r13:" id=":rf:"
> >
<rect <rect
height="20" height="20"
@@ -517,13 +517,13 @@ exports[`ThreadsActivityCentre should render the release announcement 1`] = `
</svg> </svg>
<h3 <h3
class="_typography_yh5dq_162 _font-body-lg-semibold_yh5dq_83 _header_1oa1y_46" class="_typography_yh5dq_162 _font-body-lg-semibold_yh5dq_83 _header_1oa1y_46"
id=":r4:" id=":r6:"
> >
Threads Activity Centre Threads Activity Centre
</h3> </h3>
<span <span
class="_typography_yh5dq_162 _font-body-sm-regular_yh5dq_40 _description_1oa1y_52" class="_typography_yh5dq_162 _font-body-sm-regular_yh5dq_40 _description_1oa1y_52"
id=":r5:" id=":r7:"
> >
Threads notifications have moved, find them here from now on. Threads notifications have moved, find them here from now on.
</span> </span>

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { act, renderHook, waitFor } from "@testing-library/react"; import { renderHook, waitFor } from "@testing-library/react";
import { IPushRules, MatrixClient, PushRuleKind, RuleId } from "matrix-js-sdk/src/matrix"; import { IPushRules, MatrixClient, PushRuleKind, RuleId } from "matrix-js-sdk/src/matrix";
import { useNotificationSettings } from "../../src/hooks/useNotificationSettings"; import { useNotificationSettings } from "../../src/hooks/useNotificationSettings";
@@ -67,16 +67,13 @@ describe("useNotificationSettings", () => {
}); });
it("correctly parses model", async () => { it("correctly parses model", async () => {
await act(async () => {
const { result } = renderHook(() => useNotificationSettings(cli)); const { result } = renderHook(() => useNotificationSettings(cli));
expect(result.current.model).toEqual(null); expect(result.current.model).toEqual(null);
await waitFor(() => expect(result.current.model).toEqual(expectedModel)); await waitFor(() => expect(result.current.model).toEqual(expectedModel));
expect(result.current.hasPendingChanges).toBeFalsy(); expect(result.current.hasPendingChanges).toBeFalsy();
}); });
});
it("correctly generates change calls", async () => { it("correctly generates change calls", async () => {
await act(async () => {
const addPushRule = jest.fn(cli.addPushRule); const addPushRule = jest.fn(cli.addPushRule);
cli.addPushRule = addPushRule; cli.addPushRule = addPushRule;
const deletePushRule = jest.fn(cli.deletePushRule); const deletePushRule = jest.fn(cli.deletePushRule);
@@ -113,12 +110,7 @@ describe("useNotificationSettings", () => {
expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Underride, RuleId.Message, true); expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Underride, RuleId.Message, true);
expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Underride, RuleId.EncryptedDM, true); expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Underride, RuleId.EncryptedDM, true);
expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Underride, RuleId.DM, true); expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Underride, RuleId.DM, true);
expect(setPushRuleEnabled).toHaveBeenCalledWith( expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Override, RuleId.SuppressNotices, false);
"global",
PushRuleKind.Override,
RuleId.SuppressNotices,
false,
);
expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Override, RuleId.InviteToSelf, true); expect(setPushRuleEnabled).toHaveBeenCalledWith("global", PushRuleKind.Override, RuleId.InviteToSelf, true);
expect(setPushRuleActions).toHaveBeenCalledTimes(6); expect(setPushRuleActions).toHaveBeenCalledTimes(6);
expect(setPushRuleActions).toHaveBeenCalledWith( expect(setPushRuleActions).toHaveBeenCalledWith(
@@ -158,5 +150,4 @@ describe("useNotificationSettings", () => {
StandardActions.ACTION_NOTIFY_DEFAULT_SOUND, StandardActions.ACTION_NOTIFY_DEFAULT_SOUND,
); );
}); });
});
}); });

View File

@@ -22,6 +22,7 @@ import { mocked } from "jest-mock";
import { PredictableRandom } from "./predictableRandom"; // https://github.com/jsdom/jsdom/issues/2555 import { PredictableRandom } from "./predictableRandom"; // https://github.com/jsdom/jsdom/issues/2555
declare global { declare global {
// eslint-disable-next-line no-var
var IS_REACT_ACT_ENVIRONMENT: boolean; var IS_REACT_ACT_ENVIRONMENT: boolean;
} }

View File

@@ -16,7 +16,7 @@ limitations under the License.
// //
import React from "react"; import React from "react";
import { act, render, RenderResult, screen } from "@testing-library/react"; import { act, render, RenderResult, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { ClientEvent, MatrixClient, MatrixEvent, SyncState } from "matrix-js-sdk/src/matrix"; import { ClientEvent, MatrixClient, MatrixEvent, SyncState } from "matrix-js-sdk/src/matrix";
import { sleep } from "matrix-js-sdk/src/utils"; import { sleep } from "matrix-js-sdk/src/utils";
@@ -117,11 +117,9 @@ describe("VoiceBroadcastRecordingPip", () => {
describe("and selecting another input device", () => { describe("and selecting another input device", () => {
beforeEach(async () => { beforeEach(async () => {
await act(async () => {
await userEvent.click(screen.getByLabelText("Change input device")); await userEvent.click(screen.getByLabelText("Change input device"));
await userEvent.click(screen.getByText("Device 1")); await userEvent.click(screen.getByText("Device 1"));
}); });
});
it("should select the device and pause and resume the broadcast", () => { it("should select the device and pause and resume the broadcast", () => {
expect(MediaDeviceHandler.instance.setDevice).toHaveBeenCalledWith( expect(MediaDeviceHandler.instance.setDevice).toHaveBeenCalledWith(
@@ -199,8 +197,8 @@ describe("VoiceBroadcastRecordingPip", () => {
client.emit(ClientEvent.Sync, SyncState.Catchup, SyncState.Error); client.emit(ClientEvent.Sync, SyncState.Catchup, SyncState.Error);
}); });
it("should render a paused recording", () => { it("should render a paused recording", async () => {
expect(screen.getByLabelText("resume voice broadcast")).toBeInTheDocument(); await waitFor(() => expect(screen.getByLabelText("resume voice broadcast")).toBeInTheDocument());
}); });
}); });
}); });