diff options
-rw-r--r-- | client/e2e/local-protractor.conf.js | 9 | ||||
-rw-r--r-- | client/e2e/protractor.conf.js | 7 | ||||
-rw-r--r-- | client/e2e/src/po/login.po.ts | 6 | ||||
-rw-r--r-- | client/e2e/src/po/video-upload.po.ts | 5 | ||||
-rw-r--r-- | client/e2e/src/po/video-watch.po.ts | 6 | ||||
-rw-r--r-- | client/e2e/src/videos.e2e-spec.ts | 29 | ||||
-rw-r--r-- | client/src/app/core/notification/user-notification-socket.service.ts | 15 | ||||
-rw-r--r-- | client/src/app/shared/video/video-thumbnail.component.scss | 4 | ||||
-rw-r--r-- | client/src/app/videos/+video-edit/shared/video-edit.component.ts | 11 | ||||
-rwxr-xr-x | scripts/e2e/index.sh | 1 | ||||
-rwxr-xr-x | scripts/e2e/local.sh | 2 |
11 files changed, 63 insertions, 32 deletions
diff --git a/client/e2e/local-protractor.conf.js b/client/e2e/local-protractor.conf.js index 53edf26f2..a4990fcef 100644 --- a/client/e2e/local-protractor.conf.js +++ b/client/e2e/local-protractor.conf.js | |||
@@ -7,20 +7,21 @@ exports.config = { | |||
7 | allScriptsTimeout: 25000, | 7 | allScriptsTimeout: 25000, |
8 | specs: ['./src/**/*.e2e-spec.ts'], | 8 | specs: ['./src/**/*.e2e-spec.ts'], |
9 | 9 | ||
10 | seleniumAddress: 'http://localhost:4444/wd/hub', | 10 | directConnect: true, |
11 | 11 | ||
12 | capabilities: { | 12 | capabilities: { |
13 | 'browserName': 'firefox', | 13 | 'browserName': 'firefox', |
14 | 'moz:firefoxOptions': { | 14 | 'moz:firefoxOptions': { |
15 | 'args': ["-headless"], | 15 | binary: '/usr/bin/firefox-esr', |
16 | "log": { | 16 | // args: ["-headless"], |
17 | log: { | ||
17 | "level": "info" // default is "info" | 18 | "level": "info" // default is "info" |
18 | } | 19 | } |
19 | } | 20 | } |
20 | }, | 21 | }, |
21 | 22 | ||
22 | // maxSessions: 1, | 23 | // maxSessions: 1, |
23 | baseUrl: 'http://localhost:3333/', | 24 | baseUrl: 'http://localhost:3000/', |
24 | framework: 'jasmine', | 25 | framework: 'jasmine', |
25 | jasmineNodeOpts: { | 26 | jasmineNodeOpts: { |
26 | showColors: true, | 27 | showColors: true, |
diff --git a/client/e2e/protractor.conf.js b/client/e2e/protractor.conf.js index c5c913a4a..51d0b220d 100644 --- a/client/e2e/protractor.conf.js +++ b/client/e2e/protractor.conf.js | |||
@@ -18,7 +18,6 @@ exports.config = { | |||
18 | multiCapabilities: [ | 18 | multiCapabilities: [ |
19 | { | 19 | { |
20 | browserName: 'Chrome', | 20 | browserName: 'Chrome', |
21 | version: '66', | ||
22 | name: 'Latest Chrome Desktop' | 21 | name: 'Latest Chrome Desktop' |
23 | }, | 22 | }, |
24 | { | 23 | { |
@@ -28,17 +27,15 @@ exports.config = { | |||
28 | }, | 27 | }, |
29 | { | 28 | { |
30 | browserName: 'Firefox', | 29 | browserName: 'Firefox', |
31 | version: '52', // ESR, | 30 | version: '60', // ESR, |
32 | name: 'Old Firefox ESR Desktop' | 31 | name: 'Firefox ESR Desktop' |
33 | }, | 32 | }, |
34 | { | 33 | { |
35 | browserName: 'Firefox', | 34 | browserName: 'Firefox', |
36 | version: '60', | ||
37 | name: 'Latest Firefox Desktop' | 35 | name: 'Latest Firefox Desktop' |
38 | }, | 36 | }, |
39 | { | 37 | { |
40 | browserName: 'Edge', | 38 | browserName: 'Edge', |
41 | version: '16', | ||
42 | name: 'Latest Edge Desktop' | 39 | name: 'Latest Edge Desktop' |
43 | }, | 40 | }, |
44 | { | 41 | { |
diff --git a/client/e2e/src/po/login.po.ts b/client/e2e/src/po/login.po.ts index 40f958d2b..90b65c7ea 100644 --- a/client/e2e/src/po/login.po.ts +++ b/client/e2e/src/po/login.po.ts | |||
@@ -11,6 +11,10 @@ export class LoginPage { | |||
11 | 11 | ||
12 | await element(by.css('form input[type=submit]')).click() | 12 | await element(by.css('form input[type=submit]')).click() |
13 | 13 | ||
14 | return browser.wait(browser.ExpectedConditions.urlContains('/videos/')) | 14 | expect(this.getLoggedInInfo().getText()).toContain('root') |
15 | } | ||
16 | |||
17 | private getLoggedInInfo () { | ||
18 | return element(by.css('.logged-in-display-name')) | ||
15 | } | 19 | } |
16 | } | 20 | } |
diff --git a/client/e2e/src/po/video-upload.po.ts b/client/e2e/src/po/video-upload.po.ts index 1978707e3..f79927abc 100644 --- a/client/e2e/src/po/video-upload.po.ts +++ b/client/e2e/src/po/video-upload.po.ts | |||
@@ -14,13 +14,14 @@ export class VideoUploadPage { | |||
14 | 14 | ||
15 | const fileToUpload = join(__dirname, '../../fixtures/video.mp4') | 15 | const fileToUpload = join(__dirname, '../../fixtures/video.mp4') |
16 | const fileInputSelector = '.upload-video-container input[type=file]' | 16 | const fileInputSelector = '.upload-video-container input[type=file]' |
17 | const parentFileInput = '.upload-video .button-file' | 17 | const parentFileInput = '.upload-video-container .button-file' |
18 | 18 | ||
19 | // Avoid sending keys on non visible element | 19 | // Avoid sending keys on non visible element |
20 | await browser.executeScript(`document.querySelector('${fileInputSelector}').style.opacity = 1`) | 20 | await browser.executeScript(`document.querySelector('${fileInputSelector}').style.opacity = 1`) |
21 | // await browser.executeScript(`document.querySelector('${fileInputSelector}').style.opacity = 1`) | ||
22 | await browser.executeScript(`document.querySelector('${parentFileInput}').style.overflow = 'initial'`) | 21 | await browser.executeScript(`document.querySelector('${parentFileInput}').style.overflow = 'initial'`) |
23 | 22 | ||
23 | await browser.sleep(1000) | ||
24 | |||
24 | const elem = element(by.css(fileInputSelector)) | 25 | const elem = element(by.css(fileInputSelector)) |
25 | await elem.sendKeys(fileToUpload) | 26 | await elem.sendKeys(fileToUpload) |
26 | 27 | ||
diff --git a/client/e2e/src/po/video-watch.po.ts b/client/e2e/src/po/video-watch.po.ts index d1e2a73b8..8369e1486 100644 --- a/client/e2e/src/po/video-watch.po.ts +++ b/client/e2e/src/po/video-watch.po.ts | |||
@@ -44,7 +44,7 @@ export class VideoWatchPage { | |||
44 | .then(seconds => parseInt(seconds, 10)) | 44 | .then(seconds => parseInt(seconds, 10)) |
45 | } | 45 | } |
46 | 46 | ||
47 | async pauseVideo (isAutoplay: boolean, isMobileDevice: boolean) { | 47 | async playAndPauseVideo (isAutoplay: boolean, isMobileDevice: boolean) { |
48 | if (isAutoplay === false) { | 48 | if (isAutoplay === false) { |
49 | const playButton = element(by.css('.vjs-big-play-button')) | 49 | const playButton = element(by.css('.vjs-big-play-button')) |
50 | await browser.wait(browser.ExpectedConditions.elementToBeClickable(playButton)) | 50 | await browser.wait(browser.ExpectedConditions.elementToBeClickable(playButton)) |
@@ -97,4 +97,8 @@ export class VideoWatchPage { | |||
97 | 97 | ||
98 | return browser.get(url) | 98 | return browser.get(url) |
99 | } | 99 | } |
100 | |||
101 | async goOnP2PMediaLoaderEmbed () { | ||
102 | return browser.get('https://peertube2.cpy.re/videos/embed/4b997fc0-e106-42d9-bff9-ae9d64902bbb?mode=p2p-media-loader') | ||
103 | } | ||
100 | } | 104 | } |
diff --git a/client/e2e/src/videos.e2e-spec.ts b/client/e2e/src/videos.e2e-spec.ts index 606b6ac5d..7f8ba71b1 100644 --- a/client/e2e/src/videos.e2e-spec.ts +++ b/client/e2e/src/videos.e2e-spec.ts | |||
@@ -12,8 +12,6 @@ describe('Videos workflow', () => { | |||
12 | let isSafari = false | 12 | let isSafari = false |
13 | 13 | ||
14 | beforeEach(async () => { | 14 | beforeEach(async () => { |
15 | await browser.waitForAngularEnabled(false) | ||
16 | |||
17 | videoWatchPage = new VideoWatchPage() | 15 | videoWatchPage = new VideoWatchPage() |
18 | pageUploadPage = new VideoUploadPage() | 16 | pageUploadPage = new VideoUploadPage() |
19 | loginPage = new LoginPage() | 17 | loginPage = new LoginPage() |
@@ -21,6 +19,14 @@ describe('Videos workflow', () => { | |||
21 | const caps = await browser.getCapabilities() | 19 | const caps = await browser.getCapabilities() |
22 | isMobileDevice = caps.get('realMobile') === 'true' || caps.get('realMobile') === true | 20 | isMobileDevice = caps.get('realMobile') === 'true' || caps.get('realMobile') === true |
23 | isSafari = caps.get('browserName') && caps.get('browserName').toLowerCase() === 'safari' | 21 | isSafari = caps.get('browserName') && caps.get('browserName').toLowerCase() === 'safari' |
22 | |||
23 | if (isMobileDevice) { | ||
24 | console.log('Mobile device detected.') | ||
25 | } | ||
26 | |||
27 | if (isSafari) { | ||
28 | console.log('Safari detected.') | ||
29 | } | ||
24 | }) | 30 | }) |
25 | 31 | ||
26 | it('Should log in', () => { | 32 | it('Should log in', () => { |
@@ -66,14 +72,29 @@ describe('Videos workflow', () => { | |||
66 | }) | 72 | }) |
67 | 73 | ||
68 | it('Should play the video', async () => { | 74 | it('Should play the video', async () => { |
69 | await videoWatchPage.pauseVideo(!isMobileDevice, isMobileDevice) | 75 | await videoWatchPage.playAndPauseVideo(true, isMobileDevice) |
70 | expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) | 76 | expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) |
71 | }) | 77 | }) |
72 | 78 | ||
73 | it('Should watch the associated embed video', async () => { | 79 | it('Should watch the associated embed video', async () => { |
80 | await browser.waitForAngularEnabled(false) | ||
81 | |||
74 | await videoWatchPage.goOnAssociatedEmbed() | 82 | await videoWatchPage.goOnAssociatedEmbed() |
75 | 83 | ||
76 | await videoWatchPage.pauseVideo(false, isMobileDevice) | 84 | await videoWatchPage.playAndPauseVideo(false, isMobileDevice) |
77 | expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) | 85 | expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) |
86 | |||
87 | await browser.waitForAngularEnabled(true) | ||
88 | }) | ||
89 | |||
90 | it('Should watch the p2p media loader embed video', async () => { | ||
91 | await browser.waitForAngularEnabled(false) | ||
92 | |||
93 | await videoWatchPage.goOnP2PMediaLoaderEmbed() | ||
94 | |||
95 | await videoWatchPage.playAndPauseVideo(false, isMobileDevice) | ||
96 | expect(videoWatchPage.getWatchVideoPlayerCurrentTime()).toBeGreaterThanOrEqual(2) | ||
97 | |||
98 | await browser.waitForAngularEnabled(true) | ||
78 | }) | 99 | }) |
79 | }) | 100 | }) |
diff --git a/client/src/app/core/notification/user-notification-socket.service.ts b/client/src/app/core/notification/user-notification-socket.service.ts index 493f03e35..3f22da476 100644 --- a/client/src/app/core/notification/user-notification-socket.service.ts +++ b/client/src/app/core/notification/user-notification-socket.service.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Injectable } from '@angular/core' | 1 | import { Injectable, NgZone } from '@angular/core' |
2 | import { environment } from '../../../environments/environment' | 2 | import { environment } from '../../../environments/environment' |
3 | import { UserNotification as UserNotificationServer } from '../../../../../shared' | 3 | import { UserNotification as UserNotificationServer } from '../../../../../shared' |
4 | import { Subject } from 'rxjs' | 4 | import { Subject } from 'rxjs' |
@@ -13,7 +13,8 @@ export class UserNotificationSocket { | |||
13 | private socket: SocketIOClient.Socket | 13 | private socket: SocketIOClient.Socket |
14 | 14 | ||
15 | constructor ( | 15 | constructor ( |
16 | private auth: AuthService | 16 | private auth: AuthService, |
17 | private ngZone: NgZone | ||
17 | ) {} | 18 | ) {} |
18 | 19 | ||
19 | dispatch (type: NotificationEvent, notification?: UserNotificationServer) { | 20 | dispatch (type: NotificationEvent, notification?: UserNotificationServer) { |
@@ -32,10 +33,12 @@ export class UserNotificationSocket { | |||
32 | // FIXME: import('..') returns a struct module, containing a "default" field corresponding to our sanitizeHtml function | 33 | // FIXME: import('..') returns a struct module, containing a "default" field corresponding to our sanitizeHtml function |
33 | const io: typeof import ('socket.io-client') = (await import('socket.io-client') as any).default | 34 | const io: typeof import ('socket.io-client') = (await import('socket.io-client') as any).default |
34 | 35 | ||
35 | this.socket = io(environment.apiUrl + '/user-notifications', { | 36 | this.ngZone.runOutsideAngular(() => { |
36 | query: { accessToken: this.auth.getAccessToken() } | 37 | this.socket = io(environment.apiUrl + '/user-notifications', { |
37 | }) | 38 | query: { accessToken: this.auth.getAccessToken() } |
39 | }) | ||
38 | 40 | ||
39 | this.socket.on('new-notification', (n: UserNotificationServer) => this.dispatch('new', n)) | 41 | this.socket.on('new-notification', (n: UserNotificationServer) => this.dispatch('new', n)) |
42 | }) | ||
40 | } | 43 | } |
41 | } | 44 | } |
diff --git a/client/src/app/shared/video/video-thumbnail.component.scss b/client/src/app/shared/video/video-thumbnail.component.scss index e57baba5c..b9fd9182f 100644 --- a/client/src/app/shared/video/video-thumbnail.component.scss +++ b/client/src/app/shared/video/video-thumbnail.component.scss | |||
@@ -54,8 +54,8 @@ $play-overlay-width: 18px; | |||
54 | 54 | ||
55 | transition: all $play-overlay-transition; | 55 | transition: all $play-overlay-transition; |
56 | 56 | ||
57 | border-top: calc(#{$play-overlay-height} / 2) solid transparent; | 57 | border-top: ($play-overlay-height / 2) solid transparent; |
58 | border-bottom: calc(#{$play-overlay-height} / 2) solid transparent; | 58 | border-bottom: ($play-overlay-height / 2) solid transparent; |
59 | 59 | ||
60 | border-left: $play-overlay-width solid rgba(255, 255, 255, 0.95); | 60 | border-left: $play-overlay-width solid rgba(255, 255, 255, 0.95); |
61 | 61 | ||
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts index c7ebcec25..c80efd802 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core' | 1 | import { Component, Input, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' |
2 | import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms' | 2 | import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { FormReactiveValidationMessages, VideoValidatorsService } from '@app/shared' | 4 | import { FormReactiveValidationMessages, VideoValidatorsService } from '@app/shared' |
@@ -62,7 +62,8 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
62 | private router: Router, | 62 | private router: Router, |
63 | private notifier: Notifier, | 63 | private notifier: Notifier, |
64 | private serverService: ServerService, | 64 | private serverService: ServerService, |
65 | private i18nPrimengCalendarService: I18nPrimengCalendarService | 65 | private i18nPrimengCalendarService: I18nPrimengCalendarService, |
66 | private ngZone: NgZone | ||
66 | ) { | 67 | ) { |
67 | this.tagValidators = this.videoValidatorsService.VIDEO_TAGS.VALIDATORS | 68 | this.tagValidators = this.videoValidatorsService.VIDEO_TAGS.VALIDATORS |
68 | this.tagValidatorsMessages = this.videoValidatorsService.VIDEO_TAGS.MESSAGES | 69 | this.tagValidatorsMessages = this.videoValidatorsService.VIDEO_TAGS.MESSAGES |
@@ -132,9 +133,11 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
132 | this.videoLicences = this.serverService.getVideoLicences() | 133 | this.videoLicences = this.serverService.getVideoLicences() |
133 | this.videoLanguages = this.serverService.getVideoLanguages() | 134 | this.videoLanguages = this.serverService.getVideoLanguages() |
134 | 135 | ||
135 | this.schedulerInterval = setInterval(() => this.minScheduledDate = new Date(), 1000 * 60) // Update every minute | ||
136 | |||
137 | this.initialVideoCaptions = this.videoCaptions.map(c => c.language.id) | 136 | this.initialVideoCaptions = this.videoCaptions.map(c => c.language.id) |
137 | |||
138 | this.ngZone.runOutsideAngular(() => { | ||
139 | this.schedulerInterval = setInterval(() => this.minScheduledDate = new Date(), 1000 * 60) // Update every minute | ||
140 | }) | ||
138 | } | 141 | } |
139 | 142 | ||
140 | ngOnDestroy () { | 143 | ngOnDestroy () { |
diff --git a/scripts/e2e/index.sh b/scripts/e2e/index.sh index cf2e04356..3856af06e 100755 --- a/scripts/e2e/index.sh +++ b/scripts/e2e/index.sh | |||
@@ -6,7 +6,6 @@ npm run clean:server:test | |||
6 | 6 | ||
7 | ( | 7 | ( |
8 | cd client | 8 | cd client |
9 | npm run webdriver-manager update | ||
10 | npm run webpack -- --config webpack/webpack.video-embed.js --mode development | 9 | npm run webpack -- --config webpack/webpack.video-embed.js --mode development |
11 | ) | 10 | ) |
12 | 11 | ||
diff --git a/scripts/e2e/local.sh b/scripts/e2e/local.sh index 65ec653dc..b883ccaa3 100755 --- a/scripts/e2e/local.sh +++ b/scripts/e2e/local.sh | |||
@@ -6,11 +6,9 @@ npm run clean:server:test | |||
6 | 6 | ||
7 | ( | 7 | ( |
8 | cd client | 8 | cd client |
9 | npm run webdriver-manager update | ||
10 | npm run webpack -- --config webpack/webpack.video-embed.js --mode development | 9 | npm run webpack -- --config webpack/webpack.video-embed.js --mode development |
11 | ) | 10 | ) |
12 | 11 | ||
13 | npm run concurrently -- -k -s first \ | 12 | npm run concurrently -- -k -s first \ |
14 | "cd client && npm run webdriver-manager start" \ | ||
15 | "cd client && npm run ng -- e2e --port 3333 -c local" \ | 13 | "cd client && npm run ng -- e2e --port 3333 -c local" \ |
16 | "NODE_ENV=test NODE_APP_INSTANCE=1 NODE_CONFIG='{ \"log\": { \"level\": \"warning\" } }' npm start" | 14 | "NODE_ENV=test NODE_APP_INSTANCE=1 NODE_CONFIG='{ \"log\": { \"level\": \"warning\" } }' npm start" |