diff --git a/.changeset/twenty-games-complain.md b/.changeset/twenty-games-complain.md new file mode 100644 index 00000000000..a89b97152a0 --- /dev/null +++ b/.changeset/twenty-games-complain.md @@ -0,0 +1,7 @@ +--- +"saleor-dashboard": minor +--- + +Shipping Adress change test +Billing Adress change test + diff --git a/playwright/data/e2eTestData.ts b/playwright/data/e2eTestData.ts index 74cc93b4ebb..c2a37665f74 100644 --- a/playwright/data/e2eTestData.ts +++ b/playwright/data/e2eTestData.ts @@ -1,3 +1,28 @@ +export const CUSTOMER_ADDRESS = { + changeBillingAddress: { + firstName: "Change Billing Address", + lastName: "Automation", + companyName: "Saleor", + phone: "123456789", + addressLine1: "Teczowa", + addressLine2: "7", + cityName: "WROCLAW", + zip: "53-601", + country: "Poland", + }, + changeShippingAddress: { + firstName: "Change Shipping Address", + lastName: "Automation", + companyName: "Saleor", + phone: "123456789", + addressLine1: "Teczowa", + addressLine2: "7", + cityName: "WROCLAW", + zip: "53-601", + country: "Poland", + }, +}; + export const PRODUCTS = { singleProductType: { id: "UHJvZHVjdFR5cGU6Njcy", @@ -81,6 +106,12 @@ export const ORDERS = { orderToMarkAsPaidAndFulfill: { id: "T3JkZXI6Yzg2ZDMzYmEtMTA5Yi00MzUyLTkzYWItOTljMGE3Zjk4ZGE5", }, + orderFulfilledToChangeBillingAddress: { + id: "T3JkZXI6MDIzNDhmMjktNzJiOC00ZTBkLWI1ODYtY2U3OTYwZDI0Y2Q0", + }, + orderNotFulfilledToChangeShippingAddress: { + id: "T3JkZXI6ZWFhZjA0MzgtNzkyYi00ZTdlLWIyODUtMTBkMjViMjM0MzRk", + }, }; export const SHIPPING_METHODS = { diff --git a/playwright/pages/basePage.ts b/playwright/pages/basePage.ts index ae412386f2f..9ca1029b2c7 100644 --- a/playwright/pages/basePage.ts +++ b/playwright/pages/basePage.ts @@ -1,5 +1,5 @@ import { LOCATORS } from "@data/commonLocators"; -import type { Page } from "@playwright/test"; +import type { Locator, Page } from "@playwright/test"; import { expect } from "@playwright/test"; export class BasePage { @@ -208,4 +208,14 @@ export class BasePage { // make sure all searched texts were found and checked await expect(searchText.length).toEqual(rowIndexes.length); } + + async expectElementContainsTextFromObjectValues( + locator: Locator, + object: object, + ) { + const objectValuesArray = await Object.values(object); + for (const objectProperty of objectValuesArray) { + expect(locator).toContainText(objectProperty); + } + } } diff --git a/playwright/pages/dialogs/addressDialog.ts b/playwright/pages/dialogs/addressDialog.ts index 31acd212157..49514e9bd90 100644 --- a/playwright/pages/dialogs/addressDialog.ts +++ b/playwright/pages/dialogs/addressDialog.ts @@ -1,24 +1,104 @@ -import type { Locator, Page } from "@playwright/test"; +import type { Page } from "@playwright/test"; export class AddressDialog { - readonly page: Page; - readonly existingAddressRadioButton: Locator; - readonly newAddressRadioButton: Locator; - readonly submitButton: Locator; - - constructor(page: Page) { - this.page = page; - this.newAddressRadioButton = page + constructor( + page: Page, + readonly newAddressRadioButton = page .getByTestId("newAddress") - .locator('[value="newAddress"]'); - this.existingAddressRadioButton = page + .locator('[value="newAddress"]'), + readonly existingAddressRadioButton = page .getByTestId("customerAddress") - .locator('[value="customerAddress"]'); + .locator('[value="customerAddress"]'), - this.submitButton = page.getByTestId("submit"); - } + readonly submitButton = page.getByTestId("submit"), + readonly firstNameInput = page + .getByTestId("first-name-input") + .locator("input"), + readonly lastNameInput = page + .getByTestId("last-name-input") + .locator("input"), + readonly companyNameInput = page + .getByTestId("company-name-input") + .locator("input"), + readonly phoneInput = page.getByTestId("phone-input").locator("input"), + readonly cityInput = page.getByTestId("city-input").locator("input"), + readonly zipInput = page.getByTestId("zip-input").locator("input"), + readonly addressLine1Input = page + .getByTestId("address-line-1-input") + .locator("input"), + readonly addressLine2Input = page + .getByTestId("address-line-2-input") + .locator("input"), + readonly countrySelect = page.getByTestId( + "address-edit-country-select-field", + ), + readonly countryAreaSelect = page.getByTestId( + "address-edit-country-area-field", + ), + readonly selectOptions = page.getByTestId( + "single-autocomplete-select-option", + ), + ) {} async clickConfirmButton() { await this.submitButton.click(); } + async clickCountrySelect() { + await this.countrySelect.click(); + } + async clickNewAddressRadioButton() { + await this.newAddressRadioButton.click(); + } + + async typeFirstName(name = "Test") { + await this.firstNameInput.fill(name); + } + async typeLastName(lastName = "Automation") { + await this.lastNameInput.fill(lastName); + } + async typeCompanyName(companyName = "Saleor") { + await this.companyNameInput.fill(companyName); + } + async typePhone(phone = "123456789") { + await this.phoneInput.fill(phone); + } + async typeAddressLine1(addressLine1 = "Teczowa") { + await this.addressLine1Input.fill(addressLine1); + } + async typeAddressLine2(addressLine2 = "7") { + await this.addressLine2Input.fill(addressLine2); + } + async typeCity(cityName = "Wroclaw") { + await this.cityInput.fill(cityName); + } + async typeZip(zip = "53-601") { + await this.zipInput.fill(zip); + } + + async completeAddressFormAllFields(customerInfo: { + firstName: string; + lastName: string; + companyName: string; + phone: string; + addressLine1: string; + addressLine2: string; + cityName: string; + zip: string; + country: string; + countryArea?: string; + }) { + await this.typeFirstName(customerInfo.firstName); + await this.typeLastName(customerInfo.lastName); + await this.typeCompanyName(customerInfo.companyName); + await this.typePhone(customerInfo.phone); + await this.typeAddressLine1(customerInfo.addressLine1); + await this.typeAddressLine2(customerInfo.addressLine2); + await this.typeCity(customerInfo.cityName); + await this.typeZip(customerInfo.zip); + await this.clickCountrySelect(); + await this.countrySelect.locator("input").fill(customerInfo.country); + await this.selectOptions.filter({ hasText: customerInfo.country }).click(); + await this.clickConfirmButton(); + await this.submitButton.waitFor({ state: "hidden" }); + } } diff --git a/playwright/pages/ordersPage.ts b/playwright/pages/ordersPage.ts index ea63c68fe99..d35e260005c 100644 --- a/playwright/pages/ordersPage.ts +++ b/playwright/pages/ordersPage.ts @@ -2,6 +2,7 @@ import { URL_LIST } from "@data/url"; import { AddTrackingDialog } from "@dialogs/addTrackingDialog"; import { ManualTransactionDialog } from "@dialogs/manualTransactionDialog"; import { MarkOrderAsPaidDialog } from "@dialogs/markOrderAsPaidDialog"; +import { RightSideDetailsPage } from "@pageElements/rightSideDetailsSection"; import { BasePage } from "@pages/basePage"; import { AddProductsDialog } from "@pages/dialogs/addProductsDialog"; import { AddressDialog } from "@pages/dialogs/addressDialog"; @@ -18,6 +19,7 @@ export class OrdersPage extends BasePage { basePage: BasePage; manualTransactionDialog: ManualTransactionDialog; addTrackingDialog: AddTrackingDialog; + rightSideDetailsPage: RightSideDetailsPage; constructor( page: Page, @@ -43,8 +45,7 @@ export class OrdersPage extends BasePage { readonly searchCustomerInput = page.getByTestId("select-customer"), readonly addShippingCarrierLink = page.getByTestId("add-shipping-carrier"), readonly finalizeButton = page.getByTestId("button-bar-confirm"), - readonly editShippingAddress = page.getByTestId("edit-shipping-address"), - readonly editBillingAddress = page.getByTestId("edit-billing-address"), + readonly customerEmail = page.getByTestId("customer-email"), readonly selectCustomerOption = page.getByTestId( "single-autocomplete-select-option", @@ -59,6 +60,7 @@ export class OrdersPage extends BasePage { this.shippingAddressDialog = new ShippingAddressDialog(page); this.manualTransactionDialog = new ManualTransactionDialog(page); this.addTrackingDialog = new AddTrackingDialog(page); + this.rightSideDetailsPage = new RightSideDetailsPage(page); } async selectCustomer(customer = "allison.freeman@example.com") { diff --git a/playwright/pages/pageElements/rightSideDetailsSection.ts b/playwright/pages/pageElements/rightSideDetailsSection.ts index 871c8f60bff..a67f2bb6948 100644 --- a/playwright/pages/pageElements/rightSideDetailsSection.ts +++ b/playwright/pages/pageElements/rightSideDetailsSection.ts @@ -1,58 +1,65 @@ -import { expect, Locator, Page } from "@playwright/test"; +import { expect, Page } from "@playwright/test"; export class RightSideDetailsPage { - readonly page: Page; - readonly manageChannelsButton: Locator; - readonly assignedChannels: Locator; - readonly publishedRadioButtons: Locator; - readonly availableForPurchaseRadioButtons: Locator; - readonly radioButtonsValueTrue: Locator; - readonly radioButtonsValueFalse: Locator; - readonly visibleInListingsButton: Locator; - readonly availableChannel: Locator; - readonly categoryInput: Locator; - readonly taxInput: Locator; - readonly categoryItem: Locator; - readonly collectionInput: Locator; - readonly autocompleteDropdown: Locator; - readonly categorySelectOption: Locator; - readonly taxSelectOption: Locator; - readonly selectOption: Locator; - readonly selectWarehouseShippingMethodButton: Locator; - readonly selectChannelShippingPageButton: Locator; - - constructor(page: Page) { - this.page = page; - this.selectWarehouseShippingMethodButton = page.getByTestId( + constructor( + page: Page, + readonly selectWarehouseShippingMethodButton = page.getByTestId( "select-warehouse-for-shipping-method", - ); - this.selectChannelShippingPageButton = page.getByTestId( + ), + readonly selectChannelShippingPageButton = page.getByTestId( "select-channel-for-shipping-method", - ); + ), - this.categorySelectOption = page.locator("[data-test-id*='select-option']"); - this.taxSelectOption = page.locator("[data-test-id*='select-option']"); - this.selectOption = page.getByTestId("multi-autocomplete-select-option"); - this.categoryInput = page.getByTestId("category"); - this.taxInput = page.getByTestId("taxes"); - this.categoryItem = page.getByTestId("single-autocomplete-select-option"); - this.collectionInput = page.getByTestId("collections"); - this.autocompleteDropdown = page.getByTestId("autocomplete-dropdown"); + readonly categorySelectOption = page.locator( + "[data-test-id*='select-option']", + ), + readonly taxSelectOption = page.locator("[data-test-id*='select-option']"), + readonly selectOption = page.getByTestId( + "multi-autocomplete-select-option", + ), + readonly categoryInput = page.getByTestId("category"), + readonly taxInput = page.getByTestId("taxes"), + readonly categoryItem = page.getByTestId( + "single-autocomplete-select-option", + ), + readonly collectionInput = page.getByTestId("collections"), + readonly autocompleteDropdown = page.getByTestId("autocomplete-dropdown"), - this.manageChannelsButton = page.getByTestId( + readonly manageChannelsButton = page.getByTestId( "channels-availability-manage-button", - ); - this.assignedChannels = page.getByTestId("channel-availability-item"); - this.publishedRadioButtons = page.locator("[name*='isPublished'] > "); - this.availableForPurchaseRadioButtons = page.locator( + ), + readonly assignedChannels = page.getByTestId("channel-availability-item"), + readonly publishedRadioButtons = page.locator("[name*='isPublished'] > "), + readonly availableForPurchaseRadioButtons = page.locator( "[id*='isAvailableForPurchase']", - ); - this.radioButtonsValueTrue = page.locator("[value='true']"); - this.radioButtonsValueFalse = page.locator("[value='false']"); - this.visibleInListingsButton = page.locator("[id*='visibleInListings']"); - this.availableChannel = page.locator( + ), + readonly radioButtonsValueTrue = page.locator("[value='true']"), + readonly radioButtonsValueFalse = page.locator("[value='false']"), + readonly visibleInListingsButton = page.locator( + "[id*='visibleInListings']", + ), + readonly availableChannel = page.locator( "[data-test-id*='channel-availability-item']", - ); + ), + readonly editShippingAddressButton = page.getByTestId( + "edit-shipping-address", + ), + readonly editBillingAddressButton = page.getByTestId( + "edit-billing-address", + ), + readonly shippingAddressSection = page.getByTestId( + "shipping-address-section", + ), + readonly billingAddressSection = page.getByTestId( + "billing-address-section", + ), + ) {} + + async clickEditBillingAddressButton() { + await this.editBillingAddressButton.click(); + } + async clickEditShippingAddressButton() { + await this.editShippingAddressButton.click(); } async clickWarehouseSelectShippingPage() { diff --git a/playwright/tests/orders.spec.ts b/playwright/tests/orders.spec.ts index ba53ea76b73..51bc96d2a88 100644 --- a/playwright/tests/orders.spec.ts +++ b/playwright/tests/orders.spec.ts @@ -1,4 +1,4 @@ -import { ORDERS, PRODUCTS } from "@data/e2eTestData"; +import { CUSTOMER_ADDRESS, ORDERS, PRODUCTS } from "@data/e2eTestData"; import { FulfillmentPage } from "@pages/fulfillmentPage"; import { OrdersPage } from "@pages/ordersPage"; import { expect, test } from "@playwright/test"; @@ -176,3 +176,38 @@ test("TC: SALEOR_80 Add tracking to order @e2e @order", async () => { await ordersPage.expectSuccessBannerMessage("updated"); await expect(ordersPage.setTrackingNumber).toContainText(trackingNumber); }); +test("TC: SALEOR_81 Change billing address in fulfilled order @e2e @order", async () => { + await ordersPage.goToExistingOrderPage( + ORDERS.orderFulfilledToChangeBillingAddress.id, + ); + await ordersPage.waitForGrid(); + await ordersPage.rightSideDetailsPage.clickEditBillingAddressButton(); + await ordersPage.addressDialog.clickNewAddressRadioButton(); + await ordersPage.addressDialog.completeAddressFormAllFields( + CUSTOMER_ADDRESS.changeBillingAddress, + ); + await ordersPage.expectSuccessBanner(); + + await ordersPage.expectElementContainsTextFromObjectValues( + ordersPage.rightSideDetailsPage.billingAddressSection, + CUSTOMER_ADDRESS.changeBillingAddress, + ); +}); + +test("TC: SALEOR_82 Change shipping address in not fulfilled order @e2e @order", async () => { + await ordersPage.goToExistingOrderPage( + ORDERS.orderNotFulfilledToChangeShippingAddress.id, + ); + await ordersPage.waitForGrid(); + await ordersPage.rightSideDetailsPage.clickEditShippingAddressButton(); + await ordersPage.addressDialog.clickNewAddressRadioButton(); + await ordersPage.addressDialog.completeAddressFormAllFields( + CUSTOMER_ADDRESS.changeShippingAddress, + ); + await ordersPage.expectSuccessBanner(); + + await ordersPage.expectElementContainsTextFromObjectValues( + ordersPage.rightSideDetailsPage.shippingAddressSection, + CUSTOMER_ADDRESS.changeShippingAddress, + ); +}); diff --git a/playwright/tsconfig.json b/playwright/tsconfig.json index 8ea631e961c..8ef43d59042 100644 --- a/playwright/tsconfig.json +++ b/playwright/tsconfig.json @@ -13,7 +13,8 @@ "@pages/*": ["./pages/*"], "@api/*": ["./api/*"], "@data/*": ["./data/*"], - "@dialogs/*": ["./pages/dialogs/*"] + "@dialogs/*": ["./pages/dialogs/*"], + "@pageElements/*": ["./pages/pageElements/*"] } } } diff --git a/src/components/AddressEdit/AddressEdit.tsx b/src/components/AddressEdit/AddressEdit.tsx index cb62230430f..19c12f76088 100644 --- a/src/components/AddressEdit/AddressEdit.tsx +++ b/src/components/AddressEdit/AddressEdit.tsx @@ -80,6 +80,7 @@ const AddressEdit: React.FC = props => {
= props => {
= props => {
= props => {
= props => { = props => { = props => {
= props => {
= props => { )}
- +
@@ -306,7 +306,7 @@ const OrderCustomer: React.FC = props => { )}
- +