Add e2e tests for password protected videos (#5860)
This commit is contained in:
parent
260242decd
commit
cbe06f779f
|
@ -1,4 +1,4 @@
|
||||||
import { getCheckbox, go } from '../utils'
|
import { getCheckbox, go, selectCustomSelect } from '../utils'
|
||||||
|
|
||||||
export class MyAccountPage {
|
export class MyAccountPage {
|
||||||
|
|
||||||
|
@ -117,6 +117,25 @@ export class MyAccountPage {
|
||||||
return go(url)
|
return go(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updatePlaylistPrivacy (playlistUUID: string, privacy: 'Public' | 'Private' | 'Unlisted') {
|
||||||
|
go('/my-library/video-playlists/update/' + playlistUUID)
|
||||||
|
|
||||||
|
await browser.waitUntil(async () => {
|
||||||
|
return (await $('form .video-playlist-title').getText() === 'PLAYLIST')
|
||||||
|
})
|
||||||
|
|
||||||
|
await selectCustomSelect('videoChannelId', 'Main root channel')
|
||||||
|
await selectCustomSelect('privacy', privacy)
|
||||||
|
|
||||||
|
const submit = await $('form input[type=submit]')
|
||||||
|
submit.waitForClickable()
|
||||||
|
await submit.click()
|
||||||
|
|
||||||
|
return browser.waitUntil(async () => {
|
||||||
|
return (await browser.getUrl()).includes('my-library/video-playlists')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// My account Videos
|
// My account Videos
|
||||||
|
|
||||||
private async getVideoElement (name: string) {
|
private async getVideoElement (name: string) {
|
||||||
|
|
|
@ -61,4 +61,15 @@ export class PlayerPage {
|
||||||
await playButton().waitForClickable()
|
await playButton().waitForClickable()
|
||||||
await playButton().click()
|
await playButton().click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fillEmbedVideoPassword (videoPassword: string) {
|
||||||
|
const videoPasswordInput = $('input#video-password-input')
|
||||||
|
const confirmButton = await $('button#video-password-submit')
|
||||||
|
|
||||||
|
await videoPasswordInput.clearValue()
|
||||||
|
await videoPasswordInput.setValue(videoPassword)
|
||||||
|
await confirmButton.waitForClickable()
|
||||||
|
|
||||||
|
return confirmButton.click()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,4 +62,26 @@ export class SignupPage {
|
||||||
await $('#displayName').setValue(options.displayName || `${options.name} channel display name`)
|
await $('#displayName').setValue(options.displayName || `${options.name} channel display name`)
|
||||||
await $('#name').setValue(options.name)
|
await $('#name').setValue(options.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fullSignup ({ accountInfo, channelInfo }: {
|
||||||
|
accountInfo: {
|
||||||
|
username: string
|
||||||
|
password?: string
|
||||||
|
displayName?: string
|
||||||
|
email?: string
|
||||||
|
}
|
||||||
|
channelInfo: {
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
await this.clickOnRegisterInMenu()
|
||||||
|
await this.validateStep()
|
||||||
|
await this.checkTerms()
|
||||||
|
await this.validateStep()
|
||||||
|
await this.fillAccountStep(accountInfo)
|
||||||
|
await this.validateStep()
|
||||||
|
await this.fillChannelStep(channelInfo)
|
||||||
|
await this.validateStep()
|
||||||
|
await this.getEndMessage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,15 @@ export class VideoUploadPage {
|
||||||
return selectCustomSelect('privacy', 'Private')
|
return selectCustomSelect('privacy', 'Private')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setAsPasswordProtected (videoPassword: string) {
|
||||||
|
selectCustomSelect('privacy', 'Password protected')
|
||||||
|
|
||||||
|
const videoPasswordInput = $('input#videoPassword')
|
||||||
|
await videoPasswordInput.clearValue()
|
||||||
|
|
||||||
|
return videoPasswordInput.setValue(videoPassword)
|
||||||
|
}
|
||||||
|
|
||||||
private getSecondStepSubmitButton () {
|
private getSecondStepSubmitButton () {
|
||||||
return $('.submit-container my-button')
|
return $('.submit-container my-button')
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,19 +43,25 @@ export class VideoWatchPage {
|
||||||
return $('my-privacy-concerns').isDisplayed()
|
return $('my-privacy-concerns').isDisplayed()
|
||||||
}
|
}
|
||||||
|
|
||||||
async goOnAssociatedEmbed () {
|
async goOnAssociatedEmbed (passwordProtected = false) {
|
||||||
let url = await browser.getUrl()
|
let url = await browser.getUrl()
|
||||||
url = url.replace('/w/', '/videos/embed/')
|
url = url.replace('/w/', '/videos/embed/')
|
||||||
url = url.replace(':3333', ':9001')
|
url = url.replace(':3333', ':9001')
|
||||||
|
|
||||||
await go(url)
|
await go(url)
|
||||||
await this.waitEmbedForDisplayed()
|
|
||||||
|
if (passwordProtected) await this.waitEmbedForVideoPasswordForm()
|
||||||
|
else await this.waitEmbedForDisplayed()
|
||||||
}
|
}
|
||||||
|
|
||||||
waitEmbedForDisplayed () {
|
waitEmbedForDisplayed () {
|
||||||
return $('.vjs-big-play-button').waitForDisplayed()
|
return $('.vjs-big-play-button').waitForDisplayed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitEmbedForVideoPasswordForm () {
|
||||||
|
return $('#video-password-input').waitForDisplayed()
|
||||||
|
}
|
||||||
|
|
||||||
isEmbedWarningDisplayed () {
|
isEmbedWarningDisplayed () {
|
||||||
return $('.peertube-dock-description').isDisplayed()
|
return $('.peertube-dock-description').isDisplayed()
|
||||||
}
|
}
|
||||||
|
@ -138,4 +144,75 @@ export class VideoWatchPage {
|
||||||
|
|
||||||
return elem()
|
return elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isPasswordProtected () {
|
||||||
|
return $('#confirmInput').isExisting()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillVideoPassword (videoPassword: string) {
|
||||||
|
const videoPasswordInput = $('input#confirmInput')
|
||||||
|
const confirmButton = await $('input[value="Confirm"]')
|
||||||
|
|
||||||
|
await videoPasswordInput.clearValue()
|
||||||
|
await videoPasswordInput.setValue(videoPassword)
|
||||||
|
await confirmButton.waitForClickable()
|
||||||
|
|
||||||
|
return confirmButton.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
async like () {
|
||||||
|
const likeButton = await $('.action-button-like')
|
||||||
|
const isActivated = (await likeButton.getAttribute('class')).includes('activated')
|
||||||
|
|
||||||
|
let count: number
|
||||||
|
try {
|
||||||
|
count = parseInt(await $('.action-button-like > .count').getText())
|
||||||
|
} catch (error) {
|
||||||
|
count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
await likeButton.waitForClickable()
|
||||||
|
await likeButton.click()
|
||||||
|
|
||||||
|
if (isActivated) {
|
||||||
|
if (count === 1) {
|
||||||
|
return expect(!await $('.action-button-like > .count').isExisting())
|
||||||
|
} else {
|
||||||
|
return expect(parseInt(await $('.action-button-like > .count').getText())).toBe(count - 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return expect(parseInt(await $('.action-button-like > .count').getText())).toBe(count + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createThread (comment: string) {
|
||||||
|
const textarea = await $('my-video-comment-add textarea')
|
||||||
|
|
||||||
|
await textarea.setValue(comment)
|
||||||
|
|
||||||
|
const confirmButton = await $('.comment-buttons .orange-button')
|
||||||
|
await confirmButton.waitForClickable()
|
||||||
|
await confirmButton.click()
|
||||||
|
|
||||||
|
const createdComment = await (await $('.comment-html p')).getText()
|
||||||
|
|
||||||
|
return expect(createdComment).toBe(comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
async createReply (comment: string) {
|
||||||
|
const replyButton = await $('button.comment-action-reply')
|
||||||
|
|
||||||
|
await replyButton.click()
|
||||||
|
const textarea = await $('my-video-comment my-video-comment-add textarea')
|
||||||
|
|
||||||
|
await textarea.setValue(comment)
|
||||||
|
|
||||||
|
const confirmButton = await $('my-video-comment .comment-buttons .orange-button')
|
||||||
|
await confirmButton.waitForClickable()
|
||||||
|
await confirmButton.click()
|
||||||
|
|
||||||
|
const createdComment = await (await $('.is-child .comment-html p')).getText()
|
||||||
|
|
||||||
|
return expect(createdComment).toBe(comment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
226
client/e2e/src/suites-local/video-password.e2e-spec.ts
Normal file
226
client/e2e/src/suites-local/video-password.e2e-spec.ts
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
import { LoginPage } from '../po/login.po'
|
||||||
|
import { SignupPage } from '../po/signup.po'
|
||||||
|
import { PlayerPage } from '../po/player.po'
|
||||||
|
import { VideoUploadPage } from '../po/video-upload.po'
|
||||||
|
import { VideoWatchPage } from '../po/video-watch.po'
|
||||||
|
import { go, isMobileDevice, isSafari, waitServerUp } from '../utils'
|
||||||
|
import { MyAccountPage } from '../po/my-account.po'
|
||||||
|
|
||||||
|
describe('Password protected videos', () => {
|
||||||
|
let videoUploadPage: VideoUploadPage
|
||||||
|
let loginPage: LoginPage
|
||||||
|
let videoWatchPage: VideoWatchPage
|
||||||
|
let signupPage: SignupPage
|
||||||
|
let playerPage: PlayerPage
|
||||||
|
let myAccountPage: MyAccountPage
|
||||||
|
let passwordProtectedVideoUrl: string
|
||||||
|
let playlistUrl: string
|
||||||
|
|
||||||
|
const seed = Math.random()
|
||||||
|
const passwordProtectedVideoName = seed + ' - password protected'
|
||||||
|
const publicVideoName1 = seed + ' - public 1'
|
||||||
|
const publicVideoName2 = seed + ' - public 2'
|
||||||
|
const videoPassword = 'password'
|
||||||
|
const regularUsername = 'user_1'
|
||||||
|
const regularUserPassword = 'user password'
|
||||||
|
const playlistName = seed + ' - playlist'
|
||||||
|
|
||||||
|
function testRateAndComment () {
|
||||||
|
it('Should add and remove like on video', async function () {
|
||||||
|
await videoWatchPage.like()
|
||||||
|
await videoWatchPage.like()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should create thread on video', async function () {
|
||||||
|
await videoWatchPage.createThread('My first comment')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should reply to thread on video', async function () {
|
||||||
|
await videoWatchPage.createReply('My first reply')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await waitServerUp()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
loginPage = new LoginPage(isMobileDevice())
|
||||||
|
videoUploadPage = new VideoUploadPage()
|
||||||
|
videoWatchPage = new VideoWatchPage(isMobileDevice(), isSafari())
|
||||||
|
signupPage = new SignupPage()
|
||||||
|
playerPage = new PlayerPage()
|
||||||
|
myAccountPage = new MyAccountPage()
|
||||||
|
|
||||||
|
await browser.maximizeWindow()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Owner', function () {
|
||||||
|
before(async () => {
|
||||||
|
await loginPage.loginAsRootUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should login, upload a public video and save it to a playlist', async () => {
|
||||||
|
await videoUploadPage.navigateTo()
|
||||||
|
await videoUploadPage.uploadVideo('video.mp4')
|
||||||
|
await videoUploadPage.validSecondUploadStep(publicVideoName1)
|
||||||
|
|
||||||
|
await videoWatchPage.clickOnSave()
|
||||||
|
|
||||||
|
await videoWatchPage.createPlaylist(playlistName)
|
||||||
|
|
||||||
|
await videoWatchPage.saveToPlaylist(playlistName)
|
||||||
|
await browser.pause(5000)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should upload a password protected video', async () => {
|
||||||
|
await videoUploadPage.navigateTo()
|
||||||
|
await videoUploadPage.uploadVideo('video2.mp4')
|
||||||
|
await videoUploadPage.setAsPasswordProtected(videoPassword)
|
||||||
|
await videoUploadPage.validSecondUploadStep(passwordProtectedVideoName)
|
||||||
|
|
||||||
|
await videoWatchPage.waitWatchVideoName(passwordProtectedVideoName)
|
||||||
|
|
||||||
|
passwordProtectedVideoUrl = await browser.getUrl()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should save to playlist the password protected video', async () => {
|
||||||
|
await videoWatchPage.clickOnSave()
|
||||||
|
await videoWatchPage.saveToPlaylist(playlistName)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should upload a second public video and save it to playlist', async () => {
|
||||||
|
await videoUploadPage.navigateTo()
|
||||||
|
|
||||||
|
await videoUploadPage.uploadVideo('video3.mp4')
|
||||||
|
await videoUploadPage.validSecondUploadStep(publicVideoName2)
|
||||||
|
|
||||||
|
await videoWatchPage.clickOnSave()
|
||||||
|
await videoWatchPage.saveToPlaylist(playlistName)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should play video without password', async function () {
|
||||||
|
await go(passwordProtectedVideoUrl)
|
||||||
|
|
||||||
|
expect(!await videoWatchPage.isPasswordProtected())
|
||||||
|
|
||||||
|
await videoWatchPage.waitWatchVideoName(passwordProtectedVideoName)
|
||||||
|
|
||||||
|
expect(await videoWatchPage.getPrivacy()).toBe('Password protected')
|
||||||
|
await playerPage.playAndPauseVideo(false, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testRateAndComment()
|
||||||
|
|
||||||
|
it('Should play video on embed without password', async function () {
|
||||||
|
await videoWatchPage.goOnAssociatedEmbed()
|
||||||
|
await playerPage.playAndPauseVideo(false, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should have the playlist in my account', async function () {
|
||||||
|
await go('/')
|
||||||
|
await myAccountPage.navigateToMyPlaylists()
|
||||||
|
const videosNumberText = await myAccountPage.getPlaylistVideosText(playlistName)
|
||||||
|
|
||||||
|
expect(videosNumberText).toEqual('3 videos')
|
||||||
|
await myAccountPage.clickOnPlaylist(playlistName)
|
||||||
|
|
||||||
|
const count = await myAccountPage.countTotalPlaylistElements()
|
||||||
|
expect(count).toEqual(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should update the playlist to public', async () => {
|
||||||
|
const url = await browser.getUrl()
|
||||||
|
const regex = /\/([a-f0-9-]+)$/i
|
||||||
|
const match = url.match(regex)
|
||||||
|
const uuid = match ? match[1] : null
|
||||||
|
|
||||||
|
await myAccountPage.updatePlaylistPrivacy(uuid, 'Public')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should watch the playlist', async () => {
|
||||||
|
await myAccountPage.clickOnPlaylist(playlistName)
|
||||||
|
await myAccountPage.playPlaylist()
|
||||||
|
playlistUrl = await browser.getUrl()
|
||||||
|
|
||||||
|
await videoWatchPage.waitUntilVideoName(publicVideoName1, 40 * 1000)
|
||||||
|
await videoWatchPage.waitUntilVideoName(passwordProtectedVideoName, 40 * 1000)
|
||||||
|
await videoWatchPage.waitUntilVideoName(publicVideoName2, 40 * 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await loginPage.logout()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Regular users', function () {
|
||||||
|
before(async () => {
|
||||||
|
await signupPage.fullSignup({
|
||||||
|
accountInfo: {
|
||||||
|
username: regularUsername,
|
||||||
|
password: regularUserPassword
|
||||||
|
},
|
||||||
|
channelInfo: {
|
||||||
|
name: 'user_1_channel'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should requires password to play video', async function () {
|
||||||
|
await go(passwordProtectedVideoUrl)
|
||||||
|
|
||||||
|
expect(await videoWatchPage.isPasswordProtected())
|
||||||
|
|
||||||
|
await videoWatchPage.fillVideoPassword(videoPassword)
|
||||||
|
await videoWatchPage.waitWatchVideoName(passwordProtectedVideoName)
|
||||||
|
|
||||||
|
expect(await videoWatchPage.getPrivacy()).toBe('Password protected')
|
||||||
|
await playerPage.playAndPauseVideo(true, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
testRateAndComment()
|
||||||
|
|
||||||
|
it('Should requires password to play video on embed', async function () {
|
||||||
|
await videoWatchPage.goOnAssociatedEmbed(true)
|
||||||
|
await playerPage.fillEmbedVideoPassword(videoPassword)
|
||||||
|
await playerPage.playAndPauseVideo(false, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should watch the playlist without password protected video', async () => {
|
||||||
|
await go(playlistUrl)
|
||||||
|
await playerPage.playVideo()
|
||||||
|
await videoWatchPage.waitUntilVideoName(publicVideoName2, 40 * 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await loginPage.logout()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Anonymous users', function () {
|
||||||
|
it('Should requires password to play video', async function () {
|
||||||
|
await go(passwordProtectedVideoUrl)
|
||||||
|
|
||||||
|
expect(await videoWatchPage.isPasswordProtected())
|
||||||
|
|
||||||
|
await videoWatchPage.fillVideoPassword(videoPassword)
|
||||||
|
await videoWatchPage.waitWatchVideoName(passwordProtectedVideoName)
|
||||||
|
|
||||||
|
expect(await videoWatchPage.getPrivacy()).toBe('Password protected')
|
||||||
|
await playerPage.playAndPauseVideo(true, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should requires password to play video on embed', async function () {
|
||||||
|
await videoWatchPage.goOnAssociatedEmbed(true)
|
||||||
|
await playerPage.fillEmbedVideoPassword(videoPassword)
|
||||||
|
await playerPage.playAndPauseVideo(false, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should watch the playlist without password protected video', async () => {
|
||||||
|
await go(playlistUrl)
|
||||||
|
await playerPage.playVideo()
|
||||||
|
await videoWatchPage.waitUntilVideoName(publicVideoName2, 40 * 1000)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -50,9 +50,9 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n for="privacy">Privacy</label>
|
<label i18n for="privacy">Privacy</label>
|
||||||
<div class="peertube-select-container">
|
<div class="peertube-select-container">
|
||||||
<select id="privacy" formControlName="privacy" class="form-control">
|
<my-select-options
|
||||||
<option *ngFor="let privacy of videoPlaylistPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
|
labelForId="privacy" [items]="videoPlaylistPrivacies" formControlName="privacy" [clearable]="false"
|
||||||
</select>
|
></my-select-options>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="formErrors.privacy" class="form-error">
|
<div *ngIf="formErrors.privacy" class="form-error">
|
||||||
|
|
Loading…
Reference in New Issue
Block a user