Add playlist embed E2E test
This commit is contained in:
parent
5ab7fd9da9
commit
7f90579c04
|
@ -0,0 +1,54 @@
|
||||||
|
import { browser, by, element, ExpectedConditions } from 'protractor'
|
||||||
|
import { browserSleep, isIOS, isMobileDevice } from '../utils'
|
||||||
|
|
||||||
|
export class PlayerPage {
|
||||||
|
|
||||||
|
getWatchVideoPlayerCurrentTime () {
|
||||||
|
return element(by.css('.video-js .vjs-current-time-display'))
|
||||||
|
.getText()
|
||||||
|
.then((t: string) => t.split(':')[1])
|
||||||
|
.then(seconds => parseInt(seconds, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
waitUntilPlaylistInfo (text: string) {
|
||||||
|
const elem = element(by.css('.video-js .vjs-playlist-info'))
|
||||||
|
|
||||||
|
return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, text))
|
||||||
|
}
|
||||||
|
|
||||||
|
async playAndPauseVideo (isAutoplay: boolean) {
|
||||||
|
// Autoplay is disabled on iOS
|
||||||
|
if (isAutoplay === false || await isIOS()) {
|
||||||
|
await this.clickOnPlayButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
await browserSleep(2000)
|
||||||
|
await browser.wait(browser.ExpectedConditions.invisibilityOf(element(by.css('.vjs-loading-spinner'))))
|
||||||
|
|
||||||
|
const videojsEl = element(by.css('div.video-js'))
|
||||||
|
await browser.wait(browser.ExpectedConditions.elementToBeClickable(videojsEl))
|
||||||
|
|
||||||
|
// On Android, we need to click twice on "play" (BrowserStack particularity)
|
||||||
|
if (await isMobileDevice()) {
|
||||||
|
await browserSleep(5000)
|
||||||
|
|
||||||
|
await videojsEl.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.ignoreSynchronization = false
|
||||||
|
await browserSleep(7000)
|
||||||
|
browser.ignoreSynchronization = true
|
||||||
|
|
||||||
|
await videojsEl.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
async playVideo () {
|
||||||
|
return this.clickOnPlayButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
private async clickOnPlayButton () {
|
||||||
|
const playButton = element(by.css('.vjs-big-play-button'))
|
||||||
|
await browser.wait(browser.ExpectedConditions.elementToBeClickable(playButton))
|
||||||
|
await playButton.click()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor'
|
import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor'
|
||||||
import { browserSleep, isIOS, isMobileDevice } from '../utils'
|
import { browserSleep, isMobileDevice } from '../utils'
|
||||||
|
|
||||||
export class VideoWatchPage {
|
export class VideoWatchPage {
|
||||||
async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) {
|
async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) {
|
||||||
|
@ -37,43 +37,24 @@ export class VideoWatchPage {
|
||||||
return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, videoName))
|
return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, videoName))
|
||||||
}
|
}
|
||||||
|
|
||||||
getWatchVideoPlayerCurrentTime () {
|
|
||||||
return element(by.css('.video-js .vjs-current-time-display'))
|
|
||||||
.getText()
|
|
||||||
.then((t: string) => t.split(':')[1])
|
|
||||||
.then(seconds => parseInt(seconds, 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
getVideoName () {
|
getVideoName () {
|
||||||
return this.getVideoNameElement().getText()
|
return this.getVideoNameElement().getText()
|
||||||
}
|
}
|
||||||
|
|
||||||
async playAndPauseVideo (isAutoplay: boolean) {
|
async goOnAssociatedEmbed () {
|
||||||
// Autoplay is disabled on iOS
|
let url = await browser.getCurrentUrl()
|
||||||
if (isAutoplay === false || await isIOS()) {
|
url = url.replace('/watch/', '/embed/')
|
||||||
const playButton = element(by.css('.vjs-big-play-button'))
|
url = url.replace(':3333', ':9001')
|
||||||
await browser.wait(browser.ExpectedConditions.elementToBeClickable(playButton))
|
|
||||||
await playButton.click()
|
|
||||||
}
|
|
||||||
|
|
||||||
await browserSleep(2000)
|
return browser.get(url)
|
||||||
await browser.wait(browser.ExpectedConditions.invisibilityOf(element(by.css('.vjs-loading-spinner'))))
|
}
|
||||||
|
|
||||||
const videojsEl = element(by.css('div.video-js'))
|
async goOnP2PMediaLoaderEmbed () {
|
||||||
await browser.wait(browser.ExpectedConditions.elementToBeClickable(videojsEl))
|
return browser.get('https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50')
|
||||||
|
}
|
||||||
|
|
||||||
// On Android, we need to click twice on "play" (BrowserStack particularity)
|
async goOnP2PMediaLoaderPlaylistEmbed () {
|
||||||
if (await isMobileDevice()) {
|
return browser.get('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
|
||||||
await browserSleep(5000)
|
|
||||||
|
|
||||||
await videojsEl.click()
|
|
||||||
}
|
|
||||||
|
|
||||||
browser.ignoreSynchronization = false
|
|
||||||
await browserSleep(7000)
|
|
||||||
browser.ignoreSynchronization = true
|
|
||||||
|
|
||||||
await videojsEl.click()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickOnVideo (videoName: string) {
|
async clickOnVideo (videoName: string) {
|
||||||
|
@ -101,18 +82,6 @@ export class VideoWatchPage {
|
||||||
return textToReturn
|
return textToReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
async goOnAssociatedEmbed () {
|
|
||||||
let url = await browser.getCurrentUrl()
|
|
||||||
url = url.replace('/watch/', '/embed/')
|
|
||||||
url = url.replace(':3333', ':9001')
|
|
||||||
|
|
||||||
return browser.get(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
async goOnP2PMediaLoaderEmbed () {
|
|
||||||
return browser.get('https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50')
|
|
||||||
}
|
|
||||||
|
|
||||||
async clickOnUpdate () {
|
async clickOnUpdate () {
|
||||||
const dropdown = element(by.css('my-video-actions-dropdown .action-button'))
|
const dropdown = element(by.css('my-video-actions-dropdown .action-button'))
|
||||||
await dropdown.click()
|
await dropdown.click()
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { browser } from 'protractor'
|
||||||
import { AppPage } from './po/app.po'
|
import { AppPage } from './po/app.po'
|
||||||
import { LoginPage } from './po/login.po'
|
import { LoginPage } from './po/login.po'
|
||||||
import { MyAccountPage } from './po/my-account'
|
import { MyAccountPage } from './po/my-account'
|
||||||
|
import { PlayerPage } from './po/player.po'
|
||||||
import { VideoUpdatePage } from './po/video-update.po'
|
import { VideoUpdatePage } from './po/video-update.po'
|
||||||
import { VideoUploadPage } from './po/video-upload.po'
|
import { VideoUploadPage } from './po/video-upload.po'
|
||||||
import { VideoWatchPage } from './po/video-watch.po'
|
import { VideoWatchPage } from './po/video-watch.po'
|
||||||
|
@ -23,6 +24,7 @@ describe('Videos workflow', () => {
|
||||||
let myAccountPage: MyAccountPage
|
let myAccountPage: MyAccountPage
|
||||||
let loginPage: LoginPage
|
let loginPage: LoginPage
|
||||||
let appPage: AppPage
|
let appPage: AppPage
|
||||||
|
let playerPage: PlayerPage
|
||||||
|
|
||||||
let videoName = new Date().getTime() + ' video'
|
let videoName = new Date().getTime() + ' video'
|
||||||
const video2Name = new Date().getTime() + ' second video'
|
const video2Name = new Date().getTime() + ' second video'
|
||||||
|
@ -36,6 +38,7 @@ describe('Videos workflow', () => {
|
||||||
myAccountPage = new MyAccountPage()
|
myAccountPage = new MyAccountPage()
|
||||||
loginPage = new LoginPage()
|
loginPage = new LoginPage()
|
||||||
appPage = new AppPage()
|
appPage = new AppPage()
|
||||||
|
playerPage = new PlayerPage()
|
||||||
|
|
||||||
if (await isIOS()) {
|
if (await isIOS()) {
|
||||||
// iOS does not seem to work with protractor
|
// iOS does not seem to work with protractor
|
||||||
|
@ -99,8 +102,8 @@ describe('Videos workflow', () => {
|
||||||
it('Should play the video', async () => {
|
it('Should play the video', async () => {
|
||||||
videoWatchUrl = await browser.getCurrentUrl()
|
videoWatchUrl = await browser.getCurrentUrl()
|
||||||
|
|
||||||
await videoWatchPage.playAndPauseVideo(true)
|
await playerPage.playAndPauseVideo(true)
|
||||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
expect(playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should watch the associated embed video', async () => {
|
it('Should watch the associated embed video', async () => {
|
||||||
|
@ -108,8 +111,8 @@ describe('Videos workflow', () => {
|
||||||
|
|
||||||
await videoWatchPage.goOnAssociatedEmbed()
|
await videoWatchPage.goOnAssociatedEmbed()
|
||||||
|
|
||||||
await videoWatchPage.playAndPauseVideo(false)
|
await playerPage.playAndPauseVideo(false)
|
||||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
expect(playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
|
|
||||||
await browser.waitForAngularEnabled(true)
|
await browser.waitForAngularEnabled(true)
|
||||||
})
|
})
|
||||||
|
@ -119,8 +122,8 @@ describe('Videos workflow', () => {
|
||||||
|
|
||||||
await videoWatchPage.goOnP2PMediaLoaderEmbed()
|
await videoWatchPage.goOnP2PMediaLoaderEmbed()
|
||||||
|
|
||||||
await videoWatchPage.playAndPauseVideo(false)
|
await playerPage.playAndPauseVideo(false)
|
||||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
expect(playerPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
|
|
||||||
await browser.waitForAngularEnabled(true)
|
await browser.waitForAngularEnabled(true)
|
||||||
})
|
})
|
||||||
|
@ -178,26 +181,54 @@ describe('Videos workflow', () => {
|
||||||
|
|
||||||
await myAccountPage.playPlaylist()
|
await myAccountPage.playPlaylist()
|
||||||
|
|
||||||
await videoWatchPage.waitUntilVideoName(video2Name, 20000 * 1000)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Should watch the webtorrent playlist in the embed', async () => {
|
|
||||||
if (await skipIfUploadNotSupported()) return
|
|
||||||
|
|
||||||
await browser.waitForAngularEnabled(false)
|
await browser.waitForAngularEnabled(false)
|
||||||
|
|
||||||
await myAccountPage.goOnAssociatedPlaylistEmbed()
|
|
||||||
|
|
||||||
await videoWatchPage.playAndPauseVideo(false)
|
|
||||||
|
|
||||||
await videoWatchPage.waitUntilVideoName(video2Name, 20000 * 1000)
|
await videoWatchPage.waitUntilVideoName(video2Name, 20000 * 1000)
|
||||||
|
|
||||||
await browser.waitForAngularEnabled(true)
|
await browser.waitForAngularEnabled(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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');`)
|
||||||
|
|
||||||
|
await browser.waitForAngularEnabled(false)
|
||||||
|
|
||||||
|
await myAccountPage.goOnAssociatedPlaylistEmbed()
|
||||||
|
|
||||||
|
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.refresh()
|
||||||
|
|
||||||
|
await playerPage.playVideo()
|
||||||
|
|
||||||
|
await playerPage.waitUntilPlaylistInfo('2/2')
|
||||||
|
|
||||||
|
await browser.waitForAngularEnabled(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should watch the HLS playlist in the embed', async () => {
|
||||||
|
await browser.waitForAngularEnabled(false)
|
||||||
|
|
||||||
|
await videoWatchPage.goOnP2PMediaLoaderPlaylistEmbed()
|
||||||
|
|
||||||
|
await playerPage.playVideo()
|
||||||
|
|
||||||
|
await playerPage.waitUntilPlaylistInfo('2/2')
|
||||||
|
|
||||||
|
await browser.waitForAngularEnabled(true)
|
||||||
|
})
|
||||||
|
|
||||||
it('Should delete the video 2', async () => {
|
it('Should delete the video 2', async () => {
|
||||||
if (await skipIfUploadNotSupported()) return
|
if (await skipIfUploadNotSupported()) return
|
||||||
|
|
||||||
|
// Go to the dev website
|
||||||
|
await browser.get(videoWatchUrl)
|
||||||
|
|
||||||
await myAccountPage.navigateToMyVideos()
|
await myAccountPage.navigateToMyVideos()
|
||||||
|
|
||||||
await myAccountPage.removeVideo(video2Name)
|
await myAccountPage.removeVideo(video2Name)
|
||||||
|
|
|
@ -65,8 +65,11 @@ class PlaylistMenu extends Component {
|
||||||
className: 'title'
|
className: 'title'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const playlistChannel = options.playlist.videoChannel
|
||||||
const leftSubtitle = super.createEl('div', {
|
const leftSubtitle = super.createEl('div', {
|
||||||
innerHTML: this.player().localize('By {1}', [ options.playlist.videoChannel.displayName ]),
|
innerHTML: playlistChannel
|
||||||
|
? this.player().localize('By {1}', [ playlistChannel.displayName ])
|
||||||
|
: '',
|
||||||
className: 'channel'
|
className: 'channel'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue