aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/e2e/src/po
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-08-30 16:24:25 +0200
committerChocobozzz <me@florianbigard.com>2021-09-01 15:06:46 +0200
commit3419e0e1fe8e48a08b63ca0ded31087f913eb2b6 (patch)
tree63ac7190b79194e93aec9bbfd3c336e60f469e9d /client/e2e/src/po
parent2a4c9669d2d6ac6cd4ae43544698f826ae98080f (diff)
downloadPeerTube-3419e0e1fe8e48a08b63ca0ded31087f913eb2b6.tar.gz
PeerTube-3419e0e1fe8e48a08b63ca0ded31087f913eb2b6.tar.zst
PeerTube-3419e0e1fe8e48a08b63ca0ded31087f913eb2b6.zip
Migrate to webdriverio
Diffstat (limited to 'client/e2e/src/po')
-rw-r--r--client/e2e/src/po/login.po.ts24
-rw-r--r--client/e2e/src/po/my-account.ts102
-rw-r--r--client/e2e/src/po/player.po.ts52
-rw-r--r--client/e2e/src/po/video-update.po.ts12
-rw-r--r--client/e2e/src/po/video-upload.po.ts34
-rw-r--r--client/e2e/src/po/video-watch.po.ts132
6 files changed, 216 insertions, 140 deletions
diff --git a/client/e2e/src/po/login.po.ts b/client/e2e/src/po/login.po.ts
index 20412ee0d..8e3030e43 100644
--- a/client/e2e/src/po/login.po.ts
+++ b/client/e2e/src/po/login.po.ts
@@ -1,23 +1,25 @@
1import { browser, element, by } from 'protractor' 1import { go } from '../utils'
2 2
3export class LoginPage { 3export class LoginPage {
4 async loginAsRootUser () { 4 async loginAsRootUser () {
5 await browser.get('/login') 5 await go('/login')
6 6
7 await browser.executeScript(`window.localStorage.setItem('no_instance_config_warning_modal', 'true')`) 7 await browser.execute(`window.localStorage.setItem('no_instance_config_warning_modal', 'true')`)
8 await browser.executeScript(`window.localStorage.setItem('no_welcome_modal', 'true')`) 8 await browser.execute(`window.localStorage.setItem('no_welcome_modal', 'true')`)
9 9
10 element(by.css('input#username')).sendKeys('root') 10 await $('input#username').setValue('root')
11 element(by.css('input#password')).sendKeys('test1') 11 await $('input#password').setValue('test1')
12 12
13 await browser.sleep(1000) 13 await browser.pause(1000)
14 14
15 await element(by.css('form input[type=submit]')).click() 15 await $('form input[type=submit]').click()
16 16
17 expect(this.getLoggedInInfo().getText()).toContain('root') 17 await this.getLoggedInInfoElem().waitForExist()
18
19 await expect(this.getLoggedInInfoElem()).toHaveText('root')
18 } 20 }
19 21
20 private getLoggedInInfo () { 22 private getLoggedInInfoElem () {
21 return element(by.css('.logged-in-display-name')) 23 return $('.logged-in-display-name')
22 } 24 }
23} 25}
diff --git a/client/e2e/src/po/my-account.ts b/client/e2e/src/po/my-account.ts
index 9866953e9..85dc02805 100644
--- a/client/e2e/src/po/my-account.ts
+++ b/client/e2e/src/po/my-account.ts
@@ -1,85 +1,117 @@
1import { by, element, browser } from 'protractor' 1import { go } from '../utils'
2 2
3export class MyAccountPage { 3export class MyAccountPage {
4 4
5 navigateToMyVideos () { 5 navigateToMyVideos () {
6 return element(by.css('a[href="/my-library/videos"]')).click() 6 return $('a[href="/my-library/videos"]').click()
7 } 7 }
8 8
9 navigateToMyPlaylists () { 9 navigateToMyPlaylists () {
10 return element(by.css('a[href="/my-library/video-playlists"]')).click() 10 return $('a[href="/my-library/video-playlists"]').click()
11 } 11 }
12 12
13 navigateToMyHistory () { 13 navigateToMyHistory () {
14 return element(by.css('a[href="/my-library/history/videos"]')).click() 14 return $('a[href="/my-library/history/videos"]').click()
15 } 15 }
16 16
17 // My account Videos 17 // My account Videos
18 18
19 async removeVideo (name: string) { 19 async removeVideo (name: string) {
20 const container = this.getVideoElement(name) 20 const container = await this.getVideoElement(name)
21 21
22 await container.element(by.css('.dropdown-toggle')).click() 22 await container.$('.dropdown-toggle').click()
23 23
24 const dropdownMenu = container.element(by.css('.dropdown-menu .dropdown-item:nth-child(2)')) 24 const dropdownMenu = () => container.$('.dropdown-menu .dropdown-item:nth-child(2)')
25 await browser.wait(browser.ExpectedConditions.presenceOf(dropdownMenu))
26 25
27 return dropdownMenu.click() 26 await dropdownMenu().waitForDisplayed()
27 return dropdownMenu().click()
28 } 28 }
29 29
30 validRemove () { 30 validRemove () {
31 return element(by.css('input[type=submit]')).click() 31 return $('input[type=submit]').click()
32 } 32 }
33 33
34 countVideos (names: string[]) { 34 async countVideos (names: string[]) {
35 return element.all(by.css('.video')) 35 const elements = await $$('.video').filter(async e => {
36 .filter(e => { 36 const t = await e.$('.video-miniature-name').getText()
37 return e.element(by.css('.video-miniature-name')) 37
38 .getText() 38 return names.some(n => t.includes(n))
39 .then(t => names.some(n => t.includes(n))) 39 })
40 }) 40
41 .count() 41 return elements.length
42 } 42 }
43 43
44 // My account playlists 44 // My account playlists
45 45
46 getPlaylistVideosText (name: string) { 46 async getPlaylistVideosText (name: string) {
47 return this.getPlaylist(name).element(by.css('.miniature-playlist-info-overlay')).getText() 47 const elem = await this.getPlaylist(name)
48
49 return elem.$('.miniature-playlist-info-overlay').getText()
48 } 50 }
49 51
50 clickOnPlaylist (name: string) { 52 async clickOnPlaylist (name: string) {
51 return this.getPlaylist(name).element(by.css('.miniature-thumbnail')).click() 53 const elem = await this.getPlaylist(name)
54
55 return elem.$('.miniature-thumbnail').click()
52 } 56 }
53 57
54 countTotalPlaylistElements () { 58 async countTotalPlaylistElements () {
55 return element.all(by.css('my-video-playlist-element-miniature')).count() 59 await $('<my-video-playlist-element-miniature>').waitForDisplayed()
60
61 return $$('<my-video-playlist-element-miniature>').length
56 } 62 }
57 63
58 playPlaylist () { 64 playPlaylist () {
59 return element(by.css('.playlist-info .miniature-thumbnail')).click() 65 return $('.playlist-info .miniature-thumbnail').click()
60 } 66 }
61 67
62 async goOnAssociatedPlaylistEmbed () { 68 async goOnAssociatedPlaylistEmbed () {
63 let url = await browser.getCurrentUrl() 69 let url = await browser.getUrl()
64 url = url.replace('/w/p/', '/video-playlists/embed/') 70 url = url.replace('/w/p/', '/video-playlists/embed/')
65 url = url.replace(':3333', ':9001') 71 url = url.replace(':3333', ':9001')
66 72
67 return browser.get(url) 73 return go(url)
68 } 74 }
69 75
70 // My account Videos 76 // My account Videos
71 77
72 private getVideoElement (name: string) { 78 private async getVideoElement (name: string) {
73 return element.all(by.css('.video')) 79 const video = async () => {
74 .filter(e => e.element(by.css('.video-miniature-name')).getText().then(t => t.includes(name))) 80 const videos = await $$('.video').filter(async e => {
75 .first() 81 const t = await e.$('.video-miniature-name').getText()
82
83 return t.includes(name)
84 })
85
86 return videos[0]
87 }
88
89 await browser.waitUntil(async () => {
90 return (await video()).isDisplayed()
91 })
92
93 return video()
76 } 94 }
77 95
78 // My account playlists 96 // My account playlists
79 97
80 private getPlaylist (name: string) { 98 private async getPlaylist (name: string) {
81 return element.all(by.css('my-video-playlist-miniature')) 99 const playlist = () => {
82 .filter(e => e.element(by.css('.miniature-name')).getText().then(t => t.includes(name))) 100 return $$('my-video-playlist-miniature')
83 .first() 101 .filter(async e => {
102 const t = await e.$('.miniature-name').getText()
103
104 return t.includes(name)
105 })
106 .then(elems => elems[0])
107 }
108
109 await browser.waitUntil(async () => {
110 const el = await playlist()
111
112 return el?.isDisplayed()
113 })
114
115 return playlist()
84 } 116 }
85} 117}
diff --git a/client/e2e/src/po/player.po.ts b/client/e2e/src/po/player.po.ts
index cb148a003..9d6e21009 100644
--- a/client/e2e/src/po/player.po.ts
+++ b/client/e2e/src/po/player.po.ts
@@ -1,45 +1,54 @@
1import { browser, by, element } from 'protractor'
2import { browserSleep, isIOS, isMobileDevice, isSafari } from '../utils' 1import { browserSleep, isIOS, isMobileDevice, isSafari } from '../utils'
3 2
4export class PlayerPage { 3export class PlayerPage {
5 4
6 async getWatchVideoPlayerCurrentTime () { 5 getWatchVideoPlayerCurrentTime () {
7 const elem = element(by.css('video')) 6 const elem = $('video')
8 7
9 return elem.getAttribute('currentTime') 8 if (isIOS()) {
10 } 9 return elem.getAttribute('currentTime')
10 .then(t => parseInt(t, 10))
11 .then(t => Math.round(t))
12 }
11 13
12 waitUntilPlaylistInfo (text: string) { 14 return elem.getProperty('currentTime')
13 const elem = element(by.css('.video-js .vjs-playlist-info')) 15 }
14 16
15 return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, text)) 17 waitUntilPlaylistInfo (text: string, maxTime: number) {
18 return browser.waitUntil(async () => {
19 return (await $('.video-js .vjs-playlist-info').getText()).includes(text)
20 }, { timeout: maxTime })
16 } 21 }
17 22
18 waitUntilPlayerWrapper () { 23 waitUntilPlayerWrapper () {
19 const elem = element(by.css('#placeholder-preview')) 24 return browser.waitUntil(async () => {
20 25 return !!(await $('#placeholder-preview'))
21 return browser.wait(browser.ExpectedConditions.presenceOf(elem)) 26 })
22 } 27 }
23 28
24 async playAndPauseVideo (isAutoplay: boolean) { 29 async playAndPauseVideo (isAutoplay: boolean) {
25 const videojsEl = element(by.css('div.video-js')) 30 const videojsElem = () => $('div.video-js')
26 await browser.wait(browser.ExpectedConditions.elementToBeClickable(videojsEl)) 31
32 await videojsElem().waitForExist()
27 33
28 // Autoplay is disabled on iOS and Safari 34 // Autoplay is disabled on iOS and Safari
29 if (await isIOS() || await isSafari() || await isMobileDevice()) { 35 if (isIOS() || isSafari() || isMobileDevice()) {
30 // We can't play the video using protractor if it is not muted 36 // We can't play the video using protractor if it is not muted
31 await browser.executeScript(`document.querySelector('video').muted = true`) 37 await browser.execute(`document.querySelector('video').muted = true`)
32 await this.clickOnPlayButton() 38 await this.clickOnPlayButton()
33 } else if (isAutoplay === false) { 39 } else if (isAutoplay === false) {
34 await this.clickOnPlayButton() 40 await this.clickOnPlayButton()
35 } 41 }
36 42
37 await browserSleep(2000) 43 await browserSleep(2000)
38 await browser.wait(browser.ExpectedConditions.invisibilityOf(element(by.css('.vjs-loading-spinner'))))
39 44
40 await browserSleep(2000) 45 await browser.waitUntil(async () => {
46 return !await $('.vjs-loading-spinner').isDisplayedInViewport()
47 }, { timeout: 20 * 1000 })
41 48
42 await videojsEl.click() 49 await browserSleep(4000)
50
51 await videojsElem().click()
43 } 52 }
44 53
45 async playVideo () { 54 async playVideo () {
@@ -47,8 +56,9 @@ export class PlayerPage {
47 } 56 }
48 57
49 private async clickOnPlayButton () { 58 private async clickOnPlayButton () {
50 const playButton = element(by.css('.vjs-big-play-button')) 59 const playButton = () => $('.vjs-big-play-button')
51 await browser.wait(browser.ExpectedConditions.elementToBeClickable(playButton)) 60
52 await playButton.click() 61 await playButton().waitForClickable()
62 await playButton().click()
53 } 63 }
54} 64}
diff --git a/client/e2e/src/po/video-update.po.ts b/client/e2e/src/po/video-update.po.ts
index 752741378..3ffb7ba57 100644
--- a/client/e2e/src/po/video-update.po.ts
+++ b/client/e2e/src/po/video-update.po.ts
@@ -1,11 +1,11 @@
1import { by, element } from 'protractor'
2
3export class VideoUpdatePage { 1export class VideoUpdatePage {
4 2
5 async updateName (videoName: string) { 3 async updateName (videoName: string) {
6 const nameInput = element(by.css('input#name')) 4 const nameInput = $('input#name')
7 await nameInput.clear() 5
8 await nameInput.sendKeys(videoName) 6 await nameInput.waitForDisplayed()
7 await nameInput.clearValue()
8 await nameInput.setValue(videoName)
9 } 9 }
10 10
11 async validUpdate () { 11 async validUpdate () {
@@ -15,6 +15,6 @@ export class VideoUpdatePage {
15 } 15 }
16 16
17 private getSubmitButton () { 17 private getSubmitButton () {
18 return element(by.css('.submit-container .action-button')) 18 return $('.submit-container .action-button')
19 } 19 }
20} 20}
diff --git a/client/e2e/src/po/video-upload.po.ts b/client/e2e/src/po/video-upload.po.ts
index a248912ed..34f916b55 100644
--- a/client/e2e/src/po/video-upload.po.ts
+++ b/client/e2e/src/po/video-upload.po.ts
@@ -1,33 +1,29 @@
1import { browser, by, element } from 'protractor'
2import { FileDetector } from 'selenium-webdriver/remote'
3import { join } from 'path' 1import { join } from 'path'
4 2
5export class VideoUploadPage { 3export class VideoUploadPage {
6 async navigateTo () { 4 async navigateTo () {
7 await element(by.css('.header .publish-button')).click() 5 await $('.header .publish-button').click()
8 6
9 return browser.wait(browser.ExpectedConditions.visibilityOf(element(by.css('.upload-video-container')))) 7 await $('.upload-video-container').waitForDisplayed()
10 } 8 }
11 9
12 async uploadVideo () { 10 async uploadVideo () {
13 browser.setFileDetector(new FileDetector())
14
15 const fileToUpload = join(__dirname, '../../fixtures/video.mp4') 11 const fileToUpload = join(__dirname, '../../fixtures/video.mp4')
16 const fileInputSelector = '.upload-video-container input[type=file]' 12 const fileInputSelector = '.upload-video-container input[type=file]'
17 const parentFileInput = '.upload-video-container .button-file' 13 const parentFileInput = '.upload-video-container .button-file'
18 14
19 // Avoid sending keys on non visible element 15 // Avoid sending keys on non visible element
20 await browser.executeScript(`document.querySelector('${fileInputSelector}').style.opacity = 1`) 16 await browser.execute(`document.querySelector('${fileInputSelector}').style.opacity = 1`)
21 await browser.executeScript(`document.querySelector('${parentFileInput}').style.overflow = 'initial'`) 17 await browser.execute(`document.querySelector('${parentFileInput}').style.overflow = 'initial'`)
22 18
23 await browser.sleep(1000) 19 await browser.pause(1000)
24 20
25 const elem = element(by.css(fileInputSelector)) 21 const elem = await $(fileInputSelector)
26 await elem.sendKeys(fileToUpload) 22 await elem.chooseFile(fileToUpload)
27 23
28 // Wait for the upload to finish 24 // Wait for the upload to finish
29 await browser.wait(async () => { 25 await browser.waitUntil(async () => {
30 const actionButton = this.getSecondStepSubmitButton().element(by.css('.action-button')) 26 const actionButton = this.getSecondStepSubmitButton().$('.action-button')
31 27
32 const klass = await actionButton.getAttribute('class') 28 const klass = await actionButton.getAttribute('class')
33 return !klass.includes('disabled') 29 return !klass.includes('disabled')
@@ -35,16 +31,18 @@ export class VideoUploadPage {
35 } 31 }
36 32
37 async validSecondUploadStep (videoName: string) { 33 async validSecondUploadStep (videoName: string) {
38 const nameInput = element(by.css('input#name')) 34 const nameInput = $('input#name')
39 await nameInput.clear() 35 await nameInput.clearValue()
40 await nameInput.sendKeys(videoName) 36 await nameInput.setValue(videoName)
41 37
42 await this.getSecondStepSubmitButton().click() 38 await this.getSecondStepSubmitButton().click()
43 39
44 return browser.wait(browser.ExpectedConditions.urlContains('/w/')) 40 return browser.waitUntil(async () => {
41 return (await browser.getUrl()).includes('/w/')
42 })
45 } 43 }
46 44
47 private getSecondStepSubmitButton () { 45 private getSecondStepSubmitButton () {
48 return element(by.css('.submit-container my-button')) 46 return $('.submit-container my-button')
49 } 47 }
50} 48}
diff --git a/client/e2e/src/po/video-watch.po.ts b/client/e2e/src/po/video-watch.po.ts
index c875d5854..01061d5d4 100644
--- a/client/e2e/src/po/video-watch.po.ts
+++ b/client/e2e/src/po/video-watch.po.ts
@@ -1,5 +1,4 @@
1import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor' 1import { browserSleep, go } from '../utils'
2import { browserSleep, isMobileDevice } from '../utils'
3 2
4export class VideoWatchPage { 3export class VideoWatchPage {
5 async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) { 4 async goOnVideosList (isMobileDevice: boolean, isSafari: boolean) {
@@ -12,19 +11,19 @@ export class VideoWatchPage {
12 url = '/videos/recently-added' 11 url = '/videos/recently-added'
13 } 12 }
14 13
15 await browser.get(url, 20000) 14 await go(url)
16 15
17 // Waiting the following element does not work on Safari... 16 // Waiting the following element does not work on Safari...
18 if (isSafari) return browserSleep(3000) 17 if (isSafari) return browserSleep(3000)
19 18
20 const elem = element.all(by.css('.videos .video-miniature .video-miniature-name')).first() 19 await $('.videos .video-miniature .video-miniature-name').waitForDisplayed()
21 return browser.wait(browser.ExpectedConditions.visibilityOf(elem))
22 } 20 }
23 21
24 getVideosListName () { 22 async getVideosListName () {
25 return element.all(by.css('.videos .video-miniature .video-miniature-name')) 23 const elems = await $$('.videos .video-miniature .video-miniature-name')
26 .getText() 24 const texts = await Promise.all(elems.map(e => e.getText()))
27 .then((texts: any) => texts.map((t: any) => t.trim())) 25
26 return texts.map(t => t.trim())
28 } 27 }
29 28
30 waitWatchVideoName (videoName: string, isMobileDevice: boolean, isSafari: boolean) { 29 waitWatchVideoName (videoName: string, isMobileDevice: boolean, isSafari: boolean) {
@@ -33,99 +32,134 @@ export class VideoWatchPage {
33 // On mobile we display the first node, on desktop the second 32 // On mobile we display the first node, on desktop the second
34 const index = isMobileDevice ? 0 : 1 33 const index = isMobileDevice ? 0 : 1
35 34
36 const elem = element.all(by.css('.video-info .video-info-name')).get(index) 35 return browser.waitUntil(async () => {
37 return browser.wait(browser.ExpectedConditions.textToBePresentInElement(elem, videoName)) 36 return (await $$('.video-info .video-info-name')[index].getText()).includes(videoName)
37 })
38 } 38 }
39 39
40 getVideoName () { 40 getVideoName () {
41 return this.getVideoNameElement().getText() 41 return this.getVideoNameElement().then(e => e.getText())
42 } 42 }
43 43
44 async goOnAssociatedEmbed () { 44 async goOnAssociatedEmbed () {
45 let url = await browser.getCurrentUrl() 45 let url = await browser.getUrl()
46 url = url.replace('/w/', '/videos/embed/') 46 url = url.replace('/w/', '/videos/embed/')
47 url = url.replace(':3333', ':9001') 47 url = url.replace(':3333', ':9001')
48 48
49 return browser.get(url) 49 return go(url)
50 } 50 }
51 51
52 async goOnP2PMediaLoaderEmbed () { 52 goOnP2PMediaLoaderEmbed () {
53 return browser.get('https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50') 53 return go(
54 'https://peertube2.cpy.re/videos/embed/969bf103-7818-43b5-94a0-de159e13de50'
55 )
54 } 56 }
55 57
56 async goOnP2PMediaLoaderPlaylistEmbed () { 58 goOnP2PMediaLoaderPlaylistEmbed () {
57 return browser.get('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a') 59 return go(
60 'https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a'
61 )
58 } 62 }
59 63
60 async clickOnVideo (videoName: string) { 64 async clickOnVideo (videoName: string) {
61 const video = element.all(by.css('.videos .video-miniature .video-miniature-name')) 65 const video = async () => {
62 .filter(e => e.getText().then(t => t === videoName )) 66 const videos = await $$('.videos .video-miniature .video-miniature-name').filter(async e => {
63 .first() 67 const t = await e.getText()
68
69 return t === videoName
70 })
71
72 return videos[0]
73 }
74
75 await browser.waitUntil(async () => {
76 const elem = await video()
64 77
65 await browser.wait(browser.ExpectedConditions.elementToBeClickable(video)) 78 return elem?.isClickable()
66 await video.click() 79 });
67 80
68 await browser.wait(browser.ExpectedConditions.urlContains('/w/')) 81 (await video()).click()
82
83 await browser.waitUntil(async () => (await browser.getUrl()).includes('/w/'))
69 } 84 }
70 85
71 async clickOnFirstVideo () { 86 async clickOnFirstVideo () {
72 const video = element.all(by.css('.videos .video-miniature .video-thumbnail')).first() 87 const video = () => $('.videos .video-miniature .video-thumbnail')
73 const videoName = element.all(by.css('.videos .video-miniature .video-miniature-name')).first() 88 const videoName = () => $('.videos .video-miniature .video-miniature-name')
89
90 await video().waitForClickable()
74 91
75 // Don't know why but the expectation fails on Safari 92 const textToReturn = await videoName().getText()
76 await browser.wait(browser.ExpectedConditions.elementToBeClickable(video)) 93 await video().click()
77 94
78 const textToReturn = videoName.getText() 95 await browser.waitUntil(async () => (await browser.getUrl()).includes('/w/'))
79 await video.click()
80 96
81 await browser.wait(browser.ExpectedConditions.urlContains('/w/'))
82 return textToReturn 97 return textToReturn
83 } 98 }
84 99
85 async clickOnUpdate () { 100 async clickOnUpdate () {
86 const dropdown = element(by.css('my-video-actions-dropdown .action-button')) 101 const dropdown = $('my-video-actions-dropdown .action-button')
87 await dropdown.click() 102 await dropdown.click()
88 103
89 const items: ElementFinder[] = await element.all(by.css('.dropdown-menu.show .dropdown-item')) 104 await $('.dropdown-menu.show .dropdown-item').waitForDisplayed()
105 const items = await $$('.dropdown-menu.show .dropdown-item')
90 106
91 for (const item of items) { 107 for (const item of items) {
92 const href = await item.getAttribute('href') 108 const href = await item.getAttribute('href')
93 109
94 if (href && href.includes('/update/')) { 110 if (href?.includes('/update/')) {
95 await item.click() 111 await item.click()
96 return 112 return
97 } 113 }
98 } 114 }
99 } 115 }
100 116
101 async clickOnSave () { 117 clickOnSave () {
102 return element(by.css('.action-button-save')).click() 118 return $('.action-button-save').click()
103 } 119 }
104 120
105 async createPlaylist (name: string) { 121 async createPlaylist (name: string) {
106 await element(by.css('.new-playlist-button')).click() 122 const newPlaylistButton = () => $('.new-playlist-button')
123
124 await newPlaylistButton().waitForClickable()
125 await newPlaylistButton().click()
126
127 const displayName = () => $('#displayName')
107 128
108 await element(by.css('#displayName')).sendKeys(name) 129 await displayName().waitForDisplayed()
130 await displayName().setValue(name)
109 131
110 return element(by.css('.new-playlist-block input[type=submit]')).click() 132 return $('.new-playlist-block input[type=submit]').click()
111 } 133 }
112 134
113 async saveToPlaylist (name: string) { 135 async saveToPlaylist (name: string) {
114 return element.all(by.css('my-video-add-to-playlist .playlist')) 136 const playlist = () => $('my-video-add-to-playlist').$(`.playlist=${name}`)
115 .filter(p => p.getText().then(t => t === name)) 137
116 .click() 138 await playlist().waitForDisplayed()
139
140 return playlist().click()
117 } 141 }
118 142
119 waitUntilVideoName (name: string, maxTime: number) { 143 waitUntilVideoName (name: string, maxTime: number) {
120 const elem = this.getVideoNameElement() 144 return browser.waitUntil(async () => {
121 145 return (await this.getVideoName()) === name
122 return browser.wait(ExpectedConditions.textToBePresentInElement(elem, name), maxTime) 146 }, { timeout: maxTime })
123 } 147 }
124 148
125 private getVideoNameElement () { 149 private async getVideoNameElement () {
126 // We have 2 video info name block, pick the first that is not empty 150 // We have 2 video info name block, pick the first that is not empty
127 return element.all(by.css('.video-info-first-row .video-info-name')) 151 const elem = async () => {
128 .filter(e => e.getText().then(t => !!t)) 152 const elems = await $$('.video-info-first-row .video-info-name').filter(e => e.isDisplayed())
129 .first() 153
154 return elems[0]
155 }
156
157 await browser.waitUntil(async () => {
158 const e = await elem()
159
160 return e?.isDisplayed()
161 })
162
163 return elem()
130 } 164 }
131} 165}