diff options
Diffstat (limited to 'client/e2e')
-rw-r--r-- | client/e2e/src/po/admin-plugin.po.ts | 31 | ||||
-rw-r--r-- | client/e2e/src/po/anonymous-settings.po.ts | 21 | ||||
-rw-r--r-- | client/e2e/src/po/my-account.po.ts (renamed from client/e2e/src/po/my-account.ts) | 17 | ||||
-rw-r--r-- | client/e2e/src/po/video-upload.po.ts | 27 | ||||
-rw-r--r-- | client/e2e/src/po/video-watch.po.ts | 42 | ||||
-rw-r--r-- | client/e2e/src/suites-all/videos.e2e-spec.ts | 2 | ||||
-rw-r--r-- | client/e2e/src/suites-local/custom-server-defaults.e2e-spec.ts | 86 | ||||
-rw-r--r-- | client/e2e/src/suites-local/plugins.e2e-spec.ts | 78 | ||||
-rw-r--r-- | client/e2e/src/suites-local/user-settings.e2e-spec.ts | 82 | ||||
-rw-r--r-- | client/e2e/src/suites-local/videos-list.e2e-spec.ts | 26 | ||||
-rw-r--r-- | client/e2e/src/utils/elements.ts | 21 | ||||
-rw-r--r-- | client/e2e/src/utils/hooks.ts | 72 | ||||
-rw-r--r-- | client/e2e/src/utils/index.ts | 2 | ||||
-rw-r--r-- | client/e2e/src/utils/server.ts | 63 | ||||
-rw-r--r-- | client/e2e/wdio.browserstack.conf.ts | 7 | ||||
-rw-r--r-- | client/e2e/wdio.local-test.conf.ts | 9 | ||||
-rw-r--r-- | client/e2e/wdio.local.conf.ts | 13 |
17 files changed, 571 insertions, 28 deletions
diff --git a/client/e2e/src/po/admin-plugin.po.ts b/client/e2e/src/po/admin-plugin.po.ts new file mode 100644 index 000000000..6a3f3cf28 --- /dev/null +++ b/client/e2e/src/po/admin-plugin.po.ts | |||
@@ -0,0 +1,31 @@ | |||
1 | import { browserSleep, go } from '../utils' | ||
2 | |||
3 | export class AdminPluginPage { | ||
4 | |||
5 | async navigateToSearch () { | ||
6 | await go('/admin/plugins/search') | ||
7 | |||
8 | await $('my-plugin-search').waitForDisplayed() | ||
9 | } | ||
10 | |||
11 | async search (name: string) { | ||
12 | const input = $('.search-bar input') | ||
13 | await input.waitForDisplayed() | ||
14 | await input.clearValue() | ||
15 | await input.setValue(name) | ||
16 | |||
17 | await browserSleep(1000) | ||
18 | } | ||
19 | |||
20 | async installHelloWorld () { | ||
21 | $('.plugin-name=hello-world').waitForDisplayed() | ||
22 | |||
23 | await $('.card-body my-button[icon=cloud-download]').click() | ||
24 | |||
25 | const submitModalButton = $('.modal-content input[type=submit]') | ||
26 | await submitModalButton.waitForClickable() | ||
27 | await submitModalButton.click() | ||
28 | |||
29 | await $('.card-body my-edit-button').waitForDisplayed() | ||
30 | } | ||
31 | } | ||
diff --git a/client/e2e/src/po/anonymous-settings.po.ts b/client/e2e/src/po/anonymous-settings.po.ts new file mode 100644 index 000000000..21216a8f2 --- /dev/null +++ b/client/e2e/src/po/anonymous-settings.po.ts | |||
@@ -0,0 +1,21 @@ | |||
1 | import { getCheckbox } from '../utils' | ||
2 | |||
3 | export class AnonymousSettingsPage { | ||
4 | |||
5 | async openSettings () { | ||
6 | const link = await $$('.menu-link').filter(async i => { | ||
7 | return await i.getText() === 'My settings' | ||
8 | }).then(links => links[0]) | ||
9 | |||
10 | await link.click() | ||
11 | |||
12 | await $('my-user-video-settings').waitForDisplayed() | ||
13 | } | ||
14 | |||
15 | async clickOnP2PCheckbox () { | ||
16 | const p2p = await getCheckbox('p2pEnabled') | ||
17 | await p2p.waitForClickable() | ||
18 | |||
19 | await p2p.click() | ||
20 | } | ||
21 | } | ||
diff --git a/client/e2e/src/po/my-account.ts b/client/e2e/src/po/my-account.po.ts index b51614fd9..20dafbf06 100644 --- a/client/e2e/src/po/my-account.ts +++ b/client/e2e/src/po/my-account.po.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { go } from '../utils' | 1 | import { getCheckbox, go } from '../utils' |
2 | 2 | ||
3 | export class MyAccountPage { | 3 | export class MyAccountPage { |
4 | 4 | ||
@@ -27,6 +27,21 @@ export class MyAccountPage { | |||
27 | await nsfw.scrollIntoView(false) // Avoid issues with fixed header on firefox | 27 | await nsfw.scrollIntoView(false) // Avoid issues with fixed header on firefox |
28 | await nsfw.selectByAttribute('value', newValue) | 28 | await nsfw.selectByAttribute('value', newValue) |
29 | 29 | ||
30 | await this.submitVideoSettings() | ||
31 | } | ||
32 | |||
33 | async clickOnP2PCheckbox () { | ||
34 | const p2p = await getCheckbox('p2pEnabled') | ||
35 | |||
36 | await p2p.waitForClickable() | ||
37 | await p2p.scrollIntoView(false) // Avoid issues with fixed header on firefox | ||
38 | |||
39 | await p2p.click() | ||
40 | |||
41 | await this.submitVideoSettings() | ||
42 | } | ||
43 | |||
44 | private async submitVideoSettings () { | ||
30 | const submit = $('my-user-video-settings input[type=submit]') | 45 | const submit = $('my-user-video-settings input[type=submit]') |
31 | await submit.scrollIntoView(false) | 46 | await submit.scrollIntoView(false) |
32 | await submit.click() | 47 | await submit.click() |
diff --git a/client/e2e/src/po/video-upload.po.ts b/client/e2e/src/po/video-upload.po.ts index dd437c390..38395ea2f 100644 --- a/client/e2e/src/po/video-upload.po.ts +++ b/client/e2e/src/po/video-upload.po.ts | |||
@@ -1,9 +1,12 @@ | |||
1 | import { join } from 'path' | 1 | import { join } from 'path' |
2 | import { clickOnCheckbox } from '../utils' | 2 | import { getCheckbox, selectCustomSelect } from '../utils' |
3 | 3 | ||
4 | export class VideoUploadPage { | 4 | export class VideoUploadPage { |
5 | async navigateTo () { | 5 | async navigateTo () { |
6 | await $('.header .publish-button').click() | 6 | const publishButton = await $('.header .publish-button') |
7 | |||
8 | await publishButton.waitForClickable() | ||
9 | await publishButton.click() | ||
7 | 10 | ||
8 | await $('.upload-video-container').waitForDisplayed() | 11 | await $('.upload-video-container').waitForDisplayed() |
9 | } | 12 | } |
@@ -24,15 +27,17 @@ export class VideoUploadPage { | |||
24 | 27 | ||
25 | // Wait for the upload to finish | 28 | // Wait for the upload to finish |
26 | await browser.waitUntil(async () => { | 29 | await browser.waitUntil(async () => { |
27 | const actionButton = this.getSecondStepSubmitButton().$('.action-button') | 30 | const warning = await $('=Publish will be available when upload is finished').isDisplayed() |
31 | const progress = await $('.progress-bar=100%').isDisplayed() | ||
28 | 32 | ||
29 | const klass = await actionButton.getAttribute('class') | 33 | return !warning && progress |
30 | return !klass.includes('disabled') | ||
31 | }) | 34 | }) |
32 | } | 35 | } |
33 | 36 | ||
34 | setAsNSFW () { | 37 | async setAsNSFW () { |
35 | return clickOnCheckbox('nsfw') | 38 | const checkbox = await getCheckbox('nsfw') |
39 | |||
40 | return checkbox.click() | ||
36 | } | 41 | } |
37 | 42 | ||
38 | async validSecondUploadStep (videoName: string) { | 43 | async validSecondUploadStep (videoName: string) { |
@@ -47,6 +52,14 @@ export class VideoUploadPage { | |||
47 | }) | 52 | }) |
48 | } | 53 | } |
49 | 54 | ||
55 | setAsPublic () { | ||
56 | return selectCustomSelect('privacy', 'Public') | ||
57 | } | ||
58 | |||
59 | setAsPrivate () { | ||
60 | return selectCustomSelect('privacy', 'Private') | ||
61 | } | ||
62 | |||
50 | private getSecondStepSubmitButton () { | 63 | private getSecondStepSubmitButton () { |
51 | return $('.submit-container my-button') | 64 | return $('.submit-container my-button') |
52 | } | 65 | } |
diff --git a/client/e2e/src/po/video-watch.po.ts b/client/e2e/src/po/video-watch.po.ts index 41425f4d7..cecda3a8b 100644 --- a/client/e2e/src/po/video-watch.po.ts +++ b/client/e2e/src/po/video-watch.po.ts | |||
@@ -21,12 +21,41 @@ export class VideoWatchPage { | |||
21 | return this.getVideoNameElement().then(e => e.getText()) | 21 | return this.getVideoNameElement().then(e => e.getText()) |
22 | } | 22 | } |
23 | 23 | ||
24 | getPrivacy () { | ||
25 | return $('.attribute-privacy .attribute-value').getText() | ||
26 | } | ||
27 | |||
28 | getLicence () { | ||
29 | return $('.attribute-licence .attribute-value').getText() | ||
30 | } | ||
31 | |||
32 | async isDownloadEnabled () { | ||
33 | await this.clickOnMoreDropdownIcon() | ||
34 | |||
35 | return $('.dropdown-item .icon-download').isExisting() | ||
36 | } | ||
37 | |||
38 | areCommentsEnabled () { | ||
39 | return $('my-video-comment-add').isExisting() | ||
40 | } | ||
41 | |||
42 | isPrivacyWarningDisplayed () { | ||
43 | return $('my-privacy-concerns').isDisplayed() | ||
44 | } | ||
45 | |||
24 | async goOnAssociatedEmbed () { | 46 | async goOnAssociatedEmbed () { |
25 | let url = await browser.getUrl() | 47 | let url = await browser.getUrl() |
26 | url = url.replace('/w/', '/videos/embed/') | 48 | url = url.replace('/w/', '/videos/embed/') |
27 | url = url.replace(':3333', ':9001') | 49 | url = url.replace(':3333', ':9001') |
28 | 50 | ||
29 | return go(url) | 51 | await go(url) |
52 | await $('.vjs-big-play-button').waitForDisplayed() | ||
53 | } | ||
54 | |||
55 | async isEmbedWarningDisplayed () { | ||
56 | const text = await $('.vjs-dock-description').getText() | ||
57 | |||
58 | return !!text.trim() | ||
30 | } | 59 | } |
31 | 60 | ||
32 | goOnP2PMediaLoaderEmbed () { | 61 | goOnP2PMediaLoaderEmbed () { |
@@ -38,10 +67,8 @@ export class VideoWatchPage { | |||
38 | } | 67 | } |
39 | 68 | ||
40 | async clickOnUpdate () { | 69 | async clickOnUpdate () { |
41 | const dropdown = $('my-video-actions-dropdown .action-button') | 70 | await this.clickOnMoreDropdownIcon() |
42 | await dropdown.click() | ||
43 | 71 | ||
44 | await $('.dropdown-menu.show .dropdown-item').waitForDisplayed() | ||
45 | const items = await $$('.dropdown-menu.show .dropdown-item') | 72 | const items = await $$('.dropdown-menu.show .dropdown-item') |
46 | 73 | ||
47 | for (const item of items) { | 74 | for (const item of items) { |
@@ -86,6 +113,13 @@ export class VideoWatchPage { | |||
86 | }, { timeout: maxTime }) | 113 | }, { timeout: maxTime }) |
87 | } | 114 | } |
88 | 115 | ||
116 | async clickOnMoreDropdownIcon () { | ||
117 | const dropdown = $('my-video-actions-dropdown .action-button') | ||
118 | await dropdown.click() | ||
119 | |||
120 | await $('.dropdown-menu.show .dropdown-item').waitForDisplayed() | ||
121 | } | ||
122 | |||
89 | private async getVideoNameElement () { | 123 | private async getVideoNameElement () { |
90 | // We have 2 video info name block, pick the first that is not empty | 124 | // We have 2 video info name block, pick the first that is not empty |
91 | const elem = async () => { | 125 | const elem = async () => { |
diff --git a/client/e2e/src/suites-all/videos.e2e-spec.ts b/client/e2e/src/suites-all/videos.e2e-spec.ts index 3b8305a25..b3a87c8e2 100644 --- a/client/e2e/src/suites-all/videos.e2e-spec.ts +++ b/client/e2e/src/suites-all/videos.e2e-spec.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { LoginPage } from '../po/login.po' | 1 | import { LoginPage } from '../po/login.po' |
2 | import { MyAccountPage } from '../po/my-account' | 2 | import { MyAccountPage } from '../po/my-account.po' |
3 | import { PlayerPage } from '../po/player.po' | 3 | import { PlayerPage } from '../po/player.po' |
4 | import { VideoListPage } from '../po/video-list.po' | 4 | import { VideoListPage } from '../po/video-list.po' |
5 | import { VideoUpdatePage } from '../po/video-update.po' | 5 | import { VideoUpdatePage } from '../po/video-update.po' |
diff --git a/client/e2e/src/suites-local/custom-server-defaults.e2e-spec.ts b/client/e2e/src/suites-local/custom-server-defaults.e2e-spec.ts new file mode 100644 index 000000000..e060d382f --- /dev/null +++ b/client/e2e/src/suites-local/custom-server-defaults.e2e-spec.ts | |||
@@ -0,0 +1,86 @@ | |||
1 | import { LoginPage } from '../po/login.po' | ||
2 | import { VideoUploadPage } from '../po/video-upload.po' | ||
3 | import { VideoWatchPage } from '../po/video-watch.po' | ||
4 | import { go, isMobileDevice, isSafari, waitServerUp } from '../utils' | ||
5 | |||
6 | describe('Custom server defaults', () => { | ||
7 | let videoUploadPage: VideoUploadPage | ||
8 | let loginPage: LoginPage | ||
9 | let videoWatchPage: VideoWatchPage | ||
10 | |||
11 | before(async () => { | ||
12 | await waitServerUp() | ||
13 | |||
14 | loginPage = new LoginPage() | ||
15 | videoUploadPage = new VideoUploadPage() | ||
16 | videoWatchPage = new VideoWatchPage(isMobileDevice(), isSafari()) | ||
17 | |||
18 | await browser.maximizeWindow() | ||
19 | }) | ||
20 | |||
21 | describe('Publish default values', function () { | ||
22 | before(async function () { | ||
23 | await loginPage.loginAsRootUser() | ||
24 | }) | ||
25 | |||
26 | it('Should upload a video with custom default values', async function () { | ||
27 | await videoUploadPage.navigateTo() | ||
28 | await videoUploadPage.uploadVideo() | ||
29 | await videoUploadPage.validSecondUploadStep('video') | ||
30 | |||
31 | await videoWatchPage.waitWatchVideoName('video') | ||
32 | |||
33 | expect(await videoWatchPage.getPrivacy()).toBe('Internal') | ||
34 | expect(await videoWatchPage.getLicence()).toBe('Attribution - Non Commercial') | ||
35 | expect(await videoWatchPage.isDownloadEnabled()).toBeFalsy() | ||
36 | expect(await videoWatchPage.areCommentsEnabled()).toBeFalsy() | ||
37 | }) | ||
38 | |||
39 | after(async function () { | ||
40 | await loginPage.logout() | ||
41 | }) | ||
42 | }) | ||
43 | |||
44 | describe('P2P', function () { | ||
45 | let videoUrl: string | ||
46 | |||
47 | async function goOnVideoWatchPage () { | ||
48 | await go(videoUrl) | ||
49 | await videoWatchPage.waitWatchVideoName('video') | ||
50 | } | ||
51 | |||
52 | async function checkP2P (enabled: boolean) { | ||
53 | await goOnVideoWatchPage() | ||
54 | expect(await videoWatchPage.isPrivacyWarningDisplayed()).toEqual(enabled) | ||
55 | |||
56 | await videoWatchPage.goOnAssociatedEmbed() | ||
57 | expect(await videoWatchPage.isEmbedWarningDisplayed()).toEqual(enabled) | ||
58 | } | ||
59 | |||
60 | before(async () => { | ||
61 | await loginPage.loginAsRootUser() | ||
62 | await videoUploadPage.navigateTo() | ||
63 | await videoUploadPage.uploadVideo() | ||
64 | await videoUploadPage.setAsPublic() | ||
65 | await videoUploadPage.validSecondUploadStep('video') | ||
66 | |||
67 | await videoWatchPage.waitWatchVideoName('video') | ||
68 | |||
69 | videoUrl = await browser.getUrl() | ||
70 | }) | ||
71 | |||
72 | beforeEach(async function () { | ||
73 | await goOnVideoWatchPage() | ||
74 | }) | ||
75 | |||
76 | it('Should have P2P disabled for a logged in user', async function () { | ||
77 | await checkP2P(false) | ||
78 | }) | ||
79 | |||
80 | it('Should have P2P disabled for anonymous users', async function () { | ||
81 | await loginPage.logout() | ||
82 | |||
83 | await checkP2P(false) | ||
84 | }) | ||
85 | }) | ||
86 | }) | ||
diff --git a/client/e2e/src/suites-local/plugins.e2e-spec.ts b/client/e2e/src/suites-local/plugins.e2e-spec.ts new file mode 100644 index 000000000..411f1d217 --- /dev/null +++ b/client/e2e/src/suites-local/plugins.e2e-spec.ts | |||
@@ -0,0 +1,78 @@ | |||
1 | import { AdminPluginPage } from '../po/admin-plugin.po' | ||
2 | import { LoginPage } from '../po/login.po' | ||
3 | import { VideoUploadPage } from '../po/video-upload.po' | ||
4 | import { getCheckbox, waitServerUp } from '../utils' | ||
5 | |||
6 | describe('Plugins', () => { | ||
7 | let videoUploadPage: VideoUploadPage | ||
8 | let loginPage: LoginPage | ||
9 | let adminPluginPage: AdminPluginPage | ||
10 | |||
11 | function getPluginCheckbox () { | ||
12 | return getCheckbox('hello-world-field-4') | ||
13 | } | ||
14 | |||
15 | async function expectSubmitState ({ disabled }: { disabled: boolean }) { | ||
16 | const disabledSubmit = await $('my-button .disabled') | ||
17 | |||
18 | if (disabled) expect(await disabledSubmit.isDisplayed()).toBeTruthy() | ||
19 | else expect(await disabledSubmit.isDisplayed()).toBeFalsy() | ||
20 | } | ||
21 | |||
22 | before(async () => { | ||
23 | await waitServerUp() | ||
24 | }) | ||
25 | |||
26 | beforeEach(async () => { | ||
27 | loginPage = new LoginPage() | ||
28 | videoUploadPage = new VideoUploadPage() | ||
29 | adminPluginPage = new AdminPluginPage() | ||
30 | |||
31 | await browser.maximizeWindow() | ||
32 | }) | ||
33 | |||
34 | it('Should install hello world plugin', async () => { | ||
35 | await loginPage.loginAsRootUser() | ||
36 | |||
37 | await adminPluginPage.navigateToSearch() | ||
38 | await adminPluginPage.search('hello-world') | ||
39 | await adminPluginPage.installHelloWorld() | ||
40 | await browser.refresh() | ||
41 | }) | ||
42 | |||
43 | it('Should have checkbox in video edit page', async () => { | ||
44 | await videoUploadPage.navigateTo() | ||
45 | await videoUploadPage.uploadVideo() | ||
46 | |||
47 | await $('span=Super field 4 in main tab').waitForDisplayed() | ||
48 | |||
49 | const checkbox = await getPluginCheckbox() | ||
50 | expect(await checkbox.isDisplayed()).toBeTruthy() | ||
51 | |||
52 | await expectSubmitState({ disabled: true }) | ||
53 | }) | ||
54 | |||
55 | it('Should check the checkbox and be able to submit the video', async function () { | ||
56 | const checkbox = await getPluginCheckbox() | ||
57 | await checkbox.click() | ||
58 | |||
59 | await expectSubmitState({ disabled: false }) | ||
60 | }) | ||
61 | |||
62 | it('Should uncheck the checkbox and not be able to submit the video', async function () { | ||
63 | const checkbox = await getPluginCheckbox() | ||
64 | await checkbox.click() | ||
65 | |||
66 | await expectSubmitState({ disabled: true }) | ||
67 | |||
68 | const error = await $('.form-error*=Should be enabled') | ||
69 | |||
70 | expect(await error.isDisplayed()).toBeTruthy() | ||
71 | }) | ||
72 | |||
73 | it('Should change the privacy and should hide the checkbox', async function () { | ||
74 | await videoUploadPage.setAsPrivate() | ||
75 | |||
76 | await expectSubmitState({ disabled: false }) | ||
77 | }) | ||
78 | }) | ||
diff --git a/client/e2e/src/suites-local/user-settings.e2e-spec.ts b/client/e2e/src/suites-local/user-settings.e2e-spec.ts new file mode 100644 index 000000000..b87501cd1 --- /dev/null +++ b/client/e2e/src/suites-local/user-settings.e2e-spec.ts | |||
@@ -0,0 +1,82 @@ | |||
1 | import { AnonymousSettingsPage } from '../po/anonymous-settings.po' | ||
2 | import { LoginPage } from '../po/login.po' | ||
3 | import { MyAccountPage } from '../po/my-account.po' | ||
4 | import { VideoUploadPage } from '../po/video-upload.po' | ||
5 | import { VideoWatchPage } from '../po/video-watch.po' | ||
6 | import { go, isMobileDevice, isSafari, waitServerUp } from '../utils' | ||
7 | |||
8 | describe('User settings', () => { | ||
9 | let videoUploadPage: VideoUploadPage | ||
10 | let loginPage: LoginPage | ||
11 | let videoWatchPage: VideoWatchPage | ||
12 | let myAccountPage: MyAccountPage | ||
13 | let anonymousSettingsPage: AnonymousSettingsPage | ||
14 | |||
15 | before(async () => { | ||
16 | await waitServerUp() | ||
17 | |||
18 | loginPage = new LoginPage() | ||
19 | videoUploadPage = new VideoUploadPage() | ||
20 | videoWatchPage = new VideoWatchPage(isMobileDevice(), isSafari()) | ||
21 | myAccountPage = new MyAccountPage() | ||
22 | anonymousSettingsPage = new AnonymousSettingsPage() | ||
23 | |||
24 | await browser.maximizeWindow() | ||
25 | }) | ||
26 | |||
27 | describe('P2P', function () { | ||
28 | let videoUrl: string | ||
29 | |||
30 | async function goOnVideoWatchPage () { | ||
31 | await go(videoUrl) | ||
32 | await videoWatchPage.waitWatchVideoName('video') | ||
33 | } | ||
34 | |||
35 | async function checkP2P (enabled: boolean) { | ||
36 | await goOnVideoWatchPage() | ||
37 | expect(await videoWatchPage.isPrivacyWarningDisplayed()).toEqual(enabled) | ||
38 | |||
39 | await videoWatchPage.goOnAssociatedEmbed() | ||
40 | expect(await videoWatchPage.isEmbedWarningDisplayed()).toEqual(enabled) | ||
41 | } | ||
42 | |||
43 | before(async () => { | ||
44 | await loginPage.loginAsRootUser() | ||
45 | await videoUploadPage.navigateTo() | ||
46 | await videoUploadPage.uploadVideo() | ||
47 | await videoUploadPage.validSecondUploadStep('video') | ||
48 | |||
49 | await videoWatchPage.waitWatchVideoName('video') | ||
50 | |||
51 | videoUrl = await browser.getUrl() | ||
52 | }) | ||
53 | |||
54 | beforeEach(async function () { | ||
55 | await goOnVideoWatchPage() | ||
56 | }) | ||
57 | |||
58 | it('Should have P2P enabled for a logged in user', async function () { | ||
59 | await checkP2P(true) | ||
60 | }) | ||
61 | |||
62 | it('Should disable P2P for a logged in user', async function () { | ||
63 | await myAccountPage.navigateToMySettings() | ||
64 | await myAccountPage.clickOnP2PCheckbox() | ||
65 | |||
66 | await checkP2P(false) | ||
67 | }) | ||
68 | |||
69 | it('Should have P2P enabled for anonymous users', async function () { | ||
70 | await loginPage.logout() | ||
71 | |||
72 | await checkP2P(true) | ||
73 | }) | ||
74 | |||
75 | it('Should disable P2P for an anonymous user', async function () { | ||
76 | await anonymousSettingsPage.openSettings() | ||
77 | await anonymousSettingsPage.clickOnP2PCheckbox() | ||
78 | |||
79 | await checkP2P(false) | ||
80 | }) | ||
81 | }) | ||
82 | }) | ||
diff --git a/client/e2e/src/suites-local/videos-list.e2e-spec.ts b/client/e2e/src/suites-local/videos-list.e2e-spec.ts index 1e0a88859..ce57261b9 100644 --- a/client/e2e/src/suites-local/videos-list.e2e-spec.ts +++ b/client/e2e/src/suites-local/videos-list.e2e-spec.ts | |||
@@ -1,9 +1,10 @@ | |||
1 | import { AdminConfigPage } from '../po/admin-config.po' | 1 | import { AdminConfigPage } from '../po/admin-config.po' |
2 | import { LoginPage } from '../po/login.po' | 2 | import { LoginPage } from '../po/login.po' |
3 | import { MyAccountPage } from '../po/my-account' | 3 | import { MyAccountPage } from '../po/my-account.po' |
4 | import { VideoListPage } from '../po/video-list.po' | 4 | import { VideoListPage } from '../po/video-list.po' |
5 | import { VideoSearchPage } from '../po/video-search.po' | 5 | import { VideoSearchPage } from '../po/video-search.po' |
6 | import { VideoUploadPage } from '../po/video-upload.po' | 6 | import { VideoUploadPage } from '../po/video-upload.po' |
7 | import { VideoWatchPage } from '../po/video-watch.po' | ||
7 | import { NSFWPolicy } from '../types/common' | 8 | import { NSFWPolicy } from '../types/common' |
8 | import { isMobileDevice, isSafari, waitServerUp } from '../utils' | 9 | import { isMobileDevice, isSafari, waitServerUp } from '../utils' |
9 | 10 | ||
@@ -14,6 +15,7 @@ describe('Videos list', () => { | |||
14 | let loginPage: LoginPage | 15 | let loginPage: LoginPage |
15 | let myAccountPage: MyAccountPage | 16 | let myAccountPage: MyAccountPage |
16 | let videoSearchPage: VideoSearchPage | 17 | let videoSearchPage: VideoSearchPage |
18 | let videoWatchPage: VideoWatchPage | ||
17 | 19 | ||
18 | const seed = Math.random() | 20 | const seed = Math.random() |
19 | const nsfwVideo = seed + ' - nsfw' | 21 | const nsfwVideo = seed + ' - nsfw' |
@@ -108,6 +110,7 @@ describe('Videos list', () => { | |||
108 | videoUploadPage = new VideoUploadPage() | 110 | videoUploadPage = new VideoUploadPage() |
109 | myAccountPage = new MyAccountPage() | 111 | myAccountPage = new MyAccountPage() |
110 | videoSearchPage = new VideoSearchPage() | 112 | videoSearchPage = new VideoSearchPage() |
113 | videoWatchPage = new VideoWatchPage(isMobileDevice(), isSafari()) | ||
111 | 114 | ||
112 | await browser.maximizeWindow() | 115 | await browser.maximizeWindow() |
113 | }) | 116 | }) |
@@ -191,5 +194,26 @@ describe('Videos list', () => { | |||
191 | await checkCommonVideoListPages('display') | 194 | await checkCommonVideoListPages('display') |
192 | await checkSearchPage('display') | 195 | await checkSearchPage('display') |
193 | }) | 196 | }) |
197 | |||
198 | after(async () => { | ||
199 | await loginPage.logout() | ||
200 | }) | ||
201 | }) | ||
202 | |||
203 | describe('Default upload values', function () { | ||
204 | |||
205 | it('Should have default video values', async function () { | ||
206 | await loginPage.loginAsRootUser() | ||
207 | await videoUploadPage.navigateTo() | ||
208 | await videoUploadPage.uploadVideo() | ||
209 | await videoUploadPage.validSecondUploadStep('video') | ||
210 | |||
211 | await videoWatchPage.waitWatchVideoName('video') | ||
212 | |||
213 | expect(await videoWatchPage.getPrivacy()).toBe('Public') | ||
214 | expect(await videoWatchPage.getLicence()).toBe('Unknown') | ||
215 | expect(await videoWatchPage.isDownloadEnabled()).toBeTruthy() | ||
216 | expect(await videoWatchPage.areCommentsEnabled()).toBeTruthy() | ||
217 | }) | ||
194 | }) | 218 | }) |
195 | }) | 219 | }) |
diff --git a/client/e2e/src/utils/elements.ts b/client/e2e/src/utils/elements.ts index cadc46cce..3ffa5defd 100644 --- a/client/e2e/src/utils/elements.ts +++ b/client/e2e/src/utils/elements.ts | |||
@@ -1,7 +1,22 @@ | |||
1 | function clickOnCheckbox (name: string) { | 1 | function getCheckbox (name: string) { |
2 | return $(`my-peertube-checkbox[inputname=${name}] label`).click() | 2 | return $(`my-peertube-checkbox input[id=${name}]`).parentElement() |
3 | } | ||
4 | |||
5 | async function selectCustomSelect (id: string, valueLabel: string) { | ||
6 | await $(`[formcontrolname=${id}] .ng-arrow-wrapper`).click() | ||
7 | |||
8 | const option = await $$(`[formcontrolname=${id}] .ng-option`).filter(async o => { | ||
9 | const text = await o.getText() | ||
10 | |||
11 | return text.trimStart().startsWith(valueLabel) | ||
12 | }).then(options => options[0]) | ||
13 | |||
14 | await option.waitForDisplayed() | ||
15 | |||
16 | return option.click() | ||
3 | } | 17 | } |
4 | 18 | ||
5 | export { | 19 | export { |
6 | clickOnCheckbox | 20 | getCheckbox, |
21 | selectCustomSelect | ||
7 | } | 22 | } |
diff --git a/client/e2e/src/utils/hooks.ts b/client/e2e/src/utils/hooks.ts new file mode 100644 index 000000000..e139d8183 --- /dev/null +++ b/client/e2e/src/utils/hooks.ts | |||
@@ -0,0 +1,72 @@ | |||
1 | import { ChildProcessWithoutNullStreams } from 'child_process' | ||
2 | import { basename } from 'path' | ||
3 | import { runCommand, runServer } from './server' | ||
4 | |||
5 | let appInstance: string | ||
6 | let app: ChildProcessWithoutNullStreams | ||
7 | |||
8 | async function beforeLocalSuite (suite: any) { | ||
9 | const config = buildConfig(suite.file) | ||
10 | |||
11 | await runCommand('npm run clean:server:test -- ' + appInstance) | ||
12 | app = runServer(appInstance, config) | ||
13 | } | ||
14 | |||
15 | function afterLocalSuite () { | ||
16 | app.kill() | ||
17 | app = undefined | ||
18 | } | ||
19 | |||
20 | function beforeLocalSession (config: { baseUrl: string }, capabilities: { browserName: string }) { | ||
21 | appInstance = capabilities['browserName'] === 'chrome' ? '1' : '2' | ||
22 | config.baseUrl = 'http://localhost:900' + appInstance | ||
23 | } | ||
24 | |||
25 | async function onBrowserStackPrepare () { | ||
26 | const appInstance = '1' | ||
27 | |||
28 | await runCommand('npm run clean:server:test -- ' + appInstance) | ||
29 | app = runServer(appInstance) | ||
30 | } | ||
31 | |||
32 | function onBrowserStackComplete () { | ||
33 | app.kill() | ||
34 | app = undefined | ||
35 | } | ||
36 | |||
37 | export { | ||
38 | beforeLocalSession, | ||
39 | afterLocalSuite, | ||
40 | beforeLocalSuite, | ||
41 | onBrowserStackPrepare, | ||
42 | onBrowserStackComplete | ||
43 | } | ||
44 | |||
45 | // --------------------------------------------------------------------------- | ||
46 | |||
47 | function buildConfig (suiteFile: string = undefined) { | ||
48 | const filename = basename(suiteFile) | ||
49 | |||
50 | if (filename === 'custom-server-defaults.e2e-spec.ts') { | ||
51 | return { | ||
52 | defaults: { | ||
53 | publish: { | ||
54 | download_enabled: false, | ||
55 | comments_enabled: false, | ||
56 | privacy: 4, | ||
57 | licence: 4 | ||
58 | }, | ||
59 | p2p: { | ||
60 | webapp: { | ||
61 | enabled: false | ||
62 | }, | ||
63 | embed: { | ||
64 | enabled: false | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | return {} | ||
72 | } | ||
diff --git a/client/e2e/src/utils/index.ts b/client/e2e/src/utils/index.ts index 5da1ad517..354352ee2 100644 --- a/client/e2e/src/utils/index.ts +++ b/client/e2e/src/utils/index.ts | |||
@@ -1,3 +1,5 @@ | |||
1 | export * from './common' | 1 | export * from './common' |
2 | export * from './elements' | 2 | export * from './elements' |
3 | export * from './hooks' | ||
4 | export * from './server' | ||
3 | export * from './urls' | 5 | export * from './urls' |
diff --git a/client/e2e/src/utils/server.ts b/client/e2e/src/utils/server.ts new file mode 100644 index 000000000..7089a5c9c --- /dev/null +++ b/client/e2e/src/utils/server.ts | |||
@@ -0,0 +1,63 @@ | |||
1 | import { exec, spawn } from 'child_process' | ||
2 | import { join, resolve } from 'path' | ||
3 | |||
4 | function runServer (appInstance: string, config: any = {}) { | ||
5 | const env = Object.create(process.env) | ||
6 | env['NODE_ENV'] = 'test' | ||
7 | env['NODE_APP_INSTANCE'] = appInstance | ||
8 | |||
9 | env['NODE_CONFIG'] = JSON.stringify({ | ||
10 | rates_limit: { | ||
11 | api: { | ||
12 | max: 5000 | ||
13 | }, | ||
14 | login: { | ||
15 | max: 5000 | ||
16 | } | ||
17 | }, | ||
18 | log: { | ||
19 | level: 'warn' | ||
20 | }, | ||
21 | signup: { | ||
22 | enabled: false | ||
23 | }, | ||
24 | transcoding: { | ||
25 | enabled: false | ||
26 | }, | ||
27 | |||
28 | ...config | ||
29 | }) | ||
30 | |||
31 | const forkOptions = { | ||
32 | env, | ||
33 | cwd: getRootCWD(), | ||
34 | detached: false | ||
35 | } | ||
36 | |||
37 | const p = spawn('node', [ join('dist', 'server.js') ], forkOptions) | ||
38 | p.stderr.on('data', data => console.error(data.toString())) | ||
39 | p.stdout.on('data', data => console.error(data.toString())) | ||
40 | |||
41 | return p | ||
42 | } | ||
43 | |||
44 | function runCommand (command: string) { | ||
45 | return new Promise<void>((res, rej) => { | ||
46 | const p = exec(command, { cwd: getRootCWD() }) | ||
47 | |||
48 | p.stderr.on('data', data => console.error(data.toString())) | ||
49 | p.on('error', err => rej(err)) | ||
50 | p.on('exit', () => res()) | ||
51 | }) | ||
52 | } | ||
53 | |||
54 | export { | ||
55 | runServer, | ||
56 | runCommand | ||
57 | } | ||
58 | |||
59 | // --------------------------------------------------------------------------- | ||
60 | |||
61 | function getRootCWD () { | ||
62 | return resolve('../..') | ||
63 | } | ||
diff --git a/client/e2e/wdio.browserstack.conf.ts b/client/e2e/wdio.browserstack.conf.ts index 43614a862..b89cdbc2e 100644 --- a/client/e2e/wdio.browserstack.conf.ts +++ b/client/e2e/wdio.browserstack.conf.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { onBrowserStackComplete, onBrowserStackPrepare } from './src/utils' | ||
1 | import { config as mainConfig } from './wdio.main.conf' | 2 | import { config as mainConfig } from './wdio.main.conf' |
2 | 3 | ||
3 | const user = process.env.BROWSERSTACK_USER | 4 | const user = process.env.BROWSERSTACK_USER |
@@ -114,6 +115,10 @@ module.exports = { | |||
114 | if (capabilities['bstack:options'].realMobile === true) { | 115 | if (capabilities['bstack:options'].realMobile === true) { |
115 | capabilities['bstack:options'].local = false | 116 | capabilities['bstack:options'].local = false |
116 | } | 117 | } |
117 | } | 118 | }, |
119 | |||
120 | onPrepare: onBrowserStackPrepare, | ||
121 | onComplete: onBrowserStackComplete | ||
122 | |||
118 | } as WebdriverIO.Config | 123 | } as WebdriverIO.Config |
119 | } | 124 | } |
diff --git a/client/e2e/wdio.local-test.conf.ts b/client/e2e/wdio.local-test.conf.ts index 32e6d340c..5389ebcf0 100644 --- a/client/e2e/wdio.local-test.conf.ts +++ b/client/e2e/wdio.local-test.conf.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { afterLocalSuite, beforeLocalSuite, beforeLocalSession } from './src/utils' | ||
1 | import { config as mainConfig } from './wdio.main.conf' | 2 | import { config as mainConfig } from './wdio.main.conf' |
2 | 3 | ||
3 | const prefs = { | 4 | const prefs = { |
@@ -21,12 +22,16 @@ module.exports = { | |||
21 | browserName: 'chrome', | 22 | browserName: 'chrome', |
22 | acceptInsecureCerts: true, | 23 | acceptInsecureCerts: true, |
23 | 'goog:chromeOptions': { | 24 | 'goog:chromeOptions': { |
24 | args: [ '--headless', '--disable-gpu', '--window-size=1280,1024' ], | 25 | args: [ '--disable-gpu', '--window-size=1280,1024' ], |
25 | prefs | 26 | prefs |
26 | } | 27 | } |
27 | } | 28 | } |
28 | ], | 29 | ], |
29 | 30 | ||
30 | services: [ 'chromedriver' ] | 31 | services: [ 'chromedriver' ], |
32 | |||
33 | beforeSession: beforeLocalSession, | ||
34 | beforeSuite: beforeLocalSuite, | ||
35 | afterSuite: afterLocalSuite | ||
31 | } as WebdriverIO.Config | 36 | } as WebdriverIO.Config |
32 | } | 37 | } |
diff --git a/client/e2e/wdio.local.conf.ts b/client/e2e/wdio.local.conf.ts index 43b820ca6..d02679e06 100644 --- a/client/e2e/wdio.local.conf.ts +++ b/client/e2e/wdio.local.conf.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { afterLocalSuite, beforeLocalSession, beforeLocalSuite } from './src/utils' | ||
1 | import { config as mainConfig } from './wdio.main.conf' | 2 | import { config as mainConfig } from './wdio.main.conf' |
2 | 3 | ||
3 | const prefs = { | 4 | const prefs = { |
@@ -11,7 +12,7 @@ module.exports = { | |||
11 | 12 | ||
12 | runner: 'local', | 13 | runner: 'local', |
13 | 14 | ||
14 | maxInstances: 2, | 15 | maxInstancesPerCapability: 1, |
15 | 16 | ||
16 | capabilities: [ | 17 | capabilities: [ |
17 | { | 18 | { |
@@ -34,12 +35,8 @@ module.exports = { | |||
34 | 35 | ||
35 | services: [ 'chromedriver', 'geckodriver' ], | 36 | services: [ 'chromedriver', 'geckodriver' ], |
36 | 37 | ||
37 | beforeSession: function (config, capabilities) { | 38 | beforeSession: beforeLocalSession, |
38 | if (capabilities['browserName'] === 'chrome') { | 39 | beforeSuite: beforeLocalSuite, |
39 | config.baseUrl = 'http://localhost:9001' | 40 | afterSuite: afterLocalSuite |
40 | } else { | ||
41 | config.baseUrl = 'http://localhost:9002' | ||
42 | } | ||
43 | } | ||
44 | } as WebdriverIO.Config | 41 | } as WebdriverIO.Config |
45 | } | 42 | } |