Skip to content

Commit

Permalink
[TEST] [E2E] Adding e2e tests for attributes (#4728)
Browse files Browse the repository at this point in the history
* adding e2e tests for attributes

* correcting test case ids and adding extra assertion for attributes page
  • Loading branch information
yellowee committed Mar 21, 2024
1 parent 66f565d commit a47581e
Show file tree
Hide file tree
Showing 19 changed files with 430 additions and 53 deletions.
5 changes: 5 additions & 0 deletions .changeset/thick-tools-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---

Adding e2e tests for attributes
2 changes: 2 additions & 0 deletions playwright/data/commonLocators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export const LOCATORS = {
infoBanner: "[data-test-type=\"info\"]",
dataGridTable: "[data-testid=\"data-grid-canvas\"]",
deleteButton: "[data-test-id=\"button-bar-delete\"]",
bulkDeleteButton: "[data-test-id=\"bulk-delete-button\"]",
loader: "[data-test-id=\"loader\"]",
};
50 changes: 50 additions & 0 deletions playwright/data/e2eTestData.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
export const ATTRIBUTES = {
productAttributeWithValuesToBeUpdated: {
id: "QXR0cmlidXRlOjczMg==",
name: "e2e product attribute to be updated",
valueToBeDeleted: "e2e product attribute value to be deleted",
valueToBeUpdated: "e2e product attribute value to be updated",
},
contentAttributeWithValuesToBeUpdated: {
id: "QXR0cmlidXRlOjczMw==",
name: "e2e content attribute to be updated",
valueToBeDeleted: "e2e content attribute value to be deleted",
valueToBeUpdated: "e2e content attribute value to be updated",
},
productAttributeToBeDeleted: {
id: "QXR0cmlidXRlOjczNA==",
name: "e2e product attribute to be deleted",
},
contentAttributeToBeDeleted: {
id: "QXR0cmlidXRlOjczNQ==",
name: "e2e content attribute to be deleted",
},
attributesToBeBulkDeleted: {
names: [
"e2e attribute to be bulk deleted 1/3",
"e2e attribute to be bulk deleted 2/3",
"e2e attribute to be bulk deleted 3/3",
],
},
attributesToBeUpdated:
[ {name:
"e2e product attribute to be updated 1",
id: "QXR0cmlidXRlOjc0MA=="
},
{ name: "e2e content attribute to be updated 2", id: "QXR0cmlidXRlOjczOQ==" }
],
attributeTypesWithAbilityToAddValues:{names:
["DROPDOWN","MULTISELECT","SWATCH",]
},
attributeTypesWithoutAbilityToAddValues: {
names:
["FILE",
"NUMERIC",
"RICH_TEXT",
"PLAIN_TEXT",
"BOOLEAN",
"DATE",
"DATE_TIME",]
},
attributeReferencesEntities: {names: ["PAGE", "PRODUCT", "PRODUCT_VARIANT"]},
}
export const VOUCHERS = {
vouchers: {
voucherToBeEditedWithFreeShipping: {
Expand Down
118 changes: 111 additions & 7 deletions playwright/pages/attributesPage.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { BasePage } from "@pages/basePage";
import { AddValueDialog } from "@pages/dialogs/addValueDialog";
import { DeleteAttributesInBulkDialog } from "@pages/dialogs/deleteAttributesInBulkDialog";
import { DeleteAttributeDialog } from "@pages/dialogs/deleteAttributeDialog";
import { DeleteAttributeValueDialog } from "@pages/dialogs/deleteAttributeValueDialog";
import { EditAttributeValueDialog } from "@pages/dialogs/editAttributeValueDialog";


import type { Page } from "@playwright/test";
import { URL_LIST } from "@data/url";

export class AttributesPage {
readonly page: Page;
export class AttributesPage extends BasePage {
readonly addValueDialog: AddValueDialog;
readonly basePage: BasePage;
readonly deleteAttributesInBulkDialog: DeleteAttributesInBulkDialog;
readonly deleteAttributeDialog: DeleteAttributeDialog;
readonly deleteAttributeValueDialog: DeleteAttributeValueDialog;
readonly editAttributeValueDialog: EditAttributeValueDialog;

constructor(
page: Page,
Expand All @@ -25,30 +34,125 @@ export class AttributesPage {
readonly attributeCodeInput = page
.getByTestId("attribute-code-input")
.locator("input"),
readonly bulkDeleteAttributesDialog = page.getByTestId("attribute-bulk-delete-dialog"),
readonly deleteSingleAttributeDialog = page.getByTestId("delete-single-attr-dialog"),
readonly dialog = page.getByRole("dialog"),
readonly deleteAttributeValueButton = page.getByTestId("delete-attribute-value-button"),
readonly attributeValueRows = page.getByTestId("attributes-rows"),
readonly attributeValueName = page.getByTestId("attribute-value-name"),
readonly deleteAttrValueDialog = page.getByTestId("delete-attribute-value-dialog"),
readonly editAttrValueDialog = page.getByTestId("edit-attribute-value-dialog"),
readonly attrValuesSection = page.getByTestId("attribute-values-section"),
readonly attrEntityTypeSelect = page.locator(`[id="mui-component-select-entityType"]`),
readonly attrVisibleInStorefrontSwitch = page.locator(`[name = "visibleInStorefront"]`),
readonly metadataSectionAccordionButton = page.getByTestId("metadata-item").getByTestId("expand"),
readonly metadataAddFieldButton = page.getByTestId("metadata-item").getByTestId("add-field"),
readonly metadataKeyInput = page.getByTestId("metadata-key-input").first(),
readonly metadataValueInput = page.getByTestId("metadata-value-input").first(),
) {
this.page = page;
super(page)
this.addValueDialog = new AddValueDialog(page);
this.basePage = new BasePage(page);
this.deleteAttributesInBulkDialog = new DeleteAttributesInBulkDialog(page);
this.deleteAttributeDialog = new DeleteAttributeDialog(page);
this.deleteAttributeValueDialog = new DeleteAttributeValueDialog(page);
this.editAttributeValueDialog = new EditAttributeValueDialog(page);

}

async gotoListView() {
await this.page.goto(URL_LIST.attributes);
await this.createAttributeButton.waitFor({
state: "visible",
timeout: 10000,
});
await this.gridCanvas.waitFor({
state: "visible",
timeout: 10000,
});
}
async assertSearchResultsVisibility(searchText:string) {
// Wait for all elements containing searchText to appear
const elements = await this.page.$$('text=' + searchText);

// Wait for all elements not containing searchText to disappear
const otherElements = await this.page.$$('text!=' + searchText);

// Assert that all elements containing searchText are visible
for (const element of elements) {
await element.waitForElementState('visible');
}

// Assert that all elements not containing searchText are not visible
for (const element of otherElements) {
await element.waitForElementState('hidden');
}
}
async searchForAttribute(attributeName: string) {
await this.searchInputListView.click();

}
async gotoExistingAttributePage(attributeId: string, attributeName: string) {
const existingAttributeUrl = `${URL_LIST.attributes}${attributeId}`;
await console.log(
`Navigates to existing attribute page: ${existingAttributeUrl}`,
);
await this.page.goto(existingAttributeUrl);

await this.pageHeader.getByText(attributeName).waitFor({
state: "visible",
timeout: 30000,
});
}
async clickCreateAttributeButton() {
await this.createAttributeButton.click();
}
async fillAttributeSlug(attributeSlug: string) {
await this.attributeCodeInput.fill(attributeSlug);
}
async clickValueRequiredCheckbox() {
await this.valueRequiredCheckbox.click();
}
async clickSaveButton() {
await this.saveButton.click();
}
async selectAttributeType(attributeType = "DROPDOWN") {
async selectAttributeType(attributeType: string) {
await this.page.getByTestId(attributeType).click();
}
async selectAttributeInputType(attributeType: string) {
await this.attributeSelect.click();
await this.page.getByTestId(`select-field-option-${attributeType}`).click();
}
async clickAssignAttributeValueButton() {
await this.assignAttributeValueButton.click();
}

async clickDeleteAttrValueButton(attrName: string) {
await this.attributeValueRows.filter({ hasText: attrName }).locator(this.deleteAttributeValueButton).click();
}
async clickOnExistingAttrValue(attrName: string) {
await this.attributeValueRows.filter({ hasText: attrName }).click();
await this.editAttrValueDialog.waitFor({
state: "visible",
timeout: 30000,
});
}
async typeAttributeDefaultLabel(attributeDefaultLabel: string) {
await this.attributeDefaultLabelInput.fill(attributeDefaultLabel);
}
async selectAttributeEntityType(entityType: string) {
await this.attrEntityTypeSelect.click();
await this.page.getByTestId(`select-field-option-${entityType}`).click();
}
async changeAttributeVisibility() {
await this.attrVisibleInStorefrontSwitch.click();
}
async expandMetadataSection() {
await this.metadataSectionAccordionButton.first().click();
}
async addMetadataField() {
await this.metadataAddFieldButton.click();
}
async fillMetadataFields(key: string, value: string) {
await this.metadataKeyInput.fill(key);
await this.metadataValueInput.fill(value);
}
}
9 changes: 9 additions & 0 deletions playwright/pages/basePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class BasePage {
readonly errorBanner = page.locator(LOCATORS.errorBanner),
readonly saveButton = page.locator(LOCATORS.saveButton),
readonly infoBanner = page.locator(LOCATORS.infoBanner),
readonly loader = page.locator(LOCATORS.loader),
readonly previousPagePaginationButton = page.getByTestId(
"button-pagination-back",
),
Expand All @@ -28,6 +29,7 @@ export class BasePage {
"button-pagination-next",
),
readonly searchInputListView = page.getByTestId("search-input"),
readonly emptyDataGridListView = page.getByTestId("empty-data-grid-text"),
) {
this.page = page;
}
Expand All @@ -46,6 +48,7 @@ export class BasePage {
async clickFilterButton() {
await this.filterButton.click();
}

async clickBulkDeleteGridRowsButton() {
await this.bulkDeleteGridRowsButton.click();
}
Expand Down Expand Up @@ -105,6 +108,12 @@ export class BasePage {
"No error banner should be visible",
).not.toBeVisible();
}
async resizeWindow(w: number, h: number) {
await this.page.setViewportSize({width: w, height: h,});
}
async clickOnSpecificPositionOnPage(x:number, y: number){
await this.page.mouse.click(x,y)
}

async getRandomInt(max: number) {
return Math.floor(Math.random() * (max + 1));
Expand Down
1 change: 0 additions & 1 deletion playwright/pages/configurationPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export class ConfigurationPage {
) {
this.page = page;
}

async openShippingMethods() {
await this.shippingMethodsButton.click();
}
Expand Down
2 changes: 1 addition & 1 deletion playwright/pages/dialogs/addValueDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class AddValueDialog {
this.page = page;
}

async typeAndSaveAttributeValue(value = "XXL") {
async typeAndSaveAttributeValue(value: string = "XXL") {
await this.nameInput.fill(value);
await this.saveButton.click();
}
Expand Down
18 changes: 18 additions & 0 deletions playwright/pages/dialogs/deleteAttributeDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Page } from "@playwright/test";

export class DeleteAttributeDialog {
readonly page: Page;

constructor(
page: Page,
readonly deleteButton = page.getByTestId("submit"),
readonly cancelButton = page.getByTestId("back"),
readonly deleteAttributesDialogText = page.getByTestId("delete-single-attr-dialog-text"),
) {
this.page = page;
}

async deleteAttribute() {
await this.deleteButton.click();
}
}
18 changes: 18 additions & 0 deletions playwright/pages/dialogs/deleteAttributeValueDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Page } from "@playwright/test";

export class DeleteAttributeValueDialog {
readonly page: Page;

constructor(
page: Page,
readonly deleteButton = page.getByTestId("submit"),
readonly cancelButton = page.getByTestId("back"),
readonly deleteAttributesDialogText = page.getByTestId("delete-attribute-value-dialog-text"),
) {
this.page = page;
}

async deleteAttributeValue() {
await this.deleteButton.click();
}
}
18 changes: 18 additions & 0 deletions playwright/pages/dialogs/deleteAttributesInBulkDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Page } from "@playwright/test";

export class DeleteAttributesInBulkDialog {
readonly page: Page;

constructor(
page: Page,
readonly deleteButton = page.getByTestId("submit"),
readonly cancelButton = page.getByTestId("back"),
readonly deleteAttributesDialogText = page.getByTestId("delete-attr-from-list-dialog-text"),
) {
this.page = page;
}

async deleteSelectedAttributes() {
await this.deleteButton.click();
}
}
24 changes: 24 additions & 0 deletions playwright/pages/dialogs/editAttributeValueDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Page } from "@playwright/test";
import faker from "faker";


export class EditAttributeValueDialog {
readonly page: Page;

constructor(
page: Page,
readonly saveButton = page.getByTestId("submit"),
readonly cancelButton = page.getByTestId("back"),
readonly valueInput = page.getByTestId("value-name").locator("input"),
) {
this.page = page;
}

async provideNewAttributeValue(newValue: string = faker.lorem.word(5)) {
await this.valueInput.clear();
await this.valueInput.fill(newValue);
}
async saveNewAttributeValue() {
await this.saveButton.click();
}
}
Loading

0 comments on commit a47581e

Please sign in to comment.