diff options
Diffstat (limited to 'client/e2e/src/po')
-rw-r--r-- | client/e2e/src/po/login.po.ts | 24 | ||||
-rw-r--r-- | client/e2e/src/po/my-account.ts | 102 | ||||
-rw-r--r-- | client/e2e/src/po/player.po.ts | 52 | ||||
-rw-r--r-- | client/e2e/src/po/video-update.po.ts | 12 | ||||
-rw-r--r-- | client/e2e/src/po/video-upload.po.ts | 34 | ||||
-rw-r--r-- | client/e2e/src/po/video-watch.po.ts | 132 |
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 @@ | |||
1 | import { browser, element, by } from 'protractor' | 1 | import { go } from '../utils' |
2 | 2 | ||
3 | export class LoginPage { | 3 | export 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 @@ | |||
1 | import { by, element, browser } from 'protractor' | 1 | import { go } from '../utils' |
2 | 2 | ||
3 | export class MyAccountPage { | 3 | export 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 @@ | |||
1 | import { browser, by, element } from 'protractor' | ||
2 | import { browserSleep, isIOS, isMobileDevice, isSafari } from '../utils' | 1 | import { browserSleep, isIOS, isMobileDevice, isSafari } from '../utils' |
3 | 2 | ||
4 | export class PlayerPage { | 3 | export 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 @@ | |||
1 | import { by, element } from 'protractor' | ||
2 | |||
3 | export class VideoUpdatePage { | 1 | export 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 @@ | |||
1 | import { browser, by, element } from 'protractor' | ||
2 | import { FileDetector } from 'selenium-webdriver/remote' | ||
3 | import { join } from 'path' | 1 | import { join } from 'path' |
4 | 2 | ||
5 | export class VideoUploadPage { | 3 | export 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 @@ | |||
1 | import { browser, by, element, ElementFinder, ExpectedConditions } from 'protractor' | 1 | import { browserSleep, go } from '../utils' |
2 | import { browserSleep, isMobileDevice } from '../utils' | ||
3 | 2 | ||
4 | export class VideoWatchPage { | 3 | export 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 | } |