aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/e2e/fixtures/video.mp4bin619469 -> 619477 bytes
-rw-r--r--client/e2e/src/po/app.po.ts21
-rw-r--r--client/e2e/src/videos.e2e-spec.ts9
-rw-r--r--client/src/app/shared/rxjs/zone.ts40
-rw-r--r--client/src/app/shared/user-subscription/user-subscription.service.ts14
-rw-r--r--client/src/app/shared/video-playlist/video-playlist.service.ts14
-rwxr-xr-xscripts/e2e/local.sh2
-rw-r--r--shared/extra-utils/videos/videos.ts14
8 files changed, 95 insertions, 19 deletions
diff --git a/client/e2e/fixtures/video.mp4 b/client/e2e/fixtures/video.mp4
index f9c9e2dd6..c9ba8fd04 100644
--- a/client/e2e/fixtures/video.mp4
+++ b/client/e2e/fixtures/video.mp4
Binary files differ
diff --git a/client/e2e/src/po/app.po.ts b/client/e2e/src/po/app.po.ts
new file mode 100644
index 000000000..a636e825f
--- /dev/null
+++ b/client/e2e/src/po/app.po.ts
@@ -0,0 +1,21 @@
1import { browser, by, element } from 'protractor'
2
3export class AppPage {
4
5 async closeWelcomeModal () {
6 const firstHandle = await browser.getWindowHandle()
7
8 if (await element(by.css('.configure-instance-button')).isPresent() === false) return
9
10 await element(by.css('.configure-instance-button')).click()
11
12 await browser.switchTo().window(firstHandle)
13
14 await browser.refresh()
15
16 await element(by.css('.form-group-checkbox')).click()
17 await element(by.css('.action-button-cancel')).click()
18
19 await browser.switchTo().window(firstHandle)
20 }
21}
diff --git a/client/e2e/src/videos.e2e-spec.ts b/client/e2e/src/videos.e2e-spec.ts
index 27706a506..075add531 100644
--- a/client/e2e/src/videos.e2e-spec.ts
+++ b/client/e2e/src/videos.e2e-spec.ts
@@ -4,6 +4,7 @@ import { LoginPage } from './po/login.po'
4import { browser } from 'protractor' 4import { browser } from 'protractor'
5import { VideoUpdatePage } from './po/video-update.po' 5import { VideoUpdatePage } from './po/video-update.po'
6import { MyAccountPage } from './po/my-account' 6import { MyAccountPage } from './po/my-account'
7import { AppPage } from './po/app.po'
7 8
8async function skipIfUploadNotSupported () { 9async function skipIfUploadNotSupported () {
9 if (await isMobileDevice() || await isSafari()) { 10 if (await isMobileDevice() || await isSafari()) {
@@ -30,6 +31,7 @@ describe('Videos workflow', () => {
30 let videoUpdatePage: VideoUpdatePage 31 let videoUpdatePage: VideoUpdatePage
31 let myAccountPage: MyAccountPage 32 let myAccountPage: MyAccountPage
32 let loginPage: LoginPage 33 let loginPage: LoginPage
34 let appPage: AppPage
33 35
34 let videoName = new Date().getTime() + ' video' 36 let videoName = new Date().getTime() + ' video'
35 const video2Name = new Date().getTime() + ' second video' 37 const video2Name = new Date().getTime() + ' second video'
@@ -42,6 +44,7 @@ describe('Videos workflow', () => {
42 videoUpdatePage = new VideoUpdatePage() 44 videoUpdatePage = new VideoUpdatePage()
43 myAccountPage = new MyAccountPage() 45 myAccountPage = new MyAccountPage()
44 loginPage = new LoginPage() 46 loginPage = new LoginPage()
47 appPage = new AppPage()
45 48
46 if (await isMobileDevice()) { 49 if (await isMobileDevice()) {
47 console.log('Mobile device detected.') 50 console.log('Mobile device detected.')
@@ -61,6 +64,12 @@ describe('Videos workflow', () => {
61 return loginPage.loginAsRootUser() 64 return loginPage.loginAsRootUser()
62 }) 65 })
63 66
67 it('Should close the welcome modal', async () => {
68 if (await skipIfUploadNotSupported()) return
69
70 await appPage.closeWelcomeModal()
71 })
72
64 it('Should upload a video', async () => { 73 it('Should upload a video', async () => {
65 if (await skipIfUploadNotSupported()) return 74 if (await skipIfUploadNotSupported()) return
66 75
diff --git a/client/src/app/shared/rxjs/zone.ts b/client/src/app/shared/rxjs/zone.ts
new file mode 100644
index 000000000..74eed7032
--- /dev/null
+++ b/client/src/app/shared/rxjs/zone.ts
@@ -0,0 +1,40 @@
1import { SchedulerLike, Subscription } from 'rxjs'
2import { NgZone } from '@angular/core'
3
4class LeaveZoneScheduler implements SchedulerLike {
5 constructor (private zone: NgZone, private scheduler: SchedulerLike) {
6 }
7
8 schedule (...args: any[]): Subscription {
9 return this.zone.runOutsideAngular(() =>
10 this.scheduler.schedule.apply(this.scheduler, args)
11 )
12 }
13
14 now (): number {
15 return this.scheduler.now()
16 }
17}
18
19class EnterZoneScheduler implements SchedulerLike {
20 constructor (private zone: NgZone, private scheduler: SchedulerLike) {
21 }
22
23 schedule (...args: any[]): Subscription {
24 return this.zone.run(() =>
25 this.scheduler.schedule.apply(this.scheduler, args)
26 )
27 }
28
29 now (): number {
30 return this.scheduler.now()
31 }
32}
33
34export function leaveZone (zone: NgZone, scheduler: SchedulerLike): SchedulerLike {
35 return new LeaveZoneScheduler(zone, scheduler)
36}
37
38export function enterZone (zone: NgZone, scheduler: SchedulerLike): SchedulerLike {
39 return new EnterZoneScheduler(zone, scheduler)
40}
diff --git a/client/src/app/shared/user-subscription/user-subscription.service.ts b/client/src/app/shared/user-subscription/user-subscription.service.ts
index bfb5848bc..9af9ba23e 100644
--- a/client/src/app/shared/user-subscription/user-subscription.service.ts
+++ b/client/src/app/shared/user-subscription/user-subscription.service.ts
@@ -1,7 +1,7 @@
1import { bufferTime, catchError, filter, map, tap, share, switchMap } from 'rxjs/operators' 1import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap } from 'rxjs/operators'
2import { Observable, ReplaySubject, Subject, of, merge } from 'rxjs' 2import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
3import { HttpClient, HttpParams } from '@angular/common/http' 3import { HttpClient, HttpParams } from '@angular/common/http'
4import { Injectable } from '@angular/core' 4import { Injectable, NgZone } from '@angular/core'
5import { ResultList } from '../../../../../shared' 5import { ResultList } from '../../../../../shared'
6import { environment } from '../../../environments/environment' 6import { environment } from '../../../environments/environment'
7import { RestExtractor, RestService } from '../rest' 7import { RestExtractor, RestService } from '../rest'
@@ -11,6 +11,7 @@ import { VideoChannel as VideoChannelServer } from '../../../../../shared/models
11import { ComponentPaginationLight } from '@app/shared/rest/component-pagination.model' 11import { ComponentPaginationLight } from '@app/shared/rest/component-pagination.model'
12import { uniq } from 'lodash-es' 12import { uniq } from 'lodash-es'
13import * as debug from 'debug' 13import * as debug from 'debug'
14import { enterZone, leaveZone } from '@app/shared/rxjs/zone'
14 15
15const logger = debug('peertube:subscriptions:UserSubscriptionService') 16const logger = debug('peertube:subscriptions:UserSubscriptionService')
16 17
@@ -32,13 +33,16 @@ export class UserSubscriptionService {
32 constructor ( 33 constructor (
33 private authHttp: HttpClient, 34 private authHttp: HttpClient,
34 private restExtractor: RestExtractor, 35 private restExtractor: RestExtractor,
35 private restService: RestService 36 private restService: RestService,
37 private ngZone: NgZone
36 ) { 38 ) {
37 this.existsObservable = merge( 39 this.existsObservable = merge(
38 this.existsSubject.pipe( 40 this.existsSubject.pipe(
39 bufferTime(500), 41 // We leave Angular zone so Protractor does not get stuck
42 bufferTime(500, leaveZone(this.ngZone, asyncScheduler)),
40 filter(uris => uris.length !== 0), 43 filter(uris => uris.length !== 0),
41 map(uris => uniq(uris)), 44 map(uris => uniq(uris)),
45 observeOn(enterZone(this.ngZone, asyncScheduler)),
42 switchMap(uris => this.doSubscriptionsExist(uris)), 46 switchMap(uris => this.doSubscriptionsExist(uris)),
43 share() 47 share()
44 ), 48 ),
diff --git a/client/src/app/shared/video-playlist/video-playlist.service.ts b/client/src/app/shared/video-playlist/video-playlist.service.ts
index fc5eb5337..bae6f9e04 100644
--- a/client/src/app/shared/video-playlist/video-playlist.service.ts
+++ b/client/src/app/shared/video-playlist/video-playlist.service.ts
@@ -1,6 +1,6 @@
1import { bufferTime, catchError, filter, map, share, switchMap, tap } from 'rxjs/operators' 1import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap } from 'rxjs/operators'
2import { Injectable } from '@angular/core' 2import { Injectable, NgZone } from '@angular/core'
3import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs' 3import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
4import { RestExtractor } from '../rest/rest-extractor.service' 4import { RestExtractor } from '../rest/rest-extractor.service'
5import { HttpClient, HttpParams } from '@angular/common/http' 5import { HttpClient, HttpParams } from '@angular/common/http'
6import { ResultList, VideoPlaylistElementCreate, VideoPlaylistElementUpdate } from '../../../../../shared' 6import { ResultList, VideoPlaylistElementCreate, VideoPlaylistElementUpdate } from '../../../../../shared'
@@ -23,6 +23,7 @@ import { VideoPlaylistElement as ServerVideoPlaylistElement } from '@shared/mode
23import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model' 23import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model'
24import { uniq } from 'lodash-es' 24import { uniq } from 'lodash-es'
25import * as debug from 'debug' 25import * as debug from 'debug'
26import { enterZone, leaveZone } from '@app/shared/rxjs/zone'
26 27
27const logger = debug('peertube:playlists:VideoPlaylistService') 28const logger = debug('peertube:playlists:VideoPlaylistService')
28 29
@@ -49,13 +50,16 @@ export class VideoPlaylistService {
49 private authHttp: HttpClient, 50 private authHttp: HttpClient,
50 private serverService: ServerService, 51 private serverService: ServerService,
51 private restExtractor: RestExtractor, 52 private restExtractor: RestExtractor,
52 private restService: RestService 53 private restService: RestService,
54 private ngZone: NgZone
53 ) { 55 ) {
54 this.videoExistsInPlaylistObservable = merge( 56 this.videoExistsInPlaylistObservable = merge(
55 this.videoExistsInPlaylistNotifier.pipe( 57 this.videoExistsInPlaylistNotifier.pipe(
56 bufferTime(500), 58 // We leave Angular zone so Protractor does not get stuck
59 bufferTime(500, leaveZone(this.ngZone, asyncScheduler)),
57 filter(videoIds => videoIds.length !== 0), 60 filter(videoIds => videoIds.length !== 0),
58 map(videoIds => uniq(videoIds)), 61 map(videoIds => uniq(videoIds)),
62 observeOn(enterZone(this.ngZone, asyncScheduler)),
59 switchMap(videoIds => this.doVideosExistInPlaylist(videoIds)), 63 switchMap(videoIds => this.doVideosExistInPlaylist(videoIds)),
60 share() 64 share()
61 ), 65 ),
diff --git a/scripts/e2e/local.sh b/scripts/e2e/local.sh
index b883ccaa3..e8db2e808 100755
--- a/scripts/e2e/local.sh
+++ b/scripts/e2e/local.sh
@@ -11,4 +11,4 @@ npm run clean:server:test
11 11
12npm run concurrently -- -k -s first \ 12npm run concurrently -- -k -s first \
13 "cd client && npm run ng -- e2e --port 3333 -c local" \ 13 "cd client && npm run ng -- e2e --port 3333 -c local" \
14 "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\" } }' node dist/server"
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts
index 9dec12703..d1ac48292 100644
--- a/shared/extra-utils/videos/videos.ts
+++ b/shared/extra-utils/videos/videos.ts
@@ -587,19 +587,17 @@ async function completeVideoCheck (
587 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')') 587 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')')
588 .to.be.above(minSize).and.below(maxSize) 588 .to.be.above(minSize).and.below(maxSize)
589 589
590 {
591 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
592 }
593
594 if (attributes.previewfile) {
595 await testImage(url, attributes.previewfile, videoDetails.previewPath)
596 }
597
598 const torrent = await webtorrentAdd(file.magnetUri, true) 590 const torrent = await webtorrentAdd(file.magnetUri, true)
599 expect(torrent.files).to.be.an('array') 591 expect(torrent.files).to.be.an('array')
600 expect(torrent.files.length).to.equal(1) 592 expect(torrent.files.length).to.equal(1)
601 expect(torrent.files[0].path).to.exist.and.to.not.equal('') 593 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
602 } 594 }
595
596 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
597
598 if (attributes.previewfile) {
599 await testImage(url, attributes.previewfile, videoDetails.previewPath)
600 }
603} 601}
604 602
605async function videoUUIDToId (url: string, id: number | string) { 603async function videoUUIDToId (url: string, id: number | string) {