import { expect, test } from '@playwright/test'; import { MeetRecordingAccess } from '../../../../typings/src/room-preferences'; import { MEET_TESTAPP_URL } from '../config'; import { applyVirtualBackground, closeMoreOptionsMenu, createTestRoom, deleteAllRecordings, deleteAllRooms, interactWithElementInIframe, isVirtualBackgroundApplied, joinRoomAs, leaveRoom, loginAsAdmin, openMoreOptionsMenu, prepareForJoiningRoom, updateRoomPreferences, waitForElementInIframe, waitForVirtualBackgroundToApply } from '../helpers/function-helpers'; let subscribedToAppErrors = false; test.describe('UI Feature Preferences Tests', () => { let roomId: string; let participantName: string; let adminCookie: string; // ========================================== // SETUP & TEARDOWN // ========================================== test.beforeAll(async () => { // Login as admin to get authentication cookie adminCookie = await loginAsAdmin(); // Create a test room before all tests roomId = await createTestRoom('test-room'); }); test.beforeEach(async ({ page }) => { if (!subscribedToAppErrors) { page.on('console', (msg) => { const type = msg.type(); const tag = type === 'error' ? 'ERROR' : type === 'warning' ? 'WARNING' : 'LOG'; console.log('[' + tag + ']', msg.text()); }); subscribedToAppErrors = true; } participantName = `P-${Math.random().toString(36).substring(2, 9)}`; }); test.afterAll(async ({ browser }) => { const tempContext = await browser.newContext(); const tempPage = await tempContext.newPage(); await deleteAllRooms(tempPage); await deleteAllRecordings(tempPage); await tempContext.close(); await tempPage.close(); }); // ========================================== // CHAT FEATURE TESTS // ========================================== test.describe('Chat Feature', () => { test.afterEach(async ({ page }) => { try { await leaveRoom(page); } catch (error) {} }); test('should show chat button when chat is enabled', async ({ page }) => { await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); // Check that chat button is visible const chatButton = await waitForElementInIframe(page, '#chat-panel-btn', { state: 'visible' }); await expect(chatButton).toBeVisible(); }); test('should hide chat button when chat is disabled', async ({ page }) => { // Disable chat via API await updateRoomPreferences( roomId, { chatPreferences: { enabled: false }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); // Check that chat button is not visible const chatButton = await waitForElementInIframe(page, '#chat-panel-btn', { state: 'hidden' }); await expect(chatButton).toBeHidden(); }); }); // ========================================== // RECORDING FEATURE TESTS // ========================================== test.describe('Recording Feature', () => { test('should show recording button for moderators', async ({ page }) => { await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('moderator', participantName, page); await openMoreOptionsMenu(page); // Check that recording button is visible for moderator await waitForElementInIframe(page, '#recording-btn', { state: 'visible' }); await closeMoreOptionsMenu(page); await waitForElementInIframe(page, '#activities-panel-btn', { state: 'visible' }); await interactWithElementInIframe(page, '#activities-panel-btn', { action: 'click' }); await page.waitForTimeout(500); await waitForElementInIframe(page, 'ov-recording-activity', { state: 'visible' }); await leaveRoom(page, 'moderator'); }); test('should not show recording button for speaker', async ({ page }) => { await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); // Check that recording button is not visible for speaker const recordingButton = await waitForElementInIframe(page, '#recording-btn', { state: 'hidden' }); await expect(recordingButton).toBeHidden(); await leaveRoom(page); }); test('should not show recording button for moderators when recording is disabled', async ({ page }) => { // Disable recording via API await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: false, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('moderator', participantName, page); // Check that recording button is not visible await interactWithElementInIframe(page, '#more-options-btn', { action: 'click' }); await page.waitForTimeout(500); await waitForElementInIframe(page, '#recording-btn', { state: 'hidden' }); await closeMoreOptionsMenu(page); await waitForElementInIframe(page, '#activities-panel-btn', { state: 'hidden' }); await leaveRoom(page, 'moderator'); }); }); // ========================================== // VIRTUAL BACKGROUND FEATURE TESTS // ========================================== test.describe('Virtual Background Feature', () => { test.afterEach(async ({ page }) => { try { await leaveRoom(page); } catch (error) {} }); test('should show virtual background button when enabled', async ({ page }) => { // Ensure virtual backgrounds are enabled await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); // Click more options to reveal virtual background button await openMoreOptionsMenu(page); // Check that virtual background button is visible await waitForElementInIframe(page, '#virtual-bg-btn', { state: 'visible' }); await interactWithElementInIframe(page, '#virtual-bg-btn', { action: 'click' }); await waitForElementInIframe(page, 'ov-background-effects-panel', { state: 'visible' }); }); test('should hide virtual background button when disabled', async ({ page }) => { // Disable virtual backgrounds via API await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: false } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); // Click more options to reveal virtual background button await openMoreOptionsMenu(page); // Check that virtual background button is visible await waitForElementInIframe(page, '#virtual-bg-btn', { state: 'hidden' }); await closeMoreOptionsMenu(page); }); test('should not apply virtual background when saved in local storage and feature is disabled', async ({ page }) => { // Ensure virtual backgrounds are enabled await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: true } }, adminCookie ); await page.goto(MEET_TESTAPP_URL); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); await applyVirtualBackground(page, '2'); await waitForVirtualBackgroundToApply(page); // Now disable virtual backgrounds await updateRoomPreferences( roomId, { chatPreferences: { enabled: true }, recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER }, virtualBackgroundPreferences: { enabled: false } }, adminCookie ); await leaveRoom(page); await page.reload(); await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId); await joinRoomAs('speaker', participantName, page); await page.waitForTimeout(2000); const isVBApplied = await isVirtualBackgroundApplied(page); expect(isVBApplied).toBe(false); }); }); });