jitsi-meet/tests/specs/3way/avatars.spec.ts
theluyuan 38ba663466
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
init
2025-09-02 14:49:16 +08:00

213 lines
7.5 KiB
TypeScript

import {
ensureThreeParticipants,
ensureTwoParticipants,
unmuteVideoAndCheck
} from '../../helpers/participants';
const EMAIL = 'support@jitsi.org';
const HASH = '38f014e4b7dde0f64f8157d26a8c812e';
describe('Avatar', () => {
it('setup the meeting', () =>
ensureTwoParticipants({
skipDisplayName: true
})
);
it('change and check', async () => {
const { p1, p2 } = ctx;
// check default avatar for p1 on p2
await p2.assertDefaultAvatarExist(p1);
await p1.getToolbar().clickProfileButton();
const settings = p1.getSettingsDialog();
await settings.waitForDisplay();
await settings.setEmail(EMAIL);
await settings.submit();
// check if the local avatar in the toolbar menu has changed
await p1.driver.waitUntil(
async () => (await p1.getToolbar().getProfileImage())?.includes(HASH), {
timeout: 3000, // give more time for the initial download of the image
timeoutMsg: 'Avatar has not changed for p1'
});
// check if the avatar in the local thumbnail has changed
expect(await p1.getLocalVideoAvatar()).toContain(HASH);
const p1EndpointId = await p1.getEndpointId();
await p2.driver.waitUntil(
async () => (await p2.getFilmstrip().getAvatar(p1EndpointId))?.includes(HASH), {
timeout: 5000,
timeoutMsg: 'Avatar has not changed for p1 on p2'
});
// check if the avatar in the large video has changed
expect(await p2.getLargeVideo().getAvatar()).toContain(HASH);
// we check whether the default avatar of participant2 is displayed on both sides
await p1.assertDefaultAvatarExist(p2);
await p2.assertDefaultAvatarExist(p2);
// the problem on FF where we can send keys to the input field,
// and the m from the text can mute the call, check whether we are muted
await p2.getFilmstrip().assertAudioMuteIconIsDisplayed(p1, true);
});
it('when video muted', async () => {
const { p1 } = ctx;
await ctx.p2.hangup();
// Mute p1's video
await p1.getToolbar().clickVideoMuteButton();
await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1);
await p1.driver.waitUntil(
async () => (await p1.getLargeVideo().getAvatar())?.includes(HASH), {
timeout: 2000,
timeoutMsg: 'Avatar on large video did not change'
});
const p1LargeSrc = await p1.getLargeVideo().getAvatar();
const p1ThumbSrc = await p1.getLocalVideoAvatar();
// Check if avatar on large video is the same as on local thumbnail
expect(p1ThumbSrc).toBe(p1LargeSrc);
// Join p2
await ensureTwoParticipants({
skipDisplayName: true
});
const { p2 } = ctx;
// Verify that p1 is muted from the perspective of p2
await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1);
await p2.getFilmstrip().pinParticipant(p1);
// Check if p1's avatar is on large video now
await p2.driver.waitUntil(
async () => await p2.getLargeVideo().getAvatar() === p1LargeSrc, {
timeout: 2000,
timeoutMsg: 'Avatar on large video did not change'
});
// p1 pins p2's video
await p1.getFilmstrip().pinParticipant(p2);
// Check if avatar is displayed on p1's local video thumbnail
await p1.assertThumbnailShowsAvatar(p1, false, false, true);
// Unmute - now local avatar should be hidden and local video displayed
await unmuteVideoAndCheck(p1, p2);
await p1.asserLocalThumbnailShowsVideo();
// Now both p1 and p2 have video muted
await p1.getToolbar().clickVideoMuteButton();
await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1);
await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p1);
await p2.getToolbar().clickVideoMuteButton();
await p2.getParticipantsPane().assertVideoMuteIconIsDisplayed(p2);
await p1.getParticipantsPane().assertVideoMuteIconIsDisplayed(p2);
// Start the third participant
await ensureThreeParticipants({
skipInMeetingChecks: true
});
const { p3 } = ctx;
// When the first participant is FF because of their audio mic feed it will never become dominant speaker
// and no audio track will be received by the third participant and video is muted,
// that's why we need to do a different check that expects any track just from p2
if (p1.driver.isFirefox) {
await Promise.all([ p2.waitForRemoteStreams(1), p3.waitForRemoteStreams(1) ]);
} else {
await Promise.all([ p2.waitForRemoteStreams(2), p3.waitForRemoteStreams(2) ]);
}
// Pin local video and verify avatars are displayed
await p3.getFilmstrip().pinParticipant(p3);
await p3.assertThumbnailShowsAvatar(p1, false, false, true);
await p3.assertThumbnailShowsAvatar(p2, false, true);
const p1EndpointId = await p1.getEndpointId();
const p2EndpointId = await p2.getEndpointId();
expect(await p3.getFilmstrip().getAvatar(p1EndpointId)).toBe(p1ThumbSrc);
// Click on p1's video
await p3.getFilmstrip().pinParticipant(p1);
// The avatar should be on large video and display name instead of an avatar, local video displayed
await p3.driver.waitUntil(
async () => await p3.getLargeVideo().getResource() === p1EndpointId, {
timeout: 2000,
timeoutMsg: `Large video did not switch to ${p1.name}`
});
await p3.assertDisplayNameVisibleOnStage(
await p3.getFilmstrip().getRemoteDisplayName(p1EndpointId));
// p2 has the default avatar
await p3.assertThumbnailShowsAvatar(p2, false, true);
await p3.assertThumbnailShowsAvatar(p3, true);
// Click on p2's video
await p3.getFilmstrip().pinParticipant(p2);
// The avatar should be on large video and display name instead of an avatar, local video displayed
await p3.driver.waitUntil(
async () => await p3.getLargeVideo().getResource() === p2EndpointId, {
timeout: 2000,
timeoutMsg: `Large video did not switch to ${p2.name}`
});
await p3.assertDisplayNameVisibleOnStage(
await p3.getFilmstrip().getRemoteDisplayName(p2EndpointId)
);
await p3.assertThumbnailShowsAvatar(p1, false, false, true);
await p3.assertThumbnailShowsAvatar(p3, true);
await p3.hangup();
// Unmute p1's and p2's videos
await unmuteVideoAndCheck(p1, p2);
});
it('email persistence', async () => {
let { p1 } = ctx;
if (p1.driver.isFirefox) {
// strangely this test when FF is involved, missing source mapping from jvb
// and fails with an error of: expected number of remote streams:1 in 15s for participant1
return;
}
await p1.getToolbar().clickProfileButton();
expect(await p1.getSettingsDialog().getEmail()).toBe(EMAIL);
await p1.hangup();
await ensureTwoParticipants({
skipDisplayName: true
});
p1 = ctx.p1;
await p1.getToolbar().clickProfileButton();
expect(await p1.getSettingsDialog().getEmail()).toBe(EMAIL);
});
});