mirror of
https://github.com/vector-im/element-call.git
synced 2026-01-18 02:32:27 +00:00
prettier format
This commit is contained in:
@@ -176,7 +176,6 @@ export const widgetTest = test.extend<MyFixtures>({
|
||||
.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<MyFixtures>({
|
||||
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<MyFixtures>({
|
||||
mxId: brooksMxId,
|
||||
page: ewPage1,
|
||||
clientHandle: brooksClientHandle,
|
||||
displayName: brooksDisplayName
|
||||
displayName: brooksDisplayName,
|
||||
},
|
||||
whistler: {
|
||||
mxId: whistlerMxId,
|
||||
page: ewPage2,
|
||||
clientHandle: whistlerClientHandle,
|
||||
displayName: whistlerDisplayName
|
||||
displayName: whistlerDisplayName,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -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();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -48,12 +48,7 @@ describe("MuteState", () => {
|
||||
select(): void {},
|
||||
} as unknown as MediaDevice<DeviceLabel, SelectedDevice>;
|
||||
|
||||
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<boolean> => {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -525,5 +525,8 @@ export function mockMuteStates(
|
||||
joined$: Observable<boolean> = 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,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user