Merge pull request #16720 from antonbsa/v2.6-tests-update
test: Fix and update tests
This commit is contained in:
commit
71be54303b
@ -1,22 +1,18 @@
|
||||
// const util = require('node:util');
|
||||
|
||||
const { expect } = require("@playwright/test");
|
||||
|
||||
const Page = require('../core/page');
|
||||
const parameters = require('../core/parameters');
|
||||
const { apiCall, createMeeting } = require('../core/helpers');
|
||||
const e = require('../core/elements');
|
||||
|
||||
function getMeetings() {
|
||||
return apiCall('getMeetings', {});
|
||||
}
|
||||
|
||||
function getMeetingInfo(meetingID) {
|
||||
return apiCall('getMeetingInfo', {meetingID: meetingID});
|
||||
return apiCall('getMeetingInfo', { meetingID: meetingID });
|
||||
}
|
||||
|
||||
class API {
|
||||
|
||||
constructor(browser, context, page) {
|
||||
this.modPage = new Page(browser, page);
|
||||
this.browser = browser;
|
||||
@ -46,22 +42,25 @@ class API {
|
||||
* should ensure that the API will report hasJoinedVoice?
|
||||
*/
|
||||
|
||||
const expectedUsers = [expect.objectContaining({fullName: ['Moderator'],
|
||||
role: ['MODERATOR'],
|
||||
isPresenter: ['true'],
|
||||
}),
|
||||
expect.objectContaining({fullName: ['Attendee'],
|
||||
role: ['VIEWER'],
|
||||
isPresenter: ['false'],
|
||||
})
|
||||
];
|
||||
const expectedMeeting = {meetingName : [meetingId],
|
||||
running : ['true'],
|
||||
participantCount : ['2'],
|
||||
moderatorCount : ['1'],
|
||||
isBreakout: ['false'],
|
||||
attendees: [{ attendee: expect.arrayContaining(expectedUsers) }]
|
||||
};
|
||||
const expectedUsers = [expect.objectContaining({
|
||||
fullName: ['Moderator'],
|
||||
role: ['MODERATOR'],
|
||||
isPresenter: ['true'],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
fullName: ['Attendee'],
|
||||
role: ['VIEWER'],
|
||||
isPresenter: ['false'],
|
||||
})
|
||||
];
|
||||
const expectedMeeting = {
|
||||
meetingName: [meetingId],
|
||||
running: ['true'],
|
||||
participantCount: ['2'],
|
||||
moderatorCount: ['1'],
|
||||
isBreakout: ['false'],
|
||||
attendees: [{ attendee: expect.arrayContaining(expectedUsers) }]
|
||||
};
|
||||
|
||||
/* check that this meeting is in the server's list of all meetings */
|
||||
const response = await getMeetings();
|
||||
@ -90,22 +89,25 @@ class API {
|
||||
* should ensure that the API will report hasJoinedVoice?
|
||||
*/
|
||||
|
||||
const expectedUsers = [expect.objectContaining({fullName: ['Moderator'],
|
||||
role: ['MODERATOR'],
|
||||
isPresenter: ['true'],
|
||||
}),
|
||||
expect.objectContaining({fullName: ['Attendee'],
|
||||
role: ['VIEWER'],
|
||||
isPresenter: ['false'],
|
||||
})
|
||||
];
|
||||
const expectedMeeting = {meetingName : [meetingId],
|
||||
running : ['true'],
|
||||
participantCount : ['2'],
|
||||
moderatorCount : ['1'],
|
||||
isBreakout: ['false'],
|
||||
attendees: [{ attendee: expect.arrayContaining(expectedUsers) }]
|
||||
};
|
||||
const expectedUsers = [expect.objectContaining({
|
||||
fullName: ['Moderator'],
|
||||
role: ['MODERATOR'],
|
||||
isPresenter: ['true'],
|
||||
}),
|
||||
expect.objectContaining({
|
||||
fullName: ['Attendee'],
|
||||
role: ['VIEWER'],
|
||||
isPresenter: ['false'],
|
||||
})
|
||||
];
|
||||
const expectedMeeting = {
|
||||
meetingName: [meetingId],
|
||||
running: ['true'],
|
||||
participantCount: ['2'],
|
||||
moderatorCount: ['1'],
|
||||
isBreakout: ['false'],
|
||||
attendees: [{ attendee: expect.arrayContaining(expectedUsers) }]
|
||||
};
|
||||
|
||||
/* check that we can retrieve this meeting by its meetingId */
|
||||
const response2 = await getMeetingInfo(meetingId);
|
||||
|
@ -3,7 +3,6 @@ const { API } = require('./api.js');
|
||||
const { APIBreakout } = require('./breakout.js');
|
||||
|
||||
test.describe.parallel('API', () => {
|
||||
|
||||
test('getMeetings', async ({ browser, context, page }) => {
|
||||
const api = new API(browser, context, page);
|
||||
await api.testGetMeetings();
|
||||
@ -38,5 +37,4 @@ test.describe.parallel('API', () => {
|
||||
await api.joinRoom();
|
||||
await api.testBreakoutMeetingInfoOneJoin();
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -5,11 +5,10 @@ const parameters = require('../core/parameters');
|
||||
const { apiCall, createMeetingPromise } = require('../core/helpers');
|
||||
|
||||
function getMeetingInfo(meetingID) {
|
||||
return apiCall('getMeetingInfo', {meetingID: meetingID});
|
||||
return apiCall('getMeetingInfo', { meetingID: meetingID });
|
||||
}
|
||||
|
||||
class APIBreakout extends Join {
|
||||
|
||||
constructor(browser, context) {
|
||||
super(browser, context);
|
||||
}
|
||||
@ -17,21 +16,21 @@ class APIBreakout extends Join {
|
||||
// Attempt to use API to create a breakout room without a parent
|
||||
async testBreakoutWithoutParent() {
|
||||
const response = await createMeetingPromise(parameters, `isBreakout=true&sequence=1`)
|
||||
.catch(error => error);
|
||||
.catch(error => error);
|
||||
expect(response.response.status).toEqual(500);
|
||||
}
|
||||
|
||||
// Attempt to use API to create a break room without a sequence number
|
||||
async testBreakoutWithoutSequenceNumber() {
|
||||
const response = await createMeetingPromise(parameters, `isBreakout=true&parentMeetingID=${this.modPage.meetingId}`)
|
||||
.catch(error => error);
|
||||
.catch(error => error);
|
||||
expect(response.response.status).toEqual(500);
|
||||
}
|
||||
|
||||
// Attempt to use API to create a break room with a non-existent parent meeting
|
||||
async testBreakoutWithNonexistentParent() {
|
||||
const response = await createMeetingPromise(parameters, `isBreakout=true&parentMeetingID=0000000&sequence=1`)
|
||||
.catch(error => error);
|
||||
.catch(error => error);
|
||||
expect(response.response.status).toEqual(500);
|
||||
}
|
||||
|
||||
@ -49,16 +48,17 @@ class APIBreakout extends Join {
|
||||
for (const breakoutRoom of response1.response.breakoutRooms[0].breakout) {
|
||||
const response2 = await getMeetingInfo(breakoutRoom);
|
||||
|
||||
const expectedMeeting = {meetingID : [breakoutRoom],
|
||||
isBreakout: ['true'],
|
||||
running: ['false'],
|
||||
participantCount: ['0'],
|
||||
hasUserJoined: ['false'],
|
||||
attendees: ['\n'], /* no attendees; the newline is an artifact of xml2js */
|
||||
freeJoin: ['false'],
|
||||
sequence: [ expect.stringMatching('[12]') ],
|
||||
parentMeetingID: response1.response.internalMeetingID,
|
||||
};
|
||||
const expectedMeeting = {
|
||||
meetingID: [breakoutRoom],
|
||||
isBreakout: ['true'],
|
||||
running: ['false'],
|
||||
participantCount: ['0'],
|
||||
hasUserJoined: ['false'],
|
||||
attendees: ['\n'], /* no attendees; the newline is an artifact of xml2js */
|
||||
freeJoin: ['false'],
|
||||
sequence: [expect.stringMatching('[12]')],
|
||||
parentMeetingID: response1.response.internalMeetingID,
|
||||
};
|
||||
|
||||
expect(response2.response.returncode).toEqual(['SUCCESS']);
|
||||
expect(response2.response).toMatchObject(expectedMeeting);
|
||||
@ -85,33 +85,36 @@ class APIBreakout extends Join {
|
||||
|
||||
// Attendee, a VIEWER in the parent meeting, becomes a MODERATOR (and presenter) in the breakout room
|
||||
|
||||
const expectedUser = expect.objectContaining({fullName: ['Attendee'],
|
||||
role: ['MODERATOR'],
|
||||
isPresenter: ['true'],
|
||||
});
|
||||
const expectedUser = expect.objectContaining({
|
||||
fullName: ['Attendee'],
|
||||
role: ['MODERATOR'],
|
||||
isPresenter: ['true'],
|
||||
});
|
||||
|
||||
const expectedMeeting1 = {isBreakout: ['true'],
|
||||
running: ['true'],
|
||||
participantCount: ['1'],
|
||||
hasUserJoined: ['true'],
|
||||
attendees: [{ attendee: [ expectedUser ] }],
|
||||
freeJoin: ['false'],
|
||||
sequence: [ '1' ],
|
||||
parentMeetingID: response1.response.internalMeetingID,
|
||||
};
|
||||
const expectedMeeting1 = {
|
||||
isBreakout: ['true'],
|
||||
running: ['true'],
|
||||
participantCount: ['1'],
|
||||
hasUserJoined: ['true'],
|
||||
attendees: [{ attendee: [expectedUser] }],
|
||||
freeJoin: ['false'],
|
||||
sequence: ['1'],
|
||||
parentMeetingID: response1.response.internalMeetingID,
|
||||
};
|
||||
|
||||
const expectedMeeting2 = {isBreakout: ['true'],
|
||||
running: ['false'],
|
||||
participantCount: ['0'],
|
||||
hasUserJoined: ['false'],
|
||||
attendees: ['\n'], /* no attendees; the newline is an artifact of xml2js */
|
||||
freeJoin: ['false'],
|
||||
sequence: [ '2' ],
|
||||
parentMeetingID: response1.response.internalMeetingID,
|
||||
};
|
||||
const expectedMeeting2 = {
|
||||
isBreakout: ['true'],
|
||||
running: ['false'],
|
||||
participantCount: ['0'],
|
||||
hasUserJoined: ['false'],
|
||||
attendees: ['\n'], /* no attendees; the newline is an artifact of xml2js */
|
||||
freeJoin: ['false'],
|
||||
sequence: ['2'],
|
||||
parentMeetingID: response1.response.internalMeetingID,
|
||||
};
|
||||
|
||||
const expectedResponse1 = {response: expect.objectContaining(expectedMeeting1)};
|
||||
const expectedResponse2 = {response: expect.objectContaining(expectedMeeting2)};
|
||||
const expectedResponse1 = { response: expect.objectContaining(expectedMeeting1) };
|
||||
const expectedResponse2 = { response: expect.objectContaining(expectedMeeting2) };
|
||||
|
||||
// Note that this is an array of two responses from two API calls,
|
||||
// not a single API call response containing two breakout rooms
|
||||
@ -119,7 +122,6 @@ class APIBreakout extends Join {
|
||||
const response2array = await Promise.all(breakoutRooms.map(getMeetingInfo));
|
||||
expect(response2array).toEqual(expect.arrayContaining([expectedResponse1, expectedResponse2]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.APIBreakout = APIBreakout;
|
||||
|
@ -129,7 +129,7 @@ test.describe.parallel('Breakout', () => {
|
||||
|
||||
// temporarily skipped until the following issue gets resolved:
|
||||
// https://github.com/bigbluebutton/bigbluebutton/issues/16368
|
||||
test.skip('Export breakout room whiteboard annotations', async ({ browser, context, page }) => {
|
||||
test('Export breakout room whiteboard annotations', async ({ browser, context, page }) => {
|
||||
const join = new Join(browser, context);
|
||||
await join.initPages(page);
|
||||
await join.create(false, true); // capture breakout whiteboard
|
||||
|
@ -8,7 +8,7 @@ class Create extends MultiUsers {
|
||||
super(browser, context);
|
||||
}
|
||||
|
||||
// Create Breakoutrooms
|
||||
// Create BreakoutRooms
|
||||
async create(captureNotes = false, captureWhiteboard = false) {
|
||||
await this.modPage.waitAndClick(e.manageUsers);
|
||||
await this.modPage.waitAndClick(e.createBreakoutRooms);
|
||||
@ -16,8 +16,8 @@ class Create extends MultiUsers {
|
||||
//Randomly assignment
|
||||
await this.modPage.waitAndClick(e.randomlyAssign);
|
||||
|
||||
if(captureNotes) await this.modPage.page.check(e.captureBreakoutSharedNotes);
|
||||
if(captureWhiteboard) await this.modPage.page.check(e.captureBreakoutWhiteboard);
|
||||
if (captureNotes) await this.modPage.page.check(e.captureBreakoutSharedNotes);
|
||||
if (captureWhiteboard) await this.modPage.page.check(e.captureBreakoutWhiteboard);
|
||||
await this.modPage.waitAndClick(e.modalConfirmButton, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
await this.userPage.hasElement(e.modalConfirmButton);
|
||||
|
@ -136,8 +136,7 @@ class Join extends Create {
|
||||
await this.modPage.waitAndClick(e.modalConfirmButton);
|
||||
|
||||
await this.userPage.waitForSelector(e.modalConfirmButton);
|
||||
await breakoutUserPage.hasElement(e.errorScreenMessage);
|
||||
await breakoutUserPage.hasText(e.errorScreenMessage, e.error403removedLabel);
|
||||
await breakoutUserPage.page.isClosed();
|
||||
|
||||
await this.userPage.waitAndClick(e.modalConfirmButton);
|
||||
await this.modPage.hasText(e.userNameBreakoutRoom2, /Attendee/);
|
||||
@ -161,15 +160,14 @@ class Join extends Create {
|
||||
await this.modPage.waitAndClick(e.endAllBreakouts);
|
||||
|
||||
await this.modPage.hasElement(e.presentationUploadProgressToast);
|
||||
await this.modPage.page.waitForSelector(e.presentationUploadProgressToast, { state: 'detached' });
|
||||
await this.modPage.waitForSelectorDetached(e.presentationUploadProgressToast, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
await this.modPage.waitAndClick(e.closeModal); // closing the audio modal
|
||||
await this.modPage.waitAndClick(e.actions);
|
||||
await this.modPage.checkElementCount(e.actionsItem, 9);
|
||||
await this.modPage.getLocatorByIndex(e.actionsItem, 1).click();
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
const clipObj = {
|
||||
x: wbBox.x,
|
||||
y: wbBox.y,
|
||||
@ -208,20 +206,19 @@ class Join extends Create {
|
||||
await this.modPage.waitAndClick(e.endAllBreakouts);
|
||||
|
||||
await this.modPage.waitForSelector(e.presentationUploadProgressToast, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.page.waitForSelector(e.presentationUploadProgressToast, { state: 'detached' });
|
||||
await this.modPage.waitForSelectorDetached(e.presentationUploadProgressToast, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
await this.modPage.waitAndClick(e.closeModal); // closing the audio modal
|
||||
await this.modPage.waitAndClick(e.actions);
|
||||
await this.modPage.checkElementCount(e.actionsItem, 9);
|
||||
await this.modPage.getLocatorByIndex(e.actionsItem, 1).click();
|
||||
|
||||
const wbMod = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBoxMod = await wbMod.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
const clipObj = {
|
||||
x: wbBoxMod.x,
|
||||
y: wbBoxMod.y,
|
||||
width: wbBoxMod.width,
|
||||
height: wbBoxMod.height,
|
||||
x: wbBox.x,
|
||||
y: wbBox.y,
|
||||
width: wbBox.width,
|
||||
height: wbBox.height,
|
||||
};
|
||||
await expect(this.modPage.page).toHaveScreenshot('capture-breakout-whiteboard.png', {
|
||||
maxDiffPixels: 1000,
|
||||
|
@ -25,7 +25,7 @@ test.describe.parallel('Chat', () => {
|
||||
});
|
||||
|
||||
test('Copy chat', async ({ browser, context, page }, testInfo) => {
|
||||
test.fixme(testInfo.project.use.headless, 'Only works in headed mode');
|
||||
test.skip(testInfo.project.use.headless, 'Only works in headed mode');
|
||||
const chat = new Chat(browser, page);
|
||||
await chat.init(true, true);
|
||||
await chat.copyChat(context);
|
||||
@ -78,7 +78,7 @@ test.describe.parallel('Chat', () => {
|
||||
});
|
||||
|
||||
test('Copy chat with emoji', async ({ browser, context, page }, testInfo) => {
|
||||
test.fixme(testInfo.project.use.headless, 'Only works in headed mode');
|
||||
test.skip(testInfo.project.use.headless, 'Only works in headed mode');
|
||||
const emoji = new Chat(browser, page);
|
||||
await emoji.init(true, true);
|
||||
await emoji.emojiCopyChat(context);
|
||||
@ -103,7 +103,7 @@ test.describe.parallel('Chat', () => {
|
||||
});
|
||||
|
||||
test('Copy chat with auto converted emoji', async ({ browser, context, page }, testInfo) => {
|
||||
test.fixme(testInfo.project.use.headless, 'Only works in headed mode');
|
||||
test.skip(testInfo.project.use.headless, 'Only works in headed mode');
|
||||
const emoji = new Chat(browser, page);
|
||||
await emoji.init(true, true);
|
||||
await emoji.autoConvertEmojiCopyChat(context);
|
||||
@ -121,4 +121,4 @@ test.describe.parallel('Chat', () => {
|
||||
await emoji.autoConvertEmojiSendPrivateChat();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -173,7 +173,8 @@ exports.exporthtml = 'span[id="exporthtml"]';
|
||||
|
||||
// Notifications
|
||||
exports.smallToastMsg = 'div[data-test="toastSmallMsg"]';
|
||||
exports.currentPresentationToast = 'div[data-test="toastSmallMsg"] > div';
|
||||
const currentPresentationToast = 'div[data-test="currentPresentationToast"]';
|
||||
exports.currentPresentationToast = currentPresentationToast
|
||||
exports.notificationsTab = 'span[id="notificationTab"]';
|
||||
exports.chatPopupAlertsBtn = 'input[data-test="chatPopupAlertsBtn"]';
|
||||
exports.hasUnreadMessages = 'button[data-test="hasUnreadMessages"]';
|
||||
@ -211,7 +212,10 @@ exports.restartPoll = 'button[data-test="restartPoll"]';
|
||||
exports.hidePollDesc = 'button[data-test="hidePollDesc"]';
|
||||
exports.pollingContainer = 'div[data-test="pollingContainer"]';
|
||||
exports.pollLetterAlternatives = 'button[data-test="pollLetterAlternatives"]';
|
||||
exports.pollOptionItem = 'input[data-test="pollOptionItem"]';
|
||||
const pollOptionItem = 'input[data-test="pollOptionItem"]';
|
||||
exports.pollOptionItem1 = `${pollOptionItem}>>nth=0`;
|
||||
exports.pollOptionItem2 = `${pollOptionItem}>>nth=1`;
|
||||
exports.pollOptionItem = pollOptionItem;
|
||||
exports.anonymousPoll = 'input[data-test="anonymousPollBtn"]';
|
||||
const pollAnswerOptionBtn = 'button[data-test="publishPollingLabel"]';
|
||||
exports.publishPollingLabel = pollAnswerOptionBtn;
|
||||
@ -229,11 +233,10 @@ exports.pollYesNoAbstentionBtn = 'button[data-test="pollYesNoAbstentionBtn"]';
|
||||
exports.noPresentation = 'h4[data-test="noPresentation"]';
|
||||
exports.autoOptioningPollBtn = 'input[data-test="autoOptioningPollBtn"]';
|
||||
exports.currentPollQuestion = 'span[data-test="currentPollQuestion"]';
|
||||
exports.allowMultiple = 'div[data-test="allowMultiple"] > div > input[type="checkbox"]';
|
||||
exports.pollOptionItem1 = 'input[data-test="pollOptionItem"]>>nth=0';
|
||||
exports.pollOptionItem2 = 'input[data-test="pollOptionItem"]>>nth=1';
|
||||
exports.pollAnswerDescTest1 = 'div[data-test="optionsAnswers"]>>nth=0';
|
||||
exports.pollAnswerDescTest2 = 'div[data-test="optionsAnswers"]>>nth=1';
|
||||
exports.allowMultiple = 'div[data-test="allowMultiple"] input[type="checkbox"]';
|
||||
const pollAnswerOptionDesc = 'button[data-test="pollAnswerOption"]';
|
||||
exports.firstPollAnswerDescOption = `${pollAnswerOptionDesc}>>nth=0`;
|
||||
exports.secondPollAnswerDescOption = `${pollAnswerOptionDesc}>>nth=1`;
|
||||
exports.submitAnswersMultiple = 'button[data-test="submitAnswersMultiple"]';
|
||||
exports.numberVotes = 'div[data-test="numberVotes"]';
|
||||
exports.answer1 = 'div[data-test="numberOfVotes"]>>nth=0';
|
||||
@ -241,8 +244,10 @@ exports.answer2 = 'div[data-test="numberOfVotes"]>>nth=1';
|
||||
exports.errorNoValueInput = 'div[data-test="errorNoValueInput"]';
|
||||
exports.smartSlides1 = 'smartSlidesPresentation.pdf';
|
||||
exports.responsePollQuestion = 'div[data-test="pollQuestion"]';
|
||||
exports.firstPollAnswerOptionBtn = `${pollAnswerOptionBtn}>>nth=0`;
|
||||
exports.checkboxInput = `${pollAnswerOptionBtn} > div`;
|
||||
const pollAnswersOption = 'div[data-test="optionsAnswers"]';
|
||||
exports.firstPollAnswerOptionBtn = `${pollAnswersOption}>>nth=0`;
|
||||
exports.secondPollAnswerOptionBtn = `${pollAnswersOption}>>nth=1`;
|
||||
exports.firstCheckboxInput = `${pollAnswersOption}`;
|
||||
// Presentation
|
||||
exports.currentSlideImg = 'img[id="slide-background-shape_image"]';
|
||||
exports.uploadPresentationFileName = 'uploadTest.png';
|
||||
@ -405,6 +410,7 @@ exports.wbPencilShape = 'button[id="TD-PrimaryTools-Pencil"]';
|
||||
exports.wbStickyNoteShape = 'button[id="TD-PrimaryTools-Pencil2"]';
|
||||
exports.wbTextShape = 'button[id="TD-PrimaryTools-Text"]';
|
||||
exports.wbTypedText = 'div[data-shape="text"]';
|
||||
exports.wbTypedStickyNote = 'div[data-shape="sticky"]';
|
||||
exports.wbDrawnRectangle = 'div[data-shape="rectangle"]';
|
||||
exports.wbDrawnLine = 'div[data-shape="draw"]';
|
||||
exports.multiUsersWhiteboardOn = 'button[data-test="turnMultiUsersWhiteboardOn"]';
|
||||
|
@ -1,11 +1,9 @@
|
||||
require('dotenv').config();
|
||||
const sha1 = require('sha1');
|
||||
const axios = require('axios');
|
||||
const { test } = require('@playwright/test');
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const xml2js = require('xml2js');
|
||||
|
||||
const { expect } = require("@playwright/test");
|
||||
|
||||
const parameters = require('./parameters');
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
@ -16,8 +14,8 @@ function getRandomInt(min, max) {
|
||||
|
||||
function apiCallUrl(name, callParams) {
|
||||
const query = new URLSearchParams(callParams).toString();
|
||||
const apicall = `${name}${query}${parameters.secret}`;
|
||||
const checksum = sha1(apicall);
|
||||
const apiCall = `${name}${query}${parameters.secret}`;
|
||||
const checksum = sha1(apiCall);
|
||||
const url = `${parameters.server}/${name}?${query}&checksum=${checksum}`;
|
||||
return url;
|
||||
}
|
||||
@ -27,22 +25,21 @@ function apiCall(name, callParams) {
|
||||
return axios.get(url, { adapter: 'http' }).then(response => xml2js.parseStringPromise(response.data));
|
||||
}
|
||||
|
||||
function createMeetingUrl(params, customParameter) {
|
||||
const meetingID = `random-${getRandomInt(1000000, 10000000).toString()}`;
|
||||
function createMeetingUrl(params, customParameter, customMeetingId) {
|
||||
const meetingID = (customMeetingId) ? customMeetingId : `random-${getRandomInt(1000000, 10000000).toString()}`;
|
||||
const mp = params.moderatorPW;
|
||||
const ap = params.attendeePW;
|
||||
const query = customParameter !== undefined ? `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}`
|
||||
+ `&allowStartStopRecording=true&${customParameter}&autoStartRecording=false&welcome=${params.welcome}`
|
||||
: `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}`
|
||||
const baseQuery = `name=${meetingID}&meetingID=${meetingID}&attendeePW=${ap}&moderatorPW=${mp}`
|
||||
+ `&allowStartStopRecording=true&autoStartRecording=false&welcome=${params.welcome}`;
|
||||
const apicall = `create${query}${params.secret}`;
|
||||
const checksum = sha1(apicall);
|
||||
const query = customParameter !== undefined ? `${baseQuery}&${customParameter}` : baseQuery;
|
||||
const apiCall = `create${query}${params.secret}`;
|
||||
const checksum = sha1(apiCall);
|
||||
const url = `${params.server}/create?${query}&checksum=${checksum}`;
|
||||
return url;
|
||||
}
|
||||
|
||||
function createMeetingPromise(params, customParameter) {
|
||||
const url = createMeetingUrl(params, customParameter);
|
||||
function createMeetingPromise(params, customParameter, customMeetingId) {
|
||||
const url = createMeetingUrl(params, customParameter, customMeetingId);
|
||||
return axios.get(url, { adapter: 'http' });
|
||||
}
|
||||
|
||||
@ -50,16 +47,16 @@ async function createMeeting(params, customParameter) {
|
||||
const promise = createMeetingPromise(params, customParameter);
|
||||
const response = await promise;
|
||||
expect(response.status).toEqual(200);
|
||||
const xmlresponse = await xml2js.parseStringPromise(response.data);
|
||||
return xmlresponse.response.meetingID[0];
|
||||
const xmlResponse = await xml2js.parseStringPromise(response.data);
|
||||
return xmlResponse.response.meetingID[0];
|
||||
}
|
||||
|
||||
function getJoinURL(meetingID, params, moderator, customParameter) {
|
||||
const pw = moderator ? params.moderatorPW : params.attendeePW;
|
||||
const query = customParameter !== undefined ? `fullName=${params.fullName}&meetingID=${meetingID}&password=${pw}&${customParameter}`
|
||||
: `fullName=${params.fullName}&meetingID=${meetingID}&password=${pw}`;
|
||||
const apicall = `join${query}${params.secret}`;
|
||||
const checksum = sha1(apicall);
|
||||
const baseQuery = `fullName=${params.fullName}&meetingID=${meetingID}&password=${pw}`;
|
||||
const query = customParameter !== undefined ? `${baseQuery}&${customParameter}` : baseQuery;
|
||||
const apiCall = `join${query}${params.secret}`;
|
||||
const checksum = sha1(apiCall);
|
||||
return `${params.server}/join?${query}&checksum=${checksum}`;
|
||||
}
|
||||
|
||||
|
@ -24,26 +24,26 @@ function formatWithCss(CONSOLE_options, ...args) {
|
||||
// See https://console.spec.whatwg.org/ sections 2.2.1 and 2.3.4
|
||||
|
||||
let split_arg0 = args[0].split("%");
|
||||
for (let i=1, j=1; i<split_arg0.length; i++, j++) {
|
||||
for (let i = 1, j = 1; i < split_arg0.length; i++, j++) {
|
||||
if (split_arg0[i].startsWith('c')) {
|
||||
split_arg0[i] = 's' + split_arg0[i].substr(1);
|
||||
const styles = args[j].split(';');
|
||||
args[j] = '';
|
||||
for (const style of styles) {
|
||||
const stdStyle = style.trim().toLowerCase();
|
||||
if (stdStyle.startsWith('color:') && CONSOLE_options.colorize) {
|
||||
const color = stdStyle.substr(6).trim();
|
||||
args[j] = chalk.keyword(color)._styler.open;
|
||||
} else if (stdStyle.startsWith('font-size:') && CONSOLE_options.drop_references) {
|
||||
const stdStyle = style.trim().toLowerCase();
|
||||
if (stdStyle.startsWith('color:') && CONSOLE_options.colorize) {
|
||||
const color = stdStyle.substr(6).trim();
|
||||
args[j] = chalk.keyword(color)._styler.open;
|
||||
} else if (stdStyle.startsWith('font-size:') && CONSOLE_options.drop_references) {
|
||||
// For Chrome, we "drop references" by discarding everything after a font size change
|
||||
split_arg0.length = i;
|
||||
args.length = j;
|
||||
}
|
||||
split_arg0.length = i;
|
||||
args.length = j;
|
||||
}
|
||||
}
|
||||
} else if (split_arg0[i] == "") {
|
||||
// format is "%%", so don't do special processing for
|
||||
// split_arg0[i+1], and only increment i, not j
|
||||
i ++; // NOSONAR
|
||||
i++; // NOSONAR
|
||||
}
|
||||
}
|
||||
args[0] = split_arg0.join('%');
|
||||
@ -107,16 +107,16 @@ class Page {
|
||||
if (env.CONSOLE !== undefined) {
|
||||
const CONSOLE_strings = env.CONSOLE.split(',').map(opt => opt.trim().toLowerCase());
|
||||
const CONSOLE_options = {
|
||||
colorize: CONSOLE_strings.includes('color') || CONSOLE_strings.includes('colour'),
|
||||
drop_references: CONSOLE_strings.includes('norefs'),
|
||||
drop_timestamps: CONSOLE_strings.includes('nots'),
|
||||
line_label: CONSOLE_strings.includes('label') ? this.username + " " : undefined,
|
||||
noClientLogger: CONSOLE_strings.includes('nocl') || CONSOLE_strings.includes('noclientlogger'),
|
||||
colorize: CONSOLE_strings.includes('color') || CONSOLE_strings.includes('colour'),
|
||||
drop_references: CONSOLE_strings.includes('norefs'),
|
||||
drop_timestamps: CONSOLE_strings.includes('nots'),
|
||||
line_label: CONSOLE_strings.includes('label') ? this.username + " " : undefined,
|
||||
noClientLogger: CONSOLE_strings.includes('nocl') || CONSOLE_strings.includes('noclientlogger'),
|
||||
};
|
||||
this.page.on('console', async (msg) => console.log(await console_format(msg, CONSOLE_options)));
|
||||
}
|
||||
|
||||
this.meetingId = (meetingId) ? meetingId : await helpers.createMeeting(parameters, customParameter);
|
||||
this.meetingId = (meetingId) ? meetingId : await helpers.createMeeting(parameters, customParameter, customMeetingId);
|
||||
const joinUrl = helpers.getJoinURL(this.meetingId, this.initParameters, isModerator, customParameter);
|
||||
const response = await this.page.goto(joinUrl);
|
||||
await expect(response.ok()).toBeTruthy();
|
||||
@ -143,7 +143,7 @@ class Page {
|
||||
}
|
||||
}
|
||||
|
||||
async handleNewTab(selector, context){
|
||||
async handleNewTab(selector, context) {
|
||||
const [newPage] = await Promise.all([
|
||||
context.waitForEvent('page'),
|
||||
this.waitAndClick(selector),
|
||||
@ -201,7 +201,7 @@ class Page {
|
||||
}
|
||||
|
||||
async getCopiedText(context) {
|
||||
await context.grantPermissions(['clipboard-write', 'clipboard-read'], { origin: process.env.BBB_URL});
|
||||
await context.grantPermissions(['clipboard-write', 'clipboard-read'], { origin: process.env.BBB_URL });
|
||||
return this.page.evaluate(async () => navigator.clipboard.readText());
|
||||
}
|
||||
|
||||
@ -214,6 +214,15 @@ class Page {
|
||||
await this.page.waitForSelector(selector, { timeout });
|
||||
}
|
||||
|
||||
async waitForSelectorDetached(selector, timeout = ELEMENT_WAIT_TIME) {
|
||||
await this.page.waitForSelector(selector, { state: 'detached', timeout });
|
||||
}
|
||||
|
||||
async getElementBoundingBox(selector) {
|
||||
const element = await this.page.$(selector);
|
||||
return element.boundingBox();
|
||||
}
|
||||
|
||||
async waitUntilHaveCountSelector(selector, count, timeout = ELEMENT_WAIT_TIME) {
|
||||
await this.page.waitForFunction(
|
||||
checkElementLengthEqualTo,
|
||||
@ -295,7 +304,7 @@ class Page {
|
||||
async up(key) {
|
||||
await this.page.keyboard.up(key);
|
||||
}
|
||||
|
||||
|
||||
async mouseDoubleClick(x, y) {
|
||||
await this.page.mouse.dblclick(x, y);
|
||||
}
|
||||
@ -310,7 +319,7 @@ class Page {
|
||||
}
|
||||
|
||||
async hasValue(selector, value) {
|
||||
const locator = await this.page.locator(selector);
|
||||
const locator = await this.page.locator(selector);
|
||||
await expect(locator).toHaveValue(value);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,8 @@ async function waitAndClearDefaultPresentationNotification(testPage) {
|
||||
await testPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
const hasCurrentPresentationToast = await testPage.checkElement(e.currentPresentationToast);
|
||||
if (hasCurrentPresentationToast) {
|
||||
await waitAndClearNotification(testPage);
|
||||
await testPage.waitAndClick(e.currentPresentationToast, ELEMENT_WAIT_LONGER_TIME);
|
||||
await testPage.wasRemoved(e.currentPresentationToast);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ const utilPresentation = require('../presentation/util');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { getSettings } = require('../core/settings');
|
||||
const { waitAndClearDefaultPresentationNotification } = require('../notifications/util');
|
||||
const { sleep } = require('../core/helpers');
|
||||
|
||||
class Polling extends MultiUsers {
|
||||
constructor(browser, context) {
|
||||
@ -196,8 +195,8 @@ class Polling extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.startPoll);
|
||||
await this.modPage.hasText(e.currentPollQuestion, /Test/);
|
||||
|
||||
await this.userPage.waitAndClick(e.pollAnswerDescTest1);
|
||||
await this.userPage.waitAndClick(e.pollAnswerDescTest2);
|
||||
await this.userPage.waitAndClick(e.firstPollAnswerOptionBtn);
|
||||
await this.userPage.waitAndClick(e.secondPollAnswerOptionBtn);
|
||||
await this.userPage.waitAndClickElement(e.submitAnswersMultiple);
|
||||
|
||||
await this.modPage.hasText(e.answer1, '1');
|
||||
@ -205,8 +204,10 @@ class Polling extends MultiUsers {
|
||||
}
|
||||
|
||||
async smartSlidesQuestions() {
|
||||
await this.modPage.hasElement(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await waitAndClearDefaultPresentationNotification(this.modPage);
|
||||
await utilPresentation.uploadSinglePresentation(this.modPage, e.smartSlides1, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.userPage.hasElement(e.presentationTitle);
|
||||
await this.userPage.hasElement(e.currentUser);
|
||||
|
||||
await this.modPage.waitAndClick(e.quickPoll);
|
||||
await this.userPage.hasElement(e.responsePollQuestion);
|
||||
@ -218,7 +219,7 @@ class Polling extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.publishPollingLabel);
|
||||
await this.modPage.waitAndClick(e.nextSlide);
|
||||
await this.modPage.waitAndClick(e.quickPoll);
|
||||
await this.userPage.waitAndClick(e.checkboxInput);
|
||||
await this.userPage.waitAndClick(e.firstCheckboxInput);
|
||||
await this.userPage.waitAndClick(e.submitAnswersMultiple);
|
||||
|
||||
await this.modPage.hasText(e.answer1, '1');
|
||||
@ -226,7 +227,7 @@ class Polling extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.publishPollingLabel);
|
||||
await this.modPage.waitAndClick(e.nextSlide);
|
||||
await this.modPage.waitAndClick(e.quickPoll);
|
||||
await this.userPage.waitAndClick(e.pollAnswerDescTest1);
|
||||
await this.userPage.waitAndClick(e.firstPollAnswerDescOption);
|
||||
|
||||
await this.modPage.hasText(e.answer1, '1');
|
||||
await this.modPage.hasElementDisabled(e.nextSlide);
|
||||
|
@ -34,7 +34,7 @@ class Presentation extends MultiUsers {
|
||||
async hideAndRestorePresentation() {
|
||||
const { presentationHidden } = getSettings();
|
||||
if (!presentationHidden) {
|
||||
await this.modPage.waitForSelector(e.whiteboard);
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitAndClick(e.minimizePresentation);
|
||||
}
|
||||
await this.modPage.wasRemoved(e.presentationContainer);
|
||||
@ -69,6 +69,7 @@ class Presentation extends MultiUsers {
|
||||
const userSlides0 = await getSlideOuterHtml(this.userPage);
|
||||
await expect(modSlides0).toEqual(userSlides0);
|
||||
|
||||
await waitAndClearDefaultPresentationNotification(this.modPage);
|
||||
await uploadSinglePresentation(this.modPage, e.uploadPresentationFileName);
|
||||
|
||||
const modSlides1 = await getSlideOuterHtml(this.modPage);
|
||||
@ -80,7 +81,7 @@ class Presentation extends MultiUsers {
|
||||
}
|
||||
|
||||
async uploadMultiplePresentationsTest() {
|
||||
await this.modPage.waitForSelector(e.skipSlide);
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
|
||||
const modSlides0 = await getSlideOuterHtml(this.modPage);
|
||||
const userSlides0 = await getSlideOuterHtml(this.userPage);
|
||||
@ -91,19 +92,17 @@ class Presentation extends MultiUsers {
|
||||
const modSlides1 = await getSlideOuterHtml(this.modPage);
|
||||
const userSlides1 = await getSlideOuterHtml(this.userPage);
|
||||
await expect(modSlides1).toEqual(userSlides1);
|
||||
|
||||
await expect(modSlides0).not.toEqual(modSlides1);
|
||||
await expect(userSlides0).not.toEqual(userSlides1);
|
||||
}
|
||||
|
||||
async fitToWidthTest() {
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitForSelector(e.skipSlide);
|
||||
await this.modPage.waitAndClick(e.userListToggleBtn);
|
||||
await uploadSinglePresentation(this.modPage, e.uploadPresentationFileName);
|
||||
const width1 = (await this.modPage.page.locator(e.whiteboard).boundingBox()).width;
|
||||
const width1 = (await this.modPage.getElementBoundingBox(e.whiteboard)).width;
|
||||
await this.modPage.waitAndClick(e.fitToWidthButton);
|
||||
const width2 = (await this.modPage.page.locator(e.whiteboard).boundingBox()).width;
|
||||
const width2 = (await this.modPage.getElementBoundingBox(e.whiteboard)).width;
|
||||
await expect(Number(width2) > Number(width1)).toBeTruthy();
|
||||
}
|
||||
|
||||
@ -115,7 +114,8 @@ class Presentation extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.actions);
|
||||
await this.modPage.waitAndClick(e.managePresentations);
|
||||
await this.modPage.waitAndClick(e.exportPresentationToPublicChat);
|
||||
await this.modPage.hasElement(e.downloadPresentationToast);
|
||||
await this.userPage.hasElement(e.smallToastMsg);
|
||||
await this.userPage.hasElement(e.toastDownload);
|
||||
await this.userPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.userPage.hasElement(e.downloadPresentation, ELEMENT_WAIT_EXTRA_LONG_TIME);
|
||||
const downloadPresentationLocator = this.userPage.getLocator(e.downloadPresentation);
|
||||
@ -204,6 +204,7 @@ class Presentation extends MultiUsers {
|
||||
}
|
||||
|
||||
async presentationFullscreen() {
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
const presentationLocator = await this.modPage.getLocator(e.presentationContainer);
|
||||
const height = parseInt(await getCurrentPresentationHeight(presentationLocator));
|
||||
|
||||
@ -217,6 +218,7 @@ class Presentation extends MultiUsers {
|
||||
}
|
||||
|
||||
async presentationSnapshot(testInfo) {
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitAndClick(e.whiteboardOptionsButton);
|
||||
const presentationSnapshotLocator = this.modPage.getLocator(e.presentationSnapshot);
|
||||
await this.modPage.handleDownload(presentationSnapshotLocator, testInfo);
|
||||
|
@ -1,6 +1,9 @@
|
||||
const { test } = require('@playwright/test');
|
||||
const { encodeCustomParams } = require('../customparameters/util');
|
||||
const { Presentation } = require('./presentation');
|
||||
|
||||
const customStyleAvoidUploadingNotifications = encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}`);
|
||||
|
||||
test.describe.parallel('Presentation', () => {
|
||||
// https://docs.bigbluebutton.org/2.6/release-tests.html#navigation-automated
|
||||
test('Skip slide @ci', async ({ browser, context, page }) => {
|
||||
@ -26,7 +29,8 @@ test.describe.parallel('Presentation', () => {
|
||||
// https://docs.bigbluebutton.org/2.6/release-tests.html#fit-to-width-option
|
||||
test('Presentation fit to width', async ({ browser, context, page }) => {
|
||||
const presentation = new Presentation(browser, context);
|
||||
await presentation.initPages(page);
|
||||
await presentation.initModPage(page, true, { customParameter: customStyleAvoidUploadingNotifications });
|
||||
await presentation.initUserPage(true, context);
|
||||
await presentation.fitToWidthTest();
|
||||
});
|
||||
|
||||
@ -45,7 +49,6 @@ test.describe.parallel('Presentation', () => {
|
||||
test.describe.parallel('Manage', () => {
|
||||
// https://docs.bigbluebutton.org/2.6/release-tests.html#uploading-a-presentation-automated
|
||||
test('Upload single presentation @ci', async ({ browser, context, page }) => {
|
||||
test.fixme(true, 'Different behaviors in the development and production environment');
|
||||
const presentation = new Presentation(browser, context);
|
||||
await presentation.initPages(page, true);
|
||||
await presentation.uploadSinglePresentationTest();
|
||||
@ -79,7 +82,8 @@ test.describe.parallel('Presentation', () => {
|
||||
|
||||
test('Remove previous presentation from previous presenter', async ({ browser, context, page }) => {
|
||||
const presentation = new Presentation(browser, context);
|
||||
await presentation.initPages(page);
|
||||
await presentation.initModPage(page, true, { customParameter: customStyleAvoidUploadingNotifications });
|
||||
await presentation.initUserPage(true, context);
|
||||
await presentation.removePreviousPresentationFromPreviousPresenter();
|
||||
});
|
||||
});
|
||||
|
@ -31,8 +31,7 @@ async function uploadSinglePresentation(test, fileName, uploadTimeout = ELEMENT_
|
||||
await test.hasText('body', e.statingUploadPresentationToast);
|
||||
|
||||
await test.waitAndClick(e.confirmManagePresentation);
|
||||
await test.hasText(e.presentationStatusInfo, e.convertingPresentationFileToast, uploadTimeout);
|
||||
await test.hasText(e.smallToastMsg, e.presentationUploadedToast, uploadTimeout);
|
||||
await test.hasElement(e.currentPresentationToast, uploadTimeout);
|
||||
}
|
||||
|
||||
async function uploadMultiplePresentations(test, fileNames, uploadTimeout = ELEMENT_WAIT_LONGER_TIME) {
|
||||
@ -40,7 +39,7 @@ async function uploadMultiplePresentations(test, fileNames, uploadTimeout = ELEM
|
||||
await test.waitAndClick(e.managePresentations);
|
||||
await test.waitForSelector(e.fileUpload);
|
||||
|
||||
await test.page.setInputFiles(e.fileUpload, fileNames.map(function(fileName) { return path.join(__dirname, `../core/media/${fileName}`); }));
|
||||
await test.page.setInputFiles(e.fileUpload, fileNames.map(function (fileName) { return path.join(__dirname, `../core/media/${fileName}`); }));
|
||||
await test.hasText('body', e.statingUploadPresentationToast);
|
||||
|
||||
await test.waitAndClick(e.confirmManagePresentation);
|
||||
|
@ -1,11 +1,10 @@
|
||||
const { default: test } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
const { getSettings } = require('../core/settings');
|
||||
const e = require('../core/elements');
|
||||
const { startSharedNotes, getNotesLocator, getShowMoreButtonLocator, getExportButtonLocator, getExportPlainTextLocator, getMoveToWhiteboardLocator, getSharedNotesUserWithoutPermission, getExportHTMLLocator, getExportEtherpadLocator } = require('./util');
|
||||
const { startSharedNotes, getNotesLocator, getShowMoreButtonLocator, getExportButtonLocator, getExportPlainTextLocator, getSharedNotesUserWithoutPermission, getExportHTMLLocator, getExportEtherpadLocator } = require('./util');
|
||||
const { expect } = require('@playwright/test');
|
||||
const { ELEMENT_WAIT_TIME, ELEMENT_WAIT_LONGER_TIME, ELEMENT_WAIT_EXTRA_LONG_TIME } = require('../core/constants');
|
||||
const { ELEMENT_WAIT_TIME } = require('../core/constants');
|
||||
const { sleep } = require('../core/helpers');
|
||||
const { readFileSync } = require('fs');
|
||||
const { checkTextContent } = require('../core/util');
|
||||
@ -20,19 +19,21 @@ class SharedNotes extends MultiUsers {
|
||||
const { sharedNotesEnabled } = getSettings();
|
||||
test.fail(!sharedNotesEnabled, 'Shared notes is disabled');
|
||||
await startSharedNotes(this.modPage);
|
||||
const sharedNotesContent = await getNotesLocator(this.modPage);
|
||||
await expect(sharedNotesContent).toBeEditable({ timeout: ELEMENT_WAIT_TIME });
|
||||
}
|
||||
|
||||
async editMessage(notesLocator) {
|
||||
async editMessage() {
|
||||
await this.modPage.down('Shift');
|
||||
let i = 7;
|
||||
while(i > 0) {
|
||||
while (i > 0) {
|
||||
await this.modPage.press('ArrowLeft');
|
||||
i--;
|
||||
}
|
||||
await this.modPage.up('Shift');
|
||||
await this.modPage.press('Backspace');
|
||||
i = 5;
|
||||
while(i > 0) {
|
||||
while (i > 0) {
|
||||
await this.modPage.press('ArrowLeft');
|
||||
i--;
|
||||
}
|
||||
@ -45,13 +46,12 @@ class SharedNotes extends MultiUsers {
|
||||
await startSharedNotes(this.modPage);
|
||||
const notesLocator = getNotesLocator(this.modPage);
|
||||
await notesLocator.type(e.message);
|
||||
this.editMessage(notesLocator);
|
||||
await this.editMessage(notesLocator);
|
||||
const editedMessage = '!Hello';
|
||||
await expect(notesLocator).toContainText(editedMessage, { timeout : ELEMENT_WAIT_TIME });
|
||||
await expect(notesLocator).toContainText(editedMessage, { timeout: ELEMENT_WAIT_TIME });
|
||||
}
|
||||
|
||||
async formatMessage(notesLocator) {
|
||||
|
||||
async formatMessage() {
|
||||
// U for '!'
|
||||
await this.modPage.down('Shift');
|
||||
await this.modPage.press('ArrowLeft');
|
||||
@ -62,7 +62,7 @@ class SharedNotes extends MultiUsers {
|
||||
// B for 'World'
|
||||
await this.modPage.down('Shift');
|
||||
let i = 5;
|
||||
while(i > 0) {
|
||||
while (i > 0) {
|
||||
await this.modPage.press('ArrowLeft');
|
||||
i--;
|
||||
}
|
||||
@ -75,7 +75,7 @@ class SharedNotes extends MultiUsers {
|
||||
// I for 'Hello'
|
||||
await this.modPage.down('Shift');
|
||||
i = 5;
|
||||
while(i > 0) {
|
||||
while (i > 0) {
|
||||
await this.modPage.press('ArrowLeft');
|
||||
i--;
|
||||
}
|
||||
@ -155,7 +155,7 @@ class SharedNotes extends MultiUsers {
|
||||
|
||||
await this.modPage.waitAndClick(e.notesOptions);
|
||||
await this.modPage.waitAndClick(e.sendNotesToWhiteboard);
|
||||
|
||||
|
||||
await this.modPage.hasText(e.currentSlideText, /test/, 20000);
|
||||
await this.userPage.hasText(e.currentSlideText, /test/);
|
||||
}
|
||||
@ -173,8 +173,8 @@ class SharedNotes extends MultiUsers {
|
||||
await notesLocatorUser.type('J');
|
||||
|
||||
const editedMessage = 'Jello World!';
|
||||
await expect(notesLocator).toContainText(editedMessage, { timeout : ELEMENT_WAIT_TIME });
|
||||
await expect(notesLocatorUser).toContainText(editedMessage, { timeout : ELEMENT_WAIT_TIME });
|
||||
await expect(notesLocator).toContainText(editedMessage, { timeout: ELEMENT_WAIT_TIME });
|
||||
await expect(notesLocatorUser).toContainText(editedMessage, { timeout: ELEMENT_WAIT_TIME });
|
||||
}
|
||||
|
||||
async seeNotesWithoutEditPermission() {
|
||||
@ -192,9 +192,9 @@ class SharedNotes extends MultiUsers {
|
||||
await this.modPage.waitAndClickElement(e.lockEditSharedNotes);
|
||||
await this.modPage.waitAndClick(e.applyLockSettings);
|
||||
|
||||
const notesLocatorUser = getSharedNotesUserWithoutPermission(this.userPage);
|
||||
await expect(notesLocatorUser).toContainText(/Hello/, { timeout : 20000 });
|
||||
await this.userPage.wasRemoved(e.etherpadFrame);
|
||||
const notesLocatorUser = getSharedNotesUserWithoutPermission(this.userPage);
|
||||
await expect(notesLocatorUser).toContainText(/Hello/, { timeout: 20000 });
|
||||
await this.userPage.wasRemoved(e.etherpadFrame);
|
||||
}
|
||||
|
||||
async pinNotesOntoWhiteboard() {
|
||||
@ -210,7 +210,7 @@ class SharedNotes extends MultiUsers {
|
||||
await notesLocator.type('Hello');
|
||||
const notesLocatorUser = getNotesLocator(this.userPage1);
|
||||
|
||||
await expect(notesLocator).toContainText(/Hello/, { timeout : 20000 });
|
||||
await expect(notesLocator).toContainText(/Hello/, { timeout: 20000 });
|
||||
await expect(notesLocatorUser).toContainText(/Hello/);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
const { test } = require('@playwright/test');
|
||||
const { SharedNotes, SharedNotesMultiUsers } = require('./sharednotes');
|
||||
const { SharedNotes } = require('./sharednotes');
|
||||
|
||||
test.describe.parallel('Shared Notes', () => {
|
||||
test('Open Shared notes @ci', async ({ browser, page, context }) => {
|
||||
|
@ -1,11 +1,10 @@
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const e = require('../core/elements');
|
||||
const { expect } = require('@playwright/test');
|
||||
|
||||
async function startSharedNotes(test) {
|
||||
await test.waitAndClick(e.sharedNotes);
|
||||
await test.waitForSelector(e.hideNotesLabel, ELEMENT_WAIT_LONGER_TIME);
|
||||
await test.hasElement(e.etherpadFrame);
|
||||
await test.hasElement(e.etherpadFrame, ELEMENT_WAIT_LONGER_TIME);
|
||||
}
|
||||
|
||||
function getNotesLocator(test) {
|
||||
|
@ -21,7 +21,7 @@ class MobileDevices extends MultiUsers {
|
||||
await this.userPage.wasRemoved(e.whiteboard);
|
||||
}
|
||||
|
||||
async userlistNotAppearOnMobile() {
|
||||
async userListNotAppearOnMobile() {
|
||||
await this.modPage.wasRemoved(e.userListItem);
|
||||
await this.userPage.wasRemoved(e.userListItem);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ test.describe.parallel('User', () => {
|
||||
test('Remove user and prevent rejoining', async ({ browser, context, page }) => {
|
||||
const multiusers = new MultiUsers(browser, context);
|
||||
await multiusers.initModPage(page, true);
|
||||
await multiusers.initModPage2(true, context, { customParameter: 'userID=Moderator2'});
|
||||
await multiusers.initModPage2(true, context, { customParameter: 'userID=Moderator2' });
|
||||
await multiusers.removeUserAndPreventRejoining(context);
|
||||
});
|
||||
});
|
||||
@ -268,7 +268,7 @@ test.describe.parallel('User', () => {
|
||||
await mobileDevices.mobileTagName();
|
||||
});
|
||||
|
||||
test('Whiteboard should not be accessible when chat panel or userlist are active on mobile devices', async ({ browser }) => {
|
||||
test('Whiteboard should not be accessible when chat panel or user list are active on mobile devices', async ({ browser }) => {
|
||||
test.fixme();
|
||||
const iphoneContext = await browser.newContext({ ...iPhone11 });
|
||||
const motoContext = await browser.newContext({ ...motoG4 });
|
||||
@ -279,17 +279,17 @@ test.describe.parallel('User', () => {
|
||||
await mobileDevices.whiteboardNotAppearOnMobile();
|
||||
});
|
||||
|
||||
test('Userslist should not appear when Chat Panel or Whiteboard are active on mobile devices', async ({ browser }) => {
|
||||
test('User List should not appear when Chat Panel or Whiteboard are active on mobile devices', async ({ browser }) => {
|
||||
const iphoneContext = await browser.newContext({ ...iPhone11 });
|
||||
const motoContext = await browser.newContext({ ...motoG4 });
|
||||
const modPage = await iphoneContext.newPage();
|
||||
const mobileDevices = new MobileDevices(browser, iphoneContext);
|
||||
await mobileDevices.initModPage(modPage);
|
||||
await mobileDevices.initUserPage(true, motoContext);
|
||||
await mobileDevices.userlistNotAppearOnMobile();
|
||||
await mobileDevices.userListNotAppearOnMobile();
|
||||
});
|
||||
|
||||
test('Chat Panel should not appear when Userlist or Whiteboard are active on mobile devices', async ({ browser }) => {
|
||||
test('Chat Panel should not appear when UserList or Whiteboard are active on mobile devices', async ({ browser }) => {
|
||||
const iphoneContext = await browser.newContext({ ...iPhone11 });
|
||||
const motoContext = await browser.newContext({ ...motoG4 });
|
||||
const modPage = await iphoneContext.newPage();
|
||||
|
@ -13,7 +13,7 @@ class VirtualizeList {
|
||||
// Join BigBlueButton meeting
|
||||
async init() {
|
||||
await this.page1.init(true, true, { fullName: 'BroadCaster1' });
|
||||
await this.page1.waitForSelector(e.firstUser);
|
||||
await this.page1.waitForSelector(e.currentUser);
|
||||
for (let i = 1; i <= parseInt(USER_LIST_VLIST_BOTS_LISTENING); i++) {
|
||||
const newPage = await this.browser.newPage();
|
||||
const viewerPage = new Page(this.browser, newPage);
|
||||
|
@ -2,7 +2,7 @@ const { test } = require('@playwright/test');
|
||||
const { VirtualizeList } = require('./virtualize');
|
||||
|
||||
test.describe.parallel('Virtualize list', () => {
|
||||
test.fixme('Virtualized Users List', async ({ browser, page }) => {
|
||||
test('Virtualized Users List', async ({ browser, page }) => {
|
||||
test.setTimeout(0);
|
||||
const virtualizeList = new VirtualizeList(browser, page);
|
||||
await virtualizeList.init();
|
||||
|
@ -15,8 +15,7 @@ class Draw extends Page {
|
||||
|
||||
const shapes1 = await this.getOuterHtmlDrawn();
|
||||
|
||||
const wb = await this.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.getElementBoundingBox(e.whiteboard);
|
||||
await this.page.mouse.move(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
await this.page.mouse.down();
|
||||
await this.page.mouse.move(wbBox.x + 0.7 * wbBox.width, wbBox.y + 0.7 * wbBox.height);
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -14,8 +13,7 @@ class DrawEllipse extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.wbShapesButton);
|
||||
await this.modPage.waitAndClick(e.wbEllipseShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
await this.modPage.page.mouse.down();
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.7 * wbBox.width, wbBox.y + 0.7 * wbBox.height);
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -14,8 +13,7 @@ class DrawLine extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.wbShapesButton);
|
||||
await this.modPage.waitAndClick(e.wbLineShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
await this.modPage.page.mouse.down();
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.7 * wbBox.width, wbBox.y + 0.7 * wbBox.height);
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -13,8 +12,7 @@ class DrawPencil extends MultiUsers {
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitAndClick(e.wbPencilShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
const moveOptions = { steps: 50 }; // to slow down
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.2 * wbBox.width, wbBox.y + 0.2 * wbBox.height);
|
||||
await this.modPage.page.mouse.down();
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -14,8 +13,7 @@ class DrawRectangle extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.wbShapesButton);
|
||||
await this.modPage.waitAndClick(e.wbRectangleShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
await this.modPage.page.mouse.down();
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.7 * wbBox.width, wbBox.y + 0.7 * wbBox.height);
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -13,8 +12,7 @@ class DrawStickyNote extends MultiUsers {
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitAndClick(e.wbStickyNoteShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
await this.modPage.page.mouse.click(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
|
||||
await this.modPage.press('A');
|
||||
@ -23,8 +21,8 @@ class DrawStickyNote extends MultiUsers {
|
||||
await this.modPage.press('B');
|
||||
await this.modPage.page.mouse.click(wbBox.x + 0.6 * wbBox.width, wbBox.y + 0.6 * wbBox.height);
|
||||
|
||||
await this.modPage.hasText(e.wbTypedText, 'AB');
|
||||
await this.modPage2.hasText(e.wbTypedText, 'AB');
|
||||
await this.modPage.hasText(e.wbTypedStickyNote, 'AB');
|
||||
await this.modPage2.hasText(e.wbTypedStickyNote, 'AB');
|
||||
|
||||
const clipObj = {
|
||||
x: wbBox.x,
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -13,8 +12,7 @@ class DrawText extends MultiUsers {
|
||||
await this.modPage.waitForSelector(e.whiteboard, ELEMENT_WAIT_LONGER_TIME);
|
||||
await this.modPage.waitAndClick(e.wbTextShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
await this.modPage.page.mouse.click(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
|
||||
await this.modPage.press('A');
|
||||
|
@ -1,5 +1,4 @@
|
||||
const { expect } = require('@playwright/test');
|
||||
const Page = require('../core/page');
|
||||
const e = require('../core/elements');
|
||||
const { ELEMENT_WAIT_LONGER_TIME } = require('../core/constants');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
@ -14,8 +13,7 @@ class DrawTriangle extends MultiUsers {
|
||||
await this.modPage.waitAndClick(e.wbShapesButton);
|
||||
await this.modPage.waitAndClick(e.wbTriangleShape);
|
||||
|
||||
const wb = await this.modPage.page.$(e.whiteboard);
|
||||
const wbBox = await wb.boundingBox();
|
||||
const wbBox = await this.modPage.getElementBoundingBox(e.whiteboard);
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.3 * wbBox.width, wbBox.y + 0.3 * wbBox.height);
|
||||
await this.modPage.page.mouse.down();
|
||||
await this.modPage.page.mouse.move(wbBox.x + 0.7 * wbBox.width, wbBox.y + 0.7 * wbBox.height);
|
||||
|
@ -8,7 +8,6 @@ const { DrawPencil } = require('./drawPencil');
|
||||
const { DrawText } = require('./drawText');
|
||||
const { DrawStickyNote } = require('./drawStickyNote');
|
||||
const { MultiUsers } = require('../user/multiusers');
|
||||
const { CUSTOM_MEETING_ID } = require('../core/constants');
|
||||
const { encodeCustomParams } = require('../customparameters/util');
|
||||
|
||||
test.describe.parallel('Whiteboard @ci', () => {
|
||||
@ -61,21 +60,21 @@ test.describe.parallel('Drawing - visual regression', () => {
|
||||
|
||||
test('Draw with pencil', async ({ browser, context, page }) => {
|
||||
const drawPencil = new DrawPencil(browser, context);
|
||||
await drawPencil.initModPage(page, true, { customMeetingId : 'draw_pencil_meeting', customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawPencil.initModPage(page, true, { customMeetingId: 'draw_pencil_meeting', customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawPencil.initModPage2(true, context, { customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawPencil.test();
|
||||
});
|
||||
|
||||
test('Type text', async ({ browser, context, page }) => {
|
||||
const drawText = new DrawText(browser, context);
|
||||
await drawText.initModPage(page, true, { customMeetingId : 'draw_text_meeting', customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawText.initModPage(page, true, { customMeetingId: 'draw_text_meeting', customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawText.initModPage2(true, context, { customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawText.test();
|
||||
});
|
||||
|
||||
test('Create sticky note', async ({ browser, context, page }) => {
|
||||
const drawStickyNote = new DrawStickyNote(browser, context);
|
||||
await drawStickyNote.initModPage(page, true, { customMeetingId : 'draw_sticky_meeting', customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawStickyNote.initModPage(page, true, { customMeetingId: 'draw_sticky_meeting', customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawStickyNote.initModPage2(true, context, { customParameter: encodeCustomParams(`userdata-bbb_custom_style=.presentationUploaderToast{display: none;}.currentPresentationToast{display:none;}`) });
|
||||
await drawStickyNote.test();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user