From 3dd588d704d99aae89eae2c2595027d3d83323c8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Porfirio Date: Wed, 21 Aug 2024 14:56:06 -0300 Subject: [PATCH] test: Backporting timer/stopwatch test to 2.7 (#20954) * backporting timer test * adding test on ci --- .../actions-dropdown/component.jsx | 1 + .../imports/ui/components/timer/component.jsx | 7 ++ .../components/timer/indicator/component.jsx | 1 + .../playwright/core/elements.js | 14 +++ bigbluebutton-tests/playwright/core/page.js | 2 +- bigbluebutton-tests/playwright/user/timer.js | 108 ++++++++++++++++++ .../playwright/user/user.spec.js | 13 +++ bigbluebutton-tests/playwright/user/util.js | 8 ++ 8 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 bigbluebutton-tests/playwright/user/timer.js diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx index 65efeb3bab..3aefb2636d 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx @@ -268,6 +268,7 @@ class ActionsDropdown extends PureComponent { : intl.formatMessage(intlMessages.activateTimerStopwatchLabel), key: this.timerId, onClick: () => this.handleTimerClick(), + dataTest: 'timerStopWatchFeature', }); } diff --git a/bigbluebutton-html5/imports/ui/components/timer/component.jsx b/bigbluebutton-html5/imports/ui/components/timer/component.jsx index 01c995b7c8..4fe5ef4dd4 100644 --- a/bigbluebutton-html5/imports/ui/components/timer/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/timer/component.jsx @@ -242,11 +242,13 @@ class Timer extends Component { color={color} label={intl.formatMessage(label)} onClick={() => this.handleControlClick()} + data-test="startStopTimer" /> Service.resetTimer()} + data-test="resetTimerStopWatch" /> ); @@ -342,6 +344,7 @@ class Timer extends Component { max="59" min="0" onChange={(event) => this.handleOnMinutesChange(event)} + data-test="minutesInput" /> {intl.formatMessage(intlMessages.minutes)} @@ -357,6 +360,7 @@ class Timer extends Component { max="59" min="0" onChange={(event) => this.handleOnSecondsChange(event)} + data-test="secondsInput" /> {intl.formatMessage(intlMessages.seconds)} @@ -386,6 +390,7 @@ class Timer extends Component { {this.getTime()} @@ -394,11 +399,13 @@ class Timer extends Component { label={intl.formatMessage(intlMessages.stopwatch)} onClick={() => this.handleSwitchToStopwatch()} color={stopwatch ? 'primary' : 'secondary'} + data-test="stopwatchButton" /> this.handleSwitchToTimer()} color={!stopwatch ? 'primary' : 'secondary'} + data-test="timerButton" /> {this.renderTimer()} diff --git a/bigbluebutton-html5/imports/ui/components/timer/indicator/component.jsx b/bigbluebutton-html5/imports/ui/components/timer/indicator/component.jsx index 01e2c7ad5c..64dd69f01e 100644 --- a/bigbluebutton-html5/imports/ui/components/timer/indicator/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/timer/indicator/component.jsx @@ -435,6 +435,7 @@ class Indicator extends Component { role="button" tabIndex={0} onClick={isModerator ? onClick : null} + data-test="timeIndicator" > diff --git a/bigbluebutton-tests/playwright/core/elements.js b/bigbluebutton-tests/playwright/core/elements.js index cbce5f5a34..c91cce9d07 100644 --- a/bigbluebutton-tests/playwright/core/elements.js +++ b/bigbluebutton-tests/playwright/core/elements.js @@ -159,6 +159,20 @@ exports.selectCameraQualityId = 'select[id="setQuality"]'; exports.virtualBackgrounds = 'div[data-test="virtualBackground"]'; exports.learningDashboard = 'li[data-test="learningDashboard"]'; +// Timer +exports.timerContainer = 'div[data-test="timerContainer"]'; +exports.stopwatchContainer = 'div[data-test="stopwatchContainer"]'; +exports.timerStopwatchFeature = 'li[data-test="timerStopWatchFeature"]'; +exports.timerCurrent = 'span[data-test="timerCurrent"]'; +exports.startStopTimer = 'button[data-test="startStopTimer"]'; +exports.resetTimerStopwatch = 'button[data-test="resetTimerStopWatch"]'; +exports.timerButton = 'button[data-test="timerButton"]'; +exports.timerIndicator = 'div[data-test="timeIndicator"]'; +exports.stopwatch = 'button[data-test="stopwatchButton"]'; +exports.hoursInput = 'input[data-test="hoursInput"]'; +exports.minutesInput = 'input[data-test="minutesInput"]'; +exports.secondsInput = 'input[data-test="secondsInput"]'; + // Notes exports.sharedNotes = 'div[data-test="sharedNotes"]'; exports.hideNotesLabel = 'button[data-test="hideNotesLabel"]'; diff --git a/bigbluebutton-tests/playwright/core/page.js b/bigbluebutton-tests/playwright/core/page.js index ab5df40c19..9b4abe5f9c 100644 --- a/bigbluebutton-tests/playwright/core/page.js +++ b/bigbluebutton-tests/playwright/core/page.js @@ -127,7 +127,7 @@ class Page { } async closeAudioModal() { - await this.waitForSelector(e.audioModal, ELEMENT_WAIT_LONGER_TIME); + await this.waitForSelector(e.audioModal, 20000); await this.waitAndClick(e.closeModal); } diff --git a/bigbluebutton-tests/playwright/user/timer.js b/bigbluebutton-tests/playwright/user/timer.js new file mode 100644 index 0000000000..965b05193c --- /dev/null +++ b/bigbluebutton-tests/playwright/user/timer.js @@ -0,0 +1,108 @@ +const { MultiUsers } = require('./multiusers'); +const { timeInSeconds } = require('./util'); +const { expect } = require('@playwright/test'); +const { sleep } = require('../core/helpers'); +const e = require('../core/elements'); + +class Timer extends MultiUsers { + constructor(browser, context) { + super(browser, context); + } + + async stopwatchTest() { + await this.openTimerAndStopwatch(); + const timerCurrentLocator = this.modPage.getLocator(e.timerCurrent); + const timerIndicatorLocator = this.modPage.getLocator(e.timerIndicator); + + // compare initial values of the stopwatch elements after 2 seconds running + const initialValueStopWatch = await timeInSeconds(timerCurrentLocator); + const initialValueStopWatchIndicator = await timeInSeconds(timerIndicatorLocator); + await this.modPage.hasText(e.timerCurrent, /00:00/); + await this.clickOnTimerControl(); + await sleep(5000); + await expect(await timeInSeconds(timerCurrentLocator)).toBeGreaterThan(initialValueStopWatch); + await expect(await timeInSeconds(timerIndicatorLocator)).toBeGreaterThan(initialValueStopWatchIndicator); + + // stop the stopwatch and check if the values are the same after 2 seconds + await this.clickOnTimerControl(false); + const stopWatchValueStopped = await timeInSeconds(timerCurrentLocator); + const stopWatchIndicatorValueStopped = await timeInSeconds(timerIndicatorLocator); + await sleep(2000); + await expect(await timeInSeconds(timerCurrentLocator)).toBe(stopWatchValueStopped); + await expect(await timeInSeconds(timerCurrentLocator)).toBe(stopWatchIndicatorValueStopped); + + // reset a stopped stopwatch + await this.modPage.waitAndClick(e.resetTimerStopwatch); + await this.modPage.hasText(e.timerCurrent, /00:00/); + await this.modPage.hasText(e.timerIndicator, /00:00/); + + // reset a running stopwatch and check if the values are reset + await this.clickOnTimerControl(); + await this.modPage.hasText(e.timerCurrent, /00:02/); + await this.modPage.waitAndClick(e.resetTimerStopwatch); + await expect(this.modPage.getLocator(e.startStopTimer)).toHaveAttribute('color', 'danger'); + await this.modPage.hasText(e.timerCurrent, /00:00/); + await this.modPage.hasText(e.timerIndicator, /00:00/); + } + + async timerTest() { + await this.openTimerAndStopwatch(); + await this.modPage.waitAndClick(e.timerButton); + await this.modPage.hasElement(e.timerCurrent); + const timerCurrentLocator = this.modPage.getLocator(e.timerCurrent); + const timerIndicatorLocator = this.modPage.getLocator(e.timerIndicator); + + // check for initial values + await this.modPage.hasText(e.timerCurrent, /05:00/); + await this.modPage.hasValue(e.minutesInput, '05'); + + // start timer and check the current values + await this.modPage.getLocator(e.secondsInput).press('Backspace'); + await this.modPage.type(e.secondsInput, '4'); + await this.clickOnTimerControl(); + await this.modPage.hasText(e.timerCurrent, /05:01/); + await this.modPage.hasText(e.timerIndicator, /05:01/); + + // change input value and check if the timer is updated + await this.clickOnTimerControl(false); + await this.modPage.getLocator(e.secondsInput).press('Backspace'); + await this.modPage.type(e.secondsInput, '50'); + await this.clickOnTimerControl(); + await this.modPage.hasText(e.timerCurrent, /04:56/); + await this.modPage.hasText(e.timerIndicator, /04:56/); + + // reset an active timer and check if the values are set to the previous values + await this.clickOnTimerControl(); + await sleep(2000); + await this.modPage.waitAndClick(e.resetTimerStopwatch); + await this.modPage.hasText(e.timerCurrent, /05:00/); + await this.modPage.hasText(e.timerIndicator, /05:00/); + + // check if the timer stops when clicking on the timer indicator + await this.clickOnTimerControl(); + const timerValueAfterStartingTimer = await timeInSeconds(timerCurrentLocator); + const timerIndicatorValueAfterStartingTimer = await timeInSeconds(timerIndicatorLocator); + await this.modPage.waitAndClick(e.timerIndicator); + await expect(timerValueAfterStartingTimer).toBe(await timeInSeconds(timerCurrentLocator)); + await expect(timerIndicatorValueAfterStartingTimer).toBe(await timeInSeconds(timerIndicatorLocator)); + } + + async openTimerAndStopwatch() { + await this.modPage.waitForSelector(e.whiteboard); + await this.modPage.waitAndClick(e.actions); + await this.modPage.waitAndClick(e.timerStopwatchFeature); + await this.modPage.hasElement(e.timerCurrent); + } + + async clickOnTimerControl(isStarting = true) { + await this.modPage.waitAndClick(e.startStopTimer); + const expectedColor = isStarting ? 'danger' : 'primary'; + + await expect( + this.modPage.getLocator(e.startStopTimer), + `should switch the button color after ${isStarting ? 'starting' : 'stopping'} the timer` + ).toHaveAttribute('color', expectedColor); + } +} + +exports.Timer = Timer; diff --git a/bigbluebutton-tests/playwright/user/user.spec.js b/bigbluebutton-tests/playwright/user/user.spec.js index c030da8889..07bf42acef 100644 --- a/bigbluebutton-tests/playwright/user/user.spec.js +++ b/bigbluebutton-tests/playwright/user/user.spec.js @@ -4,6 +4,7 @@ const { MultiUsers } = require('./multiusers'); const { GuestPolicy } = require('./guestPolicy'); const { LockViewers } = require('./lockViewers'); const { MobileDevices } = require('./mobileDevices'); +const { Timer } = require('./timer'); const motoG4 = devices['Moto G4']; const iPhone11 = devices['iPhone 11']; @@ -27,6 +28,18 @@ test.describe.parallel('User', () => { await multiusers.initModPage(page); await multiusers.toggleUserList(); }); + + test('Stopwatch @ci', async ({ browser, context, page })=> { + const timer = new Timer(browser, context); + await timer.initModPage(page, true); + await timer.stopwatchTest(); + }); + + test('Timer @ci', async ({ browser, context, page })=> { + const timer = new Timer(browser, context); + await timer.initModPage(page, true); + await timer.timerTest(); + }); }); test.describe.parallel('List', () => { diff --git a/bigbluebutton-tests/playwright/user/util.js b/bigbluebutton-tests/playwright/user/util.js index 9056894ca1..ae26a0636a 100644 --- a/bigbluebutton-tests/playwright/user/util.js +++ b/bigbluebutton-tests/playwright/user/util.js @@ -44,6 +44,13 @@ async function drawArrow(test) { await test.page.mouse.up(); } +async function timeInSeconds(locator) { + const text = await locator.innerText(); + const [hours, minutes, seconds] = text.split(':').map(Number); + const timeInSeconds = hours * 3600 + minutes * 60 + seconds; + return timeInSeconds; +} + exports.setStatus = setStatus; exports.openLockViewers = openLockViewers; exports.setGuestPolicyOption = setGuestPolicyOption; @@ -51,3 +58,4 @@ exports.checkAvatarIcon = checkAvatarIcon; exports.checkIsPresenter = checkIsPresenter; exports.checkMutedUsers = checkMutedUsers; exports.drawArrow = drawArrow; +exports.timeInSeconds = timeInSeconds;