diff --git a/.changeset/perfect-ligers-hope.md b/.changeset/perfect-ligers-hope.md new file mode 100644 index 00000000000..cfc7b1deeda --- /dev/null +++ b/.changeset/perfect-ligers-hope.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": minor +--- + +migrated navigation tests to playwright diff --git a/package-lock.json b/package-lock.json index 6873f81529a..1b0dabaaefc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -117,7 +117,7 @@ "@graphql-codegen/typescript-apollo-client-helpers": "^2.1.10", "@graphql-codegen/typescript-operations": "^2.2.4", "@graphql-codegen/typescript-react-apollo": "^3.2.5", - "@playwright/test": "^1.37.1", + "@playwright/test": "^1.38.1", "@saleor/app-sdk": "0.43.0", "@sentry/cli": "^2.20.6", "@swc/jest": "^0.2.26", @@ -129,6 +129,7 @@ "@types/is-ci": "^3.0.0", "@types/jscodeshift": "^0.11.3", "@types/lodash-es": "^4.17.3", + "@types/node": "^20.8.0", "@types/react": "^17.0.50", "@types/react-dom": "^17.0.17", "@types/react-dropzone": "^4.2.2", @@ -3660,6 +3661,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@formatjs/cli/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "dev": true + }, "node_modules/@formatjs/cli/node_modules/chalk": { "version": "4.1.2", "dev": true, @@ -3845,6 +3852,12 @@ } } }, + "node_modules/@formatjs/ts-transformer/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, "node_modules/@formatjs/ts-transformer/node_modules/chalk": { "version": "4.1.2", "dev": true, @@ -7056,36 +7069,18 @@ } }, "node_modules/@playwright/test": { - "version": "1.37.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", - "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", + "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==", "dev": true, "dependencies": { - "@types/node": "*", - "playwright-core": "1.37.1" + "playwright": "1.38.1" }, "bin": { "playwright": "cli.js" }, "engines": { "node": ">=16" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/@playwright/test/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/@radix-ui/number": { @@ -12432,8 +12427,9 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "node_modules/@types/node": { - "version": "14.14.37", - "license": "MIT" + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", + "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==" }, "node_modules/@types/node-fetch": { "version": "2.6.3", @@ -16730,6 +16726,12 @@ "license": "MIT", "optional": true }, + "node_modules/cypress/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "optional": true + }, "node_modules/cypress/node_modules/buffer": { "version": "5.7.1", "funding": [ @@ -19536,6 +19538,12 @@ } } }, + "node_modules/eslint-plugin-formatjs/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, "node_modules/eslint-plugin-formatjs/node_modules/@typescript-eslint/types": { "version": "5.59.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", @@ -29503,10 +29511,28 @@ "node": ">=6" } }, + "node_modules/playwright": { + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz", + "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==", + "dev": true, + "dependencies": { + "playwright-core": "1.38.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, "node_modules/playwright-core": { - "version": "1.37.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", - "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz", + "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -29515,6 +29541,20 @@ "node": ">=16" } }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/please-upgrade-node": { "version": "3.2.0", "license": "MIT", @@ -38884,6 +38924,12 @@ "version": "0.0.50", "dev": true }, + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "dev": true + }, "chalk": { "version": "4.1.2", "dev": true, @@ -39009,6 +39055,12 @@ "typescript": "^4.5" }, "dependencies": { + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, "chalk": { "version": "4.1.2", "dev": true, @@ -41395,23 +41447,12 @@ } }, "@playwright/test": { - "version": "1.37.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", - "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", + "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==", "dev": true, "requires": { - "@types/node": "*", - "fsevents": "2.3.2", - "playwright-core": "1.37.1" - }, - "dependencies": { - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - } + "playwright": "1.38.1" } }, "@radix-ui/number": { @@ -45089,7 +45130,9 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "@types/node": { - "version": "14.14.37" + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", + "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==" }, "@types/node-fetch": { "version": "2.6.3", @@ -48127,6 +48170,12 @@ "yauzl": "^2.10.0" }, "dependencies": { + "@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", + "optional": true + }, "buffer": { "version": "5.7.1", "optional": true, @@ -50221,6 +50270,12 @@ "typescript": "^4.7 || 5" } }, + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, "@typescript-eslint/types": { "version": "5.59.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.0.tgz", @@ -56965,10 +57020,29 @@ "find-up": "^3.0.0" } }, + "playwright": { + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz", + "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.38.1" + }, + "dependencies": { + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + } + } + }, "playwright-core": { - "version": "1.37.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", - "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz", + "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==", "dev": true }, "please-upgrade-node": { diff --git a/package.json b/package.json index e72f8d45f7a..d1b57b2ad0c 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "@graphql-codegen/typescript-apollo-client-helpers": "^2.1.10", "@graphql-codegen/typescript-operations": "^2.2.4", "@graphql-codegen/typescript-react-apollo": "^3.2.5", - "@playwright/test": "^1.37.1", + "@playwright/test": "^1.38.1", "@saleor/app-sdk": "0.43.0", "@sentry/cli": "^2.20.6", "@swc/jest": "^0.2.26", @@ -136,6 +136,7 @@ "@types/is-ci": "^3.0.0", "@types/jscodeshift": "^0.11.3", "@types/lodash-es": "^4.17.3", + "@types/node": "^20.8.0", "@types/react": "^17.0.50", "@types/react-dom": "^17.0.17", "@types/react-dropzone": "^4.2.2", diff --git a/playwright/data/common-locators.ts b/playwright/data/commonLocators.ts similarity index 100% rename from playwright/data/common-locators.ts rename to playwright/data/commonLocators.ts diff --git a/playwright/data/test-data.ts b/playwright/data/testData.ts similarity index 100% rename from playwright/data/test-data.ts rename to playwright/data/testData.ts diff --git a/playwright/data/userPermissions.ts b/playwright/data/userPermissions.ts new file mode 100644 index 00000000000..aee5ce4a9a0 --- /dev/null +++ b/playwright/data/userPermissions.ts @@ -0,0 +1,16 @@ +export const USER_PERMISSION = { + channel: "channel.manager@example.com", + shipping: "shipping.manager@example.com", + giftCard: "gift.card.manager@example.com", + app: "app.manager@example.com", + settings: "setting.manager@example.com", + page: "page.manager@example.com", + order: "order.manager@example.com", + translations: "translation.manager@example.com", + staff: "staff.manager@example.com", + customer: "user.manager@example.com", + productTypeAndAttribute: "product.type.and.attribute.manager@example.com", + discount: "discount.manager@example.com", + plugin: "plugin.manager@example.com", + product: "product.manager@example.com", +}; diff --git a/playwright/pages/appsPage.ts b/playwright/pages/appsPage.ts new file mode 100644 index 00000000000..502819ecd75 --- /dev/null +++ b/playwright/pages/appsPage.ts @@ -0,0 +1,13 @@ +import type { Locator, Page } from "@playwright/test"; + +export class AppsPage { + readonly page: Page; + readonly installExternalAppButton: Locator; + readonly appsLogosList: Locator; + + constructor(page: Page) { + this.page = page; + this.installExternalAppButton = page.getByTestId("add-app-from-manifest"); + this.appsLogosList = page.getByTestId("app-logo"); + } +} diff --git a/playwright/pages/base-page.ts b/playwright/pages/basePage.ts similarity index 64% rename from playwright/pages/base-page.ts rename to playwright/pages/basePage.ts index e87b9dc922c..79c793f7062 100644 --- a/playwright/pages/base-page.ts +++ b/playwright/pages/basePage.ts @@ -3,12 +3,14 @@ import type { Locator, Page } from "@playwright/test"; import { expect } from "@playwright/test"; export class BasePage { - public page: Page; - public pageHeader: Locator; + readonly page: Page; + readonly pageHeader: Locator; + readonly gridCanvas: Locator; constructor(page: Page) { this.page = page; this.pageHeader = page.getByTestId("page-header"); + this.gridCanvas = page.locator('[data-testid="data-grid-canvas"]'); } async gotoCreateProductPage(productTypeId: string) { await this.page.goto( @@ -16,4 +18,9 @@ export class BasePage { ); await expect(this.pageHeader).toBeVisible({ timeout: 10000 }); } + async expectGridToBeAttached() { + await expect(this.gridCanvas).toBeAttached({ + timeout: 10000, + }); + } } diff --git a/playwright/pages/categoriesPage.ts b/playwright/pages/categoriesPage.ts new file mode 100644 index 00000000000..1b148f12d8d --- /dev/null +++ b/playwright/pages/categoriesPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class CategoriesPage { + readonly page: Page; + readonly createCategoryButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createCategoryButton = page.getByTestId("create-category"); + } +} diff --git a/playwright/pages/channelsPage.ts b/playwright/pages/channelsPage.ts new file mode 100644 index 00000000000..d31af29e8ab --- /dev/null +++ b/playwright/pages/channelsPage.ts @@ -0,0 +1,15 @@ +import type { Locator, Page } from "@playwright/test"; + +export class ChannelPage { + readonly page: Page; + readonly createChannelButton: Locator; + readonly deleteChannelButton: Locator; + readonly channelsListTable: Locator; + + constructor(page: Page) { + this.page = page; + this.deleteChannelButton = page.getByTestId("delete-channel"); + this.createChannelButton = page.getByTestId("add-channel"); + this.channelsListTable = page.getByTestId("channel-list"); + } +} diff --git a/playwright/pages/collectionsPage.ts b/playwright/pages/collectionsPage.ts new file mode 100644 index 00000000000..d920a91a8a0 --- /dev/null +++ b/playwright/pages/collectionsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class CollectionsPage { + readonly page: Page; + readonly createCollectionButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createCollectionButton = page.getByTestId("create-collection"); + } +} diff --git a/playwright/pages/configurationPage.ts b/playwright/pages/configurationPage.ts new file mode 100644 index 00000000000..6c93cffb841 --- /dev/null +++ b/playwright/pages/configurationPage.ts @@ -0,0 +1,65 @@ +import type { Locator, Page } from "@playwright/test"; + +export class ConfigurationPage { + readonly page: Page; + readonly channelsButton: Locator; + readonly productTypesButton: Locator; + readonly webhooksAndEventsButton: Locator; + readonly taxesButton: Locator; + readonly permissionGroupsButton: Locator; + readonly pluginsButton: Locator; + readonly pageTypesButton: Locator; + readonly siteSettingsButton: Locator; + readonly staffMembersButton: Locator; + readonly shippingMethodsButton: Locator; + + constructor(page: Page) { + this.page = page; + this.pluginsButton = page.locator("[data-test-id*='plugins']"); + this.permissionGroupsButton = page.locator( + "[data-test-id*='permission-groups']", + ); + this.staffMembersButton = page.locator("[data-test-id*='staff members']"); + this.siteSettingsButton = page.locator("[data-test-id*='site-settings']"); + this.channelsButton = page.locator("[data-test-id*='channels']"); + this.shippingMethodsButton = page.locator( + "[data-test-id*='shipping methods']", + ); + this.productTypesButton = page.locator("[data-test-id*='product-types']"); + this.webhooksAndEventsButton = page.locator("[data-test-id*='webhooks']"); + this.pageTypesButton = page.locator( + "[data-test-id*='configuration-menu-page-type']", + ); + this.taxesButton = page.locator( + "[data-test-id*='configuration-menu-taxes']", + ); + } + + async openShippingMethods() { + await this.shippingMethodsButton.click(); + } + async openChannels() { + await this.channelsButton.click(); + } + async openPermissionGroups() { + await this.permissionGroupsButton.click(); + } + async openStaffMembers() { + await this.staffMembersButton.click(); + } + async openSiteSettings() { + await this.siteSettingsButton.click(); + } + async openProductTypes() { + await this.productTypesButton.click(); + } + async openPageTypes() { + await this.pageTypesButton.click(); + } + async openPlugins() { + await this.pluginsButton.click(); + } + async openWebhooksAndEvents() { + await this.webhooksAndEventsButton.click(); + } +} diff --git a/playwright/pages/contentPage.ts b/playwright/pages/contentPage.ts new file mode 100644 index 00000000000..6c1d981dfa4 --- /dev/null +++ b/playwright/pages/contentPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class ContentPage { + readonly page: Page; + readonly createContentButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createContentButton = page.getByTestId("create-page"); + } +} diff --git a/playwright/pages/customersPage.ts b/playwright/pages/customersPage.ts new file mode 100644 index 00000000000..89825a949ff --- /dev/null +++ b/playwright/pages/customersPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class CustomersPage { + readonly page: Page; + readonly createCustomerButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createCustomerButton = page.getByTestId("create-customer"); + } +} diff --git a/playwright/pages/dialogs/channel-select-dialog.ts b/playwright/pages/dialogs/channelSelectDialog.ts similarity index 100% rename from playwright/pages/dialogs/channel-select-dialog.ts rename to playwright/pages/dialogs/channelSelectDialog.ts diff --git a/playwright/pages/dialogs/product-create-dialog.ts b/playwright/pages/dialogs/productCreateDialog.ts similarity index 100% rename from playwright/pages/dialogs/product-create-dialog.ts rename to playwright/pages/dialogs/productCreateDialog.ts diff --git a/playwright/pages/discountsPage.ts b/playwright/pages/discountsPage.ts new file mode 100644 index 00000000000..fbccee51e69 --- /dev/null +++ b/playwright/pages/discountsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class DiscountsPage { + readonly page: Page; + readonly createDiscountButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createDiscountButton = page.getByTestId("create-sale"); + } +} diff --git a/playwright/pages/draftsPage.ts b/playwright/pages/draftsPage.ts new file mode 100644 index 00000000000..cb44419c527 --- /dev/null +++ b/playwright/pages/draftsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class DraftsPage { + readonly page: Page; + readonly createDraftButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createDraftButton = page.getByTestId("create-draft-order-button"); + } +} diff --git a/playwright/pages/home-page.ts b/playwright/pages/homePage.ts similarity index 100% rename from playwright/pages/home-page.ts rename to playwright/pages/homePage.ts diff --git a/playwright/pages/login-page.ts b/playwright/pages/loginPage.ts similarity index 52% rename from playwright/pages/login-page.ts rename to playwright/pages/loginPage.ts index 2628c055649..8d0391c4e55 100644 --- a/playwright/pages/login-page.ts +++ b/playwright/pages/loginPage.ts @@ -1,21 +1,39 @@ -import type { Locator, Page } from "@playwright/test"; +import { HomePage } from "@pages/homePage"; +import { expect, Locator, Page } from "@playwright/test"; export class LoginPage { readonly page: Page; readonly emailInput: Locator; readonly passwordInput: Locator; readonly signInButton: Locator; + homePage: HomePage; constructor(page: Page) { this.page = page; + this.homePage = new HomePage(page); this.emailInput = page.getByTestId("email"); this.passwordInput = page.getByTestId("password"); this.signInButton = page.getByTestId("submit"); } + + async loginAndSetStorageState( + userEmail: string, + userPassword: string, + page: Page, + path: string, + ) { + await this.goto(); + await this.typeEmail(userEmail); + await this.typePassword(userPassword); + await this.clickSignInButton(); + await expect(this.homePage.welcomeMessage).toContainText("Hello there,"); + // End of authentication steps. + await page.context().storageState({ path }); + } async typeEmail(email: string) { - await this.emailInput.type(email); + await this.emailInput.fill(email); } async typePassword(password: string) { - await this.passwordInput.type(password); + await this.passwordInput.fill(password); } async clickSignInButton() { await this.signInButton.click(); diff --git a/playwright/pages/mainMenuPage.ts b/playwright/pages/mainMenuPage.ts new file mode 100644 index 00000000000..7b090517ba5 --- /dev/null +++ b/playwright/pages/mainMenuPage.ts @@ -0,0 +1,92 @@ +import type { Locator, Page } from "@playwright/test"; +import { expect } from "@playwright/test"; + +export class MainMenuPage { + readonly page: Page; + + readonly catalog: Locator; + readonly content: Locator; + readonly categories: Locator; + readonly configuration: Locator; + readonly home: Locator; + readonly orders: Locator; + readonly discounts: Locator; + readonly appSection: Locator; + readonly vouchers: Locator; + readonly app: Locator; + readonly translations: Locator; + readonly customers: Locator; + readonly list: Locator; + readonly listItem: Locator; + readonly products: Locator; + readonly menuItem: Locator; + readonly drafts: Locator; + readonly collections: Locator; + + constructor(page: Page) { + this.page = page; + this.catalog = page.getByTestId("menu-item-label-catalogue"); + this.content = page.getByTestId("menu-item-label-pages"); + this.categories = page.getByTestId("menu-item-label-categories"); + this.collections = page.getByTestId("menu-item-label-collections"); + this.configuration = page.getByTestId("menu-item-label-configure"); + this.home = page.getByTestId("menu-item-label-home"); + this.orders = page.getByTestId("menu-item-label-orders"); + this.drafts = page.getByTestId("menu-item-label-order-drafts"); + this.discounts = page.getByTestId("menu-item-label-discounts"); + this.vouchers = page.getByTestId("menu-item-label-vouchers"); + this.appSection = page.getByTestId("menu-item-label-apps_section"); + this.app = page.getByTestId("menu-item-label-apps"); + this.translations = page.getByTestId("menu-item-label-translations"); + this.customers = page.getByTestId("menu-item-label-customers"); + this.list = page.getByTestId("menu-list"); + this.listItem = page.getByTestId("menu-list-item"); + this.products = page.getByTestId("menu-item-label-products"); + this.menuItem = page.locator("[data-test-id*='menu-item-label-']"); + } + + async openDiscounts() { + await this.discounts.click(); + } + async openProducts() { + await this.products.click(); + } + async openCategories() { + await this.products.click(); + await this.categories.click(); + } + async openCollections() { + await this.products.click(); + await this.collections.click(); + } + async openTranslations() { + await this.translations.click(); + } + async openContent() { + await this.content.click(); + } + async openCustomers() { + await this.customers.click(); + } + async openConfiguration() { + await this.configuration.click(); + } + async openApps() { + await this.app.click(); + } + async openOrders() { + await this.orders.click(); + } + async openDrafts() { + await this.orders.click(); + await this.drafts.click(); + } + async openVouchers() { + await this.discounts.click(); + await this.vouchers.click(); + } + async expectMenuItemsCount(liItemsCount: number) { + // expect li items count in menu + await expect(this.list.locator("li")).toHaveCount(liItemsCount); + } +} diff --git a/playwright/pages/ordersPage.ts b/playwright/pages/ordersPage.ts new file mode 100644 index 00000000000..806132d023c --- /dev/null +++ b/playwright/pages/ordersPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class OrdersPage { + readonly page: Page; + readonly createOrderButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createOrderButton = page.getByTestId("create-order-button"); + } +} diff --git a/playwright/pages/metadata-seo-page.ts b/playwright/pages/pageElements/metadataSeoPage.ts similarity index 96% rename from playwright/pages/metadata-seo-page.ts rename to playwright/pages/pageElements/metadataSeoPage.ts index 3e92c8ae9bd..40049a329f5 100644 --- a/playwright/pages/metadata-seo-page.ts +++ b/playwright/pages/pageElements/metadataSeoPage.ts @@ -2,7 +2,6 @@ import * as faker from "faker"; import type { Locator, Page } from "@playwright/test"; -const seoSlugName = `e2e-seoSlug-${faker.datatype.number()}`; const metaDataName = `e2e-metaDataName-${faker.datatype.number()}`; const metaDataValue = `e2e-metaDataValue-${faker.datatype.number()}`; const privateMetaDataName = `e2e-privateMetaDataName-${faker.datatype.number()}`; @@ -12,7 +11,7 @@ const seoDescriptionText = `e2e-seoSlugDescription-${faker.datatype.number()}`; export class MetadataSeoPage { readonly page: Page; - + readonly seoSlugName: string; readonly productNameInput: Locator; readonly editSeoSettings: Locator; readonly slugInput: Locator; @@ -34,6 +33,7 @@ export class MetadataSeoPage { constructor(page: Page) { this.page = page; + this.seoSlugName = `e2e-seoSlug-${Math.random().toString().substring(2)}`; this.productNameInput = page.locator("[name='name']"); this.editSeoSettings = page.getByTestId("edit-seo"); this.slugInput = page.locator("[name='slug']"); @@ -83,7 +83,7 @@ export class MetadataSeoPage { } async fillSeoSection( - seoSlug = seoSlugName, + seoSlug = this.seoSlugName, seoTitleEngine = seoEngineTitle, seoDescription = seoDescriptionText, ) { diff --git a/playwright/pages/right-side-details-section.ts b/playwright/pages/pageElements/rightSideDetailsSection.ts similarity index 100% rename from playwright/pages/right-side-details-section.ts rename to playwright/pages/pageElements/rightSideDetailsSection.ts diff --git a/playwright/pages/pageTypesPage.ts b/playwright/pages/pageTypesPage.ts new file mode 100644 index 00000000000..8c5441ae476 --- /dev/null +++ b/playwright/pages/pageTypesPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class PageTypesPage { + readonly page: Page; + readonly createPageTypeButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createPageTypeButton = page.getByTestId("create-page-type"); + } +} diff --git a/playwright/pages/permissionGroupsPage.ts b/playwright/pages/permissionGroupsPage.ts new file mode 100644 index 00000000000..d83f75f43af --- /dev/null +++ b/playwright/pages/permissionGroupsPage.ts @@ -0,0 +1,13 @@ +import type { Locator, Page } from "@playwright/test"; + +export class PermissionGroupsPage { + readonly page: Page; + readonly createPermissionGroupButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createPermissionGroupButton = page.getByTestId( + "create-permission-group", + ); + } +} diff --git a/playwright/pages/pluginsPage.ts b/playwright/pages/pluginsPage.ts new file mode 100644 index 00000000000..6b88d05097a --- /dev/null +++ b/playwright/pages/pluginsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class PluginsPage { + readonly page: Page; + readonly pluginRow: Locator; + + constructor(page: Page) { + this.page = page; + this.pluginRow = page.getByTestId("plugin"); + } +} diff --git a/playwright/pages/product-list-page.ts b/playwright/pages/product-list-page.ts deleted file mode 100644 index 2daa07fb614..00000000000 --- a/playwright/pages/product-list-page.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { URL_LIST } from "@data/url"; -import type { - Locator, - Page, -} from "@playwright/test"; - -export class ProductListPage { - readonly page: Page; - readonly productsNames: Locator; - readonly createProductButton: Locator; - readonly searchProducts: Locator; - - constructor(page: Page) { - this.page = page; - this.productsNames = page.getByTestId("name"); - this.createProductButton = page.getByTestId("add-product"); - this.searchProducts = page.locator("[placeholder='Search Products...']"); - } - - async clickCreateProductButton() { - await this.createProductButton.click(); - } - - async goto() { - await this.page.goto(URL_LIST.products); - } -} diff --git a/playwright/pages/product-type-list-page.ts b/playwright/pages/product-type-list-page.ts deleted file mode 100644 index 9f6e55fd5d3..00000000000 --- a/playwright/pages/product-type-list-page.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { URL_LIST } from "@data/url"; -import type { - Locator, - Page, -} from "@playwright/test"; - -export class ProductTypeListPage { - readonly page: Page; - readonly addProductTypeButton: Locator; - constructor(page: Page) { - this.page = page; - this.addProductTypeButton = page.getByTestId("add-product-type"); - } - async goto() { - await this.page.goto(URL_LIST.productTypes); - } - - async clickCreateProductTypeButton() { - await this.addProductTypeButton.click(); - } -} diff --git a/playwright/pages/product-page.ts b/playwright/pages/productPage.ts similarity index 86% rename from playwright/pages/product-page.ts rename to playwright/pages/productPage.ts index 817c4cdadfe..ae2d5deb8a2 100644 --- a/playwright/pages/product-page.ts +++ b/playwright/pages/productPage.ts @@ -1,9 +1,10 @@ import * as faker from "faker"; -import { LOCATORS } from "@data/common-locators"; -import { ChannelSelectDialog } from "@dialogs/channel-select-dialog"; -import { MetadataSeoPage } from "@pages/metadata-seo-page"; -import { RightSideDetailsPage } from "@pages/right-side-details-section"; +import { LOCATORS } from "@data/commonLocators"; +import { URL_LIST } from "@data/url"; +import { ChannelSelectDialog } from "@pages/dialogs/channelSelectDialog"; +import { MetadataSeoPage } from "@pages/pageElements/metadataSeoPage"; +import { RightSideDetailsPage } from "@pages/pageElements/rightSideDetailsSection"; import type { Locator, Page } from "@playwright/test"; import { expect } from "@playwright/test"; @@ -16,6 +17,9 @@ export class ProductPage { readonly productNameInput: Locator; readonly productTypeInput: Locator; readonly categoryInput: Locator; + readonly productsNames: Locator; + readonly createProductButton: Locator; + readonly searchProducts: Locator; readonly categoryItem: Locator; readonly collectionInput: Locator; readonly autocompleteDropdown: Locator; @@ -41,6 +45,7 @@ export class ProductPage { readonly editVariant: Locator; readonly saveButton: Locator; readonly firstRowDataGrid: Locator; + readonly addProductButton: Locator; readonly productUpdateFormSection: Locator; readonly manageChannelsButton: Locator; metadataSeoPage: MetadataSeoPage; @@ -52,7 +57,11 @@ export class ProductPage { this.channelSelectDialog = new ChannelSelectDialog(page); this.metadataSeoPage = new MetadataSeoPage(page); this.rightSideDetailsPage = new RightSideDetailsPage(page); + this.productsNames = page.getByTestId("name"); + this.createProductButton = page.getByTestId("add-product"); + this.searchProducts = page.locator("[placeholder='Search Products...']"); this.productNameInput = page.locator("[name='name']"); + this.addProductButton = page.getByTestId("add-product"); this.productTypeInput = page.getByTestId("product-type"); this.saveButton = page.getByTestId("button-bar-confirm"); this.categoryInput = page.getByTestId("category"); @@ -141,7 +150,9 @@ export class ProductPage { await this.saveButton.click(); } async expectSuccessBanner() { - await expect(this.page.locator(LOCATORS.successBanner)).toBeVisible(); + await expect(this.page.locator(LOCATORS.successBanner)).toBeVisible({ + timeout: 15000, + }); } async selectOneChannelAsAvailable() { await this.manageChannelsButton.click(); @@ -149,4 +160,12 @@ export class ProductPage { await this.channelSelectDialog.selectFirstChannel(); await this.channelSelectDialog.clickConfirmButton(); } + + async clickCreateProductButton() { + await this.createProductButton.click(); + } + + async gotoProductListPage() { + await this.page.goto(URL_LIST.products); + } } diff --git a/playwright/pages/product-type-page.ts b/playwright/pages/productTypePage.ts similarity index 83% rename from playwright/pages/product-type-page.ts rename to playwright/pages/productTypePage.ts index c45e47fa8d8..a1df2ddeda1 100644 --- a/playwright/pages/product-type-page.ts +++ b/playwright/pages/productTypePage.ts @@ -1,4 +1,4 @@ -import { LOCATORS } from "@data/common-locators"; +import { LOCATORS } from "@data/commonLocators"; import { URL_LIST } from "@data/url"; import type { Locator, Page } from "@playwright/test"; import { expect } from "@playwright/test"; @@ -14,9 +14,11 @@ export class ProductTypePage { readonly variantSelectionCheckbox: Locator; readonly saveButton: Locator; readonly notificationSuccess: Locator; + readonly addProductTypeButton: Locator; constructor(page: Page) { this.page = page; + this.addProductTypeButton = page.getByTestId("add-product-type"); this.notificationSuccess = page.getByTestId("notification-message"); this.nameInput = page.locator("[name='name']"); this.isShippingRequired = page.locator("[name='isShippingRequired']"); @@ -47,10 +49,18 @@ export class ProductTypePage { async selectGiftCardButton() { await this.giftCardKindCheckbox.click(); } - async goto() { + async gotoAddProductTypePage() { await this.page.goto(URL_LIST.productTypesAdd); } async expectSuccessBanner() { await expect(this.page.locator(LOCATORS.successBanner)).toBeVisible(); } + + async gotoProductTypeListPage() { + await this.page.goto(URL_LIST.productTypes); + } + + async clickCreateProductTypeButton() { + await this.addProductTypeButton.click(); + } } diff --git a/playwright/pages/shippingMethodsPage.ts b/playwright/pages/shippingMethodsPage.ts new file mode 100644 index 00000000000..4ef08550936 --- /dev/null +++ b/playwright/pages/shippingMethodsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class ShippingMethodsPage { + readonly page: Page; + readonly createShippingZoneButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createShippingZoneButton = page.getByTestId("add-shipping-zone"); + } +} diff --git a/playwright/pages/siteSettingsPage.ts b/playwright/pages/siteSettingsPage.ts new file mode 100644 index 00000000000..70ab1bd8c8f --- /dev/null +++ b/playwright/pages/siteSettingsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class SiteSettingsPage { + readonly page: Page; + readonly companyInfoSection: Locator; + + constructor(page: Page) { + this.page = page; + this.companyInfoSection = page.locator('[data-test-id="company-info"]'); + } +} diff --git a/playwright/pages/staffMembersPage.ts b/playwright/pages/staffMembersPage.ts new file mode 100644 index 00000000000..506629c9481 --- /dev/null +++ b/playwright/pages/staffMembersPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class StaffMembersPage { + readonly page: Page; + readonly inviteStaffMembersButton: Locator; + + constructor(page: Page) { + this.page = page; + this.inviteStaffMembersButton = page.getByTestId("invite-staff-member"); + } +} diff --git a/playwright/pages/translationsPage.ts b/playwright/pages/translationsPage.ts new file mode 100644 index 00000000000..e07f14ddfed --- /dev/null +++ b/playwright/pages/translationsPage.ts @@ -0,0 +1,9 @@ +import type { Page } from "@playwright/test"; + +export class TranslationsPage { + readonly page: Page; + + constructor(page: Page) { + this.page = page; + } +} diff --git a/playwright/pages/vouchersPage.ts b/playwright/pages/vouchersPage.ts new file mode 100644 index 00000000000..6c7e01943a4 --- /dev/null +++ b/playwright/pages/vouchersPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class VouchersPage { + readonly page: Page; + readonly createVoucherButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createVoucherButton = page.getByTestId("create-voucher"); + } +} diff --git a/playwright/pages/webhooksEventsPage.ts b/playwright/pages/webhooksEventsPage.ts new file mode 100644 index 00000000000..94129864a30 --- /dev/null +++ b/playwright/pages/webhooksEventsPage.ts @@ -0,0 +1,11 @@ +import type { Locator, Page } from "@playwright/test"; + +export class WebhooksEventsPage { + readonly page: Page; + readonly createAppButton: Locator; + + constructor(page: Page) { + this.page = page; + this.createAppButton = page.getByTestId("create-app"); + } +} diff --git a/playwright/tests/auth.setup.ts b/playwright/tests/auth.setup.ts index 76d1dc339d1..24ce2807410 100644 --- a/playwright/tests/auth.setup.ts +++ b/playwright/tests/auth.setup.ts @@ -1,22 +1,166 @@ -import { HomePage } from "@pages/home-page"; -import { LoginPage } from "@pages/login-page"; -import { - expect, - test as setup, -} from "@playwright/test"; +import { USER_PERMISSION } from "@data/userPermissions"; +import { LoginPage } from "@pages/loginPage"; +import { test as setup } from "@playwright/test"; const adminFile = "playwright/.auth/admin.json"; +const translationPermissionsFile = "playwright/.auth/translations.json"; +const productPermissionsFile = "playwright/.auth/product.json"; +const discountPermissionsFile = "playwright/.auth/discount.json"; +const settingsPermissionsFile = "playwright/.auth/settings.json"; +const staffMemberPermissionsFile = "playwright/.auth/staff-member.json"; +const ordersPermissionsFile = "playwright/.auth/orders.json"; +const shippingPermissionsFile = "playwright/.auth/shipping.json"; +const appsPermissionsFile = "playwright/.auth/apps.json"; +const pluginPermissionsFile = "playwright/.auth/plugins.json"; +const productTypePermissionsFile = "playwright/.auth/product-type.json"; +const giftCardsPermissionsFile = "playwright/.auth/gift-cards.json"; +const contentPermissionsFile = "playwright/.auth/content.json"; +const channelsWebhooksPermissionsFile = + "playwright/.auth/channels-webhooks.json"; +const customerWebhooksPermissionsFile = "playwright/.auth/customer.json"; setup("authenticate as admin", async ({ page }) => { const loginPage = new LoginPage(page); - await loginPage.goto(); - await loginPage.typeEmail(process.env.CYPRESS_USER_NAME!); - await loginPage.typePassword(process.env.CYPRESS_USER_PASSWORD!); - await loginPage.clickSignInButton(); - - const homePage = new HomePage(page); - await expect(homePage.welcomeMessage).toContainText("Hello there,"); + await loginPage.loginAndSetStorageState( + process.env.CYPRESS_USER_NAME!, + process.env.CYPRESS_USER_PASSWORD!, + page, + adminFile, + ); +}); +setup("authenticate as user with discount permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.discount, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + discountPermissionsFile, + ); +}); - // End of authentication steps. - await page.context().storageState({ path: adminFile }); +setup("authenticate as user with orders permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.order, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + ordersPermissionsFile, + ); +}); +setup("authenticate as user with apps permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.app, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + appsPermissionsFile, + ); +}); +setup("authenticate as user with channels permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.channel, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + channelsWebhooksPermissionsFile, + ); +}); +setup("authenticate as user with customer permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.customer, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + customerWebhooksPermissionsFile, + ); +}); +setup("authenticate as user with gift cards permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.giftCard, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + giftCardsPermissionsFile, + ); +}); +setup( + "authenticate as user with content aka page permissions", + async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.page, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + contentPermissionsFile, + ); + }, +); +setup("authenticate as user with plugins permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.plugin, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + pluginPermissionsFile, + ); +}); +setup( + "authenticate as user with product type permissions", + async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.productTypeAndAttribute, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + productTypePermissionsFile, + ); + }, +); +setup("authenticate as user with settings permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.settings, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + settingsPermissionsFile, + ); +}); +setup( + "authenticate as user with staff member permissions", + async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.staff, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + staffMemberPermissionsFile, + ); + }, +); +setup("authenticate as user with shipping permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.shipping, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + shippingPermissionsFile, + ); +}); +setup("authenticate as user with translation permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.translations, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + translationPermissionsFile, + ); +}); +setup("authenticate as user with product permissions", async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginAndSetStorageState( + USER_PERMISSION.product, + process.env.CYPRESS_PERMISSIONS_USERS_PASSWORD!, + page, + productPermissionsFile, + ); }); diff --git a/playwright/tests/orders.spec.ts b/playwright/tests/orders.spec.ts deleted file mode 100644 index 24aef0b8a23..00000000000 --- a/playwright/tests/orders.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { URL_LIST } from "@data/url"; -import { HomePage } from "@pages/home-page"; -import { - expect, - test, -} from "@playwright/test"; - -test.use({ storageState: "playwright/.auth/admin.json" }); - -test("Orders", async ({ page }) => { - await page.goto(URL_LIST.orders); - const homePage = new HomePage(page); - await expect(page.getByTestId("create-order-button")).toBeVisible(); -}); diff --git a/playwright/tests/product-types.spec.ts b/playwright/tests/product-types.spec.ts deleted file mode 100644 index 957f5a1537f..00000000000 --- a/playwright/tests/product-types.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import * as faker from "faker"; - -import { ProductTypeListPage } from "@pages/product-type-list-page"; -import { ProductTypePage } from "@pages/product-type-page"; -import { test } from "@playwright/test"; - -test.use({ storageState: "playwright/.auth/admin.json" }); -const name = `e2e-product-type-${faker.datatype.number()}`; - -test("TC: SALEOR_1 Create basic product type @basic-regression @product-type", async ({ - page, -}) => { - const productTypeListPage = new ProductTypeListPage(page); - const productTypeAddPage = new ProductTypePage(page); - - await productTypeListPage.goto(); - await productTypeListPage.clickCreateProductTypeButton(); - await productTypeAddPage.typeProductTypeName(name); - await productTypeAddPage.makeProductShippableWithWeight(); - await productTypeAddPage.clickSaveButton(); - await productTypeAddPage.expectSuccessBanner(); -}); -test("TC: SALEOR_2 Create gift card product type @basic-regression @product-type", async ({ - page, -}) => { - const productTypeAddPage = new ProductTypePage(page); - - await productTypeAddPage.goto(); - await productTypeAddPage.typeProductTypeName(name); - await productTypeAddPage.selectGiftCardButton(); - await productTypeAddPage.clickSaveButton(); - await productTypeAddPage.expectSuccessBanner(); -}); diff --git a/playwright/tests/product.spec.ts b/playwright/tests/product.spec.ts index 38cb7faa8fc..92a527fd816 100644 --- a/playwright/tests/product.spec.ts +++ b/playwright/tests/product.spec.ts @@ -1,8 +1,7 @@ -import { PRODUCTS } from "@data/test-data"; -import { BasePage } from "@pages/base-page"; -import { ProductCreateDialog } from "@pages/dialogs/product-create-dialog"; -import { ProductListPage } from "@pages/product-list-page"; -import { ProductPage } from "@pages/product-page"; +import { PRODUCTS } from "@data/testData"; +import { BasePage } from "@pages/basePage"; +import { ProductCreateDialog } from "@pages/dialogs/productCreateDialog"; +import { ProductPage } from "@pages/productPage"; import { test } from "@playwright/test"; test.use({ storageState: "playwright/.auth/admin.json" }); @@ -10,12 +9,11 @@ test.use({ storageState: "playwright/.auth/admin.json" }); test("TC: SALEOR_3 Create basic product with variants @basic-regression @product", async ({ page, }) => { - const productListPage = new ProductListPage(page); const productCreateDialog = new ProductCreateDialog(page); const productPage = new ProductPage(page); - await productListPage.goto(); - await productListPage.clickCreateProductButton(); + await productPage.gotoProductListPage(); + await productPage.clickCreateProductButton(); await productCreateDialog.selectProductTypeWithVariants(); await productCreateDialog.clickConfirmButton(); await productPage.typeNameDescAndRating(); @@ -30,7 +28,6 @@ test("TC: SALEOR_5 Create basic product without variants @basic-regression @prod page, }) => { const basePage = new BasePage(page); - const productCreateDialog = new ProductCreateDialog(page); const productPage = new ProductPage(page); await basePage.gotoCreateProductPage(PRODUCTS.singleProductType.id); diff --git a/playwright/tests/productTypes.spec.ts b/playwright/tests/productTypes.spec.ts new file mode 100644 index 00000000000..e308e8997ca --- /dev/null +++ b/playwright/tests/productTypes.spec.ts @@ -0,0 +1,31 @@ +import * as faker from "faker"; + +import { ProductTypePage } from "@pages/productTypePage"; +import { test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/admin.json" }); +const productTypeName = `e2e-product-type-${faker.datatype.number()}`; + +test("TC: SALEOR_1 Create basic product type @basic-regression @product-type", async ({ + page, +}) => { + const productTypePage = new ProductTypePage(page); + + await productTypePage.gotoProductTypeListPage(); + await productTypePage.clickCreateProductTypeButton(); + await productTypePage.typeProductTypeName(productTypeName); + await productTypePage.makeProductShippableWithWeight(); + await productTypePage.clickSaveButton(); + await productTypePage.expectSuccessBanner(); +}); +test("TC: SALEOR_2 Create gift card product type @basic-regression @product-type", async ({ + page, +}) => { + const productTypePage = new ProductTypePage(page); + + await productTypePage.gotoAddProductTypePage(); + await productTypePage.typeProductTypeName(productTypeName); + await productTypePage.selectGiftCardButton(); + await productTypePage.clickSaveButton(); + await productTypePage.expectSuccessBanner(); +}); diff --git a/playwright/tests/singlePermissions/apps.spec.ts b/playwright/tests/singlePermissions/apps.spec.ts new file mode 100644 index 00000000000..707b59fe939 --- /dev/null +++ b/playwright/tests/singlePermissions/apps.spec.ts @@ -0,0 +1,19 @@ +import { URL_LIST } from "@data/url"; +import { AppsPage } from "@pages/appsPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/apps.json" }); + +test("TC: SALEOR_10 User should be able to navigate to apps list as a staff member using APP permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const appsPage = new AppsPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openApps(); + await expect(appsPage.installExternalAppButton).toBeVisible(); + await expect(appsPage.appsLogosList.first()).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/playwright/tests/singlePermissions/channelsWebhooks.spec.ts b/playwright/tests/singlePermissions/channelsWebhooks.spec.ts new file mode 100644 index 00000000000..ea38439c4b1 --- /dev/null +++ b/playwright/tests/singlePermissions/channelsWebhooks.spec.ts @@ -0,0 +1,36 @@ +import { URL_LIST } from "@data/url"; +import { ChannelPage } from "@pages/channelsPage"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { WebhooksEventsPage } from "@pages/webhooksEventsPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/channels-webhooks.json" }); + +test("TC: SALEOR_11 User should be able to navigate to channel list as a staff member using CHANNEL permission", async ({ + page, +}) => { + const channelPage = new ChannelPage(page); + const mainMenuPage = new MainMenuPage(page); + const configurationPage = new ConfigurationPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openConfiguration(); + await mainMenuPage.expectMenuItemsCount(2); + await configurationPage.openChannels(); + + await expect(channelPage.createChannelButton).toBeVisible(); + await expect(channelPage.deleteChannelButton.first()).toBeVisible(); +}); +test("TC: SALEOR_12 User should be able to navigate to webhooks and events as a staff member using CHANNEL permission", async ({ + page, +}) => { + const webhooksEventsPage = new WebhooksEventsPage(page); + const mainMenuPage = new MainMenuPage(page); + const configurationPage = new ConfigurationPage(page); + + await page.goto(URL_LIST.configuration); + await mainMenuPage.expectMenuItemsCount(2); + await configurationPage.openWebhooksAndEvents(); + await expect(webhooksEventsPage.createAppButton).toBeVisible(); +}); diff --git a/playwright/tests/singlePermissions/contentPage.spec.ts b/playwright/tests/singlePermissions/contentPage.spec.ts new file mode 100644 index 00000000000..eb6f2171f68 --- /dev/null +++ b/playwright/tests/singlePermissions/contentPage.spec.ts @@ -0,0 +1,40 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { ContentPage } from "@pages/contentPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { PageTypesPage } from "@pages/pageTypesPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/content.json" }); + +test("TC: SALEOR_14 User should be able to navigate to content list as a staff member using CONTENT aka PAGE permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const mainMenuPage = new MainMenuPage(page); + const contentPage = new ContentPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openContent(); + await expect(contentPage.createContentButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(3); + await basePage.expectGridToBeAttached(); +}); +test("TC: SALEOR_15 User should be able to navigate to page types list as a staff member using CONTENT aka PAGE permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const configurationPage = new ConfigurationPage(page); + const mainMenuPage = new MainMenuPage(page); + const pageTypesPage = new PageTypesPage(page); + + await page.goto(URL_LIST.configuration); + await expect(configurationPage.taxesButton).toBeVisible(); + await expect(configurationPage.pageTypesButton).toBeVisible(); + await expect(configurationPage.webhooksAndEventsButton).toBeVisible(); + + await configurationPage.openPageTypes(); + await expect(pageTypesPage.createPageTypeButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(3); +}); diff --git a/playwright/tests/singlePermissions/customer.spec.ts b/playwright/tests/singlePermissions/customer.spec.ts new file mode 100644 index 00000000000..b6d7f6a8107 --- /dev/null +++ b/playwright/tests/singlePermissions/customer.spec.ts @@ -0,0 +1,21 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { CustomersPage } from "@pages/customersPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/customer.json" }); + +test("TC: SALEOR_13 User should be able to navigate to customer list as a staff member using CUSTOMER permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const mainMenuPage = new MainMenuPage(page); + const customersPage = new CustomersPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openCustomers(); + await expect(customersPage.createCustomerButton).toBeVisible(); + await basePage.expectGridToBeAttached(); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/playwright/tests/singlePermissions/discount.spec.ts b/playwright/tests/singlePermissions/discount.spec.ts new file mode 100644 index 00000000000..eaf255eaf72 --- /dev/null +++ b/playwright/tests/singlePermissions/discount.spec.ts @@ -0,0 +1,36 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { DiscountsPage } from "@pages/discountsPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { VouchersPage } from "@pages/vouchersPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/discount.json" }); + +test("TC: SALEOR_6 User should be able to navigate to discount list as a staff member using DISCOUNTS permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const mainMenuPage = new MainMenuPage(page); + const discountsPage = new DiscountsPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openDiscounts(); + await expect(discountsPage.createDiscountButton).toBeVisible(); + await basePage.expectGridToBeAttached(); + await mainMenuPage.expectMenuItemsCount(3); +}); + +test("TC: SALEOR_7 User should be able to navigate to voucher list as a staff member using DISCOUNTS permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const mainMenuPage = new MainMenuPage(page); + const vouchersPage = new VouchersPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openVouchers(); + await expect(vouchersPage.createVoucherButton).toBeVisible(); + await basePage.expectGridToBeAttached(); + await mainMenuPage.expectMenuItemsCount(3); +}); diff --git a/playwright/tests/singlePermissions/orders.spec.ts b/playwright/tests/singlePermissions/orders.spec.ts new file mode 100644 index 00000000000..b1b591fd1f8 --- /dev/null +++ b/playwright/tests/singlePermissions/orders.spec.ts @@ -0,0 +1,35 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { DraftsPage } from "@pages/draftsPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { OrdersPage } from "@pages/ordersPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/orders.json" }); + +test("TC: SALEOR_8 User should be able to navigate to order list as a staff member using ORDER permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const mainMenuPage = new MainMenuPage(page); + const ordersPage = new OrdersPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openOrders(); + await expect(ordersPage.createOrderButton).toBeVisible(); + await basePage.expectGridToBeAttached(); + await mainMenuPage.expectMenuItemsCount(3); +}); +test("TC: SALEOR_9 User should be able to navigate to draft list as a staff member using ORDER permission", async ({ + page, +}) => { + const basePage = new BasePage(page); + const mainMenuPage = new MainMenuPage(page); + const draftsPage = new DraftsPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openDrafts(); + await expect(draftsPage.createDraftButton).toBeVisible(); + await basePage.expectGridToBeAttached(); + await mainMenuPage.expectMenuItemsCount(3); +}); diff --git a/playwright/tests/singlePermissions/plugins.spec.ts b/playwright/tests/singlePermissions/plugins.spec.ts new file mode 100644 index 00000000000..64e93332909 --- /dev/null +++ b/playwright/tests/singlePermissions/plugins.spec.ts @@ -0,0 +1,20 @@ +import { URL_LIST } from "@data/url"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { PluginsPage } from "@pages/pluginsPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/plugins.json" }); + +test("TC: SALEOR_16 User should be able to navigate to plugin list as a staff member using PLUGINS permission", async ({ + page, +}) => { + const configurationPage = new ConfigurationPage(page); + const mainMenuPage = new MainMenuPage(page); + const pluginsPage = new PluginsPage(page); + + await page.goto(URL_LIST.configuration); + await configurationPage.openPlugins(); + await expect(pluginsPage.pluginRow.first()).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/playwright/tests/singlePermissions/product.spec.ts b/playwright/tests/singlePermissions/product.spec.ts new file mode 100644 index 00000000000..d1805c0e6f4 --- /dev/null +++ b/playwright/tests/singlePermissions/product.spec.ts @@ -0,0 +1,49 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { CategoriesPage } from "@pages/categoriesPage"; +import { CollectionsPage } from "@pages/collectionsPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { ProductPage } from "@pages/productPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/product.json" }); + +test("TC: SALEOR_23 User should be able to navigate to product list as a staff member using PRODUCT permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const basePage = new BasePage(page); + const productPage = new ProductPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openProducts(); + await expect(productPage.addProductButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(5); + await basePage.expectGridToBeAttached(); +}); +test("TC: SALEOR_24 User should be able to navigate to collections list as a staff member using PRODUCT permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const basePage = new BasePage(page); + const collectionsPage = new CollectionsPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openCollections(); + await expect(collectionsPage.createCollectionButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(5); + await basePage.expectGridToBeAttached(); +}); +test("TC: SALEOR_25 User should be able to navigate to categories list as a staff member using PRODUCT permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const basePage = new BasePage(page); + const categoriesPage = new CategoriesPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openCategories(); + await expect(categoriesPage.createCategoryButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(5); + await basePage.expectGridToBeAttached(); +}); diff --git a/playwright/tests/singlePermissions/productType.spec.ts b/playwright/tests/singlePermissions/productType.spec.ts new file mode 100644 index 00000000000..735ebbf1100 --- /dev/null +++ b/playwright/tests/singlePermissions/productType.spec.ts @@ -0,0 +1,20 @@ +import { URL_LIST } from "@data/url"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { ProductTypePage } from "@pages/productTypePage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/product-type.json" }); + +test("TC: SALEOR_17 User should be able to navigate to product type list as a staff member using PRODUCT TYPE permission", async ({ + page, +}) => { + const configurationPage = new ConfigurationPage(page); + const mainMenuPage = new MainMenuPage(page); + const productTypePage = new ProductTypePage(page); + + await page.goto(URL_LIST.configuration); + await configurationPage.openProductTypes(); + await expect(productTypePage.addProductTypeButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/playwright/tests/singlePermissions/settingsConfiguration.spec.ts b/playwright/tests/singlePermissions/settingsConfiguration.spec.ts new file mode 100644 index 00000000000..a38b1f92f59 --- /dev/null +++ b/playwright/tests/singlePermissions/settingsConfiguration.spec.ts @@ -0,0 +1,21 @@ +import { URL_LIST } from "@data/url"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { SiteSettingsPage } from "@pages/siteSettingsPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/settings.json" }); + +test("TC: SALEOR_18 User should be able to navigate to configuration as a staff member using SETTINGS permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const configurationPage = new ConfigurationPage(page); + const siteSettingsPage = new SiteSettingsPage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openConfiguration(); + await configurationPage.openSiteSettings(); + await expect(siteSettingsPage.companyInfoSection).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/playwright/tests/singlePermissions/shipping.spec.ts b/playwright/tests/singlePermissions/shipping.spec.ts new file mode 100644 index 00000000000..c494ae80918 --- /dev/null +++ b/playwright/tests/singlePermissions/shipping.spec.ts @@ -0,0 +1,21 @@ +import { URL_LIST } from "@data/url"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { ShippingMethodsPage } from "@pages/shippingMethodsPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/shipping.json" }); + +test("TC: SALEOR_21 User should be able to navigate to shipping zones page as a staff member using SHIPPING permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const configurationPage = new ConfigurationPage(page); + const shippingMethodsPage = new ShippingMethodsPage(page); + + await page.goto(URL_LIST.configuration); + await page.waitForTimeout(8000); + await configurationPage.openShippingMethods(); + await expect(shippingMethodsPage.createShippingZoneButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/playwright/tests/singlePermissions/staffMembers.spec.ts b/playwright/tests/singlePermissions/staffMembers.spec.ts new file mode 100644 index 00000000000..7bf3dd8e4a4 --- /dev/null +++ b/playwright/tests/singlePermissions/staffMembers.spec.ts @@ -0,0 +1,39 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { ConfigurationPage } from "@pages/configurationPage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { PermissionGroupsPage } from "@pages/permissionGroupsPage"; +import { StaffMembersPage } from "@pages/staffMembersPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/staff-member.json" }); + +test("TC: SALEOR_19 User should be able to navigate to staff members list page as a staff member using STAFF permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const basePage = new BasePage(page); + const configurationPage = new ConfigurationPage(page); + const staffMembersPage = new StaffMembersPage(page); + + await page.goto(URL_LIST.configuration); + await configurationPage.openStaffMembers(); + await expect(staffMembersPage.inviteStaffMembersButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); + await basePage.expectGridToBeAttached(); +}); + +test("TC: SALEOR_20 User should be able to navigate to permission group list page as a staff member using STAFF permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const basePage = new BasePage(page); + const configurationPage = new ConfigurationPage(page); + const permissionGroupsPage = new PermissionGroupsPage(page); + + await page.goto(URL_LIST.configuration); + await configurationPage.openPermissionGroups(); + await expect(permissionGroupsPage.createPermissionGroupButton).toBeVisible(); + await mainMenuPage.expectMenuItemsCount(2); + await basePage.expectGridToBeAttached(); +}); diff --git a/playwright/tests/singlePermissions/translations.spec.ts b/playwright/tests/singlePermissions/translations.spec.ts new file mode 100644 index 00000000000..5e077fcade1 --- /dev/null +++ b/playwright/tests/singlePermissions/translations.spec.ts @@ -0,0 +1,18 @@ +import { URL_LIST } from "@data/url"; +import { BasePage } from "@pages/basePage"; +import { MainMenuPage } from "@pages/mainMenuPage"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/translations.json" }); + +test("TC: SALEOR_22 User should be able to navigate to translations page as a staff member using TRANSLATION permission", async ({ + page, +}) => { + const mainMenuPage = new MainMenuPage(page); + const basePage = new BasePage(page); + + await page.goto(URL_LIST.homePage); + await mainMenuPage.openTranslations(); + await expect(basePage.pageHeader).toHaveText("Languages"); + await mainMenuPage.expectMenuItemsCount(2); +}); diff --git a/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx b/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx index cac6601d859..e8b9ab845a1 100644 --- a/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx +++ b/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx @@ -108,7 +108,7 @@ export const ChannelsListPage: React.FC = ({ - + {renderCollection( channelsList, channel => ( @@ -129,6 +129,7 @@ export const ChannelsListPage: React.FC = ({ onRemove(channel.id))