aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/e2e/local-protractor.conf.js9
-rw-r--r--client/e2e/protractor.conf.js7
-rw-r--r--client/e2e/src/po/login.po.ts6
-rw-r--r--client/e2e/src/po/video-upload.po.ts5
-rw-r--r--client/e2e/src/po/video-watch.po.ts6
-rw-r--r--client/e2e/src/videos.e2e-spec.ts29
-rw-r--r--client/src/app/core/notification/user-notification-socket.service.ts15
-rw-r--r--client/src/app/shared/video/video-thumbnail.component.scss4
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.ts11
-rwxr-xr-xscripts/e2e/index.sh1
-rwxr-xr-xscripts/e2e/local.sh2
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 @@
1import { Injectable } from '@angular/core' 1import { Injectable, NgZone } from '@angular/core'
2import { environment } from '../../../environments/environment' 2import { environment } from '../../../environments/environment'
3import { UserNotification as UserNotificationServer } from '../../../../../shared' 3import { UserNotification as UserNotificationServer } from '../../../../../shared'
4import { Subject } from 'rxjs' 4import { 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 @@
1import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core' 1import { Component, Input, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms' 2import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { FormReactiveValidationMessages, VideoValidatorsService } from '@app/shared' 4import { 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
13npm run concurrently -- -k -s first \ 12npm 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"