From 3419e0e1fe8e48a08b63ca0ded31087f913eb2b6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 30 Aug 2021 16:24:25 +0200 Subject: Migrate to webdriverio --- client/e2e/src/commands/upload.ts | 12 +++ client/e2e/src/po/login.po.ts | 24 +++--- client/e2e/src/po/my-account.ts | 102 ++++++++++++++++--------- client/e2e/src/po/player.po.ts | 52 +++++++------ client/e2e/src/po/video-update.po.ts | 12 +-- client/e2e/src/po/video-upload.po.ts | 34 ++++----- client/e2e/src/po/video-watch.po.ts | 132 +++++++++++++++++++++------------ client/e2e/src/types/wdio.d.ts | 5 ++ client/e2e/src/utils.ts | 39 +++++----- client/e2e/src/videos.e2e-spec.ts | 140 ++++++++++++++++------------------- 10 files changed, 316 insertions(+), 236 deletions(-) create mode 100644 client/e2e/src/commands/upload.ts create mode 100644 client/e2e/src/types/wdio.d.ts (limited to 'client/e2e/src') diff --git a/client/e2e/src/commands/upload.ts b/client/e2e/src/commands/upload.ts new file mode 100644 index 000000000..05d3f8f31 --- /dev/null +++ b/client/e2e/src/commands/upload.ts @@ -0,0 +1,12 @@ +browser.addCommand('chooseFile', async function (this: WebdriverIO.Element, localFilePath: string) { + try { + const remoteFile = await browser.uploadFile(localFilePath) + + return this.addValue(remoteFile) + } catch { + console.log('Cannot upload file, fallback to add value.') + + // Firefox does not support upload file, but if we're running the test in local we don't really need it + return this.addValue(localFilePath) + } +}, true) diff --git a/client/e2e/src/po/login.po.ts b/client/e2e/src/po/login.po.ts index 20412ee0d..8e3030e43 100644 --- a/client/e2e/src/po/login.po.ts +++ b/client/e2e/src/po/login.po.ts @@ -1,23 +1,25 @@ -import { browser, element, by } from 'protractor' +import { go } from '../utils' export class LoginPage { async loginAsRootUser () { - await browser.get('/login') + await go('/login') - await browser.executeScript(`window.localStorage.setItem('no_instance_config_warning_modal', 'true')`) - await browser.executeScript(`window.localStorage.setItem('no_welcome_modal', 'true')`) + await browser.execute(`window.localStorage.setItem('no_instance_config_warning_modal', 'true')`) + await browser.execute(`window.localStorage.setItem('no_welcome_modal', 'true')`) - element(by.css('input#username')).sendKeys('root') - element(by.css('input#password')).sendKeys('test1') + await $('input#username').setValue('root') + await $('input#password').setValue('test1') - await browser.sleep(1000) + await browser.pause(1000) - await element(by.css('form input[type=submit]')).click() + await $('form input[type=submit]').click() - expect(this.getLoggedInInfo().getText()).toContain('root') + await this.getLoggedInInfoElem().waitForExist() + + await expect(this.getLoggedInInfoElem()).toHaveText('root') } - private getLoggedInInfo () { - return element(by.css('.logged-in-display-name')) + private getLoggedInInfoElem () { + return $('.logged-in-display-name') } } diff --git a/client/e2e/src/po/my-account.ts b/client/e2e/src/po/my-account.ts index 9866953e9..85dc02805 100644 --- a/client/e2e/src/po/my-account.ts +++ b/client/e2e/src/po/my-account.ts @@ -1,85 +1,117 @@ -import { by, element, browser } from 'protractor' +import { go } from '../utils' export class MyAccountPage { navigateToMyVideos () { - return element(by.css('a[href="/my-library/videos"]')).click() + return $('a[href="/my-library/videos"]').click() } navigateToMyPlaylists () { - return element(by.css('a[href="/my-library/video-playlists"]')).click() + return $('a[href="/my-library/video-playlists"]').click() } navigateToMyHistory () { - return element(by.css('a[href="/my-library/history/videos"]')).click() + return $('a[href="/my-library/history/videos"]').click() } // My account Videos async removeVideo (name: string) { - const container = this.getVideoElement(name) + const container = await this.getVideoElement(name) - await container.element(by.css('.dropdown-toggle')).click() + await container.$('.dropdown-toggle').click() - const dropdownMenu = container.element(by.css('.dropdown-menu .dropdown-item:nth-child(2)')) - await browser.wait(browser.ExpectedConditions.presenceOf(dropdownMenu)) + const dropdownMenu = () => container.$('.dropdown-menu .dropdown-item:nth-child(2)') - return dropdownMenu.click() + await dropdownMenu().waitForDisplayed() + return dropdownMenu().click() } validRemove () { - return element(by.css('input[type=submit]')).click() + return $('input[type=submit]').click() } - countVideos (names: string[]) { - return element.all(by.css('.video')) - .filter(e => { - return e.element(by.css('.video-miniature-name')) - .getText() - .then(t => names.some(n => t.includes(n))) - }) - .count() + async countVideos (names: string[]) { + const elements = await $$('.video').filter(async e => { + const t = await e.$('.video-miniature-name').getText() + + return names.some(n => t.includes(n)) + }) + + return elements.length } // My account playlists - getPlaylistVideosText (name: string) { - return this.getPlaylist(name).element(by.css('.miniature-playlist-info-overlay')).getText() + async getPlaylistVideosText (name: string) { + const elem = await this.getPlaylist(name) + + return elem.$('.miniature-playlist-info-overlay').getText() } - clickOnPlaylist (name: string) { - return this.getPlaylist(name).element(by.css('.miniature-thumbnail')).click() + async clickOnPlaylist (name: string) { + const elem = await this.getPlaylist(name) + + return elem.$('.miniature-thumbnail').click() } - countTotalPlaylistElements () { - return element.all(by.css('my-video-playlist-element-miniature')).count() + async countTotalPlaylistElements () { + await $('').waitForDisplayed() + + return $$('').length } playPlaylist () { - return element(by.css('.playlist-info .miniature-thumbnail')).click() + return $('.playlist-info .miniature-thumbnail').click() } async goOnAssociatedPlaylistEmbed () { - let url = await browser.getCurrentUrl() + let url = await browser.getUrl() url = url.replace('/w/p/', '/video-playlists/embed/') url = url.replace(':3333', ':9001') - return browser.get(url) + return go(url) } // My account Videos - private getVideoElement (name: string) { - return element.all(by.css('.video')) - .filter(e => e.element(by.css('.video-miniature-name')).getText().then(t => t.includes(name))) - .first() + private async getVideoElement (name: string) { + const video = async () => { + const videos = await $$('.video').filter(async e => { + const t = await e.$('.video-miniature-name').getText() + + return t.includes(name) + }) + + return videos[0] + } + + await browser.waitUntil(async () => { + return (await video()).isDisplayed() + }) + + return video() } // My account playlists - private getPlaylist (name: string) { - return element.all(by.css('my-video-playlist-miniature')) - .filter(e => e.element(by.css('.miniature-name')).getText().then(t => t.includes(name))) - .first() + private async getPlaylist (name: string) { + const playlist = () => { + return $$('my-video-playlist-miniature') + .filter(async e => { + const t = await e.$('.miniature-name').getText() + + return t.includes(name) + }) + .then(elems => elems[0]) + } + + await browser.waitUntil(async () => { + const el = await playlist() + + return el?.isDisplayed() + }) + + return playlist() } } diff --git a/client/e2e/src/po/player.po.ts b/client/e2e/src/po/player.po.ts index cb148a003..9d6e21009 100644 --- a/client/e2e/src/po/player.po.ts +++ b/client/e2e/src/po/player.po.ts @@ -1,45 +1,54 @@ -import { browser, by, element } from 'protractor' import { browserSleep, isIOS, isMobileDevice, isSafari } from '../utils' export class PlayerPage { - async getWatchVideoPlayerCurrentTime () { - const elem = element(by.css('video')) + getWatchVideoPlayerCurrentTime () { + const elem = $('video') - return elem.getAttribute('currentTime') - } + if (isIOS()) { + return elem.getAttribute('currentTime') + .then(t => parseInt(t, 10)) + .then(t => Math.round(t)) + } - waitUntilPlaylistInfo (text: string) { - const elem = element(by.css('.video-js .vjs-playlist-info')) + return elem.getProperty('currentTime') + } - return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, text)) + waitUntilPlaylistInfo (text: string, maxTime: number) { + return browser.waitUntil(async () => { + return (await $('.video-js .vjs-playlist-info').getText()).includes(text) + }, { timeout: maxTime }) } waitUntilPlayerWrapper () { - const elem = element(by.css('#placeholder-preview')) - - return browser.wait(browser.ExpectedConditions.presenceOf(elem)) + return browser.waitUntil(async () => { + return !!(await $('#placeholder-preview')) + }) } async playAndPauseVideo (isAutoplay: boolean) { - const videojsEl = element(by.css('div.video-js')) - await browser.wait(browser.ExpectedConditions.elementToBeClickable(videojsEl)) + const videojsElem = () => $('div.video-js') + + await videojsElem().waitForExist() // Autoplay is disabled on iOS and Safari - if (await isIOS() || await isSafari() || await isMobileDevice()) { + if (isIOS() || isSafari() || isMobileDevice()) { // We can't play the video using protractor if it is not muted - await browser.executeScript(`document.querySelector('video').muted = true`) + await browser.execute(`document.querySelector('video').muted = true`) await this.clickOnPlayButton() } else if (isAutoplay === false) { await this.clickOnPlayButton() } await browserSleep(2000) - await browser.wait(browser.ExpectedConditions.invisibilityOf(element(by.css('.vjs-loading-spinner')))) - await browserSleep(2000) + await browser.waitUntil(async () => { + return !await $('.vjs-loading-spinner').isDisplayedInViewport() + }, { timeout: 20 * 1000 }) - await videojsEl.click() + await browserSleep(4000) + + await videojsElem().click() } async playVideo () { @@ -47,8 +56,9 @@ export class PlayerPage { } private async clickOnPlayButton () { - const playButton = element(by.css('.vjs-big-play-button')) - await browser.wait(browser.ExpectedConditions.elementToBeClickable(playButton)) - await playButton.click() + const playButton = () => $('.vjs-big-play-button') + + await playButton().waitForClickable() + await playButton().click() } } diff --git a/client/e2e/src/po/video-update.po.ts b/client/e2e/src/po/video-update.po.ts index 752741378..3ffb7ba57 100644 --- a/client/e2e/src/po/video-update.po.ts +++ b/client/e2e/src/po/video-update.po.ts @@ -1,11 +1,11 @@ -import { by, element } from 'protractor' - export class VideoUpdatePage { async updateName (videoName: string) { - const nameInput = element(by.css('input#name')) - await nameInput.clear() - await nameInput.sendKeys(videoName) + const nameInput = $('input#name') + + await nameInput.waitForDisplayed() + await nameInput.clearValue() + await nameInput.setValue(videoName) } async validUpdate () { @@ -15,6 +15,6 @@ export class VideoUpdatePage { } private getSubmitButton () { - return element(by.css('.submit-container .action-button')) + return $('.submit-container .action-button') } } diff --git a/client/e2e/src/po/video-upload.po.ts b/client/e2e/src/po/video-upload.po.ts index a248912ed..34f916b55 100644 --- a/client/e2e/src/po/video-upload.po.ts +++ b/client/e2e/src/po/video-upload.po.ts @@ -1,33 +1,29 @@ -import { browser, by, element } from 'protractor' -import { FileDetector } from 'selenium-webdriver/remote' import { join } from 'path' export class VideoUploadPage { async navigateTo () { - await element(by.css('.header .publish-button')).click() + await $('.header .publish-button').click() - return browser.wait(browser.ExpectedConditions.visibilityOf(element(by.css('.upload-video-container')))) + await $('.upload-video-container').waitForDisplayed() } async uploadVideo () { - browser.setFileDetector(new FileDetector()) - const fileToUpload = join(__dirname, '../../fixtures/video.mp4') const fileInputSelector = '.upload-video-container input[type=file]' const parentFileInput = '.upload-video-container .button-file' // Avoid sending keys on non visible element - await browser.executeScript(`document.querySelector('${fileInputSelector}').style.opacity = 1`) - await browser.executeScript(`document.querySelector('${parentFileInput}').style.overflow = 'initial'`) + await browser.execute(`document.querySelector('${fileInputSelector}').style.opacity = 1`) + await browser.execute(`document.querySelector('${parentFileInput}').style.overflow = 'initial'`) - await browser.sleep(1000) + await browser.pause(1000) - const elem = element(by.css(fileInputSelector)) - await elem.sendKeys(fileToUpload) + const elem = await $(fileInputSelector) + await elem.chooseFile(fileToUpload) // Wait for the upload to finish - await browser.wait(async () => { - const actionButton = this.getSecondStepSubmitButton().element(by.css('.action-button')) + await browser.waitUntil(async () => { + const actionButton = this.getSecondStepSubmitButton().$('.action-button') const klass = await actionButton.getAttribute('class') return !klass.includes('disabled') @@ -35,16 +31,18 @@ export class VideoUploadPage { } async validSecondUploadStep (videoName: string) { - const nameInput = element(by.css('input#name')) - await nameInput.clear() - await nameInput.sendKeys(videoName) + const nameInput = $('input#name') + await nameInput.clearValue() + await nameInput.setValue(videoName) await this.getSecondStepSubmitButton().click() - return browser.wait(browser.ExpectedConditions.urlContains('/w/')) + return browser.waitUntil(async () => { + return (await browser.getUrl()).includes('/w/') + }) } private getSecondStepSubmitButton () { - return element(by.css('.submit-container my-button')) + return $('.submit-container my-button') } } diff --git a/client/e2e/src/po/video-watch.po.ts b/client/e2e/src/po/video-watch.po.ts index c875d5854..01061d5d4 100644 --- a/client/e2e/src/po/video-watch.po.ts +++ b/client/e2e/src/po/video-watch.po.ts @@ -1,5 +1,4 @@ -import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor' -import { browserSleep, isMobileDevice } from '../utils' +import { browserSleep, go } from '../utils' export class VideoWatchPage { async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) { @@ -12,19 +11,19 @@ export class VideoWatchPage { url = '/videos/recently-added' } - await browser.get(url, 20000) + await go(url) // Waiting the following element does not work on Safari... if (isSafari) return browserSleep(3000) - const elem = element.all(by.css('.videos .video-miniature .video-miniature-name')).first() - return browser.wait(browser.ExpectedConditions.visibilityOf(elem)) + await $('.videos .video-miniature .video-miniature-name').waitForDisplayed() } - getVideosListName () { - return element.all(by.css('.videos .video-miniature .video-miniature-name')) - .getText() - .then((texts: any) => texts.map((t: any) => t.trim())) + async getVideosListName () { + const elems = await $$('.videos .video-miniature .video-miniature-name') + const texts = await Promise.all(elems.map(e => e.getText())) + + return texts.map(t => t.trim()) } waitWatchVideoName (videoName: string, isMobileDevice: boolean, isSafari: boolean) { @@ -33,99 +32,134 @@ export class VideoWatchPage { // On mobile we display the first node, on desktop the second const index = isMobileDevice ? 0 : 1 - const elem = element.all(by.css('.video-info .video-info-name')).get(index) - return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, videoName)) + return browser.waitUntil(async () => { + return (await $$('.video-info .video-info-name')[index].getText()).includes(videoName) + }) } getVideoName () { - return this.getVideoNameElement().getText() + return this.getVideoNameElement().then(e => e.getText()) } async goOnAssociatedEmbed () { - let url = await browser.getCurrentUrl() + let url = await browser.getUrl() url = url.replace('/w/', '/videos/embed/') url = url.replace(':3333', ':9001') - return browser.get(url) + return go(url) } - async goOnP2PMediaLoaderEmbed () { - return browser.get('https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50') + goOnP2PMediaLoaderEmbed () { + return go( + 'https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50' + ) } - async goOnP2PMediaLoaderPlaylistEmbed () { - return browser.get('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a') + goOnP2PMediaLoaderPlaylistEmbed () { + return go( + 'https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a' + ) } async clickOnVideo (videoName: string) { - const video = element.all(by.css('.videos .video-miniature .video-miniature-name')) - .filter(e => e.getText().then(t => t === videoName )) - .first() + const video = async () => { + const videos = await $$('.videos .video-miniature .video-miniature-name').filter(async e => { + const t = await e.getText() + + return t === videoName + }) + + return videos[0] + } + + await browser.waitUntil(async () => { + const elem = await video() - await browser.wait(browser.ExpectedConditions.elementToBeClickable(video)) - await video.click() + return elem?.isClickable() + }); - await browser.wait(browser.ExpectedConditions.urlContains('/w/')) + (await video()).click() + + await browser.waitUntil(async () => (await browser.getUrl()).includes('/w/')) } async clickOnFirstVideo () { - const video = element.all(by.css('.videos .video-miniature .video-thumbnail')).first() - const videoName = element.all(by.css('.videos .video-miniature .video-miniature-name')).first() + const video = () => $('.videos .video-miniature .video-thumbnail') + const videoName = () => $('.videos .video-miniature .video-miniature-name') + + await video().waitForClickable() - // Don't know why but the expectation fails on Safari - await browser.wait(browser.ExpectedConditions.elementToBeClickable(video)) + const textToReturn = await videoName().getText() + await video().click() - const textToReturn = videoName.getText() - await video.click() + await browser.waitUntil(async () => (await browser.getUrl()).includes('/w/')) - await browser.wait(browser.ExpectedConditions.urlContains('/w/')) return textToReturn } async clickOnUpdate () { - const dropdown = element(by.css('my-video-actions-dropdown .action-button')) + const dropdown = $('my-video-actions-dropdown .action-button') await dropdown.click() - const items: ElementFinder[] = await element.all(by.css('.dropdown-menu.show .dropdown-item')) + await $('.dropdown-menu.show .dropdown-item').waitForDisplayed() + const items = await $$('.dropdown-menu.show .dropdown-item') for (const item of items) { const href = await item.getAttribute('href') - if (href && href.includes('/update/')) { + if (href?.includes('/update/')) { await item.click() return } } } - async clickOnSave () { - return element(by.css('.action-button-save')).click() + clickOnSave () { + return $('.action-button-save').click() } async createPlaylist (name: string) { - await element(by.css('.new-playlist-button')).click() + const newPlaylistButton = () => $('.new-playlist-button') + + await newPlaylistButton().waitForClickable() + await newPlaylistButton().click() + + const displayName = () => $('#displayName') - await element(by.css('#displayName')).sendKeys(name) + await displayName().waitForDisplayed() + await displayName().setValue(name) - return element(by.css('.new-playlist-block input[type=submit]')).click() + return $('.new-playlist-block input[type=submit]').click() } async saveToPlaylist (name: string) { - return element.all(by.css('my-video-add-to-playlist .playlist')) - .filter(p => p.getText().then(t => t === name)) - .click() + const playlist = () => $('my-video-add-to-playlist').$(`.playlist=${name}`) + + await playlist().waitForDisplayed() + + return playlist().click() } waitUntilVideoName (name: string, maxTime: number) { - const elem = this.getVideoNameElement() - - return browser.wait(ExpectedConditions.textToBePresentInElement(elem, name), maxTime) + return browser.waitUntil(async () => { + return (await this.getVideoName()) === name + }, { timeout: maxTime }) } - private getVideoNameElement () { + private async getVideoNameElement () { // We have 2 video info name block, pick the first that is not empty - return element.all(by.css('.video-info-first-row .video-info-name')) - .filter(e => e.getText().then(t => !!t)) - .first() + const elem = async () => { + const elems = await $$('.video-info-first-row .video-info-name').filter(e => e.isDisplayed()) + + return elems[0] + } + + await browser.waitUntil(async () => { + const e = await elem() + + return e?.isDisplayed() + }) + + return elem() } } diff --git a/client/e2e/src/types/wdio.d.ts b/client/e2e/src/types/wdio.d.ts new file mode 100644 index 000000000..6dc2cbd87 --- /dev/null +++ b/client/e2e/src/types/wdio.d.ts @@ -0,0 +1,5 @@ +declare namespace WebdriverIO { + interface Element { + chooseFile: (path: string) => Promise + } +} diff --git a/client/e2e/src/utils.ts b/client/e2e/src/utils.ts index a9d30c03a..df1c29238 100644 --- a/client/e2e/src/utils.ts +++ b/client/e2e/src/utils.ts @@ -1,34 +1,37 @@ -import { browser } from 'protractor' - async function browserSleep (amount: number) { - const oldValue = await browser.waitForAngularEnabled() - - // iOS does not seem to work with protractor - // https://github.com/angular/protractor/issues/2840 - if (await isIOS()) browser.waitForAngularEnabled(true) + await browser.pause(amount) +} - await browser.sleep(amount) +function isMobileDevice () { + const platformName = (browser.capabilities['platformName'] || '').toLowerCase() - if (await isIOS()) browser.waitForAngularEnabled(oldValue) + return platformName === 'android' || platformName === 'ios' } -async function isMobileDevice () { - const caps = await browser.getCapabilities() - return caps.get('realMobile') === 'true' || caps.get('realMobile') === true +function isSafari () { + return browser.capabilities['browserName'] && + browser.capabilities['browserName'].toLowerCase() === 'safari' } -async function isSafari () { - const caps = await browser.getCapabilities() - return caps.get('browserName') && caps.get('browserName').toLowerCase() === 'safari' +function isIOS () { + return isMobileDevice() && isSafari() } -async function isIOS () { - return await isMobileDevice() && await isSafari() +async function go (url: string) { + await browser.url(url) + + // Hide notifications that could fail tests when hiding buttons + await browser.execute(() => { + const style = document.createElement('style') + style.innerHTML = 'p-toast { display: none }' + document.head.appendChild(style) + }) } -export { +export { isMobileDevice, isSafari, isIOS, + go, browserSleep } diff --git a/client/e2e/src/videos.e2e-spec.ts b/client/e2e/src/videos.e2e-spec.ts index fc816d1bf..7f7c814e1 100644 --- a/client/e2e/src/videos.e2e-spec.ts +++ b/client/e2e/src/videos.e2e-spec.ts @@ -1,14 +1,13 @@ -import { browser } from 'protractor' import { LoginPage } from './po/login.po' import { MyAccountPage } from './po/my-account' import { PlayerPage } from './po/player.po' import { VideoUpdatePage } from './po/video-update.po' import { VideoUploadPage } from './po/video-upload.po' import { VideoWatchPage } from './po/video-watch.po' -import { isIOS, isMobileDevice, isSafari } from './utils' +import { browserSleep, go, isIOS, isMobileDevice, isSafari } from './utils' -async function skipIfUploadNotSupported () { - if (await isMobileDevice() || await isSafari()) { +function isUploadUnsupported () { + if (isMobileDevice() || isSafari()) { console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.') return true } @@ -24,11 +23,30 @@ describe('Videos workflow', () => { let loginPage: LoginPage let playerPage: PlayerPage - let videoName = new Date().getTime() + ' video' - const video2Name = new Date().getTime() + ' second video' - const playlistName = new Date().getTime() + ' playlist' + let videoName = Math.random() + ' video' + const video2Name = Math.random() + ' second video' + const playlistName = Math.random() + ' playlist' let videoWatchUrl: string + before(async () => { + if (isIOS()) { + console.log('iOS detected') + } else if (isMobileDevice()) { + console.log('Android detected.') + } else if (isSafari()) { + console.log('Safari detected.') + } + + if (isUploadUnsupported()) return + + await browser.waitUntil(async () => { + await go('/') + await browserSleep(500) + + return $('').isDisplayed() + }, { timeout: 20 * 1000 }) + }) + beforeEach(async () => { videoWatchPage = new VideoWatchPage() videoUploadPage = new VideoUploadPage() @@ -37,25 +55,13 @@ describe('Videos workflow', () => { loginPage = new LoginPage() playerPage = new PlayerPage() - if (await isIOS()) { - // iOS does not seem to work with protractor - // https://github.com/angular/protractor/issues/2840 - browser.waitForAngularEnabled(false) - - console.log('iOS detected') - } else if (await isMobileDevice()) { - console.log('Android detected.') - } else if (await isSafari()) { - console.log('Safari detected.') - } - - if (!await isMobileDevice()) { - await browser.driver.manage().window().maximize() + if (!isMobileDevice()) { + await browser.maximizeWindow() } }) it('Should log in', async () => { - if (await isMobileDevice() || await isSafari()) { + if (isMobileDevice() || isSafari()) { console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.') return } @@ -64,7 +70,7 @@ describe('Videos workflow', () => { }) it('Should upload a video', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return await videoUploadPage.navigateTo() @@ -73,62 +79,52 @@ describe('Videos workflow', () => { }) it('Should list videos', async () => { - await videoWatchPage.goOnVideosList(await isMobileDevice(), await isSafari()) + await videoWatchPage.goOnVideosList(isMobileDevice(), isSafari()) - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return - const videoNames = videoWatchPage.getVideosListName() + const videoNames = await videoWatchPage.getVideosListName() expect(videoNames).toContain(videoName) }) it('Should go on video watch page', async () => { let videoNameToExcept = videoName - if (await isMobileDevice() || await isSafari()) { - await browser.get('https://peertube2.cpy.re/w/122d093a-1ede-43bd-bd34-59d2931ffc5e') + if (isMobileDevice() || isSafari()) { + await go('https://peertube2.cpy.re/w/122d093a-1ede-43bd-bd34-59d2931ffc5e') videoNameToExcept = 'E2E tests' } else { await videoWatchPage.clickOnVideo(videoName) } - return videoWatchPage.waitWatchVideoName(videoNameToExcept, await isMobileDevice(), await isSafari()) + return videoWatchPage.waitWatchVideoName(videoNameToExcept, isMobileDevice(), isSafari()) }) it('Should play the video', async () => { - videoWatchUrl = await browser.getCurrentUrl() + videoWatchUrl = await browser.getUrl() await playerPage.playAndPauseVideo(true) - expect(playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) + expect(await playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) }) it('Should watch the associated embed video', async () => { - const oldValue = await browser.waitForAngularEnabled() - await browser.waitForAngularEnabled(false) - await videoWatchPage.goOnAssociatedEmbed() await playerPage.playAndPauseVideo(false) - expect(playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) - - await browser.waitForAngularEnabled(oldValue) + expect(await playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) }) it('Should watch the p2p media loader embed video', async () => { - const oldValue = await browser.waitForAngularEnabled() - await browser.waitForAngularEnabled(false) - await videoWatchPage.goOnP2PMediaLoaderEmbed() await playerPage.playAndPauseVideo(false) - expect(playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) - - await browser.waitForAngularEnabled(oldValue) + expect(await playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) }) it('Should update the video', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return - await browser.get(videoWatchUrl) + await go(videoWatchUrl) await videoWatchPage.clickOnUpdate() @@ -142,14 +138,14 @@ describe('Videos workflow', () => { }) it('Should add the video in my playlist', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return await videoWatchPage.clickOnSave() await videoWatchPage.createPlaylist(playlistName) await videoWatchPage.saveToPlaylist(playlistName) - await browser.sleep(5000) + await browser.pause(5000) await videoUploadPage.navigateTo() @@ -161,7 +157,7 @@ describe('Videos workflow', () => { }) it('Should have the playlist in my account', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return await myAccountPage.navigateToMyPlaylists() @@ -175,26 +171,18 @@ describe('Videos workflow', () => { }) it('Should watch the playlist', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return await myAccountPage.playPlaylist() - const oldValue = await browser.waitForAngularEnabled() - await browser.waitForAngularEnabled(false) - - await videoWatchPage.waitUntilVideoName(video2Name, 20000 * 1000) - - await browser.waitForAngularEnabled(oldValue) + await videoWatchPage.waitUntilVideoName(video2Name, 30 * 1000) }) it('Should watch the webtorrent playlist in the embed', async () => { - if (await skipIfUploadNotSupported()) return - - const accessToken = await browser.executeScript(`return window.localStorage.getItem('access_token');`) - const refreshToken = await browser.executeScript(`return window.localStorage.getItem('refresh_token');`) + if (isUploadUnsupported()) return - const oldValue = await browser.waitForAngularEnabled() - await browser.waitForAngularEnabled(false) + const accessToken = await browser.execute(`return window.localStorage.getItem('access_token');`) + const refreshToken = await browser.execute(`return window.localStorage.getItem('refresh_token');`) await myAccountPage.goOnAssociatedPlaylistEmbed() @@ -202,49 +190,45 @@ describe('Videos workflow', () => { console.log('Will set %s and %s tokens in local storage.', accessToken, refreshToken) - await browser.executeScript(`window.localStorage.setItem('access_token', '${accessToken}');`) - await browser.executeScript(`window.localStorage.setItem('refresh_token', '${refreshToken}');`) - await browser.executeScript(`window.localStorage.setItem('token_type', 'Bearer');`) + await browser.execute(`window.localStorage.setItem('access_token', '${accessToken}');`) + await browser.execute(`window.localStorage.setItem('refresh_token', '${refreshToken}');`) + await browser.execute(`window.localStorage.setItem('token_type', 'Bearer');`) await browser.refresh() await playerPage.playVideo() - await playerPage.waitUntilPlaylistInfo('2/2') - - await browser.waitForAngularEnabled(oldValue) + await playerPage.waitUntilPlaylistInfo('2/2', 30 * 1000) }) it('Should watch the HLS playlist in the embed', async () => { - const oldValue = await browser.waitForAngularEnabled() - await browser.waitForAngularEnabled(false) - await videoWatchPage.goOnP2PMediaLoaderPlaylistEmbed() await playerPage.playVideo() - await playerPage.waitUntilPlaylistInfo('2/2') - - await browser.waitForAngularEnabled(oldValue) + await playerPage.waitUntilPlaylistInfo('2/2', 30 * 1000) }) it('Should delete the video 2', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return // Go to the dev website - await browser.get(videoWatchUrl) + await go(videoWatchUrl) await myAccountPage.navigateToMyVideos() await myAccountPage.removeVideo(video2Name) await myAccountPage.validRemove() - const count = await myAccountPage.countVideos([ videoName, video2Name ]) - expect(count).toEqual(1) + await browser.waitUntil(async () => { + const count = await myAccountPage.countVideos([ videoName, video2Name ]) + + return count === 1 + }) }) it('Should delete the first video', async () => { - if (await skipIfUploadNotSupported()) return + if (isUploadUnsupported()) return await myAccountPage.removeVideo(videoName) await myAccountPage.validRemove() -- cgit v1.2.3