ref: Refactor tests (#16315)

* ref: Move iframe tests to iframe/.

* ref: Pass iFrameApi as Participant option.

* ref: Extract IParticipantJoinOptions.

* ref: Remove displayName from IJoinOptions (unused).

* ref: Move preferGenerateToken out of Participant.
This commit is contained in:
bgrozev
2025-08-08 01:58:44 -05:00
committed by GitHub
parent b774f18f80
commit 048b089acd
12 changed files with 84 additions and 37 deletions

View File

@@ -25,7 +25,7 @@ import Visitors from '../pageobjects/Visitors';
import { LOG_PREFIX, logInfo } from './browserLogger';
import { IToken } from './token';
import { IContext, IJoinOptions } from './types';
import { IParticipantJoinOptions, IParticipantOptions } from './types';
export const P1 = 'p1';
export const P2 = 'p2';
@@ -60,6 +60,8 @@ export class Participant {
*/
private _dialInPin?: string;
private _iFrameApi: boolean = false;
/**
* The default config to use when joining.
*
@@ -116,14 +118,12 @@ export class Participant {
} as IConfig;
/**
* Creates a participant with given name.
*
* @param {string} name - The name of the participant.
* @param {string} token - The token if any.
* Creates a participant with given options.
*/
constructor(name: string, token?: IToken) {
this._name = name;
this._token = token;
constructor(options: IParticipantOptions) {
this._name = options.name;
this._token = options.token;
this._iFrameApi = options.iFrameApi || false;
}
/**
@@ -186,13 +186,12 @@ export class Participant {
/**
* Joins conference.
*
* @param {IContext} ctx - The context.
* @param {IJoinOptions} options - Options for joining.
* @returns {Promise<void>}
*/
async joinConference(ctx: IContext, options: IJoinOptions = {}): Promise<void> {
async joinConference(options: IParticipantJoinOptions): Promise<void> {
const config = {
room: ctx.roomName,
room: options.roomName,
configOverwrite: {
...this.config,
...options.configOverwrite || {}
@@ -209,17 +208,17 @@ export class Participant {
};
}
if (ctx.testProperties.useIFrameApi) {
if (this._iFrameApi) {
config.room = 'iframeAPITest.html';
}
let url = urlObjectToString(config) || '';
if (ctx.testProperties.useIFrameApi) {
if (this._iFrameApi) {
const baseUrl = new URL(this.driver.options.baseUrl || '');
// @ts-ignore
url = `${this.driver.iframePageBase}${url}&domain="${baseUrl.host}"&room="${ctx.roomName}"`;
url = `${this.driver.iframePageBase}${url}&domain="${baseUrl.host}"&room="${options.roomName}"`;
if (process.env.IFRAME_TENANT) {
url = `${url}&tenant="${process.env.IFRAME_TENANT}"`;
@@ -238,20 +237,18 @@ export class Participant {
await this.driver.setTimeout({ 'pageLoad': 30000 });
let urlToLoad = url.startsWith('/') ? url.substring(1) : url;
// drop the leading '/' so we can use the tenant if any
url = url.startsWith('/') ? url.substring(1) : url;
if (options.preferGenerateToken && !ctx.testProperties.useIFrameApi
&& process.env.JWT_KID?.startsWith('vpaas-magic-cookie-') && process.env.IFRAME_TENANT) {
// This to enables tests like invite, which can force using the jaas auth instead of the provided token
urlToLoad = `/${process.env.IFRAME_TENANT}/${urlToLoad}`;
if (options.forceTenant) {
url = `/${options.forceTenant}/${url}`;
}
// drop the leading '/' so we can use the tenant if any
await this.driver.url(urlToLoad);
await this.driver.url(url);
await this.waitForPageToLoad();
if (ctx.testProperties.useIFrameApi) {
if (this._iFrameApi) {
const mainFrame = this.driver.$('iframe');
await this.driver.switchFrame(mainFrame);

View File

@@ -214,15 +214,22 @@ async function _joinParticipant( // eslint-disable-line max-params
}
}
const newParticipant = new Participant(name, token);
const newParticipant = new Participant({ name, token, iFrameApi: ctx.testProperties.useIFrameApi });
// set the new participant instance
// @ts-ignore
ctx[name] = newParticipant;
await newParticipant.joinConference(ctx, {
displayName: name,
...options
let forceTenant;
if (options?.preferGenerateToken && !ctx.testProperties.useIFrameApi
&& process.env.JWT_KID?.startsWith('vpaas-magic-cookie-') && process.env.IFRAME_TENANT) {
forceTenant = process.env.IFRAME_TENANT;
}
await newParticipant.joinConference({
...options,
forceTenant,
roomName: ctx.roomName,
});
}

View File

@@ -3,7 +3,7 @@ import { IConfig } from '../../react/features/base/config/configType';
import type { Participant } from './Participant';
import { ITestProperties } from './TestProperties';
import type WebhookProxy from './WebhookProxy';
import { ITokenOptions } from './token';
import { IToken, ITokenOptions } from './token';
export type IContext = {
/**
@@ -24,8 +24,19 @@ export type IContext = {
webhooksProxy: WebhookProxy;
};
export type IJoinOptions = {
export type IParticipantOptions = {
/** Whether it should use the iFrame API. */
iFrameApi?: boolean;
/** Must be 'p1', 'p2', 'p3', or 'p4'. */
name: string;
/** An optional token to use. */
token?: IToken;
};
/**
* Options for joinConference.
*/
export type IParticipantJoinOptions = {
/**
* Overwrites the base url set in the config.
*/
@@ -37,9 +48,36 @@ export type IJoinOptions = {
configOverwrite?: IConfig;
/**
* The display name to use.
* An optional tenant to use. If provided the URL is prepended with /$forceTenant
*/
displayName?: string;
forceTenant?: string;
/** The name of the room to join */
roomName: string;
/**
* Whether to skip setting display name.
*/
skipDisplayName?: boolean;
/**
* Whether to skip waiting for the participant to join the room. Cases like lobby where we do not succeed to join
* based on the logic of the test.
*/
skipWaitToJoin?: boolean;
};
export type IJoinOptions = {
/**
* Overwrites the base url set in the config.
*/
baseUrl?: string;
/**
* Config overwrites to use.
*/
configOverwrite?: IConfig;
/**
* When joining the first participant and jwt singing material is available and a provided token

View File

@@ -24,7 +24,7 @@ export async function loadPage(roomName: string, instanceId: 'p1' | 'p2' | 'p3'
}
url += '#config.prejoinConfig.enabled=false&config.requireDisplayName=false';
const newParticipant = new Participant(instanceId, token);
const newParticipant = new Participant({ name: instanceId, token });
try {
await newParticipant.driver.setTimeout({ 'pageLoad': 30000 });

View File

@@ -7,7 +7,8 @@ import { fetchJson } from '../../helpers/utils';
setTestProperties(__filename, {
useIFrameApi: true,
useWebhookProxy: true
useWebhookProxy: true,
usesBrowsers: [ 'p1', 'p2' ]
});
describe('Chat', () => {

View File

@@ -7,7 +7,8 @@ import { IContext } from '../../helpers/types';
setTestProperties(__filename, {
useIFrameApi: true,
useWebhookProxy: true
useWebhookProxy: true,
usesBrowsers: [ 'p1', 'p2' ]
});
/**

View File

@@ -7,7 +7,8 @@ import { ensureOneParticipant, ensureTwoParticipants } from '../../helpers/parti
setTestProperties(__filename, {
useIFrameApi: true,
useWebhookProxy: true
useWebhookProxy: true,
usesBrowsers: [ 'p1', 'p2' ]
});
describe('Transcriptions', () => {

View File

@@ -3,7 +3,8 @@ import { ensureOneParticipant, ensureTwoParticipants } from '../../helpers/parti
setTestProperties(__filename, {
useIFrameApi: true,
useWebhookProxy: true
useWebhookProxy: true,
usesBrowsers: [ 'p1', 'p2' ]
});
describe('Visitors', () => {

View File

@@ -5,7 +5,8 @@ import { ensureOneParticipant, ensureTwoParticipants } from '../../helpers/parti
setTestProperties(__filename, {
useIFrameApi: true,
useWebhookProxy: true
useWebhookProxy: true,
usesBrowsers: [ 'p1', 'p2' ]
});
describe('Visitors', () => {

View File

@@ -21,7 +21,7 @@ if (process.env.HEADLESS === 'true') {
const mergedConfig = merge(defaultConfig, {
exclude: [
'specs/**/iFrameApi*.spec.ts', // FF does not support uploading files (uploadFile)
'specs/iframe/*.spec.ts', // FF does not support uploading files (uploadFile)
// FF does not support setting a file as mic input, no dominant speaker events
'specs/3way/activeSpeaker.spec.ts',