From: Chocobozzz Date: Thu, 17 May 2018 08:55:01 +0000 (+0200) Subject: Add videos e2e tests X-Git-Tag: v1.0.0-beta.5~14 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=5f92c4dc5f08094548be9d23080dd3ca75741c65;p=oweals%2Fpeertube.git Add videos e2e tests --- diff --git a/README.md b/README.md index 8abdaf67d..51c3747e8 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ donating to them](https://soutenir.framasoft.org/en/).** devDependency Status + + Browser Stack

diff --git a/client/e2e/fixtures/video.mp4 b/client/e2e/fixtures/video.mp4 new file mode 100644 index 000000000..35678362b Binary files /dev/null and b/client/e2e/fixtures/video.mp4 differ diff --git a/client/e2e/protractor.conf.js b/client/e2e/protractor.conf.js index 30705cb72..932eaed51 100644 --- a/client/e2e/protractor.conf.js +++ b/client/e2e/protractor.conf.js @@ -8,9 +8,15 @@ exports.config = { specs: [ './src/**/*.e2e-spec.ts' ], - capabilities: { - 'browserName': 'chrome' - }, + multiCapabilities: [ + { + 'browserName': 'firefox', + 'moz:firefoxOptions': { + binary: 'firefox-developer' + } + } + ], + maxSessions: 1, directConnect: true, baseUrl: 'http://localhost:4200/', framework: 'jasmine', diff --git a/client/e2e/src/app.e2e-spec.ts b/client/e2e/src/app.e2e-spec.ts index cdfd01f67..5b648207b 100644 --- a/client/e2e/src/app.e2e-spec.ts +++ b/client/e2e/src/app.e2e-spec.ts @@ -1,4 +1,4 @@ -import { AppPage } from './app.po' +import { AppPage } from './po/app.po' describe('PeerTube app', () => { let page: AppPage @@ -7,7 +7,7 @@ describe('PeerTube app', () => { page = new AppPage() }) - it('should display the app title', () => { + it('Should display the app title', () => { page.navigateTo() expect(page.getHeaderTitle()).toEqual('PeerTube') }) diff --git a/client/e2e/src/app.po.ts b/client/e2e/src/app.po.ts deleted file mode 100644 index e3e293d7b..000000000 --- a/client/e2e/src/app.po.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { browser, by, element } from 'protractor' - -export class AppPage { - navigateTo () { - browser.waitForAngularEnabled(false) - return browser.get('/') - } - - getHeaderTitle () { - return element(by.css('.instance-name')).getText() - } -} diff --git a/client/e2e/src/po/app.po.ts b/client/e2e/src/po/app.po.ts new file mode 100644 index 000000000..e3e293d7b --- /dev/null +++ b/client/e2e/src/po/app.po.ts @@ -0,0 +1,12 @@ +import { browser, by, element } from 'protractor' + +export class AppPage { + navigateTo () { + browser.waitForAngularEnabled(false) + return browser.get('/') + } + + getHeaderTitle () { + return element(by.css('.instance-name')).getText() + } +} diff --git a/client/e2e/src/po/login.po.ts b/client/e2e/src/po/login.po.ts new file mode 100644 index 000000000..ada52cb24 --- /dev/null +++ b/client/e2e/src/po/login.po.ts @@ -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/')) + } +} diff --git a/client/e2e/src/po/video-upload.po.ts b/client/e2e/src/po/video-upload.po.ts new file mode 100644 index 000000000..4f09bb2fa --- /dev/null +++ b/client/e2e/src/po/video-upload.po.ts @@ -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')) + } +} diff --git a/client/e2e/src/po/video-watch.po.ts b/client/e2e/src/po/video-watch.po.ts new file mode 100644 index 000000000..266c9850c --- /dev/null +++ b/client/e2e/src/po/video-watch.po.ts @@ -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') + } +} diff --git a/client/e2e/src/video-upload.e2e-spec.ts b/client/e2e/src/video-upload.e2e-spec.ts deleted file mode 100644 index 45d8ae2c9..000000000 --- a/client/e2e/src/video-upload.e2e-spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { VideoUploadPage } from './video-upload.po' - -describe('Video upload', () => { - let page: VideoUploadPage - - beforeEach(() => { - page = new VideoUploadPage() - }) -}) diff --git a/client/e2e/src/video-upload.po.ts b/client/e2e/src/video-upload.po.ts deleted file mode 100644 index df358e44b..000000000 --- a/client/e2e/src/video-upload.po.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { browser } from 'protractor' - -export class VideoUploadPage { - navigateTo () { - return browser.get('/videos/upload') - } -} diff --git a/client/e2e/src/video-watch.e2e-spec.ts b/client/e2e/src/video-watch.e2e-spec.ts deleted file mode 100644 index be3552d59..000000000 --- a/client/e2e/src/video-watch.e2e-spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { VideoWatchPage } from './video-watch.po' - -describe('Video watch', () => { - let page: VideoWatchPage - - beforeEach(() => { - page = new VideoWatchPage() - }) -}) diff --git a/client/e2e/src/video-watch.po.ts b/client/e2e/src/video-watch.po.ts deleted file mode 100644 index 3b5454ba1..000000000 --- a/client/e2e/src/video-watch.po.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { browser } from 'protractor' - -export class VideoWatchPage { - navigateTo () { - browser.waitForAngularEnabled(false) - return browser.get('/') - } -} diff --git a/client/e2e/src/videos.e2e-spec.ts b/client/e2e/src/videos.e2e-spec.ts new file mode 100644 index 000000000..4205fd7a4 --- /dev/null +++ b/client/e2e/src/videos.e2e-spec.ts @@ -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) + }) +}) diff --git a/client/package.json b/client/package.json index b108b0d11..393a4b134 100644 --- a/client/package.json +++ b/client/package.json @@ -18,7 +18,8 @@ "tslint": "tslint", "ng": "ng", "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", "resolutions": { diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html index e26cb058a..1725e9f5c 100644 --- a/client/src/app/shared/video/video-miniature.component.html +++ b/client/src/app/shared/video/video-miniature.component.html @@ -2,14 +2,12 @@

- - - {{ video.name }} - - + + {{ video.name }} + {{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views diff --git a/scripts/e2e.sh b/scripts/e2e.sh index b1e9245c1..bdd051486 100755 --- a/scripts/e2e.sh +++ b/scripts/e2e.sh @@ -2,10 +2,14 @@ set -eu -#npm run build:server npm run clean:server:test +( + cd client + npm run webdriver-manager update +) + concurrently -k -s first \ "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"