From d2907f51d308675a9d4bd8fe34f136d1c944c0f6 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 9 Jan 2026 12:35:25 +0100 Subject: [PATCH] prettier format --- playwright/fixtures/widget-user.ts | 32 ++-- playwright/widget/voice-call-dm.spec.ts | 190 +++++++++++++----------- sdk/main.ts | 5 +- src/UrlParams.ts | 5 +- src/room/RoomPage.tsx | 12 +- src/state/MuteStates.test.ts | 19 +-- src/state/initialMuteState.test.ts | 18 ++- src/utils/test.ts | 5 +- 8 files changed, 156 insertions(+), 130 deletions(-) diff --git a/playwright/fixtures/widget-user.ts b/playwright/fixtures/widget-user.ts index 0611c97e..84283cb6 100644 --- a/playwright/fixtures/widget-user.ts +++ b/playwright/fixtures/widget-user.ts @@ -176,7 +176,6 @@ export const widgetTest = test.extend({ .click(); if (callType === "room") { - await ewPage1.getByRole("menuitem", { name: "New Room" }).click(); await ewPage1.getByRole("textbox", { name: "Name" }).fill("Welcome Room"); await ewPage1.getByRole("button", { name: "Create room" }).click(); @@ -206,28 +205,35 @@ export const widgetTest = test.extend({ await ewPage2.getByRole("option", { name: "Welcome Room" }).click(); await ewPage2.getByRole("button", { name: "Accept" }).click(); await expect( - ewPage2.getByRole("main").getByRole("heading", { name: "Welcome Room" }), + ewPage2 + .getByRole("main") + .getByRole("heading", { name: "Welcome Room" }), ).toBeVisible(); } else if (callType === "dm") { await ewPage1.getByRole("menuitem", { name: "Start chat" }).click(); - await ewPage1.getByRole('textbox', { name: 'Search' }).click(); - await ewPage1.getByRole('textbox', { name: 'Search' }).fill(whistlerMxId); + await ewPage1.getByRole("textbox", { name: "Search" }).click(); + await ewPage1.getByRole("textbox", { name: "Search" }).fill(whistlerMxId); await ewPage1.getByRole("button", { name: "Go" }).click(); // Wait and send the first message to create the DM - await expect(ewPage1.getByText(/Send your first message to invite/)).toBeVisible(); + await expect( + ewPage1.getByText(/Send your first message to invite/), + ).toBeVisible(); - await ewPage1.locator('.mx_BasicMessageComposer_input > div').click(); - await ewPage1.getByRole('textbox', { name: 'Send a message…' }).fill('Hello!'); + await ewPage1.locator(".mx_BasicMessageComposer_input > div").click(); + await ewPage1 + .getByRole("textbox", { name: "Send a message…" }) + .fill("Hello!"); await ewPage1.getByRole("button", { name: "Send message" }).click(); - await expect(ewPage1.getByText('This is the beginning of your')).toBeVisible(); - + await expect( + ewPage1.getByText("This is the beginning of your"), + ).toBeVisible(); // Accept the DM invite from brooks // This how playwright record selects the DM invite in the room list - await ewPage2.getByRole('option', { name: 'Open room' }).click(); - await ewPage2.getByRole('button', { name: 'Start chatting' }).click(); + await ewPage2.getByRole("option", { name: "Open room" }).click(); + await ewPage2.getByRole("button", { name: "Start chatting" }).click(); } // Renamed use to pUse, as a workaround for eslint error that was thinking this use was a react use. @@ -236,13 +242,13 @@ export const widgetTest = test.extend({ mxId: brooksMxId, page: ewPage1, clientHandle: brooksClientHandle, - displayName: brooksDisplayName + displayName: brooksDisplayName, }, whistler: { mxId: whistlerMxId, page: ewPage2, clientHandle: whistlerClientHandle, - displayName: whistlerDisplayName + displayName: whistlerDisplayName, }, }); }, diff --git a/playwright/widget/voice-call-dm.spec.ts b/playwright/widget/voice-call-dm.spec.ts index 39a1b8cb..3595afa7 100644 --- a/playwright/widget/voice-call-dm.spec.ts +++ b/playwright/widget/voice-call-dm.spec.ts @@ -9,7 +9,7 @@ import { expect, test } from "@playwright/test"; import { widgetTest } from "../fixtures/widget-user.ts"; -widgetTest.use({callType: "dm"}); +widgetTest.use({ callType: "dm" }); widgetTest("Start a new voice call in DM as widget", async ({ asWidget }) => { test.slow(); // Triples the timeout @@ -28,8 +28,7 @@ widgetTest("Start a new voice call in DM as widget", async ({ asWidget }) => { await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); await expect( - brooks.page - .locator('iframe[title="Element Call"]') + brooks.page.locator('iframe[title="Element Call"]'), ).toBeVisible(); const brooksFrame = brooks.page @@ -37,15 +36,15 @@ widgetTest("Start a new voice call in DM as widget", async ({ asWidget }) => { .contentFrame(); // We should show a ringing overlay, let's check for that - await expect(brooksFrame.getByText(`Waiting for ${whistler.displayName} to join…`)).toBeVisible(); + await expect( + brooksFrame.getByText(`Waiting for ${whistler.displayName} to join…`), + ).toBeVisible(); - - await expect(whistler.page.getByText('Incoming voice call')).toBeVisible(); - await whistler.page.getByRole('button', { name: 'Accept' }).click(); + await expect(whistler.page.getByText("Incoming voice call")).toBeVisible(); + await whistler.page.getByRole("button", { name: "Accept" }).click(); await expect( - whistler.page - .locator('iframe[title="Element Call"]') + whistler.page.locator('iframe[title="Element Call"]'), ).toBeVisible(); const whistlerFrame = whistler.page @@ -55,129 +54,144 @@ widgetTest("Start a new voice call in DM as widget", async ({ asWidget }) => { // ASSERT the button states for whistler (the callee) { // The only way to know if it is muted or not is to look at the data-kind attribute.. - const videoButton = whistlerFrame.getByTestId('incall_videomute'); + const videoButton = whistlerFrame.getByTestId("incall_videomute"); // video should be off by default in a voice call await expect(videoButton).toHaveAttribute("aria-label", /^Start video$/); - - const audioButton = whistlerFrame.getByTestId('incall_mute'); + const audioButton = whistlerFrame.getByTestId("incall_mute"); // audio should be on for the voice call - await expect(audioButton).toHaveAttribute("aria-label", /^Mute microphone$/); + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, + ); } // ASSERT the button states for brools (the caller) { // The only way to know if it is muted or not is to look at the data-kind attribute.. - const videoButton = brooksFrame.getByTestId('incall_videomute'); + const videoButton = brooksFrame.getByTestId("incall_videomute"); // video should be off by default in a voice call await expect(videoButton).toHaveAttribute("aria-label", /^Start video$/); - - const audioButton = brooksFrame.getByTestId('incall_mute'); + const audioButton = brooksFrame.getByTestId("incall_mute"); // audio should be on for the voice call - await expect(audioButton).toHaveAttribute("aria-label", /^Mute microphone$/); + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, + ); } // In order to confirm that the call is disconnected we will check that the message composer is shown again. // So first we need to confirm that it is hidden when in the call. - await expect(whistler.page.locator(".mx_BasicMessageComposer")).not.toBeVisible(); - await expect(brooks.page.locator(".mx_BasicMessageComposer")).not.toBeVisible(); + await expect( + whistler.page.locator(".mx_BasicMessageComposer"), + ).not.toBeVisible(); + await expect( + brooks.page.locator(".mx_BasicMessageComposer"), + ).not.toBeVisible(); // ASSERT hanging up on one side ends the call for both { - const hangupButton = brooksFrame.getByTestId('incall_leave'); + const hangupButton = brooksFrame.getByTestId("incall_leave"); await hangupButton.click(); } // The widget should be closed on both sides and the timeline should be back on screen await expect(whistler.page.locator(".mx_BasicMessageComposer")).toBeVisible(); await expect(brooks.page.locator(".mx_BasicMessageComposer")).toBeVisible(); - }); +widgetTest( + "Start a new video call in DM as widget", + async ({ asWidget, browserName }) => { + test.slow(); // Triples the timeout + const { brooks, whistler } = asWidget; -widgetTest("Start a new video call in DM as widget", async ({ asWidget, browserName }) => { - test.slow(); // Triples the timeout + await expect( + brooks.page.getByRole("button", { name: "Video call" }), + ).toBeVisible(); + await brooks.page.getByRole("button", { name: "Video call" }).click(); - const { brooks, whistler } = asWidget; + await expect( + brooks.page.getByRole("menuitem", { name: "Element Call" }), + ).toBeVisible(); - await expect( - brooks.page.getByRole("button", { name: "Video call" }), - ).toBeVisible(); - await brooks.page.getByRole("button", { name: "Video call" }).click(); + await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); - await expect( - brooks.page.getByRole("menuitem", { name: "Element Call" }), - ).toBeVisible(); + await expect( + brooks.page.locator('iframe[title="Element Call"]'), + ).toBeVisible(); - await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); - - await expect( - brooks.page + const brooksFrame = brooks.page .locator('iframe[title="Element Call"]') - ).toBeVisible(); + .contentFrame(); - const brooksFrame = brooks.page - .locator('iframe[title="Element Call"]') - .contentFrame(); + // We should show a ringing overlay, let's check for that + await expect( + brooksFrame.getByText(`Waiting for ${whistler.displayName} to join…`), + ).toBeVisible(); - // We should show a ringing overlay, let's check for that - await expect(brooksFrame.getByText(`Waiting for ${whistler.displayName} to join…`)).toBeVisible(); + await expect(whistler.page.getByText("Incoming video call")).toBeVisible(); + await whistler.page.getByRole("button", { name: "Accept" }).click(); + await expect( + whistler.page.locator('iframe[title="Element Call"]'), + ).toBeVisible(); - await expect(whistler.page.getByText('Incoming video call')).toBeVisible(); - await whistler.page.getByRole('button', { name: 'Accept' }).click(); - - await expect( - whistler.page + const whistlerFrame = whistler.page .locator('iframe[title="Element Call"]') - ).toBeVisible(); + .contentFrame(); - const whistlerFrame = whistler.page - .locator('iframe[title="Element Call"]') - .contentFrame(); + // ASSERT the button states for whistler (the callee) + { + // The only way to know if it is muted or not is to look at the data-kind attribute.. + const videoButton = whistlerFrame.getByTestId("incall_videomute"); + // video should be on by default in a voice call + await expect(videoButton).toHaveAttribute("aria-label", /^Stop video$/); - // ASSERT the button states for whistler (the callee) - { - // The only way to know if it is muted or not is to look at the data-kind attribute.. - const videoButton = whistlerFrame.getByTestId('incall_videomute'); - // video should be on by default in a voice call - await expect(videoButton).toHaveAttribute("aria-label", /^Stop video$/); + const audioButton = whistlerFrame.getByTestId("incall_mute"); + // audio should be on for the voice call + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, + ); + } + // ASSERT the button states for brools (the caller) + { + // The only way to know if it is muted or not is to look at the data-kind attribute.. + const videoButton = brooksFrame.getByTestId("incall_videomute"); + // video should be on by default in a voice call + await expect(videoButton).toHaveAttribute("aria-label", /^Stop video$/); - const audioButton = whistlerFrame.getByTestId('incall_mute'); - // audio should be on for the voice call - await expect(audioButton).toHaveAttribute("aria-label", /^Mute microphone$/); - } + const audioButton = brooksFrame.getByTestId("incall_mute"); + // audio should be on for the voice call + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, + ); + } - // ASSERT the button states for brools (the caller) - { - // The only way to know if it is muted or not is to look at the data-kind attribute.. - const videoButton = brooksFrame.getByTestId('incall_videomute'); - // video should be on by default in a voice call - await expect(videoButton).toHaveAttribute("aria-label", /^Stop video$/); + // In order to confirm that the call is disconnected we will check that the message composer is shown again. + // So first we need to confirm that it is hidden when in the call. + await expect( + whistler.page.locator(".mx_BasicMessageComposer"), + ).not.toBeVisible(); + await expect( + brooks.page.locator(".mx_BasicMessageComposer"), + ).not.toBeVisible(); + // ASSERT hanging up on one side ends the call for both + { + const hangupButton = brooksFrame.getByTestId("incall_leave"); + await hangupButton.click(); + } - const audioButton = brooksFrame.getByTestId('incall_mute'); - // audio should be on for the voice call - await expect(audioButton).toHaveAttribute("aria-label", /^Mute microphone$/); - } - - // In order to confirm that the call is disconnected we will check that the message composer is shown again. - // So first we need to confirm that it is hidden when in the call. - await expect(whistler.page.locator(".mx_BasicMessageComposer")).not.toBeVisible(); - await expect(brooks.page.locator(".mx_BasicMessageComposer")).not.toBeVisible(); - - // ASSERT hanging up on one side ends the call for both - { - const hangupButton = brooksFrame.getByTestId('incall_leave'); - await hangupButton.click(); - } - - // The widget should be closed on both sides and the timeline should be back on screen - await expect(whistler.page.locator(".mx_BasicMessageComposer")).toBeVisible(); - await expect(brooks.page.locator(".mx_BasicMessageComposer")).toBeVisible(); - -}); - + // The widget should be closed on both sides and the timeline should be back on screen + await expect( + whistler.page.locator(".mx_BasicMessageComposer"), + ).toBeVisible(); + await expect(brooks.page.locator(".mx_BasicMessageComposer")).toBeVisible(); + }, +); diff --git a/sdk/main.ts b/sdk/main.ts index add71dbe..5ba5c2fb 100644 --- a/sdk/main.ts +++ b/sdk/main.ts @@ -99,7 +99,10 @@ export async function createMatrixRTCSdk( if (room === null) throw Error("could not get room from client"); const mediaDevices = new MediaDevices(scope); - const muteStates = new MuteStates(scope, mediaDevices, { audioEnabled: true, videoEnabled: true }); + const muteStates = new MuteStates(scope, mediaDevices, { + audioEnabled: true, + videoEnabled: true, + }); const slot = { application, id }; const rtcSession = new MatrixRTCSession( client, diff --git a/src/UrlParams.ts b/src/UrlParams.ts index edac5c07..a9cd5dd5 100644 --- a/src/UrlParams.ts +++ b/src/UrlParams.ts @@ -252,10 +252,7 @@ export interface UrlConfiguration { // the situations that call for this behavior ('isEmbedded'). This makes it // clearer what each flag means, and helps us avoid coupling Element Call's // behavior to the needs of specific consumers. -export interface UrlParams - extends - UrlProperties, - UrlConfiguration {} +export interface UrlParams extends UrlProperties, UrlConfiguration {} // This is here as a stopgap, but what would be far nicer is a function that // takes a UrlParams and returns a query string. That would enable us to diff --git a/src/room/RoomPage.tsx b/src/room/RoomPage.tsx index 671ab1c5..488d8da9 100644 --- a/src/room/RoomPage.tsx +++ b/src/room/RoomPage.tsx @@ -71,7 +71,17 @@ export const RoomPage: FC = () => { useEffect(() => { const scope = new ObservableScope(); - setMuteStates(new MuteStates(scope, devices, calculateInitialMuteState(urlParams, import.meta.env.VITE_PACKAGE, window.location.hostname))); + setMuteStates( + new MuteStates( + scope, + devices, + calculateInitialMuteState( + urlParams, + import.meta.env.VITE_PACKAGE, + window.location.hostname, + ), + ), + ); return (): void => scope.end(); }, [devices, urlParams]); diff --git a/src/state/MuteStates.test.ts b/src/state/MuteStates.test.ts index db3f503e..6ecba002 100644 --- a/src/state/MuteStates.test.ts +++ b/src/state/MuteStates.test.ts @@ -48,12 +48,7 @@ describe("MuteState", () => { select(): void {}, } as unknown as MediaDevice; - const muteState = new MuteState( - testScope, - deviceStub, - true, - forceMute$, - ); + const muteState = new MuteState(testScope, deviceStub, true, forceMute$); let lastEnabled: boolean = false; muteState.enabled$.subscribe((enabled) => { lastEnabled = enabled; @@ -162,14 +157,10 @@ describe("MuteStates", () => { videoInput: aVideoInput(), // other devices are not relevant for this test }); - const muteStates = new MuteStates( - testScope, - mediaDevices, - { - audioEnabled: false, - videoEnabled: false, - } - ); + const muteStates = new MuteStates(testScope, mediaDevices, { + audioEnabled: false, + videoEnabled: false, + }); let latestSyncedState: boolean | null = null; muteStates.video.setHandler(async (enabled: boolean): Promise => { diff --git a/src/state/initialMuteState.test.ts b/src/state/initialMuteState.test.ts index 08be50ef..7b3cb46c 100644 --- a/src/state/initialMuteState.test.ts +++ b/src/state/initialMuteState.test.ts @@ -10,7 +10,6 @@ import { type RTCCallIntent } from "matrix-js-sdk/lib/matrixrtc"; import { calculateInitialMuteState } from "./initialMuteState"; - test.each<{ callIntent: RTCCallIntent; packageType: "full" | "embedded"; @@ -69,7 +68,6 @@ test.each<{ }, ); - test.each<{ isDevBuild: boolean; currentHost: string; @@ -78,11 +76,14 @@ test.each<{ { isDevBuild: true, currentHost: "localhost", expectedEnabled: true }, { isDevBuild: false, currentHost: "localhost", expectedEnabled: false }, { isDevBuild: true, currentHost: "call.example.com", expectedEnabled: false }, - { isDevBuild: false, currentHost: "call.example.com", expectedEnabled: false }, -]) -("Should trust localhost domain when in dev mode isDevBuild($isDevBuild) host($currentHost)", ( - {isDevBuild, currentHost, expectedEnabled} -) => { + { + isDevBuild: false, + currentHost: "call.example.com", + expectedEnabled: false, + }, +])( + "Should trust localhost domain when in dev mode isDevBuild($isDevBuild) host($currentHost)", + ({ isDevBuild, currentHost, expectedEnabled }) => { const { audioEnabled, videoEnabled } = calculateInitialMuteState( { skipLobby: true, callIntent: "video" }, "full", @@ -92,4 +93,5 @@ test.each<{ expect(audioEnabled).toBe(expectedEnabled); expect(videoEnabled).toBe(expectedEnabled); -}); + }, +); diff --git a/src/utils/test.ts b/src/utils/test.ts index 95d6ed0c..44ac2257 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -525,5 +525,8 @@ export function mockMuteStates( joined$: Observable = of(true), ): MuteStates { const observableScope = new ObservableScope(); - return new MuteStates(observableScope, mockMediaDevices({}), { audioEnabled: false, videoEnabled: false }); + return new MuteStates(observableScope, mockMediaDevices({}), { + audioEnabled: false, + videoEnabled: false, + }); }