diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx index bde962f5c48da9fce7ea9b589aac92fdf57546af..00046f805bce6f05286059e703ebf3788025a3e4 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx @@ -561,7 +561,7 @@ class UserDropdown extends PureComponent { const contents = ( <div - data-test={isMe(user.userId) ? 'userListItemCurrent' : null} + data-test={isMe(user.userId) ? 'userListItemCurrent' : 'userListItem'} className={!actions.length ? styles.userListItem : null} > <div className={styles.userItemContents}> diff --git a/bigbluebutton-html5/tests/puppeteer/README.md b/bigbluebutton-html5/tests/puppeteer/README.md index 8122661af5e3e242645184a23cb705a5eb3c6150..635e17f71687e0123e82395045529ad4afd971b5 100644 --- a/bigbluebutton-html5/tests/puppeteer/README.md +++ b/bigbluebutton-html5/tests/puppeteer/README.md @@ -23,6 +23,8 @@ Copy the `.env-template` file to a new file, and name it `.env`. In the `.env` f To run all the tests at once, run `npm test`. If you have Jest installed globally, you can run individual tests with `jest TEST [TEST...]`. The tests are found in the `.test.js` files, but you may choose to omit file extensions when running the tests. +To run the tests and get their metrics, you will need to add inside `.env` file `METRICS_FOLDER="/tmp/bbb-metrics"` and `BBB_COLLECT_METRICS=true`; if `BBB_COLLECT_METRICS` receives `true`, the metrics will be generated at the end of the test inside `/tmp/bbb-metrics` folder. + ## Running the tests in a Docker container Using this method, you can run the tests with the latest version of the HTML5 client, which you can find in this repository. You will need Docker to run tests this way. To run the tests, just run `./test-html5.sh` from the `bigbluebutton/bigbluebutton-html5` directory. The script will start a Docker container with a BigBlueButton server and the source code for the HTML5 client, and will run the tests with this server before stopping and removing the container. diff --git a/bigbluebutton-html5/tests/puppeteer/core/helper.js b/bigbluebutton-html5/tests/puppeteer/core/helper.js index 27a73e76a152faa8191ef90e702b2a762f2e6c8a..275b51ffc071384a17d768b14e2a9f30588d169f 100644 --- a/bigbluebutton-html5/tests/puppeteer/core/helper.js +++ b/bigbluebutton-html5/tests/puppeteer/core/helper.js @@ -15,8 +15,8 @@ function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; } -async function createMeeting(params) { - const meetingID = `random-${getRandomInt(1000000, 10000000).toString()}`; +async function createMeeting(params, meetingId) { + const meetingID = meetingId || `random-${getRandomInt(1000000, 10000000).toString()}`; const mp = params.moderatorPW; const ap = params.attendeePW; const query = `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}&joinViaHtml5=true` diff --git a/bigbluebutton-html5/tests/puppeteer/core/page.js b/bigbluebutton-html5/tests/puppeteer/core/page.js index dfb891b24ffeacf8ee9382c4812667727a13484b..a7c48bc3c5b1b0a5c7330c53981bb0e808c63e6c 100644 --- a/bigbluebutton-html5/tests/puppeteer/core/page.js +++ b/bigbluebutton-html5/tests/puppeteer/core/page.js @@ -1,4 +1,6 @@ +require('dotenv').config(); const puppeteer = require('puppeteer'); +const fs = require('fs'); const helper = require('./helper'); const params = require('../params'); const e = require('./elements'); @@ -18,18 +20,25 @@ class Page { } // Join BigBlueButton meeting - async init(args) { + async init(args, meetingId, newParams) { + this.effectiveParams = newParams || params; this.browser = await puppeteer.launch(args); - this.page = await this.browser.newPage(); + this.page = await this.browser.newPage({ context: `bbb-${this.effectiveParams.fullName}` }); await this.setDownloadBehavior(`${this.parentDir}/downloads`); + this.meetingId = await helper.createMeeting(params, meetingId); - this.meetingId = await helper.createMeeting(params); - const joinURL = helper.getJoinURL(this.meetingId, params, true); + const joinURL = helper.getJoinURL(this.meetingId, this.effectiveParams, true); await this.page.goto(joinURL); await this.waitForSelector(e.audioDialog); await this.click(e.closeAudio, true); + const checkForGetMetrics = async () => { + if (process.env.BBB_COLLECT_METRICS === 'true') { + await this.getMetrics(); + } + }; + await checkForGetMetrics(); } async setDownloadBehavior(downloadPath) { @@ -129,6 +138,25 @@ class Page { async waitForSelector(element) { await this.page.waitForSelector(element, { timeout: 0 }); } + + async getMetrics() { + const metricsObj = {}; + const dir = process.env.METRICS_FOLDER; + const currentTimestamp = new Date(); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + const metric = await this.page.metrics(); + metricsObj[`metricObj-${this.effectiveParams.fullName}`] = metric; + const createFile = () => { + try { + fs.appendFileSync(`${dir}/metrics-${this.effectiveParams.fullName}-${currentTimestamp}.json`, `${JSON.stringify(metricsObj)}\n`); + } catch (error) { + console.log(error); + } + }; + createFile(); + } } module.exports = exports = Page; diff --git a/bigbluebutton-html5/tests/puppeteer/user.test.js b/bigbluebutton-html5/tests/puppeteer/user.test.js index 54ea37958e458d25d4c38bd7fa3800146a30c644..7ae783f2fbe21510e7bc211a17ea3f70d0908334 100644 --- a/bigbluebutton-html5/tests/puppeteer/user.test.js +++ b/bigbluebutton-html5/tests/puppeteer/user.test.js @@ -1,5 +1,6 @@ const Page = require('./core/page'); const Status = require('./user/status'); +const MultiUsers = require('./user/multiusers'); describe('User', () => { test('Change status', async () => { @@ -15,4 +16,18 @@ describe('User', () => { } expect(response).toBe(true); }); + + test('Multi user presence check', async () => { + const test = new MultiUsers(); + let response; + try { + await test.init(); + response = await test.test(); + } catch (err) { + console.log(err); + } finally { + await test.close(); + } + expect(response).toBe(true); + }); }); diff --git a/bigbluebutton-html5/tests/puppeteer/user/multiusers.js b/bigbluebutton-html5/tests/puppeteer/user/multiusers.js new file mode 100644 index 0000000000000000000000000000000000000000..f3e47b05a2dd0aec45d3c71adf49ff2a66f51e7b --- /dev/null +++ b/bigbluebutton-html5/tests/puppeteer/user/multiusers.js @@ -0,0 +1,38 @@ +const Page = require('../core/page'); +const params = require('../params'); + +class MultiUsers { + constructor() { + this.page1 = new Page(); + this.page2 = new Page(); + } + + // Join BigBlueButton meeting + async init(meetingId) { + await this.page1.init(Page.getArgs(), meetingId, params); + await this.page2.init(Page.getArgs(), this.page1.meetingId, { ...params, fullName: 'User2' }); + } + + // Run the test for the page + async checkForOtherUser() { + const firstCheck = await this.page1.page.evaluate(() => document.querySelectorAll('[data-test="userListItem"]').length > 0); + const secondCheck = await this.page2.page.evaluate(() => document.querySelectorAll('[data-test="userListItem"]').length > 0); + return { + firstCheck, + secondCheck, + }; + } + + async test() { + const checks = await this.checkForOtherUser(); + return checks.firstCheck !== false && checks.secondCheck !== false; + } + + // Close all Pages + async close() { + await this.page1.close(); + await this.page2.close(); + } +} + +module.exports = exports = MultiUsers;