Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Order payment and fulfillment with transaction flow tests #4561

Merged
merged 9 commits into from
Dec 20, 2023
6 changes: 6 additions & 0 deletions .changeset/rich-hairs-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"saleor-dashboard": minor
---

Mark order as fully paid and fulfill all variants test
Manual capture transactions and fulfill order test
13 changes: 13 additions & 0 deletions playwright/data/e2eTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ export const PRODUCTS = {
},
};

export const ORDERS = {
ordersWithinTransactionFlow: {
markAsPaidOrder: {
orderId: "T3JkZXI6MDE4ZWM0NGUtNTgwMC00NGM0LTliMzAtZDE3YTIxYjljOTgz",
info: "Order used to mark as paid and fulfill",
},
captureManualTransactionOrder: {
orderId: "T3JkZXI6MmE1NTNkMzktOWU0OS00ZWE5LWIyNzEtNzk2ZWI5OGJhNzcz",
info: "Order used to capture manual transactions and fulfill",
},
},
};

export const SHIPPING_METHODS = {
shippingMethodWithoutRates: {
id: "U2hpcHBpbmdab25lOjIzNzg%3D",
Expand Down
1 change: 1 addition & 0 deletions playwright/pages/basePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class BasePage {
constructor(
page: Page,
readonly pageHeader = page.getByTestId("page-header"),
readonly pageHeaderStatusInfo = page.getByTestId("status-info"),
readonly bulkDeleteGridRowsButton = page.getByTestId("bulk-delete-button"),
readonly gridCanvas = page.locator('[data-testid="data-grid-canvas"]'),
readonly gridInput = page
Expand Down
45 changes: 45 additions & 0 deletions playwright/pages/dialogs/manualTransactionDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Page } from "@playwright/test";

export class ManualTransactionDialog {
constructor(
page: Page,
readonly transactionDescriptionInput = page.getByTestId(
"transactionDescription",
),
readonly createManualTransactionButton = page.getByTestId(
"manualTransactionSubmit",
),
readonly transactionPspReferenceInput = page.getByTestId(
"transactionPspReference",
),
readonly transactAmountInput = page.getByTestId("transactAmountInput"),
) {}

async clickCreateManualTransactionButton() {
await this.createManualTransactionButton.click();
await this.createManualTransactionButton.waitFor({ state: "hidden" });
}

async typeTransactionDescription(description = "partial payment") {
await this.transactionDescriptionInput.fill(description);
}

async typeTransactionPspReference(reference = "999999999") {
await this.transactionPspReferenceInput.fill(reference);
}

async typeTransactionAmount(amount = "100") {
await this.transactAmountInput.fill(amount);
}

async completeManualTransactionDialogAndSave(
description: string,
reference: string,
transactionAmount: string,
) {
await this.typeTransactionDescription(description);
await this.typeTransactionDescription(reference);
await this.typeTransactionAmount(transactionAmount);
await this.clickCreateManualTransactionButton();
}
}
17 changes: 17 additions & 0 deletions playwright/pages/dialogs/markOrderAsPaidDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Page } from "@playwright/test";

export class MarkOrderAsPaidDialog {
constructor(
page: Page,
readonly transactionReferenceInput = page
.getByTestId("transaction-reference-input")
.locator("input"),
readonly confirmButton = page.getByTestId("submit"),
) {}

async typeAndSaveOrderReference(value = "09728937896253") {
await this.transactionReferenceInput.fill(value);
await this.confirmButton.click();
await this.transactionReferenceInput.waitFor({ state: "hidden" });
}
}
15 changes: 15 additions & 0 deletions playwright/pages/fulfillmentPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Page } from "@playwright/test";

export class FulfillmentPage {
readonly page: Page;
constructor(
page: Page,
readonly fulfillButton = page.getByTestId("button-bar-confirm"),
) {
this.page = page;
}

async clickFulfillButton() {
await this.fulfillButton.click();
}
}
30 changes: 28 additions & 2 deletions playwright/pages/ordersPage.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import { URL_LIST } from "@data/url";
import { ManualTransactionDialog } from "@dialogs/manualTransactionDialog";
import { MarkOrderAsPaidDialog } from "@dialogs/markOrderAsPaidDialog";
import { BasePage } from "@pages/basePage";
import { AddProductsDialog } from "@pages/dialogs/addProductsDialog";
import { AddressDialog } from "@pages/dialogs/addressDialog";
import { OrderCreateDialog } from "@pages/dialogs/orderCreateDialog";
import { ShippingAddressDialog } from "@pages/dialogs/shippingMethodDialog";
import { Page } from "@playwright/test";

import { BasePage } from "./basePage";

export class OrdersPage extends BasePage {
orderCreateDialog: OrderCreateDialog;
markOrderAsPaidDialog: MarkOrderAsPaidDialog;
addProductsDialog: AddProductsDialog;
addressDialog: AddressDialog;
shippingAddressDialog: ShippingAddressDialog;
basePage: BasePage;
manualTransactionDialog: ManualTransactionDialog;

constructor(
page: Page,
readonly createOrderButton = page.getByTestId("create-order-button"),
readonly markAsPaidButton = page.getByTestId("markAsPaidButton"),
readonly manualTransactionButton = page.getByTestId(
"captureManualTransactionButton",
),
readonly orderSummarySection = page.getByTestId("OrderSummaryCard"),
readonly paymentSummarySection = page.getByTestId("payment-section"),
readonly paymentStatusInfo = page.getByTestId("payment-status"),
readonly fulfillButton = page.getByTestId("fulfill-button"),
readonly addProducts = page.getByTestId("add-products-button"),
readonly orderTransactionsList = page
.getByTestId("orderTransactionsList")
.locator("table"),
readonly salesChannel = page.getByTestId("salesChannel"),
readonly editCustomerButton = page.getByTestId("edit-customer"),
readonly searchCustomerInput = page.getByTestId("select-customer"),
Expand All @@ -35,11 +45,13 @@ export class OrdersPage extends BasePage {
),
) {
super(page);
this.markOrderAsPaidDialog = new MarkOrderAsPaidDialog(page);
this.orderCreateDialog = new OrderCreateDialog(page);
this.basePage = new BasePage(page);
this.addProductsDialog = new AddProductsDialog(page);
this.addressDialog = new AddressDialog(page);
this.shippingAddressDialog = new ShippingAddressDialog(page);
this.manualTransactionDialog = new ManualTransactionDialog(page);
}

async selectCustomer(customer = "allison.freeman@example.com") {
Expand All @@ -48,6 +60,15 @@ export class OrdersPage extends BasePage {
async clickCreateOrderButton() {
await this.createOrderButton.click();
}
async clickManualTransactionButton() {
await this.manualTransactionButton.click();
}
async clickMarkAsPaidButton() {
await this.markAsPaidButton.click();
}
async clickFulfillButton() {
await this.fulfillButton.click();
}
async clickAddShippingCarrierButton() {
await this.addShippingCarrierLink.click();
}
Expand All @@ -70,4 +91,9 @@ export class OrdersPage extends BasePage {
async goToOrdersListView() {
await this.page.goto(URL_LIST.orders);
}
async goToExistingOrderPage(orderId: string) {
const orderLink = URL_LIST.orders + orderId;
await console.log("Navigating to order details view: " + orderLink);
await this.page.goto(orderLink);
}
}
92 changes: 91 additions & 1 deletion playwright/tests/orders.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { PRODUCTS } from "@data/e2eTestData";
import { ORDERS, PRODUCTS } from "@data/e2eTestData";
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 fulfillmentPage: FulfillmentPage;

test.beforeEach(({ page }) => {
ordersPage = new OrdersPage(page);
fulfillmentPage = new FulfillmentPage(page);
});

test("TC: SALEOR_28 Create basic order @e2e @order", async () => {
Expand Down Expand Up @@ -55,3 +58,90 @@ test("TC: SALEOR_76 Create order with transaction flow activated @e2e @order", a
await expect(ordersPage.orderSummarySection).toBeVisible();
await expect(ordersPage.fulfillButton).toBeDisabled();
});

test("TC: SALEOR_77 Mark order as paid and fulfill it with transaction flow activated @e2e @order", async () => {
await ordersPage.goToExistingOrderPage(
ORDERS.ordersWithinTransactionFlow.markAsPaidOrder.orderId,
);
await ordersPage.waitForGrid();
await ordersPage.clickMarkAsPaidButton();
await ordersPage.markOrderAsPaidDialog.typeAndSaveOrderReference();
await ordersPage.expectSuccessBannerMessage("paid");
const transactionsMadeRows = await ordersPage.orderTransactionsList.locator(
"tr",
);
expect(await transactionsMadeRows.count()).toEqual(1);
await expect(transactionsMadeRows).toContainText("Success");
await ordersPage.clickFulfillButton();
await fulfillmentPage.clickFulfillButton();
await ordersPage.expectSuccessBannerMessage("fulfilled");
expect(await ordersPage.pageHeaderStatusInfo).toContainText("Fulfilled");
});

test("TC: SALEOR_78 Capture partial amounts by manual transactions and fulfill order with transaction flow activated @e2e @order", async () => {
const firstManualTransactionAmount = "100";
const secondManualTransactionAmount = "20";

await ordersPage.goToExistingOrderPage(
ORDERS.ordersWithinTransactionFlow.captureManualTransactionOrder.orderId,
);
await ordersPage.waitForGrid();
await ordersPage.clickManualTransactionButton();
await ordersPage.manualTransactionDialog.completeManualTransactionDialogAndSave(
"partial payment 1",
"111111",
firstManualTransactionAmount,
);
const completedTransactionsRows =
await ordersPage.orderTransactionsList.locator("tr");

await expect(
completedTransactionsRows.filter({
hasText: `EUR${firstManualTransactionAmount}`,
}),
"Row with first manual transaction details is visible with Success status",
).toContainText("Success");
expect(
await ordersPage.pageHeaderStatusInfo,
"Order should not be yet fulfilled",
).toContainText("Unfulfilled");
expect(
await ordersPage.paymentStatusInfo,
"Order should be partially paid",
).toContainText("Partially paid");

await ordersPage.clickManualTransactionButton();
await ordersPage.manualTransactionDialog.completeManualTransactionDialogAndSave(
"partial payment 2",
"222222",
secondManualTransactionAmount,
);

await expect(
completedTransactionsRows.filter({
hasText: `EUR${secondManualTransactionAmount}`,
}),
"Row with first manual transaction details is visible with Success status",
).toContainText("Success");
expect(
await completedTransactionsRows.filter({ hasText: "Success" }).count(),
"Two rows are visible within Manual capture sections with Success status",
).toEqual(2);
expect(
await ordersPage.pageHeaderStatusInfo,
"Order should not be yet fulfilled",
).toContainText("Unfulfilled");
expect(
await ordersPage.paymentStatusInfo,
"Order should fully paid",
).toContainText("Fully paid");

await ordersPage.clickFulfillButton();
await fulfillmentPage.clickFulfillButton();
await ordersPage.expectSuccessBannerMessage("fulfilled");

expect(
await ordersPage.pageHeaderStatusInfo,
"Order should be yet fulfilled",
).toContainText("Fulfilled");
});
2 changes: 1 addition & 1 deletion src/orders/components/OrderDetailsPage/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const Title: React.FC<TitleProps> = props => {
{ orderNumber: order?.number },
)}
<div className={classes.statusContainer}>
<Pill label={localized} color={status} />
<Pill data-test-id="status-info" label={localized} color={status} />
</div>
</Box>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const OrderPaymentSummaryCard: React.FC<OrderPaymementProps> = ({
label={payment.localized}
color={payment.status}
className={classes.paymentStatus}
data-test-id="payment-status"
/>
}
title={<FormattedMessage {...orderPaymentMessages.paymentTitle} />}
Expand Down
Loading