Skip to content

Commit

Permalink
e2e tests for refunds
Browse files Browse the repository at this point in the history
  • Loading branch information
yellowee committed Jun 27, 2024
1 parent 6b8be89 commit f403822
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 11 deletions.
31 changes: 27 additions & 4 deletions playwright/data/e2eTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,17 +433,40 @@ export const ORDERS = {
id: "T3JkZXI6ZWFhZjA0MzgtNzkyYi00ZTdlLWIyODUtMTBkMjViMjM0MzRk",
},
fullyPaidOrdersWithSingleTransaction: {
ids: [
"T3JkZXI6ZjZjZWUxMzItNDk2Zi00MWUyLWJkNTItYTk1MDM1YTVlZmVm",
"T3JkZXI6YzI4YjFmYmEtZWU1NS00YmU5LTg5MjktNTMyYzk5MDlkZGVk",
],
first: {
id: "T3JkZXI6ZjZjZWUxMzItNDk2Zi00MWUyLWJkNTItYTk1MDM1YTVlZmVm",
lineItems: [
{
name: "Bean Juice",
quantity: "1",
},
{ name: "Lake Tunes", quantity: "2" },
],
},
second: {
id: "T3JkZXI6YzI4YjFmYmEtZWU1NS00YmU5LTg5MjktNTMyYzk5MDlkZGVk",
lineItems: ["Blue Hoodie 2", "Black Hoodie", "Mustard Hoodie", "White Hoodie"],
},
},
fullyPaidOrderWithSeveralTransactions: {
id: "T3JkZXI6MTVhYTEwMzYtZWE3OS00MzJiLTliODctNDhlYTMwYmU1NmNl",
},
partiallyPaidOrder: {
id: "T3JkZXI6NmVlMDMwMTctZTViOS00OGNmLWFkYTQtODg4YTQ5MDI3ZjNk",
},
orderWithRefunds: {
id: "T3JkZXI6Y2YyY2EwNWYtZmQ3Yy00ODk5LThjZTktMzQ4NjYxYThjZDkx",
refunds: [
{
lineOrderRefundId: "T3JkZXJHcmFudGVkUmVmdW5kOjE=",
amount: 4.5,
},
{
manualRefundId: "",
amount: 22.0,
},
],
},
};

export const SHIPPING_METHODS = {
Expand Down
21 changes: 21 additions & 0 deletions playwright/pages/dialogs/lineRefundReasonDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Page } from "@playwright/test";

export class AddLineRefundReasonDialog {
readonly page: Page;

constructor(
page: Page,
readonly lineRefundReasonInput = page.getByTestId("line-refund-reason-input"),
readonly confirmButton = page.getByTestId("confirm-button"),
) {
this.page = page;
}

async provideLineRefundReason(reason: string) {
await this.lineRefundReasonInput.fill(reason);
}

async submitLineRefundReason() {
await this.confirmButton.click();
}
}
24 changes: 24 additions & 0 deletions playwright/pages/dialogs/orderRefundDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { BasePage } from "@pages/basePage";
import { Page } from "@playwright/test";

export class OrderRefundDialog extends BasePage {
constructor(
page: Page,
readonly standardRefund = page.getByTestId("standard-refund"),
readonly manualRefund = page.getByTestId("manual-refund"),
readonly backButton = page.getByTestId("back-button"),
readonly proceedButton = page.getByTestId("proceed-button"),
) {
super(page);
}

async pickLineItemsRefund() {
await this.standardRefund.click();
await this.proceedButton.click();
}

async pickManualRefund() {
await this.manualRefund.click();
await this.proceedButton.click();
}
}
15 changes: 13 additions & 2 deletions playwright/pages/ordersPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { OrderCreateDialog } from "@pages/dialogs/orderCreateDialog";
import { ShippingAddressDialog } from "@pages/dialogs/shippingMethodDialog";
import { Page } from "@playwright/test";

import { OrderRefundDialog } from "./dialogs/orderRefundDialog";

export class OrdersPage extends BasePage {
orderCreateDialog: OrderCreateDialog;

Expand All @@ -29,6 +31,8 @@ export class OrdersPage extends BasePage {

rightSideDetailsPage: RightSideDetailsPage;

orderRefundDialog: OrderRefundDialog;

constructor(
page: Page,
readonly createOrderButton = page.getByTestId("create-order-button"),
Expand All @@ -47,8 +51,9 @@ export class OrdersPage extends BasePage {
readonly salesChannel = page.getByTestId("salesChannel"),
readonly addShippingCarrierLink = page.getByTestId("add-shipping-carrier"),
readonly finalizeButton = page.getByTestId("button-bar-confirm"),

readonly addRefundButton = page.getByTestId("add-new-refund-button"),
readonly customerEmail = page.getByTestId("customer-email"),
readonly orderRefundModal = page.getByTestId("order-refund-dialog"),
) {
super(page);
this.markOrderAsPaidDialog = new MarkOrderAsPaidDialog(page);
Expand All @@ -60,6 +65,7 @@ export class OrdersPage extends BasePage {
this.manualTransactionDialog = new ManualTransactionDialog(page);
this.addTrackingDialog = new AddTrackingDialog(page);
this.rightSideDetailsPage = new RightSideDetailsPage(page);
this.orderRefundDialog = new OrderRefundDialog(page);
}

async clickCreateOrderButton() {
Expand Down Expand Up @@ -104,6 +110,11 @@ export class OrdersPage extends BasePage {

await console.log("Navigating to order details view: " + orderLink);
await this.page.goto(orderLink);
await this.waitForGrid();
await this.waitForDOMToFullyLoad();
}

async clickAddRefundButton() {
await this.addRefundButton.click();
await this.orderRefundModal.waitFor({ state: "visible" });
}
}
78 changes: 78 additions & 0 deletions playwright/pages/refundPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { URL_LIST } from "@data/url";
import { AddLineRefundReasonDialog } from "@pages/dialogs/lineRefundReasonDialog";
import { OrdersPage } from "@pages/ordersPage";
import { expect, Page } from "@playwright/test";

export class RefundPage extends OrdersPage {
addLineRefundReasonDialog: AddLineRefundReasonDialog;

constructor(
page: Page,
readonly allButton = page.getByTestId("all-button"),
readonly productQuantityInput = page.getByTestId("product-quantity-input"),
readonly maxLineRefundQuantity = page.getByTestId("max-line-refund-quantity"),
readonly refundReasonInput = page.getByTestId("refund-reason-input"),
readonly lineRefundReasonDialog = page.getByTestId("refund-reason-dialog"),
readonly lineRefundReasonButton = page.getByTestId("line-refund-reason-button"),
) {
super(page);
this.addLineRefundReasonDialog = new AddLineRefundReasonDialog(page);
}

async getProductRow(productName: string) {
return await this.page.locator("table tr").filter({ hasText: productName });
}

async expectLineItemsRefundPageOpen(orderId: string) {
const orderLink = `${URL_LIST.orders}${orderId}/refund`;

await expect(this.page).toHaveURL(orderLink);
await this.waitForDOMToFullyLoad();
await expect(this.pageHeader).toContainText("Create refund with line items");
}

async expectManualRefundPageOpen(orderId: string) {
const orderLink = `${URL_LIST.orders}${orderId}/manual-refund`;

await expect(this.page).toHaveURL(orderLink);
await expect(this.pageHeader).toContainText("Refund with manual amount");
}

async pickAllProductQuantityToRefund(productName: string) {
const productRow = await this.getProductRow(productName);

await productRow.locator(this.allButton).click();

const maxLineRefundQuantityText = await productRow
.locator(this.maxLineRefundQuantity)
.first()
.innerText();
const value = maxLineRefundQuantityText.slice(-1);

await expect(productRow.locator(this.productQuantityInput)).toHaveValue(value);
}

async provideRefundReason(reason: string) {
await this.refundReasonInput.fill(reason);
}

async clickLineRefundReasonButton(productName: string) {
const productRow = await this.getProductRow(productName);

await productRow.locator(this.lineRefundReasonButton).click();
await this.lineRefundReasonDialog.waitFor({ state: "visible" });
}

async inputProductLineQuantity(productName: string, amount: string) {
const productRow = await this.getProductRow(productName);

await productRow.locator(this.productQuantityInput).fill(amount);
await expect(productRow.locator(this.productQuantityInput)).toHaveValue(amount);
}

async saveDraft() {
await expect(this.saveButton).toHaveText("Save draft");
await this.clickSaveButton();
await this.waitForDOMToFullyLoad();
}
}
27 changes: 27 additions & 0 deletions playwright/tests/orders.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DraftOrdersPage } from "@pages/draftOrdersPage";
import { AddressForm } from "@pages/forms/addressForm";
import { FulfillmentPage } from "@pages/fulfillmentPage";
import { OrdersPage } from "@pages/ordersPage";
import { RefundPage } from "@pages/refundPage";
import { expect, test } from "@playwright/test";

test.use({ storageState: "./playwright/.auth/admin.json" });
Expand All @@ -16,6 +17,7 @@ let fulfillmentPage: FulfillmentPage;
let addressDialog: AddressDialog;
let addressForm: AddressForm;
let addressesListPage: AddressesListPage;
let refundPage: RefundPage;

test.beforeEach(({ page }) => {
ordersPage = new OrdersPage(page);
Expand All @@ -24,6 +26,7 @@ test.beforeEach(({ page }) => {
addressDialog = new AddressDialog(page);
addressesListPage = new AddressesListPage(page);
addressForm = new AddressForm(page);
refundPage = new RefundPage(page);
});

const variantSKU = PRODUCTS.productAvailableWithTransactionFlow.variant1sku;
Expand Down Expand Up @@ -252,3 +255,27 @@ test("TC: SALEOR_84 Create draft order @e2e @draft", async () => {
await draftOrdersPage.clickFinalizeButton();
await draftOrdersPage.expectSuccessBannerMessage("finalized");
});

test("TC: SALEOR_191 Refund products from the fully paid order @e2e @refunds", async () => {
const order = ORDERS.fullyPaidOrdersWithSingleTransaction.first;

await ordersPage.goToExistingOrderPage(order.id);
await ordersPage.clickAddRefundButton();
await ordersPage.orderRefundDialog.pickLineItemsRefund();
await ordersPage.orderRefundModal.waitFor({ state: "hidden" });
await refundPage.expectLineItemsRefundPageOpen(order.id);
await refundPage.pickAllProductQuantityToRefund(order.lineItems[0].name);

const productRow = await refundPage.getProductRow(order.lineItems[0].name);

expect(productRow.locator(refundPage.productQuantityInput)).toHaveValue(
order.lineItems[0].quantity,
);

await refundPage.inputProductLineQuantity(order.lineItems[1].name, "1");
await refundPage.clickLineRefundReasonButton(order.lineItems[0].name);
await refundPage.addLineRefundReasonDialog.provideLineRefundReason("Item is damaged");
await refundPage.addLineRefundReasonDialog.submitLineRefundReason();
await refundPage.provideRefundReason("Expectations not met");
await refundPage.saveDraft();
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const OrderDetailsRefundTable: React.FC<OrderDetailsRefundTableProps> = (
<Tooltip>
<Tooltip.Trigger>
<Button
data-test-id="add-new-refund-button"
variant="secondary"
onClick={onRefundAdd}
disabled={!isRefundPossible.canRefund}
Expand Down
9 changes: 6 additions & 3 deletions src/orders/components/OrderRefundDialog/OrderRefundDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const OrderRefundDialog = ({

return (
<DashboardModal open={open} onChange={onClose}>
<DashboardModal.Content __width="400px">
<DashboardModal.Content __width="400px" data-test-id="order-refund-dialog">
<DashboardModal.Title>
{intl.formatMessage(orderRefundDialogMesages.title)}
</DashboardModal.Title>
Expand Down Expand Up @@ -71,10 +71,13 @@ export const OrderRefundDialog = ({
</Box>
</RadioTiles>
<DashboardModal.Actions>
<Button onClick={onClose} variant="secondary">
<Button onClick={onClose} variant="secondary" data-test-id="back-button">
<Text fontWeight="medium">{intl.formatMessage(buttonMessages.back)}</Text>
</Button>
<Button onClick={selectedRefundType === "standard" ? onStandardRefund : onManualRefund}>
<Button
onClick={selectedRefundType === "standard" ? onStandardRefund : onManualRefund}
data-test-id="proceed-button"
>
<Text fontWeight="medium" color="buttonDefaultPrimary">
{intl.formatMessage(buttonMessages.proceed)}
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const OrderTransactionReason: React.FC<OrderTransactionReasonProps> = ({
<FormattedMessage {...transactionRefundReasonMessages.reasonForRefund} />
</Text>
<Textarea
data-test-id="refund-reason-input"
placeholder={intl.formatMessage(transactionRefundReasonMessages.optionalPlaceholder)}
size="medium"
rows={4}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const OrderTransactionReasonModal = ({
</DashboardModal.Title>

<Textarea
data-test-id="line-refund-reason-input"
rows={5}
value={tempReason}
onChange={event => setTempReason(event.target.value)}
Expand All @@ -50,7 +51,7 @@ export const OrderTransactionReasonModal = ({
onConfirm(tempReason);
onClose();
}}
data-test-id="edit-reason-button"
data-test-id="confirm-button"
>
<FormattedMessage {...buttonMessages.confirm} />
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ export const RefundTableInputCell: React.FC<RefundTableInputCellProps> = ({
name={`linesToRefund.${index}`}
render={({ field: inputField }) => (
<Input
data-test-id="product-quantity-input"
{...inputField}
__minWidth="40px"
width="100%"
placeholder="0"
endAdornment={
<Box whiteSpace="nowrap">
<Box whiteSpace="nowrap" data-test-id="max-line-refund-quantity">
<FormattedMessage
{...refundTableMessages.maxToRefund}
values={{ value: maxQtyToRefund.toString() }}
Expand All @@ -60,6 +61,7 @@ export const RefundTableInputCell: React.FC<RefundTableInputCellProps> = ({
/>

<Button
data-test-id="all-button"
variant="secondary"
size="medium"
onClick={handleMaxRefund}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const RefundTableReasonCell: React.FC<RefundTableReasonCellProps> = ({
return (
<GridTable.Cell>
<Button
data-test-id="line-refund-reason-button"
variant="secondary"
whiteSpace="nowrap"
onClick={() => onEditReasonModal(index)}
Expand Down

0 comments on commit f403822

Please sign in to comment.