Add videos e2e tests
This commit is contained in:
parent
74af5a8361
commit
5f92c4dc5f
|
@ -24,6 +24,8 @@ donating to them](https://soutenir.framasoft.org/en/).**
|
||||||
<a href="https://david-dm.org/Chocobozzz/PeerTube?path=client&type=dev">
|
<a href="https://david-dm.org/Chocobozzz/PeerTube?path=client&type=dev">
|
||||||
<img src="https://david-dm.org/Chocobozzz/PeerTube/dev-status.svg?path=client" alt="devDependency Status" />
|
<img src="https://david-dm.org/Chocobozzz/PeerTube/dev-status.svg?path=client" alt="devDependency Status" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<img src="http://lutim.cpy.re/js3rkfIc.png" alt="Browser Stack" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|
Binary file not shown.
|
@ -8,9 +8,15 @@ exports.config = {
|
||||||
specs: [
|
specs: [
|
||||||
'./src/**/*.e2e-spec.ts'
|
'./src/**/*.e2e-spec.ts'
|
||||||
],
|
],
|
||||||
capabilities: {
|
multiCapabilities: [
|
||||||
'browserName': 'chrome'
|
{
|
||||||
},
|
'browserName': 'firefox',
|
||||||
|
'moz:firefoxOptions': {
|
||||||
|
binary: 'firefox-developer'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
maxSessions: 1,
|
||||||
directConnect: true,
|
directConnect: true,
|
||||||
baseUrl: 'http://localhost:4200/',
|
baseUrl: 'http://localhost:4200/',
|
||||||
framework: 'jasmine',
|
framework: 'jasmine',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AppPage } from './app.po'
|
import { AppPage } from './po/app.po'
|
||||||
|
|
||||||
describe('PeerTube app', () => {
|
describe('PeerTube app', () => {
|
||||||
let page: AppPage
|
let page: AppPage
|
||||||
|
@ -7,7 +7,7 @@ describe('PeerTube app', () => {
|
||||||
page = new AppPage()
|
page = new AppPage()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should display the app title', () => {
|
it('Should display the app title', () => {
|
||||||
page.navigateTo()
|
page.navigateTo()
|
||||||
expect(page.getHeaderTitle()).toEqual('PeerTube')
|
expect(page.getHeaderTitle()).toEqual('PeerTube')
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { browser, element, by } from 'protractor'
|
||||||
|
|
||||||
|
export class LoginPage {
|
||||||
|
async loginAsRootUser () {
|
||||||
|
await browser.get('/login')
|
||||||
|
|
||||||
|
element(by.css('input#username')).sendKeys('root')
|
||||||
|
element(by.css('input#password')).sendKeys('test1')
|
||||||
|
|
||||||
|
await element(by.css('form input[type=submit]')).click()
|
||||||
|
|
||||||
|
return browser.wait(browser.ExpectedConditions.urlContains('/videos/'))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { browser, element, by } from 'protractor'
|
||||||
|
import { join } from 'path'
|
||||||
|
|
||||||
|
export class VideoUploadPage {
|
||||||
|
navigateTo () {
|
||||||
|
return browser.get('/videos/upload')
|
||||||
|
}
|
||||||
|
|
||||||
|
async uploadVideo () {
|
||||||
|
const fileToUpload = join(__dirname, '../../fixtures/video.mp4')
|
||||||
|
|
||||||
|
await element(by.css('.upload-video-container input[type=file]')).sendKeys(fileToUpload)
|
||||||
|
|
||||||
|
// Wait for the upload to finish
|
||||||
|
await browser.wait(browser.ExpectedConditions.elementToBeClickable(this.getSecondStepSubmitButton()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async validSecondUploadStep (videoName: string) {
|
||||||
|
const nameInput = element(by.css('input#name'))
|
||||||
|
await nameInput.clear()
|
||||||
|
await nameInput.sendKeys(videoName)
|
||||||
|
|
||||||
|
await this.getSecondStepSubmitButton().click()
|
||||||
|
|
||||||
|
return browser.wait(browser.ExpectedConditions.urlContains('/watch/'))
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSecondStepSubmitButton () {
|
||||||
|
return element(by.css('.submit-button:not(.disabled) input'))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { by, element, browser } from 'protractor'
|
||||||
|
|
||||||
|
export class VideoWatchPage {
|
||||||
|
async goOnRecentlyAdded () {
|
||||||
|
const url = '/videos/recently-added'
|
||||||
|
|
||||||
|
await browser.get(url)
|
||||||
|
return browser.wait(browser.ExpectedConditions.elementToBeClickable(element(this.getFirstVideoListSelector())))
|
||||||
|
}
|
||||||
|
|
||||||
|
getVideosListName () {
|
||||||
|
return element.all(this.getFirstVideoListSelector()).getText()
|
||||||
|
}
|
||||||
|
|
||||||
|
waitWatchVideoName (videoName: string) {
|
||||||
|
const elem = element(by.css('.video-info .video-info-name'))
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
async pauseVideo () {
|
||||||
|
const el = element(by.css('video'))
|
||||||
|
await browser.wait(browser.ExpectedConditions.elementToBeClickable(el))
|
||||||
|
|
||||||
|
return el.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
async clickOnFirstVideoOfList () {
|
||||||
|
const video = element(by.css('.videos .video-miniature:first-child .video-thumbnail'))
|
||||||
|
|
||||||
|
await video.click()
|
||||||
|
|
||||||
|
await browser.wait(browser.ExpectedConditions.urlContains('/watch/'))
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFirstVideoListSelector () {
|
||||||
|
return by.css('.videos .video-miniature-name')
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
import { VideoUploadPage } from './video-upload.po'
|
|
||||||
|
|
||||||
describe('Video upload', () => {
|
|
||||||
let page: VideoUploadPage
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new VideoUploadPage()
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -1,7 +0,0 @@
|
||||||
import { browser } from 'protractor'
|
|
||||||
|
|
||||||
export class VideoUploadPage {
|
|
||||||
navigateTo () {
|
|
||||||
return browser.get('/videos/upload')
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { VideoWatchPage } from './video-watch.po'
|
|
||||||
|
|
||||||
describe('Video watch', () => {
|
|
||||||
let page: VideoWatchPage
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new VideoWatchPage()
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { browser } from 'protractor'
|
|
||||||
|
|
||||||
export class VideoWatchPage {
|
|
||||||
navigateTo () {
|
|
||||||
browser.waitForAngularEnabled(false)
|
|
||||||
return browser.get('/')
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { VideoWatchPage } from './po/video-watch.po'
|
||||||
|
import { VideoUploadPage } from './po/video-upload.po'
|
||||||
|
import { LoginPage } from './po/login.po'
|
||||||
|
import { browser } from 'protractor'
|
||||||
|
|
||||||
|
describe('Videos workflow', () => {
|
||||||
|
let videoWatchPage: VideoWatchPage
|
||||||
|
let pageUploadPage: VideoUploadPage
|
||||||
|
let loginPage: LoginPage
|
||||||
|
const videoName = new Date().getTime() + ' video'
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
videoWatchPage = new VideoWatchPage()
|
||||||
|
pageUploadPage = new VideoUploadPage()
|
||||||
|
loginPage = new LoginPage()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should log in', () => {
|
||||||
|
return loginPage.loginAsRootUser()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should upload a video', async () => {
|
||||||
|
pageUploadPage.navigateTo()
|
||||||
|
|
||||||
|
await pageUploadPage.uploadVideo()
|
||||||
|
return pageUploadPage.validSecondUploadStep(videoName)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should list the video', async () => {
|
||||||
|
await videoWatchPage.goOnRecentlyAdded()
|
||||||
|
|
||||||
|
const videoNames = videoWatchPage.getVideosListName()
|
||||||
|
expect(videoNames).toContain(videoName)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should go on video watch page', async () => {
|
||||||
|
await videoWatchPage.clickOnFirstVideoOfList()
|
||||||
|
|
||||||
|
return videoWatchPage.waitWatchVideoName(videoName)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should play the video', async () => {
|
||||||
|
await browser.sleep(4000)
|
||||||
|
|
||||||
|
await videoWatchPage.pauseVideo()
|
||||||
|
expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2)
|
||||||
|
})
|
||||||
|
})
|
|
@ -18,7 +18,8 @@
|
||||||
"tslint": "tslint",
|
"tslint": "tslint",
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"postinstall": "npm rebuild node-sass && node angular-cli-patch.js",
|
"postinstall": "npm rebuild node-sass && node angular-cli-patch.js",
|
||||||
"webpack-bundle-analyzer": "webpack-bundle-analyzer"
|
"webpack-bundle-analyzer": "webpack-bundle-analyzer",
|
||||||
|
"webdriver-manager": "webdriver-manager"
|
||||||
},
|
},
|
||||||
"license": "GPLv3",
|
"license": "GPLv3",
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|
|
@ -2,14 +2,12 @@
|
||||||
<my-video-thumbnail [video]="video" [nsfw]="isVideoBlur()"></my-video-thumbnail>
|
<my-video-thumbnail [video]="video" [nsfw]="isVideoBlur()"></my-video-thumbnail>
|
||||||
|
|
||||||
<div class="video-miniature-information">
|
<div class="video-miniature-information">
|
||||||
<span class="video-miniature-name">
|
|
||||||
<a
|
<a
|
||||||
class="video-miniature-name"
|
class="video-miniature-name"
|
||||||
[routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }"
|
[routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }"
|
||||||
>
|
>
|
||||||
{{ video.name }}
|
{{ video.name }}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
<span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||||
<a class="video-miniature-account" [routerLink]="[ '/accounts', video.account.id ]">{{ video.by }}</a>
|
<a class="video-miniature-account" [routerLink]="[ '/accounts', video.account.id ]">{{ video.by }}</a>
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
#npm run build:server
|
|
||||||
npm run clean:server:test
|
npm run clean:server:test
|
||||||
|
|
||||||
|
(
|
||||||
|
cd client
|
||||||
|
npm run webdriver-manager update
|
||||||
|
)
|
||||||
|
|
||||||
concurrently -k -s first \
|
concurrently -k -s first \
|
||||||
"cd client && npm run ng -- e2e" \
|
"cd client && npm run ng -- e2e" \
|
||||||
"NODE_ENV=test NODE_APP_INSTANCE=1 npm start"
|
"NODE_ENV=test NODE_APP_INSTANCE=1 NODE_CONFIG='{ \"log\": { \"level\": \"warning\" } }' npm start"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue