Skip to content

Commit

Permalink
migrated create products tests to Playwright (#4273)
Browse files Browse the repository at this point in the history
  • Loading branch information
wojteknowacki authored Oct 3, 2023
1 parent 8957582 commit e71633a
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-radios-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---

migrated create products tests to Playwright
2 changes: 1 addition & 1 deletion cypress/e2e/products/createProduct.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe("As an admin I should be able to create product", () => {
);

it(
"should be able to create product without variants as an admin. SALEOR_2702",
"should be able to create product without variants as an admin. SALEOR_2702 - migration in progress - to delete when done",
{ tags: ["@products", "@allEnv", "@critical", "@stable", "@oldRelease"] },
() => {
const prices = { sellingPrice: 6, costPrice: 3 };
Expand Down
6 changes: 6 additions & 0 deletions playwright/data/test-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const PRODUCTS = {
singleProductType: {
id: "UHJvZHVjdFR5cGU6Njcy",
name: "Single product type",
},
};
1 change: 1 addition & 0 deletions playwright/data/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const URL_LIST = {
permissionsGroups: "permission-groups/",
plugins: "plugins/",
products: "products/",
productsAdd: "add?product-type-id=",
productTypes: "product-types/",
productTypesAdd: "product-types/add",
sales: "discounts/sales/",
Expand Down
19 changes: 19 additions & 0 deletions playwright/pages/base-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { URL_LIST } from "@data/url";
import type { Locator, Page } from "@playwright/test";
import { expect } from "@playwright/test";

export class BasePage {
public page: Page;
public pageHeader: Locator;

constructor(page: Page) {
this.page = page;
this.pageHeader = page.getByTestId("page-header");
}
async gotoCreateProductPage(productTypeId: string) {
await this.page.goto(
`${URL_LIST.products}${URL_LIST.productsAdd}${productTypeId}`,
);
await expect(this.pageHeader).toBeVisible({ timeout: 10000 });
}
}
30 changes: 30 additions & 0 deletions playwright/pages/dialogs/channel-select-dialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Locator, Page } from "@playwright/test";

export class ChannelSelectDialog {
readonly page: Page;
readonly allChannelsCheckbox: Locator;
readonly displayedChannels: Locator;
readonly confirmButton: Locator;
readonly displayedChannelsCheckboxes: Locator;

constructor(page: Page) {
this.page = page;
this.allChannelsCheckbox = page.locator("[name='allChannels']");
this.displayedChannels = page.getByTestId("channel-row");
this.displayedChannelsCheckboxes = page.locator("[type=checkbox]");
this.confirmButton = page.getByTestId("submit");
}

async clickAllChannelsCheckbox() {
await this.allChannelsCheckbox.click();
}
async selectFirstChannel() {
await this.displayedChannels
.first()
.locator(this.displayedChannelsCheckboxes)
.click();
}
async clickConfirmButton() {
await this.confirmButton.first().click();
}
}
5 changes: 1 addition & 4 deletions playwright/pages/dialogs/product-create-dialog.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import type {
Locator,
Page,
} from "@playwright/test";
import type { Locator, Page } from "@playwright/test";

export class ProductCreateDialog {
readonly page: Page;
Expand Down
32 changes: 30 additions & 2 deletions playwright/pages/product-page.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
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 type { Locator, Page } from "@playwright/test";
import { expect } from "@playwright/test";

const productName = `e2e-productName-${faker.datatype.number()}`;
const productDescription = `e2e-productDescription-${faker.datatype.number()}`;
const productRating = `9`;

export class ProductPage {
readonly page: Page;
Expand Down Expand Up @@ -42,11 +42,14 @@ export class ProductPage {
readonly saveButton: Locator;
readonly firstRowDataGrid: Locator;
readonly productUpdateFormSection: Locator;
readonly manageChannelsButton: Locator;
metadataSeoPage: MetadataSeoPage;
rightSideDetailsPage: RightSideDetailsPage;
channelSelectDialog: ChannelSelectDialog;

constructor(page: Page) {
this.page = page;
this.channelSelectDialog = new ChannelSelectDialog(page);
this.metadataSeoPage = new MetadataSeoPage(page);
this.rightSideDetailsPage = new RightSideDetailsPage(page);
this.productNameInput = page.locator("[name='name']");
Expand Down Expand Up @@ -76,6 +79,9 @@ export class ProductPage {
this.channelAvailabilityItem = page.locator(
"[data-test-id*='channel-availability-item']",
);
this.manageChannelsButton = page.getByTestId(
"channels-availability-manage-button",
);
this.addVariantButton = page.locator(
"[data-test-id*='button-add-variant']",
);
Expand Down Expand Up @@ -111,14 +117,36 @@ export class ProductPage {
async typeProductDescription(description = productDescription) {
await this.descriptionInput.type(description);
}
async typeProductRating(rating = productRating) {
async typeProductRating(rating = "9") {
await this.ratingInput.fill(rating);
}
async typeSellingPriceForChannel(
channelName: string,
sellingPriceValue = "50",
) {
const channel = this.page.locator(
`[data-test-id="Channel-${channelName}"]`,
);
await channel.locator(this.sellingPriceInput).fill(sellingPriceValue);
}

async typeCostPrice(channelName: string, costPriceValue = "40") {
const channel = this.page.locator(
`[data-test-id="Channel-${channelName}"]`,
);
await channel.locator(this.costPriceInput).fill(costPriceValue);
}

async clickSaveButton() {
await this.saveButton.click();
}
async expectSuccessBanner() {
await expect(this.page.locator(LOCATORS.successBanner)).toBeVisible();
}
async selectOneChannelAsAvailable() {
await this.manageChannelsButton.click();
await this.channelSelectDialog.clickAllChannelsCheckbox();
await this.channelSelectDialog.selectFirstChannel();
await this.channelSelectDialog.clickConfirmButton();
}
}
9 changes: 5 additions & 4 deletions playwright/pages/right-side-details-section.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import type {
Locator,
Page,
} from "@playwright/test";
import type { Locator, Page } from "@playwright/test";

export class RightSideDetailsPage {
readonly page: Page;
Expand Down Expand Up @@ -51,6 +48,10 @@ export class RightSideDetailsPage {
);
}

async openChannelsDialog() {
await this.manageChannelsButton.click();
}

async selectFirstCategory() {
await this.categoryInput.click();
await this.categorySelectOption.first().click();
Expand Down
23 changes: 22 additions & 1 deletion playwright/tests/product.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
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 { test } from "@playwright/test";

test.use({ storageState: "playwright/.auth/admin.json" });

test("TC: SALEOR_3 Create basic product with variants @basic-regression @product-type", async ({
test("TC: SALEOR_3 Create basic product with variants @basic-regression @product", async ({
page,
}) => {
const productListPage = new ProductListPage(page);
Expand All @@ -24,3 +26,22 @@ test("TC: SALEOR_3 Create basic product with variants @basic-regression @product
await productPage.clickSaveButton();
await productPage.expectSuccessBanner();
});
test("TC: SALEOR_5 Create basic product without variants @basic-regression @product", async ({
page,
}) => {
const basePage = new BasePage(page);
const productCreateDialog = new ProductCreateDialog(page);
const productPage = new ProductPage(page);

await basePage.gotoCreateProductPage(PRODUCTS.singleProductType.id);
await productPage.selectOneChannelAsAvailable();
await productPage.typeNameDescAndRating();
await productPage.addSeo();
await productPage.addAllMetaData();
await productPage.selectFirstCategory();
await productPage.selectFirstTaxOption();
await productPage.typeSellingPriceForChannel("PLN");
await productPage.typeCostPrice("PLN");
await productPage.clickSaveButton();
await productPage.expectSuccessBanner();
});
3 changes: 2 additions & 1 deletion playwright/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"paths": {
"@pages/*": ["./pages/*"],
"@api/*": ["./api/*"],
"@data/*": ["./data/*"]
"@data/*": ["./data/*"],
"@dialogs/*": ["./pages/dialogs/*"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ export const ProductVariantPrice: React.FC<
);

return (
<TableRowLink key={listing?.id || `skeleton-${index}`}>
<TableRowLink
key={listing?.id || `skeleton-${index}`}
data-test-id={listing?.name}
>
<TableCell style={{ paddingLeft: vars.spacing[6] }}>
<Text>{listing?.name || <Skeleton />}</Text>
</TableCell>
Expand Down

0 comments on commit e71633a

Please sign in to comment.