Add more e2e tests
This commit is contained in:
parent
6b226c3278
commit
e69cb173ba
4 changed files with 264 additions and 30 deletions
72
client/e2e/src/po/my-account.ts
Normal file
72
client/e2e/src/po/my-account.ts
Normal file
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
20
client/e2e/src/po/video-update.po.ts
Normal file
20
client/e2e/src/po/video-update.po.ts
Normal file
|
@ -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 {
|
export class VideoWatchPage {
|
||||||
async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) {
|
async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) {
|
||||||
|
@ -44,6 +44,10 @@ export class VideoWatchPage {
|
||||||
.then(seconds => parseInt(seconds, 10))
|
.then(seconds => parseInt(seconds, 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getVideoName () {
|
||||||
|
return this.getVideoNameElement().getText()
|
||||||
|
}
|
||||||
|
|
||||||
async playAndPauseVideo (isAutoplay: boolean, isMobileDevice: boolean) {
|
async playAndPauseVideo (isAutoplay: boolean, isMobileDevice: boolean) {
|
||||||
if (isAutoplay === false) {
|
if (isAutoplay === false) {
|
||||||
const playButton = element(by.css('.vjs-big-play-button'))
|
const playButton = element(by.css('.vjs-big-play-button'))
|
||||||
|
@ -101,4 +105,41 @@ export class VideoWatchPage {
|
||||||
async goOnP2PMediaLoaderEmbed () {
|
async goOnP2PMediaLoaderEmbed () {
|
||||||
return browser.get('https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50?mode=p2p-media-loader')
|
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 { VideoUploadPage } from './po/video-upload.po'
|
||||||
import { LoginPage } from './po/login.po'
|
import { LoginPage } from './po/login.po'
|
||||||
import { browser } from 'protractor'
|
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', () => {
|
describe('Videos workflow', () => {
|
||||||
let videoWatchPage: VideoWatchPage
|
let videoWatchPage: VideoWatchPage
|
||||||
let pageUploadPage: VideoUploadPage
|
let videoUploadPage: VideoUploadPage
|
||||||
|
let videoUpdatePage: VideoUpdatePage
|
||||||
|
let myAccountPage: MyAccountPage
|
||||||
let loginPage: LoginPage
|
let loginPage: LoginPage
|
||||||
|
|
||||||
const videoName = new Date().getTime() + ' video'
|
const videoName = new Date().getTime() + ' video'
|
||||||
let isMobileDevice = false
|
let videoWatchUrl: string
|
||||||
let isSafari = false
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
videoWatchPage = new VideoWatchPage()
|
videoWatchPage = new VideoWatchPage()
|
||||||
pageUploadPage = new VideoUploadPage()
|
videoUploadPage = new VideoUploadPage()
|
||||||
|
videoUpdatePage = new VideoUpdatePage()
|
||||||
|
myAccountPage = new MyAccountPage()
|
||||||
loginPage = new LoginPage()
|
loginPage = new LoginPage()
|
||||||
|
|
||||||
const caps = await browser.getCapabilities()
|
if (await isMobileDevice()) {
|
||||||
isMobileDevice = caps.get('realMobile') === 'true' || caps.get('realMobile') === true
|
|
||||||
isSafari = caps.get('browserName') && caps.get('browserName').toLowerCase() === 'safari'
|
|
||||||
|
|
||||||
if (isMobileDevice) {
|
|
||||||
console.log('Mobile device detected.')
|
console.log('Mobile device detected.')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSafari) {
|
if (await isSafari()) {
|
||||||
console.log('Safari detected.')
|
console.log('Safari detected.')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should log in', () => {
|
it('Should log in', async () => {
|
||||||
if (isMobileDevice || isSafari) {
|
if (await isMobileDevice() || await isSafari()) {
|
||||||
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -39,24 +60,18 @@ describe('Videos workflow', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should upload a video', async () => {
|
it('Should upload a video', async () => {
|
||||||
if (isMobileDevice || isSafari) {
|
if (await skipIfUploadNotSupported()) return
|
||||||
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await pageUploadPage.navigateTo()
|
await videoUploadPage.navigateTo()
|
||||||
|
|
||||||
await pageUploadPage.uploadVideo()
|
await videoUploadPage.uploadVideo()
|
||||||
return pageUploadPage.validSecondUploadStep(videoName)
|
return videoUploadPage.validSecondUploadStep(videoName)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should list videos', async () => {
|
it('Should list videos', async () => {
|
||||||
await videoWatchPage.goOnVideosList(isMobileDevice, isSafari)
|
await videoWatchPage.goOnVideosList(await isMobileDevice(), await isSafari())
|
||||||
|
|
||||||
if (isMobileDevice || isSafari) {
|
if (await skipIfUploadNotSupported()) return
|
||||||
console.log('Skipping because we are on a real device or Safari and BrowserStack does not support file upload.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const videoNames = videoWatchPage.getVideosListName()
|
const videoNames = videoWatchPage.getVideosListName()
|
||||||
expect(videoNames).toContain(videoName)
|
expect(videoNames).toContain(videoName)
|
||||||
|
@ -65,14 +80,16 @@ describe('Videos workflow', () => {
|
||||||
it('Should go on video watch page', async () => {
|
it('Should go on video watch page', async () => {
|
||||||
let videoNameToExcept = videoName
|
let videoNameToExcept = videoName
|
||||||
|
|
||||||
if (isMobileDevice || isSafari) videoNameToExcept = await videoWatchPage.clickOnFirstVideo()
|
if (await isMobileDevice() || await isSafari()) videoNameToExcept = await videoWatchPage.clickOnFirstVideo()
|
||||||
else await videoWatchPage.clickOnVideo(videoName)
|
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 () => {
|
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)
|
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -81,7 +98,7 @@ describe('Videos workflow', () => {
|
||||||
|
|
||||||
await videoWatchPage.goOnAssociatedEmbed()
|
await videoWatchPage.goOnAssociatedEmbed()
|
||||||
|
|
||||||
await videoWatchPage.playAndPauseVideo(false, isMobileDevice)
|
await videoWatchPage.playAndPauseVideo(false, await isMobileDevice())
|
||||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
|
|
||||||
await browser.waitForAngularEnabled(true)
|
await browser.waitForAngularEnabled(true)
|
||||||
|
@ -92,9 +109,93 @@ describe('Videos workflow', () => {
|
||||||
|
|
||||||
await videoWatchPage.goOnP2PMediaLoaderEmbed()
|
await videoWatchPage.goOnP2PMediaLoaderEmbed()
|
||||||
|
|
||||||
await videoWatchPage.playAndPauseVideo(false, isMobileDevice)
|
await videoWatchPage.playAndPauseVideo(false, await isMobileDevice())
|
||||||
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
|
|
||||||
await browser.waitForAngularEnabled(true)
|
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 a new issue