ov-components: Add internal directives tests and update related components for recording functionality

master
Carlos Santos 2025-07-29 11:38:46 +02:00
parent 9bac0f6490
commit 5a249fc3e1
7 changed files with 135 additions and 21 deletions

View File

@ -0,0 +1,84 @@
import { Builder, WebDriver } from 'selenium-webdriver';
import { OpenViduComponentsPO } from './utils.po.test';
import { TestAppConfig } from './selenium.conf';
let url = '';
describe('Testing Internal Directives', () => {
let browser: WebDriver;
let utils: OpenViduComponentsPO;
async function createChromeBrowser(): Promise<WebDriver> {
return await new Builder()
.forBrowser(TestAppConfig.browserName)
.withCapabilities(TestAppConfig.browserCapabilities)
.setChromeOptions(TestAppConfig.browserOptions)
.usingServer(TestAppConfig.seleniumAddress)
.build();
}
beforeEach(async () => {
browser = await createChromeBrowser();
utils = new OpenViduComponentsPO(browser);
url = `${TestAppConfig.appUrl}&roomName=INTERNAL_DIRECTIVES_${Math.floor(Math.random() * 1000)}`;
});
afterEach(async () => {
try {
} catch (error) {}
await browser.sleep(500);
await browser.quit();
});
it('should show/hide toolbar view recording button with toolbarViewRecordingsButton directive', async () => {
await browser.get(`${url}&prejoin=false&toolbarViewRecordingsButton=true`);
await utils.checkSessionIsPresent();
await utils.toggleToolbarMoreOptions();
expect(await utils.isPresent('#view-recordings-btn')).toBeTrue();
await browser.get(`${url}&prejoin=false`);
await browser.navigate().refresh();
await utils.checkSessionIsPresent();
await utils.toggleToolbarMoreOptions();
expect(await utils.isPresent('#view-recordings-btn')).toBeFalse();
});
it('should show/hide participant name in prejoin with prejoinDisplayParticipantName directive', async () => {
await browser.get(`${url}&prejoin=true`);
await utils.checkPrejoinIsPresent();
expect(await utils.isPresent('.participant-name-container')).toBeTrue();
await browser.get(`${url}&prejoin=true&prejoinDisplayParticipantName=false`);
await browser.navigate().refresh();
await utils.checkPrejoinIsPresent();
expect(await utils.isPresent('.participant-name-container')).toBeFalse();
});
it('should show/hide view recordings button with recordingActivityViewRecordingsButton directive', async () => {
await browser.get(`${url}&prejoin=false&recordingActivityViewRecordingsButton=true`);
await utils.checkSessionIsPresent();
await utils.togglePanel('activities');
await utils.clickOn('#recording-activity');
expect(await utils.isPresent('#view-recordings-btn')).toBeTrue();
await browser.get(`${url}&prejoin=false`);
await browser.navigate().refresh();
await utils.checkSessionIsPresent();
await utils.togglePanel('activities');
await utils.clickOn('#recording-activity');
expect(await utils.isPresent('#view-recordings-btn')).toBeFalse();
});
it('should show/hide start/stop recording buttons with recordingActivityStartStopRecordingButton directive', async () => {
await browser.get(`${url}&prejoin=false&recordingActivityStartStopRecordingButton=false`);
await utils.checkSessionIsPresent();
await utils.togglePanel('activities');
await utils.clickOn('#recording-activity');
expect(await utils.isPresent('#start-recording-btn')).toBeFalse();
await browser.sleep(3000);
await browser.get(`${url}&prejoin=false`);
await browser.navigate().refresh();
await utils.checkSessionIsPresent();
await utils.togglePanel('activities');
await utils.clickOn('#recording-activity');
expect(await utils.isPresent('#start-recording-btn')).toBeTrue();
});
});

View File

@ -195,5 +195,7 @@ export class OpenViduComponentsPO {
await this.clickOn('#toolbar-settings-btn');
break;
}
await this.browser.sleep(500);
}
}

View File

@ -35,7 +35,7 @@
"@types/node": "20.12.14",
"@types/selenium-webdriver": "4.1.16",
"@types/ws": "^8.5.12",
"chromedriver": "136.0.2",
"chromedriver": "138.0.0",
"concat": "^1.0.3",
"cross-env": "^7.0.3",
"eslint-config-prettier": "^9.1.0",
@ -8126,9 +8126,9 @@
}
},
"node_modules/chromedriver": {
"version": "136.0.2",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-136.0.2.tgz",
"integrity": "sha512-yJ52GN01edLYWYK/OspYBv3plzF08Ucdq4ukYigJGOX8dWr/tP5PXSZPWFPVarmbmcO57pNLP9Im8hsYljMEjw==",
"version": "138.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-138.0.0.tgz",
"integrity": "sha512-bJ/DNm5Y0TbqM71ARaAohTWVwcQ2SsWciYC5Q9Ul7DC/oTxm6B1vI2h6WscFCOOi49ul4tXZVjA/LOruljjmjA==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@ -8145,7 +8145,7 @@
"chromedriver": "bin/chromedriver"
},
"engines": {
"node": ">=18"
"node": ">=20"
}
},
"node_modules/cli-cursor": {

View File

@ -27,7 +27,7 @@
"@types/node": "20.12.14",
"@types/selenium-webdriver": "4.1.16",
"@types/ws": "^8.5.12",
"chromedriver": "136.0.2",
"chromedriver": "138.0.0",
"concat": "^1.0.3",
"cross-env": "^7.0.3",
"eslint-config-prettier": "^9.1.0",
@ -89,6 +89,7 @@
"e2e:nested-structural-directives": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/nested-components/structural-directives.test.js",
"e2e:nested-attribute-directives": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/nested-components/attribute-directives.test.js",
"e2e:lib-directives": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/api-directives.test.js",
"e2e:lib-internal-directives": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/internal-directives.test.js",
"e2e:lib-chat": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/chat.test.js",
"e2e:lib-events": "tsc --project ./e2e && npx jasmine ./e2e/dist/events.test.js",
"e2e:lib-media-devices": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/media-devices.test.js",

View File

@ -213,7 +213,17 @@
<!-- Actions menu row -->
@if (recording.status !== recStatusEnum.STARTED) {
<div class="recording-actions-menu">
@if (!isReadOnlyMode) {
@if (isReadOnlyMode) {
<button
mat-button
(click)="onViewRecordingClicked.emit(recording.id)"
class="action-btn action-view"
id="external-view-recording-btn"
>
<mat-icon>open_in_new</mat-icon>
{{ 'PANEL.RECORDING.WATCH' | translate }}
</button>
} @else {
@if (showControls.play) {
<button
mat-icon-button
@ -261,16 +271,6 @@
<mat-icon>delete_outline</mat-icon>
</button>
}
} @else {
<button
mat-button
(click)="onViewRecordingClicked.emit(recording.id)"
class="action-btn action-view"
id="external-view-recording-btn"
>
<mat-icon>open_in_new</mat-icon>
{{ 'PANEL.RECORDING.WATCH' | translate }}
</button>
}
</div>
}

View File

@ -32,6 +32,17 @@
[activitiesPanelRecordingActivity]="activitiesPanelRecordingActivity"
[activitiesPanelBroadcastingActivity]="activitiesPanelBroadcastingActivity"
[toolbarSettingsButton]="toolbarSettingsButton"
[toolbarViewRecordingsButton]="toolbarViewRecordingsButton"
[recordingActivityShowControls]="{
play: false,
download: false,
delete: false,
externalView: true
}"
[recordingActivityReadOnly]="false"
[recordingActivityStartStopRecordingButton]="recordingActivityStartStopRecordingButton"
[recordingActivityViewRecordingsButton]="recordingActivityViewRecordingsButton"
[recordingActivityShowRecordingsList]="true"
(onTokenRequested)="onTokenRequested($event)"
(onReadyToJoin)="onReadyToJoin()"
(onRoomCreated)="onRoomCreated($event)"
@ -54,6 +65,7 @@
(onBroadcastingStopRequested)="onBroadcastingStopRequested($event)"
(onSettingsPanelStatusChanged)="onSettingsPanelStatusChanged($event)"
(onActivitiesPanelStatusChanged)="onActivitiesPanelStatusChanged($event)"
(onViewRecordingClicked)="onRoomDisconnected()"
>
</ov-videoconference>
}

View File

@ -34,7 +34,6 @@ export class CallComponent implements OnInit {
{ name: 'custom', lang: 'cus' }
];
prejoin: boolean = true;
prejoinDisplayParticipantName: boolean = true;
participantName: string = `Participant${Math.floor(Math.random() * 1000)}`;
videoEnabled: boolean = true;
audioEnabled: boolean = true;
@ -59,6 +58,13 @@ export class CallComponent implements OnInit {
activitiesPanelBroadcastingActivity: boolean = true;
toolbarSettingsButton: boolean = true;
fakeDevices: boolean = false;
// Internal directive inputs (public for E2E)
prejoinDisplayParticipantName: boolean = true;
public recordingActivityViewRecordingsButton: boolean = false;
public recordingActivityStartStopRecordingButton: boolean = true;
toolbarViewRecordingsButton: boolean = false;
private redirectToHomeOnLeaves: boolean = true;
private staticVideos = [
@ -104,8 +110,6 @@ export class CallComponent implements OnInit {
} catch {}
}
if (params['prejoin'] !== undefined) this.prejoin = params['prejoin'] === 'true';
if (params['displayParticipantName'] !== undefined)
this.prejoinDisplayParticipantName = params['displayParticipantName'] === 'true';
if (params['participantName']) this.participantName = params['participantName'];
if (params['videoEnabled'] !== undefined) this.videoEnabled = params['videoEnabled'] === 'true';
if (params['audioEnabled'] !== undefined) this.audioEnabled = params['audioEnabled'] === 'true';
@ -141,6 +145,15 @@ export class CallComponent implements OnInit {
if (params['fakeDevices'] !== undefined) this.fakeDevices = params['fakeDevices'] === 'true';
// Internal/private directive params
if (params['prejoinDisplayParticipantName'] !== undefined)
this.prejoinDisplayParticipantName = params['prejoinDisplayParticipantName'] === 'true';
if (params['recordingActivityViewRecordingsButton'] !== undefined)
this.recordingActivityViewRecordingsButton = params['recordingActivityViewRecordingsButton'] === 'true';
if (params['recordingActivityStartStopRecordingButton'] !== undefined)
this.recordingActivityStartStopRecordingButton = params['recordingActivityStartStopRecordingButton'] === 'true';
if (params['toolbarViewRecordingsButton'] !== undefined)
this.toolbarViewRecordingsButton = params['toolbarViewRecordingsButton'] === 'true';
if (params['redirectToHome'] === undefined) {
this.redirectToHomeOnLeaves = true;
} else {
@ -198,7 +211,9 @@ export class CallComponent implements OnInit {
if (publication.videoTrack?.attachedElements) {
this.replaceWithStaticVideos(publication.videoTrack?.attachedElements);
const firstVideo = this.staticVideos.shift();
this.staticVideos.push(firstVideo);
if (firstVideo) {
this.staticVideos.push(firstVideo);
}
}
}, 2000);
}