feat(tests): Adds tile view test.

This commit is contained in:
damencho
2025-02-14 10:11:02 -06:00
committed by Дамян Минков
parent f2238935b5
commit 8261cf2811
2 changed files with 156 additions and 16 deletions

View File

@@ -406,7 +406,6 @@ export class Participant {
});
}
/**
* Waits for remote streams.
*
@@ -803,26 +802,54 @@ export class Participant {
/**
* Waits for remote video state - receiving and displayed.
* @param endpointId
* @param reverse
*/
async waitForRemoteVideo(endpointId: string) {
await this.driver.waitUntil(async () =>
await this.execute(epId => JitsiMeetJS.app.testing.isRemoteVideoReceived(`${epId}`),
endpointId) && await this.driver.$(
`//span[@id="participant_${endpointId}" and contains(@class, "display-video")]`).isExisting(), {
timeout: 15_000,
timeoutMsg: `expected remote video for ${endpointId} to be received 15s by ${this.name}`
});
async waitForRemoteVideo(endpointId: string, reverse = false) {
if (reverse) {
await this.driver.waitUntil(async () =>
!await this.execute(epId => JitsiMeetJS.app.testing.isRemoteVideoReceived(`${epId}`),
endpointId) && !await this.driver.$(
`//span[@id="participant_${endpointId}" and contains(@class, "display-video")]`).isExisting(), {
timeout: 15_000,
timeoutMsg: `expected remote video for ${endpointId} to not be received 15s by ${this.displayName}`
});
} else {
await this.driver.waitUntil(async () =>
await this.execute(epId => JitsiMeetJS.app.testing.isRemoteVideoReceived(`${epId}`),
endpointId) && await this.driver.$(
`//span[@id="participant_${endpointId}" and contains(@class, "display-video")]`).isExisting(), {
timeout: 15_000,
timeoutMsg: `expected remote video for ${endpointId} to be received 15s by ${this.displayName}`
});
}
}
/**
* Waits for ninja icon to be displayed.
* @param endpointId
* @param endpointId When no endpoint id is passed we check for any ninja icon.
*/
async waitForNinjaIcon(endpointId: string) {
await this.driver.$(`//span[@id='participant_${endpointId}']//span[@class='connection_ninja']`)
.waitForDisplayed({
timeout: 15_000,
timeoutMsg: `expected ninja icon for ${endpointId} to be displayed in 15s by ${this.name}`
});
async waitForNinjaIcon(endpointId?: string) {
if (endpointId) {
await this.driver.$(`//span[@id='participant_${endpointId}']//span[@class='connection_ninja']`)
.waitForDisplayed({
timeout: 15_000,
timeoutMsg: `expected ninja icon for ${endpointId} to be displayed in 15s by ${this.name}`
});
} else {
await this.driver.$('//span[contains(@class,"videocontainer")]//span[contains(@class,"connection_ninja")]')
.waitForDisplayed({
timeout: 5_000,
timeoutMsg: `expected ninja icon to be displayed in 5s by ${this.displayName}`
});
}
}
/**
* Waits for dominant speaker icon to appear in remote video of a participant.
* @param endpointId the endpoint ID of the participant whose dominant speaker icon status will be checked.
*/
waitForDominantSpeaker(endpointId: string) {
return this.driver.$(`//span[@id="participant_${endpointId}" and contains(@class, "dominant-speaker")]`)
.waitForDisplayed({ timeout: 5_000 });
}
}

View File

@@ -0,0 +1,113 @@
import { ensureThreeParticipants, ensureTwoParticipants } from '../../helpers/participants';
/**
* The CSS selector for local video when outside of tile view. It should
* be in a container separate from remote videos so remote videos can
* scroll while local video stays docked.
*/
const FILMSTRIP_VIEW_LOCAL_VIDEO_CSS_SELECTOR = '#filmstripLocalVideo #localVideoContainer';
/**
* The CSS selector for local video tile view is enabled. It should display
* at the end of all the other remote videos, as the last tile.
*/
const TILE_VIEW_LOCAL_VIDEO_CSS_SELECTOR = '.remote-videos #localVideoContainer';
describe('TileView', () => {
it('joining the meeting', () => ensureTwoParticipants(ctx));
// TODO: implements etherpad check
it('pinning exits', async () => {
await enterTileView();
const { p1, p2 } = ctx;
await p1.getFilmstrip().pinParticipant(p2);
await p1.waitForTileViewDisplay(true);
});
it('local video display', async () => {
await enterTileView();
const { p1 } = ctx;
await p1.driver.$(TILE_VIEW_LOCAL_VIDEO_CSS_SELECTOR).waitForDisplayed({ timeout: 3000 });
await p1.driver.$(FILMSTRIP_VIEW_LOCAL_VIDEO_CSS_SELECTOR).waitForDisplayed({
timeout: 3000,
reverse: true
});
});
it('can exit', async () => {
const { p1 } = ctx;
await p1.getToolbar().clickExitTileViewButton();
await p1.waitForTileViewDisplay(true);
});
it('local video display independently from remote', async () => {
const { p1 } = ctx;
await p1.driver.$(TILE_VIEW_LOCAL_VIDEO_CSS_SELECTOR).waitForDisplayed({
timeout: 3000,
reverse: true
});
await p1.driver.$(FILMSTRIP_VIEW_LOCAL_VIDEO_CSS_SELECTOR).waitForDisplayed({ timeout: 3000 });
});
it('lastN', async () => {
const { p1, p2 } = ctx;
if (p1.driver.isFirefox) {
// Firefox does not support external audio file as input.
// Not testing as second participant cannot be dominant speaker.
return;
}
await p2.getToolbar().clickAudioMuteButton();
await ensureThreeParticipants(ctx, {
configOverwrite: {
channelLastN: 1,
startWithAudioMuted: true
}
});
const { p3 } = ctx;
// one inactive icon should appear in few seconds
await p3.waitForNinjaIcon();
const p1EpId = await p1.getEndpointId();
await p3.waitForRemoteVideo(p1EpId);
const p2EpId = await p2.getEndpointId();
await p3.waitForNinjaIcon(p2EpId);
// no video for participant 2
await p3.waitForRemoteVideo(p2EpId, true);
// mute audio for participant 1
await p1.getToolbar().clickAudioMuteButton();
// unmute audio for participant 2
await p2.getToolbar().clickAudioUnmuteButton();
await p3.waitForDominantSpeaker(p2EpId);
// check video of participant 2 should be received
await p3.waitForRemoteVideo(p2EpId);
});
});
/**
* Attempts to enter tile view and verifies tile view has been entered.
*/
async function enterTileView() {
await ctx.p1.getToolbar().clickEnterTileViewButton();
await ctx.p1.waitForTileViewDisplay();
}