diff options
author | Chocobozzz <me@florianbigard.com> | 2018-05-17 10:55:01 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-05-17 15:20:21 +0200 |
commit | 5f92c4dc5f08094548be9d23080dd3ca75741c65 (patch) | |
tree | a5fd5e2e7f46b28817733afc3cd1a3afcdab0c3a /client | |
parent | 74af5a8361f4ccb460001706ce249d50c747f361 (diff) | |
download | PeerTube-5f92c4dc5f08094548be9d23080dd3ca75741c65.tar.gz PeerTube-5f92c4dc5f08094548be9d23080dd3ca75741c65.tar.zst PeerTube-5f92c4dc5f08094548be9d23080dd3ca75741c65.zip |
Add videos e2e tests
Diffstat (limited to 'client')
-rw-r--r-- | client/e2e/fixtures/video.mp4 | bin | 0 -> 38783 bytes | |||
-rw-r--r-- | client/e2e/protractor.conf.js | 12 | ||||
-rw-r--r-- | client/e2e/src/app.e2e-spec.ts | 4 | ||||
-rw-r--r-- | client/e2e/src/po/app.po.ts (renamed from client/e2e/src/app.po.ts) | 0 | ||||
-rw-r--r-- | client/e2e/src/po/login.po.ts | 14 | ||||
-rw-r--r-- | client/e2e/src/po/video-upload.po.ts | 31 | ||||
-rw-r--r-- | client/e2e/src/po/video-watch.po.ts | 45 | ||||
-rw-r--r-- | client/e2e/src/video-upload.e2e-spec.ts | 9 | ||||
-rw-r--r-- | client/e2e/src/video-upload.po.ts | 7 | ||||
-rw-r--r-- | client/e2e/src/video-watch.e2e-spec.ts | 9 | ||||
-rw-r--r-- | client/e2e/src/video-watch.po.ts | 8 | ||||
-rw-r--r-- | client/e2e/src/videos.e2e-spec.ts | 48 | ||||
-rw-r--r-- | client/package.json | 3 | ||||
-rw-r--r-- | client/src/app/shared/video/video-miniature.component.html | 14 |
14 files changed, 157 insertions, 47 deletions
diff --git a/client/e2e/fixtures/video.mp4 b/client/e2e/fixtures/video.mp4 new file mode 100644 index 000000000..35678362b --- /dev/null +++ b/client/e2e/fixtures/video.mp4 | |||
Binary files 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 = { | |||
8 | specs: [ | 8 | specs: [ |
9 | './src/**/*.e2e-spec.ts' | 9 | './src/**/*.e2e-spec.ts' |
10 | ], | 10 | ], |
11 | capabilities: { | 11 | multiCapabilities: [ |
12 | 'browserName': 'chrome' | 12 | { |
13 | }, | 13 | 'browserName': 'firefox', |
14 | 'moz:firefoxOptions': { | ||
15 | binary: 'firefox-developer' | ||
16 | } | ||
17 | } | ||
18 | ], | ||
19 | maxSessions: 1, | ||
14 | directConnect: true, | 20 | directConnect: true, |
15 | baseUrl: 'http://localhost:4200/', | 21 | baseUrl: 'http://localhost:4200/', |
16 | framework: 'jasmine', | 22 | 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 @@ | |||
1 | import { AppPage } from './app.po' | 1 | import { AppPage } from './po/app.po' |
2 | 2 | ||
3 | describe('PeerTube app', () => { | 3 | describe('PeerTube app', () => { |
4 | let page: AppPage | 4 | let page: AppPage |
@@ -7,7 +7,7 @@ describe('PeerTube app', () => { | |||
7 | page = new AppPage() | 7 | page = new AppPage() |
8 | }) | 8 | }) |
9 | 9 | ||
10 | it('should display the app title', () => { | 10 | it('Should display the app title', () => { |
11 | page.navigateTo() | 11 | page.navigateTo() |
12 | expect(page.getHeaderTitle()).toEqual('PeerTube') | 12 | expect(page.getHeaderTitle()).toEqual('PeerTube') |
13 | }) | 13 | }) |
diff --git a/client/e2e/src/app.po.ts b/client/e2e/src/po/app.po.ts index e3e293d7b..e3e293d7b 100644 --- a/client/e2e/src/app.po.ts +++ b/client/e2e/src/po/app.po.ts | |||
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 @@ | |||
1 | import { browser, element, by } from 'protractor' | ||
2 | |||
3 | export class LoginPage { | ||
4 | async loginAsRootUser () { | ||
5 | await browser.get('/login') | ||
6 | |||
7 | element(by.css('input#username')).sendKeys('root') | ||
8 | element(by.css('input#password')).sendKeys('test1') | ||
9 | |||
10 | await element(by.css('form input[type=submit]')).click() | ||
11 | |||
12 | return browser.wait(browser.ExpectedConditions.urlContains('/videos/')) | ||
13 | } | ||
14 | } | ||
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 @@ | |||
1 | import { browser, element, by } from 'protractor' | ||
2 | import { join } from 'path' | ||
3 | |||
4 | export class VideoUploadPage { | ||
5 | navigateTo () { | ||
6 | return browser.get('/videos/upload') | ||
7 | } | ||
8 | |||
9 | async uploadVideo () { | ||
10 | const fileToUpload = join(__dirname, '../../fixtures/video.mp4') | ||
11 | |||
12 | await element(by.css('.upload-video-container input[type=file]')).sendKeys(fileToUpload) | ||
13 | |||
14 | // Wait for the upload to finish | ||
15 | await browser.wait(browser.ExpectedConditions.elementToBeClickable(this.getSecondStepSubmitButton())) | ||
16 | } | ||
17 | |||
18 | async validSecondUploadStep (videoName: string) { | ||
19 | const nameInput = element(by.css('input#name')) | ||
20 | await nameInput.clear() | ||
21 | await nameInput.sendKeys(videoName) | ||
22 | |||
23 | await this.getSecondStepSubmitButton().click() | ||
24 | |||
25 | return browser.wait(browser.ExpectedConditions.urlContains('/watch/')) | ||
26 | } | ||
27 | |||
28 | private getSecondStepSubmitButton () { | ||
29 | return element(by.css('.submit-button:not(.disabled) input')) | ||
30 | } | ||
31 | } | ||
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 @@ | |||
1 | import { by, element, browser } from 'protractor' | ||
2 | |||
3 | export class VideoWatchPage { | ||
4 | async goOnRecentlyAdded () { | ||
5 | const url = '/videos/recently-added' | ||
6 | |||
7 | await browser.get(url) | ||
8 | return browser.wait(browser.ExpectedConditions.elementToBeClickable(element(this.getFirstVideoListSelector()))) | ||
9 | } | ||
10 | |||
11 | getVideosListName () { | ||
12 | return element.all(this.getFirstVideoListSelector()).getText() | ||
13 | } | ||
14 | |||
15 | waitWatchVideoName (videoName: string) { | ||
16 | const elem = element(by.css('.video-info .video-info-name')) | ||
17 | return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, videoName)) | ||
18 | } | ||
19 | |||
20 | getWatchVideoPlayerCurrentTime () { | ||
21 | return element(by.css('.video-js .vjs-current-time-display')) | ||
22 | .getText() | ||
23 | .then((t: string) => t.split(':')[1]) | ||
24 | .then(seconds => parseInt(seconds, 10)) | ||
25 | } | ||
26 | |||
27 | async pauseVideo () { | ||
28 | const el = element(by.css('video')) | ||
29 | await browser.wait(browser.ExpectedConditions.elementToBeClickable(el)) | ||
30 | |||
31 | return el.click() | ||
32 | } | ||
33 | |||
34 | async clickOnFirstVideoOfList () { | ||
35 | const video = element(by.css('.videos .video-miniature:first-child .video-thumbnail')) | ||
36 | |||
37 | await video.click() | ||
38 | |||
39 | await browser.wait(browser.ExpectedConditions.urlContains('/watch/')) | ||
40 | } | ||
41 | |||
42 | private getFirstVideoListSelector () { | ||
43 | return by.css('.videos .video-miniature-name') | ||
44 | } | ||
45 | } | ||
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 @@ | |||
1 | import { VideoUploadPage } from './video-upload.po' | ||
2 | |||
3 | describe('Video upload', () => { | ||
4 | let page: VideoUploadPage | ||
5 | |||
6 | beforeEach(() => { | ||
7 | page = new VideoUploadPage() | ||
8 | }) | ||
9 | }) | ||
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 @@ | |||
1 | import { browser } from 'protractor' | ||
2 | |||
3 | export class VideoUploadPage { | ||
4 | navigateTo () { | ||
5 | return browser.get('/videos/upload') | ||
6 | } | ||
7 | } | ||
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 @@ | |||
1 | import { VideoWatchPage } from './video-watch.po' | ||
2 | |||
3 | describe('Video watch', () => { | ||
4 | let page: VideoWatchPage | ||
5 | |||
6 | beforeEach(() => { | ||
7 | page = new VideoWatchPage() | ||
8 | }) | ||
9 | }) | ||
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 @@ | |||
1 | import { browser } from 'protractor' | ||
2 | |||
3 | export class VideoWatchPage { | ||
4 | navigateTo () { | ||
5 | browser.waitForAngularEnabled(false) | ||
6 | return browser.get('/') | ||
7 | } | ||
8 | } | ||
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 @@ | |||
1 | import { VideoWatchPage } from './po/video-watch.po' | ||
2 | import { VideoUploadPage } from './po/video-upload.po' | ||
3 | import { LoginPage } from './po/login.po' | ||
4 | import { browser } from 'protractor' | ||
5 | |||
6 | describe('Videos workflow', () => { | ||
7 | let videoWatchPage: VideoWatchPage | ||
8 | let pageUploadPage: VideoUploadPage | ||
9 | let loginPage: LoginPage | ||
10 | const videoName = new Date().getTime() + ' video' | ||
11 | |||
12 | beforeEach(() => { | ||
13 | videoWatchPage = new VideoWatchPage() | ||
14 | pageUploadPage = new VideoUploadPage() | ||
15 | loginPage = new LoginPage() | ||
16 | }) | ||
17 | |||
18 | it('Should log in', () => { | ||
19 | return loginPage.loginAsRootUser() | ||
20 | }) | ||
21 | |||
22 | it('Should upload a video', async () => { | ||
23 | pageUploadPage.navigateTo() | ||
24 | |||
25 | await pageUploadPage.uploadVideo() | ||
26 | return pageUploadPage.validSecondUploadStep(videoName) | ||
27 | }) | ||
28 | |||
29 | it('Should list the video', async () => { | ||
30 | await videoWatchPage.goOnRecentlyAdded() | ||
31 | |||
32 | const videoNames = videoWatchPage.getVideosListName() | ||
33 | expect(videoNames).toContain(videoName) | ||
34 | }) | ||
35 | |||
36 | it('Should go on video watch page', async () => { | ||
37 | await videoWatchPage.clickOnFirstVideoOfList() | ||
38 | |||
39 | return videoWatchPage.waitWatchVideoName(videoName) | ||
40 | }) | ||
41 | |||
42 | it('Should play the video', async () => { | ||
43 | await browser.sleep(4000) | ||
44 | |||
45 | await videoWatchPage.pauseVideo() | ||
46 | expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) | ||
47 | }) | ||
48 | }) | ||
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 @@ | |||
18 | "tslint": "tslint", | 18 | "tslint": "tslint", |
19 | "ng": "ng", | 19 | "ng": "ng", |
20 | "postinstall": "npm rebuild node-sass && node angular-cli-patch.js", | 20 | "postinstall": "npm rebuild node-sass && node angular-cli-patch.js", |
21 | "webpack-bundle-analyzer": "webpack-bundle-analyzer" | 21 | "webpack-bundle-analyzer": "webpack-bundle-analyzer", |
22 | "webdriver-manager": "webdriver-manager" | ||
22 | }, | 23 | }, |
23 | "license": "GPLv3", | 24 | "license": "GPLv3", |
24 | "resolutions": { | 25 | "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 @@ | |||
2 | <my-video-thumbnail [video]="video" [nsfw]="isVideoBlur()"></my-video-thumbnail> | 2 | <my-video-thumbnail [video]="video" [nsfw]="isVideoBlur()"></my-video-thumbnail> |
3 | 3 | ||
4 | <div class="video-miniature-information"> | 4 | <div class="video-miniature-information"> |
5 | <span class="video-miniature-name"> | 5 | <a |
6 | <a | 6 | class="video-miniature-name" |
7 | class="video-miniature-name" | 7 | [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }" |
8 | [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }" | 8 | > |
9 | > | 9 | {{ video.name }} |
10 | {{ video.name }} | 10 | </a> |
11 | </a> | ||
12 | </span> | ||
13 | 11 | ||
14 | <span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> | 12 | <span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> |
15 | <a class="video-miniature-account" [routerLink]="[ '/accounts', video.account.id ]">{{ video.by }}</a> | 13 | <a class="video-miniature-account" [routerLink]="[ '/accounts', video.account.id ]">{{ video.by }}</a> |