diff --git a/.changeset/unlucky-seahorses-enjoy.md b/.changeset/unlucky-seahorses-enjoy.md new file mode 100644 index 00000000000..037b8e49378 --- /dev/null +++ b/.changeset/unlucky-seahorses-enjoy.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": minor +--- + +Draft orders bulk delete & Create draft order tests diff --git a/playwright/data/e2eTestData.ts b/playwright/data/e2eTestData.ts index c2a37665f74..a57a9c858df 100644 --- a/playwright/data/e2eTestData.ts +++ b/playwright/data/e2eTestData.ts @@ -90,6 +90,9 @@ export const PRODUCTS = { }; export const ORDERS = { + draftOrdersToBeDeleted: { + ids: ["#3266", "#3265"], + }, ordersWithinTransactionFlow: { markAsPaidOrder: { orderId: "T3JkZXI6MDE4ZWM0NGUtNTgwMC00NGM0LTliMzAtZDE3YTIxYjljOTgz", diff --git a/playwright/pages/dialogs/deleteDraftOrdersDialog.ts b/playwright/pages/dialogs/deleteDraftOrdersDialog.ts new file mode 100644 index 00000000000..9b902cf8663 --- /dev/null +++ b/playwright/pages/dialogs/deleteDraftOrdersDialog.ts @@ -0,0 +1,17 @@ +import type { Locator, Page } from "@playwright/test"; + +export class DeleteDraftOrdersDialog { + readonly page: Page; + + readonly deleteButton: Locator; + + constructor(page: Page) { + this.page = page; + + this.deleteButton = page.getByTestId("submit"); + } + + async clickDeleteButton() { + await this.deleteButton.first().click(); + } +} diff --git a/playwright/pages/dialogs/draftOrderCreateDialog.ts b/playwright/pages/dialogs/draftOrderCreateDialog.ts new file mode 100644 index 00000000000..70a6ebae6d0 --- /dev/null +++ b/playwright/pages/dialogs/draftOrderCreateDialog.ts @@ -0,0 +1,28 @@ +import type { Locator, Page } from "@playwright/test"; + +export class DraftOrderCreateDialog { + readonly page: Page; + readonly channelNameInput: Locator; + readonly channelOption: Locator; + readonly confirmButton: Locator; + + constructor(page: Page) { + this.page = page; + this.channelNameInput = page.getByTestId("channel-autocomplete"); + this.confirmButton = page.getByTestId("submit"); + this.channelOption = page.locator("[data-test-id*='select-field-option']"); + } + + async expandChannelsSearchList() { + await this.channelNameInput.click(); + } + async clickConfirmButton() { + await this.confirmButton.click(); + } + + async completeDraftOrderCreateDialogWithFirstChannel() { + await this.expandChannelsSearchList(); + await this.channelOption.first().click(); + await this.clickConfirmButton(); + } +} diff --git a/playwright/pages/draftOrdersPage.ts b/playwright/pages/draftOrdersPage.ts new file mode 100644 index 00000000000..f54617791a4 --- /dev/null +++ b/playwright/pages/draftOrdersPage.ts @@ -0,0 +1,61 @@ +import { URL_LIST } from "@data/url"; +import { AddProductsDialog } from "@dialogs/addProductsDialog"; +import { AddressDialog } from "@dialogs/addressDialog"; +import { DeleteDraftOrdersDialog } from "@dialogs/deleteDraftOrdersDialog"; +import { DraftOrderCreateDialog } from "@dialogs/draftOrderCreateDialog"; +import { ShippingAddressDialog } from "@dialogs/shippingMethodDialog"; +import { RightSideDetailsPage } from "@pageElements/rightSideDetailsSection"; +import { BasePage } from "@pages/basePage"; +import type { Page } from "@playwright/test"; + +export class DraftOrdersPage extends BasePage { + readonly page: Page; + readonly deleteDraftOrdersDialog: DeleteDraftOrdersDialog; + readonly draftOrderCreateDialog: DraftOrderCreateDialog; + readonly addProductsDialog: AddProductsDialog; + readonly rightSideDetailsPage: RightSideDetailsPage; + readonly addressDialog: AddressDialog; + readonly shippingAddressDialog: ShippingAddressDialog; + constructor( + page: Page, + readonly createDraftOrderButton = page.getByTestId( + "create-draft-order-button", + ), + readonly bulkDeleteButton = page.getByTestId("bulk-delete-button"), + readonly addProducts = page.getByTestId("add-products-button"), + readonly finalizeButton = page.getByTestId("button-bar-confirm"), + readonly addShippingCarrierLink = page.getByTestId("add-shipping-carrier"), + ) { + super(page); + this.page = page; + this.deleteDraftOrdersDialog = new DeleteDraftOrdersDialog(page); + this.draftOrderCreateDialog = new DraftOrderCreateDialog(page); + this.addProductsDialog = new AddProductsDialog(page); + this.rightSideDetailsPage = new RightSideDetailsPage(page); + this.addressDialog = new AddressDialog(page); + this.shippingAddressDialog = new ShippingAddressDialog(page); + } + + async clickCreateDraftOrderButton() { + await this.createDraftOrderButton.click(); + } + async goToDraftOrdersListView() { + await this.page.goto(URL_LIST.draftOrders); + } + + async clickBulkDeleteButton() { + await this.bulkDeleteButton.click(); + } + + async clickAddProductsButton() { + await this.addProducts.click(); + } + + async clickAddShippingCarrierButton() { + await this.addShippingCarrierLink.click(); + } + + async clickFinalizeButton() { + await this.finalizeButton.click(); + } +} diff --git a/playwright/pages/ordersPage.ts b/playwright/pages/ordersPage.ts index d35e260005c..263c9ccdcfa 100644 --- a/playwright/pages/ordersPage.ts +++ b/playwright/pages/ordersPage.ts @@ -41,15 +41,10 @@ export class OrdersPage extends BasePage { .getByTestId("orderTransactionsList") .locator("table"), readonly salesChannel = page.getByTestId("salesChannel"), - readonly editCustomerButton = page.getByTestId("edit-customer"), - readonly searchCustomerInput = page.getByTestId("select-customer"), readonly addShippingCarrierLink = page.getByTestId("add-shipping-carrier"), readonly finalizeButton = page.getByTestId("button-bar-confirm"), readonly customerEmail = page.getByTestId("customer-email"), - readonly selectCustomerOption = page.getByTestId( - "single-autocomplete-select-option", - ), ) { super(page); this.markOrderAsPaidDialog = new MarkOrderAsPaidDialog(page); @@ -63,9 +58,6 @@ export class OrdersPage extends BasePage { this.rightSideDetailsPage = new RightSideDetailsPage(page); } - async selectCustomer(customer = "allison.freeman@example.com") { - await this.selectCustomerOption.locator(`text=${customer}`).click(); - } async clickCreateOrderButton() { await this.createOrderButton.click(); } @@ -87,12 +79,7 @@ export class OrdersPage extends BasePage { async clickAddProductsButton() { await this.addProducts.click(); } - async clickEditCustomerButton() { - await this.editCustomerButton.click(); - } - async clickSearchCustomerInput() { - await this.searchCustomerInput.click(); - } + async clickFinalizeButton() { await this.finalizeButton.click(); } diff --git a/playwright/pages/pageElements/rightSideDetailsSection.ts b/playwright/pages/pageElements/rightSideDetailsSection.ts index a67f2bb6948..6767e73e6cb 100644 --- a/playwright/pages/pageElements/rightSideDetailsSection.ts +++ b/playwright/pages/pageElements/rightSideDetailsSection.ts @@ -53,6 +53,11 @@ export class RightSideDetailsPage { readonly billingAddressSection = page.getByTestId( "billing-address-section", ), + readonly editCustomerButton = page.getByTestId("edit-customer"), + readonly searchCustomerInput = page.getByTestId("select-customer"), + readonly selectCustomerOption = page.getByTestId( + "single-autocomplete-select-option", + ), ) {} async clickEditBillingAddressButton() { @@ -106,4 +111,16 @@ export class RightSideDetailsPage { await this.collectionInput.click(); await this.selectOption.first().click(); } + + async clickEditCustomerButton() { + await this.editCustomerButton.click(); + } + + async clickSearchCustomerInput() { + await this.searchCustomerInput.click(); + } + + async selectCustomer(customer = "allison.freeman@example.com") { + await this.selectCustomerOption.locator(`text=${customer}`).click(); + } } diff --git a/playwright/tests/orders.spec.ts b/playwright/tests/orders.spec.ts index 51bc96d2a88..323bbbac4e5 100644 --- a/playwright/tests/orders.spec.ts +++ b/playwright/tests/orders.spec.ts @@ -1,15 +1,21 @@ import { CUSTOMER_ADDRESS, ORDERS, PRODUCTS } from "@data/e2eTestData"; +import { DraftOrderCreateDialog } from "@pages/dialogs/draftOrderCreateDialog"; +import { DraftOrdersPage } from "@pages/draftOrdersPage"; import { FulfillmentPage } from "@pages/fulfillmentPage"; import { OrdersPage } from "@pages/ordersPage"; import { expect, test } from "@playwright/test"; test.use({ storageState: "playwright/.auth/admin.json" }); let ordersPage: OrdersPage; +let draftOrdersPage: DraftOrdersPage; let fulfillmentPage: FulfillmentPage; +let draftOrderCreateDialog: DraftOrderCreateDialog; test.beforeEach(({ page }) => { ordersPage = new OrdersPage(page); + draftOrdersPage = new DraftOrdersPage(page); fulfillmentPage = new FulfillmentPage(page); + draftOrderCreateDialog = new DraftOrderCreateDialog(page); }); test("TC: SALEOR_28 Create basic order @e2e @order", async () => { @@ -18,9 +24,9 @@ test("TC: SALEOR_28 Create basic order @e2e @order", async () => { await ordersPage.orderCreateDialog.completeOrderCreateDialogWithFirstChannel(); await ordersPage.clickAddProductsButton(); await ordersPage.addProductsDialog.selectVariantWithSkuOnListAndConfirm(); - await ordersPage.clickEditCustomerButton(); - await ordersPage.clickSearchCustomerInput(); - await ordersPage.selectCustomer(); + await ordersPage.rightSideDetailsPage.clickEditCustomerButton(); + await ordersPage.rightSideDetailsPage.clickSearchCustomerInput(); + await ordersPage.rightSideDetailsPage.selectCustomer(); await expect( ordersPage.addressDialog.existingAddressRadioButton, ).toBeVisible(); @@ -40,9 +46,9 @@ test("TC: SALEOR_76 Create order with transaction flow activated @e2e @order", a await ordersPage.addProductsDialog.selectVariantWithSkuOnListAndConfirm( PRODUCTS.productAvailableWithTransactionFlow.variant1sku, ); - await ordersPage.clickEditCustomerButton(); - await ordersPage.clickSearchCustomerInput(); - await ordersPage.selectCustomer(); + await ordersPage.rightSideDetailsPage.clickEditCustomerButton(); + await ordersPage.rightSideDetailsPage.clickSearchCustomerInput(); + await ordersPage.rightSideDetailsPage.selectCustomer(); await expect( ordersPage.addressDialog.existingAddressRadioButton, ).toBeVisible(); @@ -211,3 +217,44 @@ test("TC: SALEOR_82 Change shipping address in not fulfilled order @e2e @order", CUSTOMER_ADDRESS.changeShippingAddress, ); }); +test("TC: SALEOR_83 Draft orders bulk delete @e2e @draft", async () => { + await draftOrdersPage.goToDraftOrdersListView(); + await draftOrdersPage.waitForGrid(); + await draftOrdersPage.checkListRowsBasedOnContainingText( + ORDERS.draftOrdersToBeDeleted.ids, + ); + await draftOrdersPage.clickBulkDeleteButton(); + await draftOrdersPage.deleteDraftOrdersDialog.clickDeleteButton(); + await draftOrdersPage.expectSuccessBanner(); + await draftOrdersPage.waitForGrid(); + await expect( + await draftOrdersPage.findRowIndexBasedOnText( + PRODUCTS.productsToBeBulkDeleted.names, + ), + `Given draft orders: ${ORDERS.draftOrdersToBeDeleted.ids} should be deleted from the list`, + ).toEqual([]); +}); +test("TC: SALEOR_84 Create draft order @e2e @draft", async () => { + await draftOrdersPage.goToDraftOrdersListView(); + await draftOrdersPage.waitForGrid(); + await draftOrdersPage.clickCreateDraftOrderButton(); + await draftOrdersPage.draftOrderCreateDialog.completeDraftOrderCreateDialogWithFirstChannel(); + await draftOrdersPage.clickAddProductsButton(); + await draftOrdersPage.addProductsDialog.selectVariantWithSkuOnListAndConfirm(); + await draftOrdersPage.rightSideDetailsPage.clickEditCustomerButton(); + await draftOrdersPage.rightSideDetailsPage.clickSearchCustomerInput(); + await draftOrdersPage.rightSideDetailsPage.selectCustomer(); + + await expect( + draftOrdersPage.addressDialog.existingAddressRadioButton, + ).toBeVisible(); + + await draftOrdersPage.addressDialog.clickConfirmButton(); + await draftOrdersPage.clickAddShippingCarrierButton(); + await draftOrdersPage.shippingAddressDialog.pickAndConfirmFirstShippingMethod(); + await draftOrdersPage.clickFinalizeButton(); + + await draftOrdersPage.successBanner + .filter({ hasText: "finalized" }) + .waitFor({ state: "visible" }); +});