From 445cd8d239b2cbcd26c1d588900218d03471fe74 Mon Sep 17 00:00:00 2001 From: Vitalii Date: Tue, 19 Dec 2023 15:55:38 +0200 Subject: [PATCH] testsuite/playwright-ui: make existing tests to pass Updated test files to pass with existing tests. Branded test requires signup config to be copied to local folder. Issue: https://github.com/storj/storj/issues/6598 Change-Id: If1d9617d4cc2a8dd1862f843c792f5b5b219ec2e --- testsuite/playwright-ui/lib/BaseTest.ts | 5 ++ testsuite/playwright-ui/package-lock.json | 27 ++++++- testsuite/playwright-ui/package.json | 9 ++- .../AllProjectsPageObjects.ts | 4 + .../objectRepository/BucketsPageObjects.ts | 18 ++--- .../objectRepository/CommonObjects.ts | 7 ++ .../objectRepository/LoginPageObjects.ts | 1 - .../objectRepository/SignupPageObjects.ts | 4 +- .../pageRepository/AllProjectsPage.ts | 7 ++ .../pageFactory/pageRepository/BucketsPage.ts | 37 ++------- .../pageFactory/pageRepository/Common.ts | 23 ++++++ .../pageFactory/pageRepository/LoginPage.ts | 8 +- .../pageFactory/pageRepository/SignupPage.ts | 23 +++--- testsuite/playwright-ui/playwright.config.ts | 8 +- testsuite/playwright-ui/scripts/prerun-dev.sh | 4 + .../tests/branded.signup.test.ts | 4 +- testsuite/playwright-ui/tests/bucket.test.ts | 75 ++++++++++++------- testsuite/playwright-ui/tests/login.test.ts | 1 + testsuite/playwright-ui/tsconfig.json | 6 +- .../components/modals/CreateBucketModal.vue | 6 +- 20 files changed, 175 insertions(+), 102 deletions(-) create mode 100644 testsuite/playwright-ui/pageFactory/objectRepository/CommonObjects.ts create mode 100644 testsuite/playwright-ui/pageFactory/pageRepository/Common.ts create mode 100755 testsuite/playwright-ui/scripts/prerun-dev.sh diff --git a/testsuite/playwright-ui/lib/BaseTest.ts b/testsuite/playwright-ui/lib/BaseTest.ts index ee88b5bfd9e8..f93c79b37559 100644 --- a/testsuite/playwright-ui/lib/BaseTest.ts +++ b/testsuite/playwright-ui/lib/BaseTest.ts @@ -8,6 +8,7 @@ import { NavigationMenu } from '@pages/NavigationMenu'; import { BucketsPage } from '@pages/BucketsPage'; import { SignupPage } from '@pages/SignupPage'; import { AllProjectsPage } from '@pages/AllProjectsPage'; +import { Common } from '@pages/Common'; const test = baseTest.extend<{ loginPage: LoginPage; @@ -16,6 +17,7 @@ const test = baseTest.extend<{ bucketsPage: BucketsPage; signupPage: SignupPage; allProjectsPage: AllProjectsPage; + common: Common; }>({ loginPage: async ({ page }, use) => { await use(new LoginPage(page)); @@ -35,6 +37,9 @@ const test = baseTest.extend<{ allProjectsPage: async ({ page }, use) => { await use(new AllProjectsPage(page)); }, + common: async ({ page }, use) => { + await use(new Common(page)); + }, }); export default test; diff --git a/testsuite/playwright-ui/package-lock.json b/testsuite/playwright-ui/package-lock.json index 25f5de845b93..a22636ba8778 100644 --- a/testsuite/playwright-ui/package-lock.json +++ b/testsuite/playwright-ui/package-lock.json @@ -13,13 +13,15 @@ "@slack/socket-mode": "1.3.2", "@slack/types": "2.8.0", "@slack/web-api": "6.8.0", + "@types/uuid": "9.0.7", "@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/parser": "6.14.0", "allure-commandline": "2.23.0", "allure-playwright": "2.4.0", "eslint": "8.56.0", "mocha-multi-reporters": "1.5.1", - "playwright-slack-report": "1.0.19" + "playwright-slack-report": "1.0.19", + "uuid": "9.0.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -278,6 +280,11 @@ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==" }, + "node_modules/@types/uuid": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", + "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==" + }, "node_modules/@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -523,6 +530,14 @@ "uuid": "^8.3.0" } }, + "node_modules/allure-js-commons/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/allure-playwright": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/allure-playwright/-/allure-playwright-2.4.0.tgz", @@ -2229,9 +2244,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } diff --git a/testsuite/playwright-ui/package.json b/testsuite/playwright-ui/package.json index c706bb084d4b..fdf3c2ae101e 100644 --- a/testsuite/playwright-ui/package.json +++ b/testsuite/playwright-ui/package.json @@ -9,9 +9,10 @@ "browser-debug": "DEBUG=pw:browser* npx playwright test", "lint": "eslint . --ext .ts --fix", "posttest": "npm run allure:generate && npm run allure:local", + "prerun-dev": "chmod +x ./scripts/prerun-dev.sh && ./scripts/prerun-dev.sh", "test": "npx playwright test ./tests/", - "test-debug": "DEBUG=pw:browser* npx playwright test ./tests/login.test.ts --trace on", - "test-dev": "npx playwright test ./tests/bucket.test.ts --headed --project=chromium --trace on" + "test-debug": "DEBUG=pw:browser* npx playwright test ./tests/bucket.test.ts --trace on", + "test-dev": "npm run prerun-dev && npx playwright test ./tests/ --headed --project=chromium-hd --trace on" }, "license": "ISC", "dependencies": { @@ -21,10 +22,12 @@ "@slack/web-api": "6.8.0", "@typescript-eslint/parser": "6.14.0", "@typescript-eslint/eslint-plugin": "6.14.0", + "@types/uuid": "9.0.7", "allure-commandline": "2.23.0", "allure-playwright": "2.4.0", "eslint": "8.56.0", "mocha-multi-reporters": "1.5.1", - "playwright-slack-report": "1.0.19" + "playwright-slack-report": "1.0.19", + "uuid": "9.0.1" } } diff --git a/testsuite/playwright-ui/pageFactory/objectRepository/AllProjectsPageObjects.ts b/testsuite/playwright-ui/pageFactory/objectRepository/AllProjectsPageObjects.ts index 5e52ba6b9802..d61092cd870d 100644 --- a/testsuite/playwright-ui/pageFactory/objectRepository/AllProjectsPageObjects.ts +++ b/testsuite/playwright-ui/pageFactory/objectRepository/AllProjectsPageObjects.ts @@ -5,4 +5,8 @@ export class AllProjectsPageObjects { static ALL_PROJECTS_HEADER_TITLE_XPATH = `//span[contains(text(),'My Projects')]`; static OPEN_PROJECT_BUTTON_TEXT = `Open Project`; static PROJECT_ITEM_XPATH = `//*[contains(@class, 'project-item')]`; + static CREATE_PROJECT_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Create a Project')]`; + static CONFIRM_CREATE_PROJECT_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Create Project -->')]`; + static NEW_PROJECT_NAME_FIELD_XPATH = `//input[@id='Project Name']`; + static SKIP_ONBOARDING_LABEL = ` Skip and go directly to dashboard `; } diff --git a/testsuite/playwright-ui/pageFactory/objectRepository/BucketsPageObjects.ts b/testsuite/playwright-ui/pageFactory/objectRepository/BucketsPageObjects.ts index 3e0fda50416a..50523165887b 100644 --- a/testsuite/playwright-ui/pageFactory/objectRepository/BucketsPageObjects.ts +++ b/testsuite/playwright-ui/pageFactory/objectRepository/BucketsPageObjects.ts @@ -4,24 +4,18 @@ export class BucketsPageObjects { static ENCRYPTION_PASSPHRASE_XPATH = `//input[@id='Encryption Passphrase']`; static CONTINUE_BUTTON_PASSPHRASE_MODAL_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Continue ->')]`; - static DOWNLOAD_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Download')]`; - static SHARE_BUTTON_XPATH = `div:nth-child(4) > .button-icon`; - static DOWNLOAD_NOTIFICATION = `//p[contains(text(),'Keep this download link private.If you want to share, use the Share option.')]`; - static OBJECT_MAP_TEXT_XPATH = `//div[contains(text(),'Nodes storing this file')]`; - static OBJECT_MAP_IMAGE_XPATH = `//*[contains(@class, 'object-map')]`; + static OBJECT_PREVIEW_BUTTON_XPATH = `//div[contains(@class, 'button-icon')]`; + static OBJECT_MAP_IMAGE_XPATH = `//*[contains(@class, 'modal__map')]`; static COPY_LINK_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Copy Link')]`; - static COPIED_TEXT = `Copied!`; - static CLOSE_MODAL_BUTTON_XPATH = `.mask__wrapper__container__close`; - static CLOSE_FILE_PREVIEW_BUTTON_XPATH = `//body/div[@id='app']/div[2]/div[1]/div[2]/div[5]/div[1]`; + static COPIED_TEXT = `Link Copied`; static NEW_FOLDER_BUTTON_TEXT = `New Folder`; static NEW_FOLDER_NAME_FIELD_XPATH = `//input[@id='Folder name']`; static CREATE_FOLDER_BUTTON_TEXT = `Create Folder`; static DELETE_BUTTON_XPATH = `//p[contains(text(),'Delete')]`; static YES_BUTTON_XPATH = `//*[contains(@class, 'delete-confirmation__options__item yes')]`; - static VIEW_BUCKET_DETAILS_BUTTON_CSS = `.bucket-settings-nav__dropdown__itprivateem`; + static VIEW_BUCKET_DETAILS_BUTTON_CSS = `.bucket-settings-nav__dropdown__item__label`; static BUCKET_SETTINGS_BUTTON_CSS = `.bucket-settings-nav`; static SHARE_BUCKET_BUTTON_XPATH = '//p[contains(text(),\'Share bucket\')]'; - static COPY_BUTTON_SHARE_BUCKET_MODAL_XPATH = `//span[contains(text(),'Copy')]`; // Create new bucket flow static NEW_BUCKET_BUTTON_XPATH = `//p[contains(text(),'New Bucket')]`; @@ -30,7 +24,7 @@ export class BucketsPageObjects { static ENTER_PASSPHRASE_RADIO_BUTTON_XPATH = `//h4[contains(text(),'Enter passphrase')]`; static PASSPHRASE_INPUT_NEW_BUCKET_XPATH = `//input[@id='Your Passphrase']`; static CHECKMARK_ENTER_PASSPHRASE_XPATH = `//label[contains(text(),'I understand, and I have saved the passphrase.')]`; - static BUCKET_NAME_DELETE_BUCKET_MODAL_XPATH = `//input[@id='Bucket Name']`; - static CONFIRM_DELETE_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Confirm Delete Bucket')]`; + static BUCKET_NAME_DELETE_BUCKET_MODAL_XPATH = `//input[@id='Type the name of the bucket to confirm']`; + static CONFIRM_DELETE_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, 'Delete Bucket')]`; static DELETE_BUCKET_XPATH = `//p[contains(text(),'Delete Bucket')]`; } diff --git a/testsuite/playwright-ui/pageFactory/objectRepository/CommonObjects.ts b/testsuite/playwright-ui/pageFactory/objectRepository/CommonObjects.ts new file mode 100644 index 000000000000..e6ffde50140f --- /dev/null +++ b/testsuite/playwright-ui/pageFactory/objectRepository/CommonObjects.ts @@ -0,0 +1,7 @@ +// Copyright (C) 2023 Storj Labs, Inc. +// See LICENSE for copying information. + +export class CommonObjects { + static CLOSE_MODAL_BUTTON_XPATH = `.mask__wrapper__container__close`; + static LOADER_XPATH = `//div[contains(@class, 'loader')]`; +} diff --git a/testsuite/playwright-ui/pageFactory/objectRepository/LoginPageObjects.ts b/testsuite/playwright-ui/pageFactory/objectRepository/LoginPageObjects.ts index 80b410a42b70..040ac51ba23b 100644 --- a/testsuite/playwright-ui/pageFactory/objectRepository/LoginPageObjects.ts +++ b/testsuite/playwright-ui/pageFactory/objectRepository/LoginPageObjects.ts @@ -4,5 +4,4 @@ export class LoginPageObjects { static EMAIL_EDITBOX_ID = `//input[@id='Email Address']`; static PASSWORD_EDITBOX_ID = `//input[@id='Password']`; - static SIGN_IN_BUTTON_XPATH = `//div[contains(@class, 'container login-area__content-area__container__button') and contains(.//span, 'Sign In')]`; } diff --git a/testsuite/playwright-ui/pageFactory/objectRepository/SignupPageObjects.ts b/testsuite/playwright-ui/pageFactory/objectRepository/SignupPageObjects.ts index 33c875b57b9f..105b5fc61bb6 100644 --- a/testsuite/playwright-ui/pageFactory/objectRepository/SignupPageObjects.ts +++ b/testsuite/playwright-ui/pageFactory/objectRepository/SignupPageObjects.ts @@ -8,17 +8,19 @@ export class SignupPageObjects { static INPUT_PASSWORD_XPATH = `//input[@id='Password']`; static INPUT_RETYPE_PASSWORD_XPATH = `//input[@id='Retype Password']`; static TOS_CHECKMARK_BUTTON_XPATH = `.checkmark-container`; + static CREATE_ACCOUNT_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Get Started')]`; // SIGNUP SUCCESS PAGE static SIGNUP_SUCCESS_MESSAGE_XPATH = `//h2[contains(text(),"You're almost there!")]`; static GOTO_LOGIN_PAGE_BUTTON_XPATH = `//a[contains(text(),'Go to Login page')]`; // IX BRANDED SIGNUP - static CREATE_ACCOUNT_BUTTON_XPATH = `//body/div[@id='app']/div[@id='app']/div[1]/div[1]/div[2]/div[1]/div[10]`; + static IX_BRANDED_CREATE_ACCOUNT_BUTTON_XPATH = `//div[contains(@class, 'container') and contains(.//span, ' Create an iX-Storj Account')]`; static IX_BRANDED_HEADER_TEXT_XPATH = `//h1[contains(text(),'Globally Distributed Storage for TrueNAS')]`; static IX_BRANDED_SUBHEADER_TEXT_XPATH = `//p[contains(text(),'iX and Storj have partnered to offer a secure, hig')]`; // BUSINESS TAB + static IX_BRANDED_PERSONAL_BUTTON_XPATH = `//li[contains(text(),'Personal')]`; static IX_BRANDED_BUSINESS_BUTTON_XPATH = `//li[contains(text(),'Business')]`; static COMPANY_NAME_INPUT_XPATH = `//input[@id='Company Name']`; static POSITION_INPUT_XPATH = `//input[@id='Position']`; diff --git a/testsuite/playwright-ui/pageFactory/pageRepository/AllProjectsPage.ts b/testsuite/playwright-ui/pageFactory/pageRepository/AllProjectsPage.ts index 039a6d383cfd..82e1edcbd245 100644 --- a/testsuite/playwright-ui/pageFactory/pageRepository/AllProjectsPage.ts +++ b/testsuite/playwright-ui/pageFactory/pageRepository/AllProjectsPage.ts @@ -7,6 +7,13 @@ import type { Page } from '@playwright/test'; export class AllProjectsPage { constructor(readonly page: Page) {} + async createProject(name: string): Promise { + await this.page.locator(AllProjectsPageObjects.CREATE_PROJECT_BUTTON_XPATH).first().click(); + await this.page.locator(AllProjectsPageObjects.NEW_PROJECT_NAME_FIELD_XPATH).fill(name); + await this.page.locator(AllProjectsPageObjects.CONFIRM_CREATE_PROJECT_BUTTON_XPATH).click(); + await this.page.getByText(AllProjectsPageObjects.SKIP_ONBOARDING_LABEL).click(); + } + async clickOnProject(name: string): Promise { await this.page.locator(AllProjectsPageObjects.ALL_PROJECTS_HEADER_TITLE_XPATH).isVisible(); const listItem = this.page.locator(AllProjectsPageObjects.PROJECT_ITEM_XPATH, { hasText: name }); diff --git a/testsuite/playwright-ui/pageFactory/pageRepository/BucketsPage.ts b/testsuite/playwright-ui/pageFactory/pageRepository/BucketsPage.ts index b9608b90fe6c..95ecadb05cc5 100644 --- a/testsuite/playwright-ui/pageFactory/pageRepository/BucketsPage.ts +++ b/testsuite/playwright-ui/pageFactory/pageRepository/BucketsPage.ts @@ -24,20 +24,18 @@ export class BucketsPage { await this.page.locator(BucketsPageObjects.CONTINUE_BUTTON_PASSPHRASE_MODAL_XPATH).click(); } - async downloadFileByName(name: string): Promise { - const uiTestFile = this.page.getByText(name); + async downloadFromPreview(name: string): Promise { + const uiTestFile = this.page.getByText(name, { exact: true }).nth(1); await expect(uiTestFile).toBeVisible(); - await uiTestFile.click(); await Promise.all([ this.page.waitForEvent('download'), - this.page.locator(BucketsPageObjects.DOWNLOAD_BUTTON_XPATH).click(), + this.page.locator(BucketsPageObjects.OBJECT_PREVIEW_BUTTON_XPATH).nth(2).click(), ]); await expect(this.page.getByText('Keep this download link private.If you want to share, use the Share option.')).toBeVisible(); - } async clickShareButton(): Promise { - await this.page.locator(BucketsPageObjects.SHARE_BUTTON_XPATH).click(); + await this.page.locator(BucketsPageObjects.OBJECT_PREVIEW_BUTTON_XPATH).nth(3).click(); } async clickCopyLinkButton(): Promise { @@ -52,7 +50,7 @@ export class BucketsPage { } async verifyObjectMapIsVisible(): Promise { - await this.page.locator(BucketsPageObjects.OBJECT_MAP_TEXT_XPATH).isVisible(); + await this.page.locator(BucketsPageObjects.OBJECT_PREVIEW_BUTTON_XPATH).nth(1).click(); await this.page.locator(BucketsPageObjects.OBJECT_MAP_IMAGE_XPATH).isVisible(); } @@ -60,12 +58,8 @@ export class BucketsPage { await this.page.getByRole('img', { name: 'preview' }).isVisible(); } - async closeModal(): Promise { - await this.page.locator(BucketsPageObjects.CLOSE_MODAL_BUTTON_XPATH).click(); - } - async closeFilePreview(): Promise { - await this.page.locator(BucketsPageObjects.CLOSE_FILE_PREVIEW_BUTTON_XPATH).click(); + await this.page.locator(BucketsPageObjects.OBJECT_PREVIEW_BUTTON_XPATH).nth(4).click(); } async openFileDropdownByName(name: string): Promise { @@ -88,11 +82,6 @@ export class BucketsPage { await this.page.getByText(BucketsPageObjects.CREATE_FOLDER_BUTTON_TEXT).click(); } - async openFileByName(name: string): Promise { - await this.page.getByText(name).click(); - await this.page.locator(`//p[contains(text(),'${name}')]`).isVisible(); - } - async openBucketSettings(): Promise { await this.page.locator(BucketsPageObjects.BUCKET_SETTINGS_BUTTON_CSS).click(); } @@ -134,7 +123,7 @@ export class BucketsPage { } async clickNewBucketButton(): Promise { - await this.page.locator(BucketsPageObjects.NEW_BUCKET_BUTTON_XPATH).click(); + await this.page.locator(BucketsPageObjects.NEW_BUCKET_BUTTON_XPATH).nth(0).click(); } async enterNewBucketName(name: string): Promise { @@ -145,18 +134,6 @@ export class BucketsPage { await this.page.locator(BucketsPageObjects.CONTINUE_BUTTON_CREATE_BUCKET_FLOW_XPATH).click(); } - async clickEnterPassphraseRadioButton(): Promise { - await this.page.locator(BucketsPageObjects.ENTER_PASSPHRASE_RADIO_BUTTON_XPATH).click(); - } - - async enterNewBucketPassphrase(passphrase: string): Promise { - await this.page.locator(BucketsPageObjects.PASSPHRASE_INPUT_NEW_BUCKET_XPATH).fill(passphrase); - } - - async clickConfirmCheckmark(): Promise { - await this.page.locator(BucketsPageObjects.CHECKMARK_ENTER_PASSPHRASE_XPATH).click(); - } - async openBucketDropdownByName(name: string): Promise { const row = await this.page.waitForSelector('*css=tr >> text=' + name); const button = await row.$('th:nth-child(7)'); diff --git a/testsuite/playwright-ui/pageFactory/pageRepository/Common.ts b/testsuite/playwright-ui/pageFactory/pageRepository/Common.ts new file mode 100644 index 000000000000..f87dfc994e0c --- /dev/null +++ b/testsuite/playwright-ui/pageFactory/pageRepository/Common.ts @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Storj Labs, Inc. +// See LICENSE for copying information. + +import { expect, Page } from '@playwright/test'; +import { CommonObjects } from '@objects/CommonObjects'; +import { testConfig } from '../../testConfig'; + +export class Common { + constructor(readonly page: Page) {} + + async goToAllProjects(): Promise { + await this.page.goto(`${testConfig.host}${testConfig.port}/all-projects`); + } + + async closeModal(): Promise { + await this.page.locator(CommonObjects.CLOSE_MODAL_BUTTON_XPATH).click(); + } + + async waitLoading(): Promise { + const loader = this.page.locator(CommonObjects.LOADER_XPATH); + await expect(loader).toBeHidden(); + } +} diff --git a/testsuite/playwright-ui/pageFactory/pageRepository/LoginPage.ts b/testsuite/playwright-ui/pageFactory/pageRepository/LoginPage.ts index b2740fbc9d05..bd04069d18d4 100644 --- a/testsuite/playwright-ui/pageFactory/pageRepository/LoginPage.ts +++ b/testsuite/playwright-ui/pageFactory/pageRepository/LoginPage.ts @@ -9,7 +9,13 @@ export class LoginPage { constructor(readonly page: Page) {} async navigateToURL(): Promise { - await this.page.goto(testConfig.host+testConfig.port); + await this.page.goto(`${testConfig.host}${testConfig.port}/login`); + } + + async loginByCreds(email: string, password: string): Promise { + await this.page.locator(LoginPageObjects.EMAIL_EDITBOX_ID).fill(email); + await this.page.locator(LoginPageObjects.PASSWORD_EDITBOX_ID).fill(password); + await this.page.locator('span').filter({ hasText: 'Sign In' }).click(); } async loginToApplication(): Promise { diff --git a/testsuite/playwright-ui/pageFactory/pageRepository/SignupPage.ts b/testsuite/playwright-ui/pageFactory/pageRepository/SignupPage.ts index afc37c281e9b..3b03d93f834e 100644 --- a/testsuite/playwright-ui/pageFactory/pageRepository/SignupPage.ts +++ b/testsuite/playwright-ui/pageFactory/pageRepository/SignupPage.ts @@ -9,21 +9,30 @@ import { testConfig } from '../../testConfig'; export class SignupPage { constructor(readonly page: Page) {} + async navigateToSignup(): Promise { + await this.page.goto(`${testConfig.host}${testConfig.port}/signup`); + } + async navigateToPartnerSignup(): Promise { - await this.page.goto(testConfig.host + testConfig.port + '/signup?partner=ix-storj-1'); + await this.page.goto(`${testConfig.host}${testConfig.port}/signup?partner=ix-storj-1`); + } + + async clickOnPersonalButton(): Promise { + await this.page.locator(SignupPageObjects.IX_BRANDED_PERSONAL_BUTTON_XPATH).click(); } async clickOnBusinessButton(): Promise { await this.page.locator(SignupPageObjects.IX_BRANDED_BUSINESS_BUTTON_XPATH).click(); } - async signupApplicationPersonal(name: string, email: string, password: string): Promise { + async signupApplicationPersonal(name: string, email: string, password: string, branded = false): Promise { + await this.clickOnPersonalButton(); await this.page.locator(SignupPageObjects.INPUT_NAME_XPATH).fill(name); await this.page.locator(SignupPageObjects.INPUT_EMAIL_XPATH).fill(email); await this.page.locator(SignupPageObjects.INPUT_PASSWORD_XPATH).fill(password); await this.page.locator(SignupPageObjects.INPUT_RETYPE_PASSWORD_XPATH).fill(password); await this.clickOnEveryCheckmark(); - await this.page.locator(SignupPageObjects.CREATE_ACCOUNT_BUTTON_XPATH).click(); + await this.page.locator(branded ? SignupPageObjects.IX_BRANDED_CREATE_ACCOUNT_BUTTON_XPATH : SignupPageObjects.CREATE_ACCOUNT_BUTTON_XPATH).click(); } async clickOnEveryCheckmark(): Promise { @@ -34,21 +43,17 @@ export class SignupPage { } } - async signupApplicationBusiness(name: string, email: string, password: string, company: string, position: string): Promise { + async signupApplicationBusiness(name: string, email: string, password: string, company: string, position: string, branded = false): Promise { await this.clickOnBusinessButton(); await this.page.locator(SignupPageObjects.COMPANY_NAME_INPUT_XPATH).fill(company); await this.page.locator(SignupPageObjects.POSITION_INPUT_XPATH).fill(position); - await this.signupApplicationPersonal(name, email, password); + await this.signupApplicationPersonal(name, email, password, branded); } async verifySuccessMessage(): Promise { await expect(this.page.locator(SignupPageObjects.SIGNUP_SUCCESS_MESSAGE_XPATH)).toBeVisible(); } - async clickOnGotoLoginPage(): Promise { - await this.page.locator(SignupPageObjects.GOTO_LOGIN_PAGE_BUTTON_XPATH).click(); - } - async verifyIXBrandedHeader(): Promise { await expect(this.page.locator(SignupPageObjects.IX_BRANDED_HEADER_TEXT_XPATH)).toBeVisible(); } diff --git a/testsuite/playwright-ui/playwright.config.ts b/testsuite/playwright-ui/playwright.config.ts index e8c5c2ca8a07..9e52a1af1831 100644 --- a/testsuite/playwright-ui/playwright.config.ts +++ b/testsuite/playwright-ui/playwright.config.ts @@ -3,7 +3,7 @@ import * as os from 'os'; // import generateCustomLayoutSimpleMeta from './slackReporter'; -import { PlaywrightTestConfig, ReporterDescription } from '@playwright/test'; +import { defineConfig, ReporterDescription } from '@playwright/test'; // require('dotenv').config(); @@ -42,7 +42,7 @@ const addReporter = (): ReporterDescription[] => { const isPipeline = !!process.env.CI; const threshold = 0.95; -const config: PlaywrightTestConfig = { +export default defineConfig({ expect: { timeout: 4000, // Maximum time expect() should wait for the condition to be met. toMatchSnapshot: { threshold }, // Only require the screenshots to be the same within a certain threshold. @@ -111,6 +111,4 @@ const config: PlaywrightTestConfig = { }, }, workers: process.env.CI ? 1 : undefined, -}; - -export default config; +}); diff --git a/testsuite/playwright-ui/scripts/prerun-dev.sh b/testsuite/playwright-ui/scripts/prerun-dev.sh new file mode 100755 index 000000000000..0d40be46dec7 --- /dev/null +++ b/testsuite/playwright-ui/scripts/prerun-dev.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# Install latest chromium browser +npx playwright install chromium diff --git a/testsuite/playwright-ui/tests/branded.signup.test.ts b/testsuite/playwright-ui/tests/branded.signup.test.ts index e3a00df43593..c6f96e83ede8 100644 --- a/testsuite/playwright-ui/tests/branded.signup.test.ts +++ b/testsuite/playwright-ui/tests/branded.signup.test.ts @@ -15,13 +15,13 @@ test.describe('Check for branded signup page, and sign up personal/business acco await signupPage.verifyIXBrandedHeader(); await signupPage.verifyIXBrandedSubHeader(); - await signupPage.signupApplicationPersonal(name, email, password); + await signupPage.signupApplicationPersonal(name, email, password, true); await signupPage.verifySuccessMessage(); await signupPage.navigateToPartnerSignup(); await signupPage.verifyIXBrandedHeader(); - await signupPage.signupApplicationBusiness(name, email, password, company, position); + await signupPage.signupApplicationBusiness(name, email, password, company, position, true); await signupPage.verifySuccessMessage(); }); }); diff --git a/testsuite/playwright-ui/tests/bucket.test.ts b/testsuite/playwright-ui/tests/bucket.test.ts index 9b6c7e92a2f3..7704da1a16f9 100644 --- a/testsuite/playwright-ui/tests/bucket.test.ts +++ b/testsuite/playwright-ui/tests/bucket.test.ts @@ -2,69 +2,88 @@ // See LICENSE for copying information. import test from '@lib/BaseTest'; +import { v4 as uuidv4 } from 'uuid'; test.describe('Filebrowser + edge services', () => { test.beforeEach(async ({ + signupPage, loginPage, dashboardPage, allProjectsPage, + bucketsPage, + common, }, testInfo) => { console.log(`Running ${testInfo.title}`); - const projectName = 'testproject'; + const name = 'test'; + const email = `${uuidv4()}@storj.io`; + const password = '123a123'; + const passphrase = 'qazwsx'; + await signupPage.navigateToSignup(); + await signupPage.signupApplicationPersonal(name, email, password); + await signupPage.verifySuccessMessage(); await loginPage.navigateToURL(); - await loginPage.loginToApplication(); - await allProjectsPage.clickOnProject(projectName); + await loginPage.loginByCreds(email, password); + await allProjectsPage.createProject(name); + await common.closeModal(); + await common.goToAllProjects(); + await allProjectsPage.clickOnProject(name); + await bucketsPage.enterPassphrase(passphrase); + await bucketsPage.clickContinueConfirmPassphrase(); await dashboardPage.verifyWelcomeMessage(); }); // This test check file download, upload using drag and drop function and basic link-sharing features test('File download and upload', async ({ - navigationMenu, bucketsPage, + navigationMenu, + common, }) => { - const bucketName = 'uitest1'; - const bucketPassphrase = 'qazwsx'; const fileName = 'test.txt'; + const bucketName = uuidv4(); await navigationMenu.clickOnBuckets(); - await bucketsPage.openBucketByName(bucketName); - await bucketsPage.enterPassphrase(bucketPassphrase); - await bucketsPage.clickContinueConfirmPassphrase(); + await common.waitLoading(); + await bucketsPage.enterNewBucketName(bucketName); + await bucketsPage.clickContinueCreateBucket(); + await bucketsPage.dragAndDropFile(fileName, 'text/plain'); // Checks for successful download - await bucketsPage.downloadFileByName(fileName); + await bucketsPage.downloadFromPreview(fileName); // Checks if the link-sharing buttons work await bucketsPage.verifyObjectMapIsVisible(); + await common.closeModal(); await bucketsPage.clickShareButton(); + await common.waitLoading(); await bucketsPage.clickCopyButtonShareBucketModal(); - await bucketsPage.closeModal(); + await common.closeModal(); await bucketsPage.closeFilePreview(); // Delete old file and upload new with the same file name await bucketsPage.deleteFileByName(fileName); await bucketsPage.dragAndDropFile(fileName, 'text/csv'); await bucketsPage.verifyObjectMapIsVisible(); + await common.closeModal(); await bucketsPage.clickShareButton(); await bucketsPage.clickCopyButtonShareBucketModal(); }); // This test check folder creation, upload using drag and drop function test('Folder creation and folder drag and drop upload', async ({ - navigationMenu, bucketsPage, + navigationMenu, + common, }) => { - const bucketName = 'testbucket'; - const bucketPassphrase = 'qazwsx'; + const bucketName = uuidv4(); const fileName = 'test.txt'; const folderName = 'test_folder'; await navigationMenu.clickOnBuckets(); - await bucketsPage.openBucketByName(bucketName); - await bucketsPage.enterPassphrase(bucketPassphrase); - await bucketsPage.clickContinueConfirmPassphrase(); + await common.waitLoading(); + await bucketsPage.enterNewBucketName(bucketName); + await bucketsPage.clickContinueCreateBucket(); // Create empty folder using New Folder Button await bucketsPage.createNewFolder(folderName); @@ -74,20 +93,21 @@ test.describe('Filebrowser + edge services', () => { await bucketsPage.dragAndDropFolder(folderName, fileName, 'text/csv'); await bucketsPage.deleteFileByName(folderName); }); + test('Share bucket and bucket details page', async ({ navigationMenu, bucketsPage, page, + common, }) => { - const bucketName = 'sharebucket'; - const bucketPassphrase = 'qazwsx'; + const bucketName = uuidv4(); const fileName = 'test1.jpeg'; await navigationMenu.clickOnBuckets(); - await bucketsPage.openBucketByName(bucketName); - await bucketsPage.enterPassphrase(bucketPassphrase); - await bucketsPage.clickContinueConfirmPassphrase(); - await bucketsPage.openFileByName(fileName); + await common.waitLoading(); + await bucketsPage.enterNewBucketName(bucketName); + await bucketsPage.clickContinueCreateBucket(); + await bucketsPage.dragAndDropFile(fileName, 'image/jpeg'); // Checks the image preview of the tiny apple png file await bucketsPage.verifyImagePreviewIsVisible(); @@ -103,19 +123,17 @@ test.describe('Filebrowser + edge services', () => { await bucketsPage.openBucketSettings(); await bucketsPage.clickShareBucketButton(); await bucketsPage.clickCopyButtonShareBucketModal(); - /* toDO: - add check for linksharing link - - compare image from linksharing to original - */ }); + test('Create and delete bucket', async ({ navigationMenu, bucketsPage, + common, }) => { const bucketName = 'testdelete'; await navigationMenu.clickOnBuckets(); - - await bucketsPage.clickNewBucketButton(); + await common.waitLoading(); await bucketsPage.enterNewBucketName(bucketName); await bucketsPage.clickContinueCreateBucket(); await navigationMenu.clickOnBuckets(); @@ -123,6 +141,7 @@ test.describe('Filebrowser + edge services', () => { await bucketsPage.clickDeleteBucketButton(); await bucketsPage.enterBucketNameDeleteBucket(bucketName); await bucketsPage.clickConfirmDeleteButton(); + await common.waitLoading(); await bucketsPage.verifyBucketNotVisible(bucketName); }); }); diff --git a/testsuite/playwright-ui/tests/login.test.ts b/testsuite/playwright-ui/tests/login.test.ts index af76948824e6..b9e5e7c3d152 100644 --- a/testsuite/playwright-ui/tests/login.test.ts +++ b/testsuite/playwright-ui/tests/login.test.ts @@ -12,6 +12,7 @@ test.describe('Login Test', () => { test('Login', async ({ loginPage }, testInfo) => { console.log(`Running ${testInfo.title}`); + await loginPage.navigateToURL(); await loginPage.loginToApplication(); }); }); diff --git a/testsuite/playwright-ui/tsconfig.json b/testsuite/playwright-ui/tsconfig.json index ed4fad4df018..787b51bae341 100644 --- a/testsuite/playwright-ui/tsconfig.json +++ b/testsuite/playwright-ui/tsconfig.json @@ -1,9 +1,7 @@ { "compilerOptions": { - "baseUrl": ".", - /* Specify the base directory to resolve non-relative module names. */ - "paths": { - /* Specify a set of entries that re-map imports to additional lookup locations. */ + "baseUrl": ".", // Specify the base directory to resolve non-relative module names. + "paths": { // Specify a set of entries that re-map imports to additional lookup locations. "@pages/*": [ "pageFactory/pageRepository/*" ], diff --git a/web/satellite/src/components/modals/CreateBucketModal.vue b/web/satellite/src/components/modals/CreateBucketModal.vue index 76a686b7803a..da2fcb160cde 100644 --- a/web/satellite/src/components/modals/CreateBucketModal.vue +++ b/web/satellite/src/components/modals/CreateBucketModal.vue @@ -54,7 +54,7 @@