diff --git a/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx b/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx index 5aeae436eb7a..6ff927e5ea33 100755 --- a/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/breakout-join-confirmation/component.jsx @@ -192,7 +192,7 @@ class BreakoutJoinConfirmation extends Component { )) } - { waiting ? {intl.formatMessage(intlMessages.generatingURL)} : null} + { waiting ? {intl.formatMessage(intlMessages.generatingURL)} : null} ); } diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx b/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx index 272966945bdc..251e9d2ceccb 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx @@ -536,6 +536,7 @@ class BreakoutRoom extends PureComponent { size="lg" label={intl.formatMessage(intlMessages.endAllBreakouts)} className={styles.endButton} + data-test="endBreakoutRoomsButton" onClick={() => { this.closePanel(); endAllBreakouts(); diff --git a/bigbluebutton-tests/puppeteer/core/constants.js b/bigbluebutton-tests/puppeteer/core/constants.js index 52e8308878ef..8beb4477dd11 100644 --- a/bigbluebutton-tests/puppeteer/core/constants.js +++ b/bigbluebutton-tests/puppeteer/core/constants.js @@ -10,6 +10,7 @@ exports.CLIENT_RECONNECTION_TIMEOUT = 120000; // STRESS TESTS VARS exports.JOIN_AS_MODERATOR_TEST_ROUNDS = 100; 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; diff --git a/bigbluebutton-tests/puppeteer/core/elements.js b/bigbluebutton-tests/puppeteer/core/elements.js index 814ec446074f..5d30b8312e6a 100644 --- a/bigbluebutton-tests/puppeteer/core/elements.js +++ b/bigbluebutton-tests/puppeteer/core/elements.js @@ -52,6 +52,9 @@ exports.breakoutRoomsButton = 'div[aria-label="Breakout Rooms"]'; exports.generateRoom1 = 'button[aria-label="Generate URL Room 1"]'; exports.joinGeneratedRoom1 = 'button[aria-label="Generated Room 1"]'; exports.joinRoom1 = 'button[aria-label="Join room Room 1"]'; +exports.allowChoiceRoom = 'input[id="freeJoinCheckbox"]'; +exports.labelGeneratingURL = 'span[data-test="labelGeneratingURL"]'; +exports.endBreakoutRoomsButton = 'button[data-test="endBreakoutRoomsButton"]'; // Chat exports.chatButton = 'div[data-test="chatButton"]'; diff --git a/bigbluebutton-tests/puppeteer/stress/stress.js b/bigbluebutton-tests/puppeteer/stress/stress.js index 446541d840b0..ff6f70fb01e0 100644 --- a/bigbluebutton-tests/puppeteer/stress/stress.js +++ b/bigbluebutton-tests/puppeteer/stress/stress.js @@ -4,9 +4,10 @@ const c = require('../core/constants'); const util = require('./util'); const { checkElementLengthEqualTo } = require('../core/util'); -class Stress extends Page { +class Stress { constructor() { - super(); + this.modPage = new Page(); + this.userPages = []; } async moderatorAsPresenter(testName) { @@ -14,26 +15,97 @@ class Stress extends Page { 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.init(true, true, testName, `Moderator-${i}`); - await this.waitForSelector(e.userAvatar); - const hasPresenterClass = await this.page.evaluate(util.checkIncludeClass, e.userAvatar, e.presenterClassName); - await this.waitAndClick(e.actions); - const canStartPoll = await this.page.evaluate(checkElementLengthEqualTo, e.polling, 1); + await this.modPage.init(true, true, testName, `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.page.evaluate(checkElementLengthEqualTo, e.polling, 1); if (!hasPresenterClass || !canStartPoll) { failureCount++; - await this.screenshot(testName, `loop-${i}-failure-${testName}`); + await this.modPage.screenshot(testName, `loop-${i}-failure-${testName}`); } - await this.close(); - await this.logger(`Loop ${i} of ${c.JOIN_AS_MODERATOR_TEST_ROUNDS} completed`); + await this.modPage.close(); + await this.modPage.logger(`Loop ${i} of ${c.JOIN_AS_MODERATOR_TEST_ROUNDS} completed`); if (failureCount > maxFailRate) return false; } return true; } catch (err) { - await this.close(); - this.logger(err); + await this.modPage.logger(err); return false; } } + + async breakoutRoomInvitation(testName) { + try { + await this.modPage.init(true, true, testName, 'Moderator'); + for (let i = 1; i <= c.BREAKOUT_ROOM_INVITATION_TEST_ROUNDS; i++) { + const userName = `User-${i}`; + const userPage = new Page(); + await userPage.init(false, true, testName, userName, this.modPage.meetingId); + await userPage.logger(`${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.screenshot(testName, '01-modPage-before-create-breakout-rooms-allowing-choice'); + await this.modPage.waitAndClick(e.modalConfirmButton); + + for (const page of this.userPages) { + await page.bringToFront(); + const firstCheck = await page.hasElement(e.modalConfirmButton, c.ELEMENT_WAIT_LONGER_TIME); + const secondCheck = await page.wasRemoved(e.labelGeneratingURL, c.ELEMENT_WAIT_LONGER_TIME); + + if (!firstCheck || !secondCheck) { + await page.screenshot(testName, `${page.effectiveParams.fullName}-breakout-modal-failed`); + return false; + } + await page.screenshot(testName, `${page.effectiveParams.fullName}-breakout-modal-allowing-choice-success`); + } + + // 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.screenshot(testName, '02-modPage-before-create-breakout-rooms-not-allowing-choice'); + await this.modPage.waitAndClick(e.modalConfirmButton); + + for (const page of this.userPages) { + await page.bringToFront(); + const check = await page.hasElement(e.modalConfirmButton); + + if (!check) { + await page.screenshot(testName, `${page.effectiveParams.fullName}-breakout-modal-not-allowing-choose-failed`); + return false; + } + await page.screenshot(testName, `${page.effectiveParams.fullName}-breakout-modal-not-allowing-choose-success`); + } + + return true; + } catch (err) { + await this.modPage.logger(err); + return false; + } + } + + async closeUserPages() { + for (const page of this.userPages) { + try { + await page.close(); + } catch (err) { + await this.modPage.logger(err); + } + } + } } module.exports = exports = Stress; \ No newline at end of file diff --git a/bigbluebutton-tests/puppeteer/stress/stress.obj.js b/bigbluebutton-tests/puppeteer/stress/stress.obj.js index 142e1beaee3d..a9a592219df7 100644 --- a/bigbluebutton-tests/puppeteer/stress/stress.obj.js +++ b/bigbluebutton-tests/puppeteer/stress/stress.obj.js @@ -7,11 +7,31 @@ const stressTest = () => { let response; try { const testName = 'firstModeratorAsPresenter'; - await test.logger('begin of ', testName); + await test.modPage.logger('begin of ', testName); response = await test.moderatorAsPresenter(testName); - await test.logger('end of ', testName); + await test.modPage.logger('end of ', testName); } catch (err) { - await test.logger(err); + await test.modPage.logger(err); + } finally { + await test.modPage.close(); + } + expect(response).toBe(true); + }); + + // Check that all users invited to a breakout room can join it + test('All users must receive breakout room invitations', async () => { + const test = new Stress(); + let response; + try { + const testName = 'breakoutRoomInvitation'; + await test.modPage.logger('begin of ', testName); + response = await test.breakoutRoomInvitation(testName); + await test.modPage.logger('end of ', testName); + } catch (err) { + await test.modPage.logger(err); + } finally { + await test.modPage.close(); + await test.closeUserPages(); } expect(response).toBe(true); });