From 38e8e5975a3d1cd7e077de1850181948614eac1a Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 9 Jan 2026 16:37:06 +0100 Subject: [PATCH] Try re-enable FF test with webRTC team options --- playwright.config.ts | 21 +- playwright/widget/voice-call-dm.spec.ts | 334 +++++++++++------------- 2 files changed, 176 insertions(+), 179 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index b7d22284..19e2fd7e 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -65,10 +65,27 @@ export default defineConfig({ ignoreHTTPSErrors: true, launchOptions: { firefoxUserPrefs: { + // Use the same set of options used by WebRTC tests in Firefox + // see https://webrtc.org/getting-started/testing + "media.navigator.permission.disabled": true, "permissions.default.microphone": 1, "permissions.default.camera": 1, - // "media.navigator.streams.fake": true, - // "media.navigator.permission.disabled": true, + "browser.cache.disk.enable": false, + "browser.cache.disk.capacity": 0, + "browser.cache.disk.smart_size.enabled": false, + "browser.cache.disk.smart_size.first_run": false, + "browser.sessionstore.resume_from_crash": false, + "browser.startup.page": 0, + "media.navigator.streams.fake": true, + "media.navigator.permission.disabled": true, + "device.storage.enabled": false, + "media.gstreamer.enabled": false, + "browser.startup.homepage": "about:blank", + "browser.startup.firstrunSkipsHomepage": false, + "extensions.update.enabled": false, + "app.update.enabled": false, + "network.http.use-cache": false, + "browser.shell.checkDefaultBrowser": false, }, }, }, diff --git a/playwright/widget/voice-call-dm.spec.ts b/playwright/widget/voice-call-dm.spec.ts index a7aed984..e80bac4b 100644 --- a/playwright/widget/voice-call-dm.spec.ts +++ b/playwright/widget/voice-call-dm.spec.ts @@ -11,202 +11,182 @@ import { widgetTest } from "../fixtures/widget-user.ts"; widgetTest.use({ callType: "dm" }); -widgetTest( - "Start a new voice call in DM as widget", - async ({ asWidget, browserName }) => { - test.skip( - browserName === "firefox", - "The is test is not working on firefox CI environment. No mic/audio device inputs so cam/mic are disabled", +widgetTest("Start a new voice call in DM as widget", async ({ asWidget }) => { + test.slow(); // Triples the timeout + + const { brooks, whistler } = asWidget; + + await expect( + brooks.page.getByRole("button", { name: "Voice call" }), + ).toBeVisible(); + await brooks.page.getByRole("button", { name: "Voice call" }).click(); + + await expect( + brooks.page.getByRole("menuitem", { name: "Element Call" }), + ).toBeVisible(); + + await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); + + await expect( + brooks.page.locator('iframe[title="Element Call"]'), + ).toBeVisible(); + + 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(); + + 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"]'), + ).toBeVisible(); + + 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 off by default in a voice call + await expect(videoButton).toHaveAttribute("aria-label", /^Start video$/); + + const audioButton = whistlerFrame.getByTestId("incall_mute"); + // audio should be on for the voice call + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, ); + } - test.slow(); // Triples the timeout + // 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 off by default in a voice call + await expect(videoButton).toHaveAttribute("aria-label", /^Start video$/); - const { brooks, whistler } = asWidget; - - await expect( - brooks.page.getByRole("button", { name: "Voice call" }), - ).toBeVisible(); - await brooks.page.getByRole("button", { name: "Voice call" }).click(); - - await expect( - brooks.page.getByRole("menuitem", { name: "Element Call" }), - ).toBeVisible(); - - await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); - - await expect( - brooks.page.locator('iframe[title="Element Call"]'), - ).toBeVisible(); - - 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(); - - 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"]'), - ).toBeVisible(); - - 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 off by default in a voice call - await expect(videoButton).toHaveAttribute("aria-label", /^Start 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 off by default in a voice call - await expect(videoButton).toHaveAttribute("aria-label", /^Start video$/); - - 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(); - }, -); - -widgetTest( - "Start a new video call in DM as widget", - async ({ asWidget, browserName }) => { - test.skip( - browserName === "firefox", - "The is test is not working on firefox CI environment. No mic/audio device inputs so cam/mic are disabled", + const audioButton = brooksFrame.getByTestId("incall_mute"); + // audio should be on for the voice call + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, ); + } - test.slow(); // Triples the timeout + // 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(); - const { brooks, whistler } = asWidget; + // ASSERT hanging up on one side ends the call for both + { + const hangupButton = brooksFrame.getByTestId("incall_leave"); + await hangupButton.click(); + } - await expect( - brooks.page.getByRole("button", { name: "Video call" }), - ).toBeVisible(); - await brooks.page.getByRole("button", { name: "Video call" }).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(); +}); - await expect( - brooks.page.getByRole("menuitem", { name: "Element Call" }), - ).toBeVisible(); +widgetTest("Start a new video call in DM as widget", async ({ asWidget }) => { + test.slow(); // Triples the timeout - await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); + const { brooks, whistler } = asWidget; - await expect( - brooks.page.locator('iframe[title="Element Call"]'), - ).toBeVisible(); + await expect( + brooks.page.getByRole("button", { name: "Video call" }), + ).toBeVisible(); + await brooks.page.getByRole("button", { name: "Video call" }).click(); - const brooksFrame = brooks.page - .locator('iframe[title="Element Call"]') - .contentFrame(); + await expect( + brooks.page.getByRole("menuitem", { name: "Element Call" }), + ).toBeVisible(); - // We should show a ringing overlay, let's check for that - await expect( - brooksFrame.getByText(`Waiting for ${whistler.displayName} to join…`), - ).toBeVisible(); + await brooks.page.getByRole("menuitem", { name: "Element Call" }).click(); - await expect(whistler.page.getByText("Incoming video call")).toBeVisible(); - await whistler.page.getByRole("button", { name: "Accept" }).click(); + await expect( + brooks.page.locator('iframe[title="Element Call"]'), + ).toBeVisible(); - await expect( - whistler.page.locator('iframe[title="Element Call"]'), - ).toBeVisible(); + const brooksFrame = brooks.page + .locator('iframe[title="Element Call"]') + .contentFrame(); - const whistlerFrame = whistler.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(); - // 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$/); + await expect(whistler.page.getByText("Incoming video call")).toBeVisible(); + await whistler.page.getByRole("button", { name: "Accept" }).click(); - const audioButton = whistlerFrame.getByTestId("incall_mute"); - // audio should be on for the voice call - await expect(audioButton).toHaveAttribute( - "aria-label", - /^Mute microphone$/, - ); - } + await expect( + whistler.page.locator('iframe[title="Element Call"]'), + ).toBeVisible(); - // 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 whistlerFrame = whistler.page + .locator('iframe[title="Element Call"]') + .contentFrame(); - 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 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$/); - // 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(); + const audioButton = whistlerFrame.getByTestId("incall_mute"); + // audio should be on for the voice call + await expect(audioButton).toHaveAttribute( + "aria-label", + /^Mute microphone$/, + ); + } - // ASSERT hanging up on one side ends the call for both - { - const hangupButton = brooksFrame.getByTestId("incall_leave"); - await hangupButton.click(); - } + // 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$/); - // 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(); - }, -); + 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(); +});