Merge branch 'develop' of https://github.com/bigbluebutton/bigbluebutton into issue-8544
This commit is contained in:
commit
81d0d5b0dc
6
.github/ISSUE_TEMPLATE/html5-issue.md
vendored
6
.github/ISSUE_TEMPLATE/html5-issue.md
vendored
@ -26,6 +26,12 @@ A clear and concise description of what you expected to happen.
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**BBB version (optional):**
|
||||
BigBlueButton continually evolves. Providing the version/build helps us to pinpoint when an issue was introduced.
|
||||
Example:
|
||||
$ sudo bbb-conf --check | grep BigBlueButton
|
||||
BigBlueButton Server 2.2.2 (1816)
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Windows, Mac]
|
||||
- Browser [e.g. Chrome, Safari]
|
||||
|
@ -128,6 +128,7 @@ class ActionsDropdown extends PureComponent {
|
||||
? (
|
||||
<DropdownListItem
|
||||
icon="polling"
|
||||
data-test="polling"
|
||||
label={formatMessage(pollBtnLabel)}
|
||||
description={formatMessage(pollBtnDesc)}
|
||||
key={this.pollId}
|
||||
|
@ -174,6 +174,7 @@ class Poll extends Component {
|
||||
label={label}
|
||||
color="default"
|
||||
className={styles.pollBtn}
|
||||
data-test="pollBtn"
|
||||
key={_.uniqueId('quick-poll-')}
|
||||
onClick={() => {
|
||||
Session.set('pollInitiated', true);
|
||||
@ -338,6 +339,7 @@ class Poll extends Component {
|
||||
<header className={styles.header}>
|
||||
<Button
|
||||
ref={(node) => { this.hideBtn = node; }}
|
||||
data-test="hidePollDesc"
|
||||
tabIndex={0}
|
||||
label={intl.formatMessage(intlMessages.pollPaneTitle)}
|
||||
icon="left_arrow"
|
||||
|
@ -206,6 +206,7 @@ class LiveResult extends PureComponent {
|
||||
stopPoll();
|
||||
}}
|
||||
label={intl.formatMessage(intlMessages.publishLabel)}
|
||||
data-test="publishLabel"
|
||||
color="primary"
|
||||
className={styles.btn}
|
||||
/>
|
||||
|
@ -683,7 +683,7 @@ class PresentationUploader extends Component {
|
||||
disablepreview="true"
|
||||
onDrop={this.handleFiledrop}
|
||||
>
|
||||
<Icon className={styles.dropzoneIcon} iconName="upload" />
|
||||
<Icon className={styles.dropzoneIcon} data-test="fileUploadDropZone" iconName="upload" />
|
||||
<p className={styles.dropzoneMessage}>
|
||||
{intl.formatMessage(intlMessages.dropzoneLabel)}
|
||||
|
||||
|
@ -114,6 +114,7 @@
|
||||
.presenter {
|
||||
&:before {
|
||||
content: "\00a0\e90b\00a0";
|
||||
padding: var(--md-padding-y);
|
||||
}
|
||||
@include presenterIndicator();
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ class VideoListItem extends Component {
|
||||
>
|
||||
{
|
||||
!videoIsReady
|
||||
&& <div className={styles.connecting} />
|
||||
&& <div data-test="webcamConnecting" className={styles.connecting} />
|
||||
}
|
||||
<div
|
||||
className={styles.videoContainer}
|
||||
|
@ -1,2 +1,18 @@
|
||||
# meeting credentials
|
||||
BBB_SERVER_URL=""
|
||||
BBB_SHARED_SECRET=""
|
||||
BBB_SHARED_SECRET=""
|
||||
|
||||
# collecting metrics
|
||||
BBB_COLLECT_METRICS= # (true/false): true to collect metrics
|
||||
METRICS_FOLDER= # full path of your audio.wav file
|
||||
|
||||
# files paths for audio and webcams tests
|
||||
AUDIO_FILE= # full path of your audio.wav file
|
||||
VIDEO_FILE= # full path of your video.y4m file
|
||||
|
||||
# webcams test
|
||||
LOOP_INTERVAL= # time to loop in the webcams test in milliseconds
|
||||
CAMERA_SHARE_FAILED_WAIT_TIME=15000 # this is set by default in the BBB server
|
||||
|
||||
# audio test
|
||||
IS_AUDIO_TEST= # (true/false): true if the test will require enabling audio
|
@ -1,7 +1,7 @@
|
||||
const util = require('./util');
|
||||
const utilNotification = require('../notifications/util');
|
||||
const Page = require('../core/page');
|
||||
const params = require('../params');
|
||||
const pe = require('../core/elements');
|
||||
const util = require('./util');
|
||||
|
||||
class Audio {
|
||||
constructor() {
|
||||
@ -17,6 +17,11 @@ class Audio {
|
||||
await this.page2.joinMicrophone();
|
||||
}
|
||||
|
||||
async initOneUser(page,meetingId) {
|
||||
await page.init(Page.getArgsWithAudio(), meetingId, {...params, fullName: 'User1'});
|
||||
await page.joinMicrophone();
|
||||
}
|
||||
|
||||
async test() {
|
||||
// User1 is checking if User2 is talking
|
||||
const isTalkingIndicatorUser1 = await util.checkUserIsTalkingIndicator(this.page1);
|
||||
@ -43,6 +48,11 @@ class Audio {
|
||||
return response;
|
||||
}
|
||||
|
||||
async audioNotification(page) {
|
||||
const resp = await utilNotification.getLastToastValue(page);
|
||||
return resp;
|
||||
}
|
||||
|
||||
async close() {
|
||||
this.page1.close();
|
||||
this.page2.close();
|
||||
|
@ -6,7 +6,6 @@ exports.echoYes = 'button[aria-label="Echo is audible"]';
|
||||
exports.title = '._imports_ui_components_nav_bar__styles__presentationTitle';
|
||||
exports.alerts = '.toastify-content';
|
||||
|
||||
|
||||
exports.isTalking = '[data-test="isTalking"]';
|
||||
exports.wasTalking = '[data-test="wasTalking"]';
|
||||
exports.joinAudio = 'button[aria-label="Join Audio"]';
|
||||
|
3
bigbluebutton-html5/tests/puppeteer/notes/elements.js
Normal file
3
bigbluebutton-html5/tests/puppeteer/notes/elements.js
Normal file
@ -0,0 +1,3 @@
|
||||
exports.sharedNotes = 'div[data-test="sharedNotes"]';
|
||||
exports.hideNoteLabel = 'button[data-test="hideNoteLabel"]';
|
||||
exports.etherpad = 'iframe[title="etherpad"]';
|
19
bigbluebutton-html5/tests/puppeteer/notes/sharednotes.js
Normal file
19
bigbluebutton-html5/tests/puppeteer/notes/sharednotes.js
Normal file
@ -0,0 +1,19 @@
|
||||
const Create = require('../breakout/create');
|
||||
const util = require('./util');
|
||||
|
||||
class SharedNotes extends Create {
|
||||
constructor() {
|
||||
super('shared-notes');
|
||||
}
|
||||
|
||||
async test() {
|
||||
const response = await util.startSharedNotes(this.page1);
|
||||
return response;
|
||||
}
|
||||
|
||||
async close() {
|
||||
await this.page1.close();
|
||||
await this.page2.close();
|
||||
}
|
||||
}
|
||||
module.exports = exports = SharedNotes;
|
18
bigbluebutton-html5/tests/puppeteer/notes/util.js
Normal file
18
bigbluebutton-html5/tests/puppeteer/notes/util.js
Normal file
@ -0,0 +1,18 @@
|
||||
const se = require('./elements');
|
||||
|
||||
async function startSharedNotes(test) {
|
||||
await test.waitForSelector(se.sharedNotes);
|
||||
await test.click(se.sharedNotes, true);
|
||||
await test.waitForSelector(se.hideNoteLabel);
|
||||
const resp = await test.page.evaluate(getTestElement, se.etherpad);
|
||||
await test.waitForSelector(se.etherpad);
|
||||
return resp;
|
||||
}
|
||||
|
||||
async function getTestElement(element) {
|
||||
const response = document.querySelectorAll(element).length >= 1;
|
||||
return response;
|
||||
}
|
||||
|
||||
exports.getTestElement = getTestElement;
|
||||
exports.startSharedNotes = startSharedNotes;
|
@ -1,6 +1,6 @@
|
||||
const Page = require('./core/page');
|
||||
const MultiUsers = require('./user/multiusers');
|
||||
const Notifications = require('./notifications/notifications');
|
||||
const ShareScreen = require('./screenshare/screenshare');
|
||||
const Audio = require('./audio/audio');
|
||||
|
||||
describe('Notifications', () => {
|
||||
test('Save settings notification', async () => {
|
||||
@ -8,7 +8,7 @@ describe('Notifications', () => {
|
||||
let response;
|
||||
try {
|
||||
await test.init();
|
||||
response = await test.saveSttingsNotification();
|
||||
response = await test.saveSettingsNotification();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
@ -44,4 +44,79 @@ describe('Notifications', () => {
|
||||
}
|
||||
expect(response).toBe(true);
|
||||
});
|
||||
|
||||
test('User join notification', async () => {
|
||||
const test = new Notifications();
|
||||
let response;
|
||||
try {
|
||||
await test.initUser3();
|
||||
await test.userJoinNotification();
|
||||
await test.initUser4();
|
||||
response = await test.getUserJoinPopupResponse();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await test.closePages();
|
||||
}
|
||||
expect(response).toBe('User4 joined the session');
|
||||
});
|
||||
|
||||
test('Presentation upload notification', async () => {
|
||||
const test = new Notifications();
|
||||
let response;
|
||||
try {
|
||||
await test.initUser3();
|
||||
response = await test.fileUploaderNotification();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await test.closePage(test.page3);
|
||||
}
|
||||
expect(response).toContain('Current presentation');
|
||||
});
|
||||
|
||||
test('Poll results notification', async () => {
|
||||
const test = new Notifications();
|
||||
let response;
|
||||
try {
|
||||
await test.initUser3();
|
||||
response = await test.publishPollResults();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await test.closePage(test.page3);
|
||||
}
|
||||
expect(response).toContain('Poll results were published to Public Chat and Whiteboard');
|
||||
});
|
||||
|
||||
test('Screenshare notification', async () => {
|
||||
const test = new ShareScreen();
|
||||
const page = new Notifications()
|
||||
let response;
|
||||
try {
|
||||
await page.initUser3();
|
||||
response = await test.toast(page.page3);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await page.closePage(page.page3);
|
||||
}
|
||||
expect(response).toBe('Screenshare has started');
|
||||
});
|
||||
|
||||
test('Audio notifications', async () => {
|
||||
const test = new Audio();
|
||||
const page = new Notifications();
|
||||
let response;
|
||||
try {
|
||||
process.env.IS_AUDIO_TEST = true;
|
||||
await test.initOneUser(page.page3);
|
||||
response = await test.audioNotification(page.page3);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await page.closePage(page.page3);
|
||||
}
|
||||
expect(response).toBe('You have joined the audio conference');
|
||||
})
|
||||
});
|
||||
|
@ -9,3 +9,13 @@ exports.publicChatToast = 'New Public Chat message';
|
||||
exports.privateChatToast = 'New Private Chat message';
|
||||
exports.userListNotifiedIcon = '[class^=btnWithNotificationDot]';
|
||||
exports.hasUnreadMessages = 'button[data-test="hasUnreadMessages"]';
|
||||
|
||||
exports.modalConfirmButton = 'button[data-test="modalConfirmButton"]';
|
||||
exports.userJoinPushAlerts = '[data-test="userJoinPushAlerts"]';
|
||||
exports.uploadPresentation = '[data-test="uploadPresentation"]';
|
||||
exports.dropdownContent = '[data-test="dropdownContent"]';
|
||||
exports.fileUploadDropZone = '[data-test="fileUploadDropZone"]';
|
||||
exports.polling = '[data-test="polling"]';
|
||||
exports.hidePollDesc = '[data-test="hidePollDesc"]';
|
||||
exports.pollBtn = '[data-test="pollBtn"]';
|
||||
exports.publishLabel = '[data-test="publishLabel"]';
|
||||
|
@ -1,16 +1,17 @@
|
||||
const Page = require('../core/page');
|
||||
const util = require('./util');
|
||||
const utilMultiUsers = require('../chat/util');
|
||||
const MultiUsers = require('../user/multiusers');
|
||||
const Page = require('../core/page');
|
||||
const params = require('../params');
|
||||
const util = require('./util');
|
||||
const ne = require('./elements');
|
||||
const e = require('../chat/elements');
|
||||
const we = require('../whiteboard/elements');
|
||||
|
||||
class Notifications extends MultiUsers {
|
||||
constructor() {
|
||||
super('notifications');
|
||||
this.page1 = new Page();
|
||||
this.page2 = new Page();
|
||||
this.page3 = new Page();
|
||||
this.page4 = new Page();
|
||||
}
|
||||
|
||||
async init(meetingId) {
|
||||
@ -18,13 +19,23 @@ class Notifications extends MultiUsers {
|
||||
await this.page2.init(Page.getArgs(), this.page1.meetingId, { ...params, fullName: 'User2' });
|
||||
}
|
||||
|
||||
async saveSttingsNotification() {
|
||||
async initUser3(meetingId) {
|
||||
await this.page3.init(Page.getArgs(), meetingId, { ...params, fullName: 'User3' });
|
||||
}
|
||||
|
||||
async initUser4() {
|
||||
await this.page4.init(Page.getArgs(), this.page3.meetingId, { ...params, fullName: 'User4' });
|
||||
}
|
||||
|
||||
// Save Settings toast notification
|
||||
async saveSettingsNotification() {
|
||||
await util.popupMenu(this.page1);
|
||||
await util.saveSettings(this.page1);
|
||||
const resp = await util.getLastToastValue(this.page1) === ne.savedSettingsToast;
|
||||
return resp;
|
||||
}
|
||||
|
||||
// Public chat toast notification
|
||||
async publicChatNotification() {
|
||||
await util.popupMenu(this.page1);
|
||||
await util.enableChatPopup(this.page1);
|
||||
@ -36,7 +47,7 @@ class Notifications extends MultiUsers {
|
||||
return expectedToastValue === lastToast;
|
||||
}
|
||||
|
||||
|
||||
// Private chat toast notification
|
||||
async privateChatNotification() {
|
||||
await util.popupMenu(this.page1);
|
||||
await util.enableChatPopup(this.page1);
|
||||
@ -47,6 +58,44 @@ class Notifications extends MultiUsers {
|
||||
const lastToast = await util.getOtherToastValue(this.page1);
|
||||
return expectedToastValue === lastToast;
|
||||
}
|
||||
|
||||
// User join toast notification
|
||||
async userJoinNotification() {
|
||||
await util.popupMenu(this.page3);
|
||||
await util.enableUserJoinPopup(this.page3);
|
||||
await util.saveSettings(this.page3);
|
||||
}
|
||||
|
||||
async getUserJoinPopupResponse() {
|
||||
await this.page3.waitForSelector(ne.smallToastMsg);
|
||||
const response = await util.getOtherToastValue(this.page3);
|
||||
return response;
|
||||
}
|
||||
|
||||
// File upload notification
|
||||
async fileUploaderNotification() {
|
||||
await util.uploadFileMenu(this.page3);
|
||||
await this.page3.waitForSelector(ne.fileUploadDropZone);
|
||||
const inputUploadHandle = await this.page3.page.$('input[type=file]');
|
||||
await inputUploadHandle.uploadFile(process.env.PDF_FILE);
|
||||
await this.page3.page.evaluate(util.clickTestElement, ne.modalConfirmButton);
|
||||
const resp = await util.getLastToastValue(this.page3);
|
||||
await this.page3.waitForSelector(we.whiteboard);
|
||||
return resp;
|
||||
}
|
||||
|
||||
async publishPollResults() {
|
||||
await this.page3.waitForSelector(we.whiteboard);
|
||||
await util.startPoll(this.page3);
|
||||
await this.page3.waitForSelector(ne.smallToastMsg);
|
||||
const resp = await util.getLastToastValue(this.page3);
|
||||
return resp;
|
||||
}
|
||||
|
||||
async closePages() {
|
||||
await this.page3.close();
|
||||
await this.page4.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Notifications;
|
||||
|
@ -1,13 +1,15 @@
|
||||
const e = require('../core/elements');
|
||||
const ne = require('../notifications/elements');
|
||||
const ce = require('../chat/elements');
|
||||
const ule = require('../user/elements');
|
||||
const ce = require('../chat/elements');
|
||||
const e = require('../core/elements');
|
||||
|
||||
async function popupMenu(page1) {
|
||||
await page1.waitForSelector(e.options);
|
||||
await page1.click(e.options, true);
|
||||
await page1.waitForSelector(ne.settings);
|
||||
await page1.click(ne.settings, true);
|
||||
async function clickTestElement(element) {
|
||||
await document.querySelectorAll(element)[0].click();
|
||||
}
|
||||
|
||||
async function popupMenu(page) {
|
||||
await page.page.evaluate(clickTestElement, e.options);
|
||||
await page.page.evaluate(clickTestElement, ne.settings);
|
||||
}
|
||||
|
||||
async function enableChatPopup(test) {
|
||||
@ -15,9 +17,14 @@ async function enableChatPopup(test) {
|
||||
await test.page.evaluate(() => document.querySelector('[data-test="chatPushAlerts"]').children[0].click());
|
||||
}
|
||||
|
||||
async function saveSettings(page1) {
|
||||
await page1.waitForSelector(ne.saveSettings);
|
||||
await page1.click(ne.saveSettings, true);
|
||||
async function enableUserJoinPopup(test) {
|
||||
await test.waitForSelector(ne.userJoinPushAlerts);
|
||||
await test.page.evaluate(() => document.querySelector('[data-test="userJoinPushAlerts"]').children[0].click());
|
||||
}
|
||||
|
||||
async function saveSettings(page) {
|
||||
await page.waitForSelector(ne.saveSettings);
|
||||
await page.click(ne.saveSettings, true);
|
||||
}
|
||||
|
||||
async function waitForToast(test) {
|
||||
@ -28,8 +35,8 @@ async function waitForToast(test) {
|
||||
|
||||
async function getLastToastValue(test) {
|
||||
await test.waitForSelector(ne.smallToastMsg);
|
||||
const toast = test.page.evaluate(async () => {
|
||||
const lastToast = await document.querySelectorAll('[data-test="toastSmallMsg"]')[0].innerText;
|
||||
const toast = test.page.evaluate(() => {
|
||||
const lastToast = document.querySelectorAll('[data-test="toastSmallMsg"]')[0].innerText;
|
||||
return lastToast;
|
||||
});
|
||||
return toast;
|
||||
@ -37,9 +44,9 @@ async function getLastToastValue(test) {
|
||||
|
||||
async function getOtherToastValue(test) {
|
||||
await test.waitForSelector(ne.smallToastMsg);
|
||||
const toast = test.page.evaluate(async () => {
|
||||
const lastToast = await document.querySelectorAll('[data-test="toastSmallMsg"]')[1];
|
||||
return lastToast.innerText;
|
||||
const toast = test.page.evaluate(() => {
|
||||
const lastToast = document.querySelectorAll('[data-test="toastSmallMsg"]')[1].innerText;
|
||||
return lastToast;
|
||||
});
|
||||
return toast;
|
||||
}
|
||||
@ -48,8 +55,7 @@ async function getTestElement(element) {
|
||||
await document.querySelectorAll(element)[1];
|
||||
}
|
||||
|
||||
|
||||
async function clickOnTheOtherUser(element) {
|
||||
async function clickOnElement(element) {
|
||||
await document.querySelectorAll(element)[0].click();
|
||||
}
|
||||
|
||||
@ -59,7 +65,7 @@ async function clickThePrivateChatButton(element) {
|
||||
|
||||
async function publicChatMessageToast(page1, page2) {
|
||||
// Open private Chat with the other User
|
||||
await page1.page.evaluate(clickOnTheOtherUser, ule.userListItem);
|
||||
await page1.page.evaluate(clickOnElement, ule.userListItem);
|
||||
await page1.page.evaluate(clickThePrivateChatButton, ce.activeChat);
|
||||
// send a public message
|
||||
await page2.page.type(ce.publicChat, ce.publicMessage1);
|
||||
@ -69,7 +75,7 @@ async function publicChatMessageToast(page1, page2) {
|
||||
|
||||
async function privateChatMessageToast(page2) {
|
||||
// Open private Chat with the other User
|
||||
await page2.page.evaluate(clickOnTheOtherUser, ule.userListItem);
|
||||
await page2.page.evaluate(clickOnElement, ule.userListItem);
|
||||
await page2.page.evaluate(clickThePrivateChatButton, ce.activeChat);
|
||||
// send a private message
|
||||
await page2.page.type(ce.privateChat, ce.message1);
|
||||
@ -77,12 +83,43 @@ async function privateChatMessageToast(page2) {
|
||||
return ne.privateChatToast;
|
||||
}
|
||||
|
||||
// File upload notification
|
||||
async function uploadFileMenu(test) {
|
||||
await test.page.evaluate(clickOnElement, ne.dropdownContent);
|
||||
await test.page.evaluate(clickOnElement, ne.uploadPresentation);
|
||||
}
|
||||
|
||||
async function getFileItemStatus(element, value) {
|
||||
document.querySelectorAll(element)[1].innerText.includes(value);
|
||||
}
|
||||
|
||||
async function clickRandomPollOption(element) {
|
||||
document.querySelector(element).click();
|
||||
}
|
||||
|
||||
async function startPoll(test) {
|
||||
await test.page.evaluate(clickOnElement, ne.dropdownContent);
|
||||
await test.page.evaluate(clickOnElement, ne.polling);
|
||||
await test.waitForSelector(ne.hidePollDesc);
|
||||
await test.waitForSelector(ne.pollBtn);
|
||||
await test.page.evaluate(clickRandomPollOption, ne.pollBtn);
|
||||
await test.waitForSelector(ne.publishLabel);
|
||||
await test.page.evaluate(clickOnElement, ne.publishLabel);
|
||||
await test.waitForSelector(ne.smallToastMsg);
|
||||
}
|
||||
|
||||
exports.getFileItemStatus = getFileItemStatus;
|
||||
exports.privateChatMessageToast = privateChatMessageToast;
|
||||
exports.publicChatMessageToast = publicChatMessageToast;
|
||||
exports.enableUserJoinPopup = enableUserJoinPopup;
|
||||
exports.getOtherToastValue = getOtherToastValue;
|
||||
exports.getLastToastValue = getLastToastValue;
|
||||
exports.enableChatPopup = enableChatPopup;
|
||||
exports.uploadFileMenu = uploadFileMenu;
|
||||
exports.getTestElement = getTestElement;
|
||||
exports.saveSettings = saveSettings;
|
||||
exports.waitForToast = waitForToast;
|
||||
exports.popupMenu = popupMenu;
|
||||
exports.clickTestElement = clickTestElement;
|
||||
exports.startPoll = startPoll;
|
||||
exports.clickOnElement = clickOnElement;
|
||||
|
@ -1,4 +1,5 @@
|
||||
const Page = require('../core/page');
|
||||
const utilNotifications = require('../notifications/util');
|
||||
const util = require('./util');
|
||||
const e = require('../core/elements');
|
||||
|
||||
@ -9,13 +10,17 @@ class ShareScreen extends Page {
|
||||
|
||||
async test() {
|
||||
await util.startScreenshare(this.page);
|
||||
this.page.on('dialog', async (dialog) => {
|
||||
await dialog.accept();
|
||||
});
|
||||
|
||||
await this.page.waitForSelector(e.screenShareVideo);
|
||||
const response = await util.getScreenShareContainer(this.page);
|
||||
return response;
|
||||
}
|
||||
|
||||
async toast(page) {
|
||||
await util.startScreenshare(page);
|
||||
const response = await utilNotifications.getLastToastValue(page);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = ShareScreen;
|
||||
|
17
bigbluebutton-html5/tests/puppeteer/sharednotes.test.js
Normal file
17
bigbluebutton-html5/tests/puppeteer/sharednotes.test.js
Normal file
@ -0,0 +1,17 @@
|
||||
const SharedNotes = require('./notes/sharednotes');
|
||||
|
||||
describe('Shared notes', () => {
|
||||
test('Open Shared notes', async () => {
|
||||
const test = new SharedNotes();
|
||||
let response;
|
||||
try {
|
||||
await test.init();
|
||||
response = await test.test();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await test.close();
|
||||
}
|
||||
expect(response).toBe(true);
|
||||
});
|
||||
});
|
@ -50,6 +50,10 @@ class MultiUsers {
|
||||
await this.page1.close();
|
||||
await this.page2.close();
|
||||
}
|
||||
|
||||
async closePage(page) {
|
||||
await page.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = MultiUsers;
|
||||
|
@ -1,13 +1,13 @@
|
||||
const Share = require('./webcam/share');
|
||||
const Check = require('./webcam/check');
|
||||
const LoadingTime = require('./webcam/loadtime');
|
||||
const Page = require('./core/page');
|
||||
|
||||
describe('Webcam', () => {
|
||||
test('Shares webcam', async () => {
|
||||
const test = new Share();
|
||||
let response;
|
||||
try {
|
||||
await test.init();
|
||||
await test.init(Page.getArgsWithVideo());
|
||||
response = await test.test();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
@ -17,25 +17,11 @@ describe('Webcam', () => {
|
||||
expect(response).toBe(true);
|
||||
});
|
||||
|
||||
test('Check Webcam loading time', async () => {
|
||||
const test = new LoadingTime();
|
||||
let response;
|
||||
try {
|
||||
await test.init();
|
||||
response = await test.test();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
await test.close();
|
||||
}
|
||||
expect(response).toBeLessThan(parseInt(process.env.CAMERA_SHARE_FAILED_WAIT_TIME));
|
||||
});
|
||||
|
||||
test('Checks content of webcam', async () => {
|
||||
const test = new Check();
|
||||
let response;
|
||||
try {
|
||||
await test.init();
|
||||
await test.init(Page.getArgsWithVideo());
|
||||
response = await test.test();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
@ -7,11 +7,9 @@ class Check extends Share {
|
||||
}
|
||||
|
||||
async test() {
|
||||
await util.startAndCheckForWebcams(this.page1);
|
||||
await util.startAndCheckForWebcams(this.page2);
|
||||
const responseUser1 = await util.webcamContentCheck(this.page1);
|
||||
const responseUser2 = await util.webcamContentCheck(this.page2);
|
||||
return responseUser1 && responseUser2;
|
||||
await util.enableWebcam(this.page);
|
||||
const respUser = await util.webcamContentCheck(this.page);
|
||||
return respUser === true;
|
||||
}
|
||||
}
|
||||
module.exports = exports = Check;
|
||||
|
@ -2,5 +2,4 @@ exports.joinVideo = 'button[data-test="joinVideo"]';
|
||||
exports.videoPreview = 'video[data-test="videoPreview"]';
|
||||
exports.startSharingWebcam = 'button[data-test="startSharingWebcam"]';
|
||||
exports.videoContainer = 'video[data-test="videoContainer"]';
|
||||
exports.webcamConnectingStatus = '[data-test="webcamConnectingStatus"]';
|
||||
exports.presentationFullscreenButton = '[data-test="presentationFullscreenButton"]';
|
||||
exports.webcamConnecting = '[data-test="webcamConnecting"]';
|
||||
|
@ -1,19 +0,0 @@
|
||||
const Share = require('./share');
|
||||
const util = require('./util');
|
||||
|
||||
class LoadingTime extends Share {
|
||||
constructor() {
|
||||
super('check-webcam-loading-time');
|
||||
}
|
||||
|
||||
async test() {
|
||||
await util.enableWebcam(this.page1);
|
||||
await util.enableWebcam(this.page2);
|
||||
const now = new Date().getMilliseconds();
|
||||
await util.waitForWebcamsLoading(this.page1);
|
||||
await util.waitForWebcamsLoading(this.page2);
|
||||
const end = new Date().getMilliseconds();
|
||||
return end - now;
|
||||
}
|
||||
}
|
||||
module.exports = exports = LoadingTime;
|
@ -1,29 +1,15 @@
|
||||
const Page = require('../core/page');
|
||||
const util = require('./util');
|
||||
const params = require('../params');
|
||||
|
||||
class Share {
|
||||
class Share extends Page{
|
||||
constructor() {
|
||||
this.page1 = new Page();
|
||||
this.page2 = new Page();
|
||||
}
|
||||
|
||||
async init(meetingId) {
|
||||
await this.page1.init(Page.getArgsWithVideo(), meetingId, { ...params, fullName: 'Streamer1' });
|
||||
await this.page2.init(Page.getArgsWithVideo(), this.page1.meetingId, { ...params, fullName: 'Streamer2' });
|
||||
super('webcam-test');
|
||||
}
|
||||
|
||||
async test() {
|
||||
await util.enableWebcam(this.page1);
|
||||
await util.enableWebcam(this.page2);
|
||||
const responseUser1 = await util.evaluateCheck(this.page1);
|
||||
const responseUser2 = await util.evaluateCheck(this.page2);
|
||||
return responseUser1 && responseUser2;
|
||||
}
|
||||
|
||||
async close() {
|
||||
await this.page1.close();
|
||||
await this.page2.close();
|
||||
await util.enableWebcam(this.page);
|
||||
const response = await util.evaluateCheck(this.page);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@ const we = require('./elements');
|
||||
async function enableWebcam(test) {
|
||||
// Enabling webcam
|
||||
await test.waitForSelector(we.joinVideo);
|
||||
await test.click(we.joinVideo, true);
|
||||
await test.click(we.joinVideo);
|
||||
await test.waitForSelector(we.videoPreview);
|
||||
await test.waitForSelector(we.startSharingWebcam);
|
||||
await test.click(we.startSharingWebcam, true);
|
||||
await test.click(we.startSharingWebcam);
|
||||
}
|
||||
|
||||
async function getTestElement(element) {
|
||||
@ -15,8 +15,7 @@ async function getTestElement(element) {
|
||||
|
||||
async function evaluateCheck(test) {
|
||||
await test.waitForSelector(we.videoContainer);
|
||||
await test.waitForSelector(we.webcamConnectingStatus);
|
||||
const videoContainer = await test.page.evaluate(getTestElement, we.presentationFullscreenButton);
|
||||
const videoContainer = await test.evaluate(getTestElement, we.presentationFullscreenButton);
|
||||
const response = videoContainer !== null;
|
||||
return response;
|
||||
}
|
||||
@ -27,35 +26,41 @@ async function startAndCheckForWebcams(test) {
|
||||
return response;
|
||||
}
|
||||
|
||||
async function checkCameras() {
|
||||
const videos = document.querySelectorAll('video');
|
||||
const lastVideoColor = document.lastVideoColor || {};
|
||||
document.lastVideoColor = lastVideoColor;
|
||||
|
||||
for (let v = 0; v < videos.length; v++) {
|
||||
const video = videos[v];
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
||||
const pixel = context.getImageData(50, 50, 1, 1).data;
|
||||
const pixelString = new Array(pixel).join(' ').toString();
|
||||
|
||||
if (lastVideoColor[v]) {
|
||||
if (lastVideoColor[v] == pixelString) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return lastVideoColor[v] !== pixelString === true;
|
||||
}
|
||||
}
|
||||
|
||||
async function webcamContentCheck(test) {
|
||||
await test.waitForSelector(we.videoContainer);
|
||||
await test.waitForFunction(() => !document.querySelector('[data-test="webcamConnecting"]'));
|
||||
|
||||
const repeats = 5;
|
||||
let check;
|
||||
for (let i = repeats; i >= 0; i--) {
|
||||
await test.page.waitFor(parseInt(process.env.LOOP_INTERVAL));
|
||||
return check = await test.page.evaluate(checkCameras);
|
||||
for (let i = repeats; i >= 1; i--) {
|
||||
console.log(`loop ${i}`);
|
||||
const checkCameras = function (i) {
|
||||
const videos = document.querySelectorAll('video');
|
||||
const lastVideoColor = document.lastVideoColor || {};
|
||||
document.lastVideoColor = lastVideoColor;
|
||||
|
||||
for (let v = 0; v < videos.length; v++) {
|
||||
const video = videos[v];
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
||||
const pixel = context.getImageData(50, 50, 1, 1).data;
|
||||
const pixelString = new Array(pixel).join(' ').toString();
|
||||
|
||||
if (lastVideoColor[v]) {
|
||||
if (lastVideoColor[v] == pixelString) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
lastVideoColor[v] = pixelString;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
check = await test.evaluate(checkCameras, i);
|
||||
await test.waitFor(parseInt(process.env.LOOP_INTERVAL));
|
||||
}
|
||||
return check === true;
|
||||
}
|
||||
|
||||
exports.startAndCheckForWebcams = startAndCheckForWebcams;
|
||||
|
Loading…
Reference in New Issue
Block a user