diff --git a/.changeset/pretty-masks-lay.md b/.changeset/pretty-masks-lay.md deleted file mode 100644 index 2f5c9fcf640..00000000000 --- a/.changeset/pretty-masks-lay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"saleor-dashboard": patch ---- - -You can now run E2E tests locally with no issues diff --git a/playwright/api/basics.ts b/playwright/api/basics.ts index e29926e0dc6..e1e75f11c09 100644 --- a/playwright/api/basics.ts +++ b/playwright/api/basics.ts @@ -51,6 +51,6 @@ export class BasicApiService { }); const loginResponseJson = await loginResponse.json(); - return loginResponseJson; + return loginResponseJson as ApiResponse; } } diff --git a/playwright/pages/appPageThirdparty.ts b/playwright/pages/appPageThirdparty.ts index dd05fa5c646..39fc41ee994 100644 --- a/playwright/pages/appPageThirdparty.ts +++ b/playwright/pages/appPageThirdparty.ts @@ -26,7 +26,6 @@ export class AppPage extends BasePage { const appUrl = URL_LIST.apps + appId; await this.page.goto(appUrl); - await this.pageHeader.waitFor({ state: "visible", timeout: 10000 }); } async clickAppSettingsButton() { diff --git a/playwright/pages/appsPage.ts b/playwright/pages/appsPage.ts index 172f3e1597f..040c2f1a99d 100644 --- a/playwright/pages/appsPage.ts +++ b/playwright/pages/appsPage.ts @@ -30,7 +30,6 @@ export class AppsPage extends BasePage { async gotoAppsList() { await this.page.goto(URL_LIST.apps); - await this.waitForDOMToFullyLoad(); } async typeManifestUrl(manifestUrl: string) { diff --git a/playwright/pages/shippingRatesPage.ts b/playwright/pages/shippingRatesPage.ts index 9db6a36f6b2..c7bc0ea4e84 100644 --- a/playwright/pages/shippingRatesPage.ts +++ b/playwright/pages/shippingRatesPage.ts @@ -52,7 +52,9 @@ export class ShippingRatesPage extends BasePage { await this.assignDialogProductRow.filter({ hasText: name }).waitFor({ state: "visible" }); await this.assignProductsDialog.selectProduct(name); await expect(this.assignProductsDialog.assignAndSaveButton).toBeEnabled(); - await this.assignProductsDialog.assignAndSaveButton.click(); + await this.waitForNetworkIdleAfterAction(() => + this.assignProductsDialog.assignAndSaveButton.click(), + ); await this.assignProductsDialog.assignAndSaveButton.waitFor({ state: "hidden", timeout: 5000, diff --git a/playwright/tests/apps.spec.ts b/playwright/tests/apps.spec.ts index e7f86228543..367e387bb37 100644 --- a/playwright/tests/apps.spec.ts +++ b/playwright/tests/apps.spec.ts @@ -20,6 +20,7 @@ test.skip("TC: SALEOR_119 User should be able to install and configure app from page, }) => { await appsPage.gotoAppsList(); + await appsPage.waitForDOMToFullyLoad(); await expect(appsPage.installExternalAppButton).toBeVisible(); await appsPage.installExternalAppButton.click(); await appsPage.typeManifestUrl("https://klaviyo.saleor.app/api/manifest"); @@ -49,7 +50,10 @@ test.skip("TC: SALEOR_119 User should be able to install and configure app from await appsPage.expectSuccessBanner(); }); test("TC: SALEOR_120 User should be able to delete thirdparty app @e2e", async () => { - await appPage.goToExistingAppPage(APPS.appToBeDeleted.id); + await appPage.waitForNetworkIdleAfterAction(() => + appPage.goToExistingAppPage(APPS.appToBeDeleted.id), + ); + await appPage.pageHeader.waitFor({ state: "visible", timeout: 10000 }); await expect(appPage.pageHeader).toContainText("Saleor QA App"); await appPage.deleteButton.click(); await appPage.deleteAppDialog.clickDeleteButton(); diff --git a/playwright/tests/auth.setup.ts b/playwright/tests/auth.setup.ts index 403b07b38f5..71929959873 100644 --- a/playwright/tests/auth.setup.ts +++ b/playwright/tests/auth.setup.ts @@ -1,24 +1,11 @@ import { BasicApiService } from "@api/basics"; -import { permissions, USER_PERMISSION } from "@data/userPermissions"; -import { APIRequestContext, expect, test as setup } from "@playwright/test"; +import { permissions, USER_PERMISSION, UserPermissionType } from "@data/userPermissions"; +import { APIRequestContext, test as setup } from "@playwright/test"; import fs from "fs"; import path from "path"; setup.describe.configure({ mode: "serial" }); -const removeAuthFolder = () => { - const authDir = path.join(__dirname, "../.auth"); - - if (fs.existsSync(authDir)) { - fs.rmSync(authDir, { recursive: true }); - console.log(".auth folder removed"); - } -}; - -setup.beforeAll(() => { - removeAuthFolder(); -}); - const authenticateAndSaveState = async ( request: APIRequestContext, email: string, @@ -27,32 +14,19 @@ const authenticateAndSaveState = async ( ) => { const basicApiService = new BasicApiService(request); - const loginResponse = await basicApiService.logInUserViaApi({ email, password }); - const errors = loginResponse.data.tokenCreate.errors; - - if ( - setup.info().title === - "TC: SALEOR_137 Admin User should be able to deactivate other user @e2e @staff-members" - ) { - await expect(errors[0].code).toEqual("INACTIVE"); - } else { - await expect(errors).toEqual([]); - } + await basicApiService.logInUserViaApi({ email, password }); const loginJsonInfo = await request.storageState(); - loginJsonInfo.origins = [ - { - origin: process.env.BASE_URL!, - localStorage: [ - { - name: "_saleorRefreshToken", - value: loginResponse.data.tokenCreate.refreshToken, - }, - ], - }, - ]; - + loginJsonInfo.origins.push({ + origin: process.env.BASE_URL!, + localStorage: [ + { + name: "_saleorRefreshToken", + value: loginJsonInfo.cookies[0].value, + }, + ], + }); fs.writeFileSync(filePath, JSON.stringify(loginJsonInfo, null, 2)); }; const authSetup = async ( @@ -83,12 +57,11 @@ setup("Authenticate as admin via API", async ({ request }) => { ); }); -setup("Authenticate permission users via API", async ({ request }) => { - for (const permission of permissions) { - const email = USER_PERMISSION[permission]; - const password = process.env.E2E_PERMISSIONS_USERS_PASSWORD!; - const fileName = `${permission}.json`; +const user: UserPermissionType = USER_PERMISSION; +const password: string = process.env.E2E_PERMISSIONS_USERS_PASSWORD!; - await authSetup(request, email, password, fileName); - } -}); +for (const permission of permissions) { + setup(`Authenticate as ${permission} user via API`, async ({ request }) => { + await authSetup(request, user[permission], password, `${permission}.json`); + }); +} diff --git a/playwright/tests/singlePermissions/product.spec.ts b/playwright/tests/singlePermissions/product.spec.ts index e2c20f1a94b..09d1acba260 100644 --- a/playwright/tests/singlePermissions/product.spec.ts +++ b/playwright/tests/singlePermissions/product.spec.ts @@ -3,50 +3,42 @@ import { CollectionsPage } from "@pages/collectionsPage"; import { HomePage } from "@pages/homePage"; import { MainMenuPage } from "@pages/mainMenuPage"; import { ProductPage } from "@pages/productPage"; -import { BrowserContext, expect, test } from "@playwright/test"; +import { expect, test } from "@playwright/test"; + +test.use({ storageState: "playwright/.auth/product.json" }); -let context: BrowserContext; let home: HomePage; let mainMenuPage: MainMenuPage; let productPage: ProductPage; let categoriesPage: CategoriesPage; let collectionsPage: CollectionsPage; -test.beforeEach(async ({ browser }) => { - context = await browser.newContext({ - storageState: "playwright/.auth/product.json", - }); - - const page = await context.newPage(); - +test.beforeEach(({ page }) => { productPage = new ProductPage(page); home = new HomePage(page); mainMenuPage = new MainMenuPage(page); categoriesPage = new CategoriesPage(page); collectionsPage = new CollectionsPage(page); - - await home.goto(); - await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 }); -}); - -test.afterEach(async () => { - await context.close(); }); - test("TC: SALEOR_23 User should be able to navigate to product list as a staff member using PRODUCT permission @e2e", async () => { + await home.goto(); + await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 }); await mainMenuPage.openProducts(); await expect(productPage.addProductButton).toBeVisible(); await mainMenuPage.expectMenuItemsCount(6); await productPage.expectGridToBeAttached(); }); - test("TC: SALEOR_24 User should be able to navigate to collections list as a staff member using PRODUCT permission @e2e", async () => { + await home.goto(); + await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 }); await mainMenuPage.openCollections(); await expect(collectionsPage.createCollectionButton).toBeVisible(); await mainMenuPage.expectMenuItemsCount(6); await collectionsPage.expectGridToBeAttached(); }); test("TC: SALEOR_25 User should be able to navigate to categories list as a staff member using PRODUCT permission @e2e", async () => { + await home.goto(); + await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 }); await mainMenuPage.openCategories(); await expect(categoriesPage.createCategoryButton).toBeVisible(); await mainMenuPage.expectMenuItemsCount(6); diff --git a/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts b/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts index b12657aa41d..c7a1778a096 100644 --- a/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts +++ b/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts @@ -1,8 +1,8 @@ +import { URL_LIST } from "@data/url"; import { permissions } from "@data/userPermissions"; import { AppDetailsPage } from "@pages/appDetailsPage"; import { AppPage } from "@pages/appPageThirdparty"; import { AppsPage } from "@pages/appsPage"; -import { HomePage } from "@pages/homePage"; import { MainMenuPage } from "@pages/mainMenuPage"; import { expect, test } from "@playwright/test"; @@ -11,19 +11,17 @@ const permissionList = permissions.filter(item => item !== permissionToExclude); for (const permission of permissionList) { test.use({ storageState: `playwright/.auth/${permission}.json` }); - test(`TC: SALEOR_131 User with ${permission} permissions should have readonly access to Apps @e2e @app`, async ({ + test(`TC: SALEOR_131 User with ${permission} permissions should have readonly access to Apps @e2e @appp`, async ({ page, }) => { - const home = new HomePage(page); const mainMenuPage = new MainMenuPage(page); const appsPage = new AppsPage(page); const appPage = new AppPage(page); const appDetailsPage = new AppDetailsPage(page); - await home.goto(); - await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 }); - await mainMenuPage.openApps(); - + await page.goto(URL_LIST.homePage); + await mainMenuPage.waitForNetworkIdleAfterAction(() => mainMenuPage.openApps()); + await mainMenuPage.waitForDOMToFullyLoad(); await expect(appsPage.installExternalAppButton).not.toBeVisible(); const appLists = [ @@ -36,9 +34,9 @@ for (const permission of permissionList) { await appsPage.waitForDOMToFullyLoad(); await expect(appList).toBeVisible(); } - await appsPage.installedAppRow.first().click(); + await appsPage.waitForNetworkIdleAfterAction(() => appsPage.installedAppRow.first().click()); await expect(appPage.appSettingsButton).toBeVisible(); - await appPage.appSettingsButton.click(); + await appsPage.waitForNetworkIdleAfterAction(() => appPage.appSettingsButton.click()); await expect(appDetailsPage.appDetailsSection).toBeVisible(); const buttons = [