diff --git a/bigbluebutton-tests/playwright/core/constants.js b/bigbluebutton-tests/playwright/core/constants.js index e65e422e84..7425e3d6a4 100644 --- a/bigbluebutton-tests/playwright/core/constants.js +++ b/bigbluebutton-tests/playwright/core/constants.js @@ -4,6 +4,11 @@ exports.ELEMENT_WAIT_LONGER_TIME = 10000; exports.LOOP_INTERVAL = 1200; exports.NOTIFICATION_WAIT_TIME = 6000; +// STRESS TESTS VARS +exports.JOIN_AS_MODERATOR_TEST_ROUNDS = 15; +exports.MAX_JOIN_AS_MODERATOR_FAIL_RATE = 0.05; +exports.BREAKOUT_ROOM_INVITATION_TEST_ROUNDS = 20; + // MEDIA CONNECTION TIMEOUTS exports.VIDEO_LOADING_WAIT_TIME = 15000; exports.UPLOAD_PDF_WAIT_TIME = 20000; \ No newline at end of file diff --git a/bigbluebutton-tests/playwright/core/elements.js b/bigbluebutton-tests/playwright/core/elements.js index 77f847143f..05b6e7310f 100644 --- a/bigbluebutton-tests/playwright/core/elements.js +++ b/bigbluebutton-tests/playwright/core/elements.js @@ -30,6 +30,9 @@ exports.alreadyConnected = 'span[class^="alreadyConnected--"]'; exports.askJoinRoom1 = 'button[aria-label="Ask to join Room 1"]'; exports.joinRoom1 = 'button[aria-label="Join room Room 1"]'; exports.breakoutRoomsButton = 'div[aria-label="Breakout Rooms"]'; +exports.allowChoiceRoom = 'input[id="freeJoinCheckbox"]'; +exports.labelGeneratingURL = 'span[data-test="labelGeneratingURL"]'; +exports.endBreakoutRoomsButton = 'button[data-test="endBreakoutRoomsButton"]'; // Chat exports.chatBox = '#message-input'; @@ -144,6 +147,7 @@ exports.userListItem = 'div[data-test="userListItem"]'; exports.firstUser = '[data-test="userListItemCurrent"]'; exports.multiWhiteboardTool = 'span[data-test="multiWhiteboardTool"]'; exports.manageUsers = 'button[data-test="manageUsers"]'; +exports.presenterClassName = 'presenter--'; // Locales exports.locales = ['af', 'ar', 'az', 'bg-BG', 'bn', 'ca', 'cs-CZ', 'da', 'de', diff --git a/bigbluebutton-tests/playwright/stress/stress.js b/bigbluebutton-tests/playwright/stress/stress.js new file mode 100644 index 0000000000..0cdd463d14 --- /dev/null +++ b/bigbluebutton-tests/playwright/stress/stress.js @@ -0,0 +1,79 @@ +const { expect } = require('@playwright/test'); +const Page = require('../core/page'); +const e = require('../core/elements'); +const c = require('../core/constants'); +const util = require('./util'); + +class Stress { + constructor(browser, context, page) { + this.modPage = new Page(browser, page); + this.browser = browser; + this.context = context; + this.userPages = []; + } + + async moderatorAsPresenter() { + const maxFailRate = c.JOIN_AS_MODERATOR_TEST_ROUNDS * c.MAX_JOIN_AS_MODERATOR_FAIL_RATE; + let failureCount = 0; + for (let i = 1; i <= c.JOIN_AS_MODERATOR_TEST_ROUNDS; i++) { + await this.modPage.init(true, true, { fullName: `Moderator-${i}` }); + await this.modPage.waitForSelector(e.userAvatar); + const hasPresenterClass = await this.modPage.page.evaluate(util.checkIncludeClass, [e.userAvatar, e.presenterClassName]); + await this.modPage.waitAndClick(e.actions); + const canStartPoll = await this.modPage.checkElement(e.polling); + if (!hasPresenterClass || !canStartPoll) { + failureCount++; + } + + const newPage = await this.context.newPage(); + await this.modPage.page.close(); + this.modPage.page = newPage; + console.log(`Loop ${i} of ${c.JOIN_AS_MODERATOR_TEST_ROUNDS} completed`); + await expect(failureCount).toBeLessThanOrEqual(maxFailRate); + } + } + + async breakoutRoomInvitation() { + await this.modPage.init(true, true, { fullName: 'Moderator' }); + for (let i = 1; i <= c.BREAKOUT_ROOM_INVITATION_TEST_ROUNDS; i++) { + const userName = `User-${i}`; + const newPage = await this.browser.newPage(); + const userPage = new Page(this.browser, newPage); + await userPage.init(false, true, { fullName: userName, meetingId: this.modPage.meetingId }); + console.log(`${userName} joined`); + this.userPages.push(userPage); + } + + // Create breakout rooms with the allow choice option enabled + await this.modPage.bringToFront(); + await this.modPage.waitAndClick(e.manageUsers); + await this.modPage.waitAndClick(e.createBreakoutRooms); + await this.modPage.waitAndClick(e.allowChoiceRoom); + await this.modPage.waitAndClick(e.modalConfirmButton); + + for (const page of this.userPages) { + await page.bringToFront(); + await page.hasElement(e.modalConfirmButton, c.ELEMENT_WAIT_LONGER_TIME); + await page.hasElement(e.labelGeneratingURL, c.ELEMENT_WAIT_LONGER_TIME); + } + + // End breakout rooms + await this.modPage.bringToFront(); + await this.modPage.waitAndClick(e.breakoutRoomsItem); + await this.modPage.waitAndClick(e.endBreakoutRoomsButton); + await this.modPage.closeAudioModal(); + + // Create breakout rooms with the allow choice option NOT enabled (randomly assign) + await this.modPage.waitAndClick(e.manageUsers); + await this.modPage.waitAndClick(e.createBreakoutRooms); + await this.modPage.waitAndClick(e.randomlyAssign); + await this.modPage.waitAndClick(e.modalConfirmButton); + + for (const page of this.userPages) { + await page.bringToFront(); + await page.hasElement(e.modalConfirmButton); + } + } +} + +exports.Stress = Stress; \ No newline at end of file diff --git a/bigbluebutton-tests/playwright/stress/stress.spec.js b/bigbluebutton-tests/playwright/stress/stress.spec.js new file mode 100644 index 0000000000..6034837745 --- /dev/null +++ b/bigbluebutton-tests/playwright/stress/stress.spec.js @@ -0,0 +1,16 @@ +const { test } = require('@playwright/test'); +const { Stress } = require('./stress.js'); + +test.describe.parallel('Stress', () => { + test.beforeEach(async () => test.setTimeout(0)); + + test('First moderator joining as presenter', async ({ browser, context, page }) => { + const stress = new Stress(browser, context, page); + await stress.moderatorAsPresenter(); + }); + + test('All users must receive breakout room invitations', async ({ browser, context, page }) => { + const stress = new Stress(browser, context, page); + await stress.breakoutRoomInvitation(); + }); +}) \ No newline at end of file diff --git a/bigbluebutton-tests/playwright/stress/util.js b/bigbluebutton-tests/playwright/stress/util.js new file mode 100644 index 0000000000..4afb6a2006 --- /dev/null +++ b/bigbluebutton-tests/playwright/stress/util.js @@ -0,0 +1,5 @@ +function checkIncludeClass([selector, className]) { + return document.querySelectorAll(selector)[0]?.className.includes(className); +} + +exports.checkIncludeClass = checkIncludeClass; \ No newline at end of file