mirror of https://github.com/Chocobozzz/PeerTube
Add more e2e tests
parent
6b226c3278
commit
e69cb173ba
|
@ -0,0 +1,72 @@
|
|||
import { by, element } from 'protractor'
|
||||
|
||||
export class MyAccountPage {
|
||||
|
||||
navigateToMyVideos () {
|
||||
return element(by.css('a[href="/my-account/videos"]')).click()
|
||||
}
|
||||
|
||||
navigateToMyPlaylists () {
|
||||
return element(by.css('a[href="/my-account/video-playlists"]')).click()
|
||||
}
|
||||
|
||||
navigateToMyHistory () {
|
||||
return element(by.css('a[href="/my-account/history/videos"]')).click()
|
||||
}
|
||||
|
||||
// My account Videos
|
||||
|
||||
getLastVideoName () {
|
||||
return this.getAllVideoNameElements().first().getText()
|
||||
}
|
||||
|
||||
removeLastVideo () {
|
||||
return this.getLastVideoElement().element(by.css('my-delete-button')).click()
|
||||
}
|
||||
|
||||
validRemove () {
|
||||
return element(by.css('.action-button-submit')).click()
|
||||
}
|
||||
|
||||
countVideos () {
|
||||
return this.getAllVideoNameElements().count()
|
||||
}
|
||||
|
||||
// My account playlists
|
||||
|
||||
getLastUpdatedPlaylistName () {
|
||||
return this.getLastUpdatedPlaylist().element(by.css('.miniature-name')).getText()
|
||||
}
|
||||
|
||||
getLastUpdatedPlaylistVideosText () {
|
||||
return this.getLastUpdatedPlaylist().element(by.css('.miniature-playlist-info-overlay')).getText()
|
||||
}
|
||||
|
||||
clickOnLastUpdatedPlaylist () {
|
||||
return this.getLastUpdatedPlaylist().element(by.css('.miniature-thumbnail')).click()
|
||||
}
|
||||
|
||||
countTotalPlaylistElements () {
|
||||
return element.all(by.css('my-video-playlist-element-miniature')).count()
|
||||
}
|
||||
|
||||
playPlaylist () {
|
||||
return element(by.css('.playlist-info .miniature-thumbnail')).click()
|
||||
}
|
||||
|
||||
// My account Videos
|
||||
|
||||
private getLastVideoElement () {
|
||||
return element.all(by.css('.video')).first()
|
||||
}
|
||||
|
||||
private getAllVideoNameElements () {
|
||||
return element.all(by.css('.video-miniature-name'))
|
||||
}
|
||||
|
||||
// My account playlists
|
||||
|
||||
private getLastUpdatedPlaylist () {
|
||||
return element.all(by.css('my-video-playlist-miniature')).first()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
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)
|
||||
}
|
||||
|
||||
async validUpdate () {
|
||||
const submitButton = await this.getSubmitButton()
|
||||
|
||||
return submitButton.click()
|
||||
}
|
||||
|
||||
private getSubmitButton () {
|
||||
return element(by.css('.submit-button:not(.disabled) input'))
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { browser, by, element } from 'protractor'
|
||||
import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor'
|
||||
|
||||
export class VideoWatchPage {
|
||||
async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) {
|
||||
|
@ -44,6 +44,10 @@ export class VideoWatchPage {
|
|||
.then(seconds => parseInt(seconds, 10))
|
||||
}
|
||||
|
||||
getVideoName () {
|
||||
return this.getVideoNameElement().getText()
|
||||
}
|
||||
|
||||
async playAndPauseVideo (isAutoplay: boolean, isMobileDevice: boolean) {
|
||||
if (isAutoplay === false) {
|
||||
const playButton = element(by.css('.vjs-big-play-button'))
|
||||
|
@ -101,4 +105,41 @@ export class VideoWatchPage {
|
|||
async goOnP2PMediaLoaderEmbed () {
|
||||
return browser.get('https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50?mode=p2p-media-loader')
|
||||
}
|
||||
|
||||
async clickOnUpdate () {
|
||||
const dropdown = element(by.css('my-video-actions-dropdown .action-button'))
|
||||
await dropdown.click()
|
||||
|
||||
const items: ElementFinder[] = await element.all(by.css('my-video-actions-dropdown .dropdown-menu .dropdown-item'))
|
||||
|
||||
for (const item of items) {
|
||||
const href = await item.getAttribute('href')
|
||||
|
||||
if (href && href.includes('/update/')) {
|
||||
await item.click()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async clickOnSave () {
|
||||
return element(by.css('.action-button-save')).click()
|
||||
}
|
||||
|
||||
async saveToWatchLater () {
|
||||
return element.all(by.css('my-video-add-to-playlist .playlist')).first().click()
|
||||
}
|
||||
|
||||
waitUntilVideoName (name: string, maxTime: number) {
|
||||
const elem = this.getVideoNameElement()
|
||||
|
||||
return browser.wait(ExpectedConditions.textToBePresentInElement(elem, name), maxTime)
|
||||
}
|
||||
|
||||
private getVideoNameElement () {
|
||||
// We have 2 video info name block, pick the first that is not empty
|
||||
return element.all(by.css('.video-bottom .video-info-name'))
|
||||
.filter(e => e.getText().then(t => !!t))
|
||||
.first()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,35 +2,56 @@ import { VideoWatchPage } from './po/video-watch.po'
|
|||
import { VideoUploadPage } from './po/video-upload.po'
|
||||
import { LoginPage } from './po/login.po'
|
||||
import { browser } from 'protractor'
|
||||
import { VideoUpdatePage } from './po/video-update.po'
|
||||
import { MyAccountPage } from './po/my-account'
|
||||
|
||||
async function skipIfUploadNotSupported () {
|
||||
if (await isMobileDevice() || await isSafari()) {
|
||||
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
async function isMobileDevice () {
|
||||
const caps = await browser.getCapabilities()
|
||||
return caps.get('realMobile') === 'true' || caps.get('realMobile') === true
|
||||
}
|
||||
|
||||
async function isSafari () {
|
||||
const caps = await browser.getCapabilities()
|
||||
return caps.get('browserName') && caps.get('browserName').toLowerCase() === 'safari'
|
||||
}
|
||||
|
||||
describe('Videos workflow', () => {
|
||||
let videoWatchPage: VideoWatchPage
|
||||
let pageUploadPage: VideoUploadPage
|
||||
let videoUploadPage: VideoUploadPage
|
||||
let videoUpdatePage: VideoUpdatePage
|
||||
let myAccountPage: MyAccountPage
|
||||
let loginPage: LoginPage
|
||||
|
||||
const videoName = new Date().getTime() + ' video'
|
||||
let isMobileDevice = false
|
||||
let isSafari = false
|
||||
let videoWatchUrl: string
|
||||
|
||||
beforeEach(async () => {
|
||||
videoWatchPage = new VideoWatchPage()
|
||||
pageUploadPage = new VideoUploadPage()
|
||||
videoUploadPage = new VideoUploadPage()
|
||||
videoUpdatePage = new VideoUpdatePage()
|
||||
myAccountPage = new MyAccountPage()
|
||||
loginPage = new LoginPage()
|
||||
|
||||
const caps = await browser.getCapabilities()
|
||||
isMobileDevice = caps.get('realMobile') === 'true' || caps.get('realMobile') === true
|
||||
isSafari = caps.get('browserName') && caps.get('browserName').toLowerCase() === 'safari'
|
||||
|
||||
if (isMobileDevice) {
|
||||
if (await isMobileDevice()) {
|
||||
console.log('Mobile device detected.')
|
||||
}
|
||||
|
||||
if (isSafari) {
|
||||
if (await isSafari()) {
|
||||
console.log('Safari detected.')
|
||||
}
|
||||
})
|
||||
|
||||
it('Should log in', () => {
|
||||
if (isMobileDevice || isSafari) {
|
||||
it('Should log in', async () => {
|
||||
if (await isMobileDevice() || await isSafari()) {
|
||||
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
||||
return
|
||||
}
|
||||
|
@ -39,24 +60,18 @@ describe('Videos workflow', () => {
|
|||
})
|
||||
|
||||
it('Should upload a video', async () => {
|
||||
if (isMobileDevice || isSafari) {
|
||||
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
||||
return
|
||||
}
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await pageUploadPage.navigateTo()
|
||||
await videoUploadPage.navigateTo()
|
||||
|
||||
await pageUploadPage.uploadVideo()
|
||||
return pageUploadPage.validSecondUploadStep(videoName)
|
||||
await videoUploadPage.uploadVideo()
|
||||
return videoUploadPage.validSecondUploadStep(videoName)
|
||||
})
|
||||
|
||||
it('Should list videos', async () => {
|
||||
await videoWatchPage.goOnVideosList(isMobileDevice, isSafari)
|
||||
await videoWatchPage.goOnVideosList(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
|
||||
}
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
const videoNames = videoWatchPage.getVideosListName()
|
||||
expect(videoNames).toContain(videoName)
|
||||
|
@ -65,14 +80,16 @@ describe('Videos workflow', () => {
|
|||
it('Should go on video watch page', async () => {
|
||||
let videoNameToExcept = videoName
|
||||
|
||||
if (isMobileDevice || isSafari) videoNameToExcept = await videoWatchPage.clickOnFirstVideo()
|
||||
if (await isMobileDevice() || await isSafari()) videoNameToExcept = await videoWatchPage.clickOnFirstVideo()
|
||||
else await videoWatchPage.clickOnVideo(videoName)
|
||||
|
||||
return videoWatchPage.waitWatchVideoName(videoNameToExcept, isMobileDevice, isSafari)
|
||||
return videoWatchPage.waitWatchVideoName(videoNameToExcept, await isMobileDevice(), await isSafari())
|
||||
})
|
||||
|
||||
it('Should play the video', async () => {
|
||||
await videoWatchPage.playAndPauseVideo(true, isMobileDevice)
|
||||
videoWatchUrl = await browser.getCurrentUrl()
|
||||
|
||||
await videoWatchPage.playAndPauseVideo(true, await isMobileDevice())
|
||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||
})
|
||||
|
||||
|
@ -81,7 +98,7 @@ describe('Videos workflow', () => {
|
|||
|
||||
await videoWatchPage.goOnAssociatedEmbed()
|
||||
|
||||
await videoWatchPage.playAndPauseVideo(false, isMobileDevice)
|
||||
await videoWatchPage.playAndPauseVideo(false, await isMobileDevice())
|
||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||
|
||||
await browser.waitForAngularEnabled(true)
|
||||
|
@ -92,9 +109,93 @@ describe('Videos workflow', () => {
|
|||
|
||||
await videoWatchPage.goOnP2PMediaLoaderEmbed()
|
||||
|
||||
await videoWatchPage.playAndPauseVideo(false, isMobileDevice)
|
||||
await videoWatchPage.playAndPauseVideo(false, await isMobileDevice())
|
||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||
|
||||
await browser.waitForAngularEnabled(true)
|
||||
})
|
||||
|
||||
it('Should update the video', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await browser.get(videoWatchUrl)
|
||||
|
||||
await videoWatchPage.clickOnUpdate()
|
||||
|
||||
await videoUpdatePage.updateName('my new name')
|
||||
|
||||
await videoUpdatePage.validUpdate()
|
||||
|
||||
const name = await videoWatchPage.getVideoName()
|
||||
expect(name).toEqual('my new name')
|
||||
})
|
||||
|
||||
it('Should add the video in my playlist', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await videoWatchPage.clickOnSave()
|
||||
await videoWatchPage.saveToWatchLater()
|
||||
|
||||
await videoUploadPage.navigateTo()
|
||||
|
||||
await videoUploadPage.uploadVideo()
|
||||
await videoUploadPage.validSecondUploadStep('second video')
|
||||
|
||||
await videoWatchPage.clickOnSave()
|
||||
await videoWatchPage.saveToWatchLater()
|
||||
})
|
||||
|
||||
it('Should have the watch later playlist in my account', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await myAccountPage.navigateToMyPlaylists()
|
||||
|
||||
const name = await myAccountPage.getLastUpdatedPlaylistName()
|
||||
expect(name).toEqual('Watch later')
|
||||
|
||||
const videosNumberText = await myAccountPage.getLastUpdatedPlaylistVideosText()
|
||||
expect(videosNumberText).toEqual('2 videos')
|
||||
|
||||
await myAccountPage.clickOnLastUpdatedPlaylist()
|
||||
|
||||
const count = await myAccountPage.countTotalPlaylistElements()
|
||||
expect(count).toEqual(2)
|
||||
})
|
||||
|
||||
it('Should watch the playlist', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await myAccountPage.playPlaylist()
|
||||
|
||||
await videoWatchPage.waitUntilVideoName('second video', 20000 * 1000)
|
||||
})
|
||||
|
||||
it('Should have the video in my account', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await myAccountPage.navigateToMyVideos()
|
||||
|
||||
const lastVideoName = await myAccountPage.getLastVideoName()
|
||||
expect(lastVideoName).toEqual('second video')
|
||||
})
|
||||
|
||||
it('Should delete the last video', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await myAccountPage.removeLastVideo()
|
||||
await myAccountPage.validRemove()
|
||||
|
||||
const count = await myAccountPage.countVideos()
|
||||
expect(count).toEqual(1)
|
||||
})
|
||||
|
||||
it('Should delete the first video', async () => {
|
||||
if (await skipIfUploadNotSupported()) return
|
||||
|
||||
await myAccountPage.removeLastVideo()
|
||||
await myAccountPage.validRemove()
|
||||
|
||||
const count = await myAccountPage.countVideos()
|
||||
expect(count).toEqual(0)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue