From 0b1d0a3a54d1620e6f1f4565aca2de79fa6ffc56 Mon Sep 17 00:00:00 2001 From: Karolina Rakoczy Date: Mon, 31 May 2021 09:50:31 +0200 Subject: [PATCH] Saleor 3357 tests for orders (#1119) * add tests for puchase by type * add expect for isShippingRequired * tests for adyen * tests for adyen * tests for adyen * tests for adyen * adyen * adyen * adyen * adyen * adyen * warehouses in chcekout * rm warehouses in chcekout * adyen payments * adyen * tests for orders * fix shipping * unskipp * orders * add empty lines * add empty lines and reduce * add empty lines --- cypress/apiRequests/Order.js | 35 ++++- cypress/elements/orders/order-refund.js | 3 + cypress/elements/orders/orders-selectors.js | 6 +- cypress/elements/shared/button-selectors.js | 3 +- cypress/elements/shared/sharedElements.js | 3 +- .../allEnv/configuration/shippingMethod.js | 8 ++ .../allEnv/homePage/homePageAnalitics.js | 53 +++---- cypress/integration/allEnv/orders/orders.js | 77 +++++++++- cypress/steps/shippingMethodSteps.js | 3 + cypress/utils/ordersUtils.js | 29 +++- src/components/CardMenu/CardMenu.tsx | 2 + .../OrderDetailsPage/OrderDetailsPage.tsx | 2 +- .../OrderFulfilledProductsCard.tsx | 3 +- .../OrderFulfillmentCancelDialog.tsx | 6 +- .../components/OrderPayment/OrderPayment.tsx | 7 +- .../__snapshots__/Stories.test.ts.snap | 133 ++++++++++++++++-- 16 files changed, 324 insertions(+), 49 deletions(-) create mode 100644 cypress/elements/orders/order-refund.js diff --git a/cypress/apiRequests/Order.js b/cypress/apiRequests/Order.js index dc1f8613d..add292725 100644 --- a/cypress/apiRequests/Order.js +++ b/cypress/apiRequests/Order.js @@ -52,19 +52,25 @@ export function createDraftOrder( .sendRequestWithQuery(mutation) .its("body.data.draftOrderCreate.order"); } + export function completeOrder(orderId) { const mutation = `mutation{ draftOrderComplete(id:"${orderId}"){ order{ id + number + lines{ + id + } } orderErrors{ message } } }`; - return cy.sendRequestWithQuery(mutation); + return cy.sendRequestWithQuery(mutation).its("body.data.draftOrderComplete"); } + export function getOrder(orderId) { const query = `query getOrder{ order(id:"${orderId}"){ @@ -78,3 +84,30 @@ export function getOrder(orderId) { }`; cy.sendRequestWithQuery(query).its("body.data.order"); } + +export function fulfillOrder({ orderId, warehouse, quantity, linesId }) { + const lines = linesId.reduce((lines, lineId) => { + const line = `{orderLineId:"${lineId.id}" + stocks:{ + quantity:${quantity} + warehouse:"${warehouse}" + } + }`; + return lines + line; + }, ""); + const mutation = `mutation fulfill{ + orderFulfill(order:"${orderId}" input:{ + lines:[${lines}] + }){ + errors{ + field + message + } + order{ + id + number + } + } +}`; + return cy.sendRequestWithQuery(mutation).its("body.data.orderFulfill"); +} diff --git a/cypress/elements/orders/order-refund.js b/cypress/elements/orders/order-refund.js new file mode 100644 index 000000000..266799b2c --- /dev/null +++ b/cypress/elements/orders/order-refund.js @@ -0,0 +1,3 @@ +export const ORDER_REFUND = { + productsQuantityInput: '[data-test="quantityInput"]' +}; diff --git a/cypress/elements/orders/orders-selectors.js b/cypress/elements/orders/orders-selectors.js index ac1b301c6..c35489ec7 100644 --- a/cypress/elements/orders/orders-selectors.js +++ b/cypress/elements/orders/orders-selectors.js @@ -2,5 +2,9 @@ export const ORDERS_SELECTORS = { orders: "[data-test='submenu-item-label'][data-test-id='orders']", createOrder: "[data-test-id='create-order-button']", orderRow: "[data-test-id='order-table-row']", - salesChannel: "[data-test-id='order-sales-channel']" + salesChannel: "[data-test-id='order-sales-channel']", + cancelFulfillment: "[data-test-id='cancelFulfillmentButton']", + cancelFulfillmentSelectField: "[data-test-id='cancelFulfillmentSelectField']", + orderFulfillmentFrame: "[data-test-id='orderFulfillment']", + refundButton: '[data-test-id="refund-button"]' }; diff --git a/cypress/elements/shared/button-selectors.js b/cypress/elements/shared/button-selectors.js index 584f90913..0b2102f20 100644 --- a/cypress/elements/shared/button-selectors.js +++ b/cypress/elements/shared/button-selectors.js @@ -8,5 +8,6 @@ export const BUTTON_SELECTORS = { selectOption: "[data-test*='select-option']", notSelectedOption: ":not([aria-selected])", deleteButton: '[data-test="button-bar-delete"]', - expandIcon: '[data-test-id="expand-icon"]' + expandIcon: '[data-test-id="expand-icon"]', + showMoreButton: '[data-test-id="showMoreButton"]' }; diff --git a/cypress/elements/shared/sharedElements.js b/cypress/elements/shared/sharedElements.js index 4a2375bb6..8333d8fd9 100644 --- a/cypress/elements/shared/sharedElements.js +++ b/cypress/elements/shared/sharedElements.js @@ -1,5 +1,6 @@ export const SHARED_ELEMENTS = { header: "[data-test-id='page-header']", progressBar: '[role="progressbar"]', - skeleton: '[data-test-id="skeleton"]' + skeleton: '[data-test-id="skeleton"]', + table: 'table[class*="Table"]' }; diff --git a/cypress/integration/allEnv/configuration/shippingMethod.js b/cypress/integration/allEnv/configuration/shippingMethod.js index af13fa2e9..87aea03de 100644 --- a/cypress/integration/allEnv/configuration/shippingMethod.js +++ b/cypress/integration/allEnv/configuration/shippingMethod.js @@ -8,6 +8,8 @@ import { addChannelToShippingZone } from "../../../apiRequests/ShippingMethod"; import { createWarehouse } from "../../../apiRequests/Warehouse"; +import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors"; +import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements"; import { SHIPPING_ZONE_DETAILS } from "../../../elements/shipping/shipping-zone-details"; import { selectChannelInHeader } from "../../../steps/channelsSteps"; import { @@ -121,6 +123,12 @@ describe("Shipping methods", () => { ) .then(() => { cy.addAliasToGraphRequest("ShippingZone"); + cy.getTextFromElement(SHARED_ELEMENTS.table); + }) + .then(tableText => { + if (!tableText.includes(shippingZone.name)) { + cy.get(BUTTON_SELECTORS.nextPaginationButton).click(); + } cy.contains(shippingZone.name).click(); cy.wait("@ShippingZone"); selectChannelInHeader(defaultChannel.name); diff --git a/cypress/integration/allEnv/homePage/homePageAnalitics.js b/cypress/integration/allEnv/homePage/homePageAnalitics.js index d4a741107..41110c169 100644 --- a/cypress/integration/allEnv/homePage/homePageAnalitics.js +++ b/cypress/integration/allEnv/homePage/homePageAnalitics.js @@ -18,7 +18,7 @@ import * as shippingUtils from "../../../utils/shippingUtils"; // describe("Homepage analytics", () => { - const startsWith = "CyHomeAnalytics-"; + const startsWith = "CyHomeAnalytics"; let customerId; let defaultChannel; @@ -33,7 +33,7 @@ describe("Homepage analytics", () => { const productPrice = 22; const shippingPrice = 12; const randomName = startsWith + faker.datatype.number(); - const randomEmail = randomName + "@example.com"; + const randomEmail = `${startsWith}${randomName}@example.com`; before(() => { cy.clearSessionData().loginUserViaRequest(); @@ -109,13 +109,13 @@ describe("Homepage analytics", () => { homePageUtils .getOrdersReadyToFulfill(defaultChannel.slug) .as("ordersReadyToFulfill"); - createReadyToFulfillOrder( + createReadyToFulfillOrder({ customerId, - shippingMethod.id, - defaultChannel.id, - createdVariants, - addresses.plAddress - ); + shippingMethodId: shippingMethod.id, + channelId: defaultChannel.id, + variantsList: createdVariants, + address: addresses.plAddress + }); cy.get("@ordersReadyToFulfill").then(ordersReadyToFulfillBefore => { const allOrdersReadyToFulfill = ordersReadyToFulfillBefore + 1; const notANumberRegex = "\\D*"; @@ -130,6 +130,7 @@ describe("Homepage analytics", () => { ).should("be.visible"); }); }); + it("should correct amount of payments waiting for capture be displayed", () => { homePageUtils .getOrdersReadyForCapture(defaultChannel.slug) @@ -157,6 +158,7 @@ describe("Homepage analytics", () => { ).should("be.visible"); }); }); + it("should correct amount of products out of stock be displayed", () => { homePageUtils .getProductsOutOfStock(defaultChannel.slug) @@ -188,16 +190,17 @@ describe("Homepage analytics", () => { ).should("be.visible"); }); }); + it("should correct amount of sales be displayed", () => { homePageUtils.getSalesAmount(defaultChannel.slug).as("salesAmount"); - createReadyToFulfillOrder( + createReadyToFulfillOrder({ customerId, - shippingMethod.id, - defaultChannel.id, - createdVariants, - addresses.plAddress - ); + shippingMethodId: shippingMethod.id, + channelId: defaultChannel.id, + variantsList: createdVariants, + address: addresses.plAddress + }); cy.get("@salesAmount").then(salesAmount => { const totalAmount = salesAmount + productPrice; @@ -205,10 +208,11 @@ describe("Homepage analytics", () => { const totalAmountIntegerValue = totalAmountString.split(".")[0]; const totalAmountDecimalValue = totalAmountString.split(".")[1]; const decimalSeparator = "[,.]"; - const totalAmountIntegerWithThousandsSeparator = totalAmountIntegerValue.replace( - /(\d)(?=(\d{3})+(?!\d))/g, - "1[,.]*" - ); + const totalAmountIntegerWithThousandsSeparator = new Intl.NumberFormat( + "en" + ) + .format(totalAmountIntegerValue) + .replaceAll(",", "[,.]*"); const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`; const notANumberRegex = "\\D*"; const salesAmountRegexp = new RegExp( @@ -221,16 +225,17 @@ describe("Homepage analytics", () => { ); }); }); + it("should correct amount of orders be displayed", () => { homePageUtils.getTodaysOrders(defaultChannel.slug).as("todaysOrders"); - createReadyToFulfillOrder( + createReadyToFulfillOrder({ customerId, - shippingMethod.id, - defaultChannel.id, - createdVariants, - addresses.plAddress - ); + shippingMethodId: shippingMethod.id, + channelId: defaultChannel.id, + variantsList: createdVariants, + address: addresses.plAddress + }); cy.get("@todaysOrders").then(ordersBefore => { const allOrders = ordersBefore + 1; diff --git a/cypress/integration/allEnv/orders/orders.js b/cypress/integration/allEnv/orders/orders.js index c46373f3a..d9bc610fc 100644 --- a/cypress/integration/allEnv/orders/orders.js +++ b/cypress/integration/allEnv/orders/orders.js @@ -5,12 +5,21 @@ import { createCustomer, deleteCustomersStartsWith } from "../../../apiRequests/Customer"; +import { getOrder } from "../../../apiRequests/Order"; +import { ORDER_REFUND } from "../../../elements/orders/order-refund"; import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors"; +import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors"; +import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements"; import { selectChannelInPicker } from "../../../steps/channelsSteps"; import { finalizeDraftOrder } from "../../../steps/draftOrderSteps"; +import { fillAutocompleteSelect } from "../../../steps/shared/autocompleteSelect"; import { urlList } from "../../../url/urlList"; import { getDefaultChannel } from "../../../utils/channelsUtils"; -import { createOrder } from "../../../utils/ordersUtils"; +import { + createFulfilledOrder, + createOrder, + createReadyToFulfillOrder +} from "../../../utils/ordersUtils"; import * as productsUtils from "../../../utils/products/productsUtils"; import { createShipping, @@ -98,6 +107,7 @@ describe("Orders", () => { ); }); }); + it("should not be possible to change channel in order", () => { createOrder({ customerId: customer.id, @@ -113,4 +123,69 @@ describe("Orders", () => { .should("not.exist"); }); }); + + it("should cancel fulfillment", () => { + let order; + createFulfilledOrder({ + customerId: customer.id, + channelId: defaultChannel.id, + shippingMethodId: shippingMethod.id, + variantsList, + address, + warehouse: warehouse.id + }) + .then(({ order: orderResp }) => { + order = orderResp; + cy.visit(urlList.orders); + cy.contains(ORDERS_SELECTORS.orderRow, order.number).click(); + cy.get(SHARED_ELEMENTS.skeleton) + .should("not.exist") + .get(ORDERS_SELECTORS.orderFulfillmentFrame) + .find(BUTTON_SELECTORS.showMoreButton) + .click() + .get(ORDERS_SELECTORS.cancelFulfillment) + .click(); + }) + .then(() => { + fillAutocompleteSelect( + ORDERS_SELECTORS.cancelFulfillmentSelectField, + warehouse.name + ); + cy.addAliasToGraphRequest("OrderFulfillmentCancel"); + cy.get(BUTTON_SELECTORS.submit).click(); + cy.wait("@OrderFulfillmentCancel"); + getOrder(order.id); + }) + .then(orderResp => { + expect(orderResp.status).to.be.eq("UNFULFILLED"); + }); + }); + + it("should make a refund", () => { + let order; + createReadyToFulfillOrder({ + customerId: customer.id, + channelId: defaultChannel.id, + shippingMethodId: shippingMethod.id, + variantsList, + address + }) + .then(({ order: orderResp }) => { + order = orderResp; + cy.visit(urlList.orders); + cy.contains(ORDERS_SELECTORS.orderRow, order.number).click(); + cy.get(ORDERS_SELECTORS.refundButton) + .click() + .get(ORDER_REFUND.productsQuantityInput) + .type("1") + .addAliasToGraphRequest("OrderFulfillmentRefundProducts"); + cy.get(BUTTON_SELECTORS.submit) + .click() + .wait("@OrderFulfillmentRefundProducts"); + getOrder(order.id); + }) + .then(orderResp => { + expect(orderResp.paymentStatus).to.be.eq("FULLY_REFUNDED"); + }); + }); }); diff --git a/cypress/steps/shippingMethodSteps.js b/cypress/steps/shippingMethodSteps.js index eb77a7045..2905c79af 100644 --- a/cypress/steps/shippingMethodSteps.js +++ b/cypress/steps/shippingMethodSteps.js @@ -1,4 +1,5 @@ import { BUTTON_SELECTORS } from "../elements/shared/button-selectors"; +import { SHARED_ELEMENTS } from "../elements/shared/sharedElements"; import { SHIPPING_RATE_DETAILS } from "../elements/shipping/shipping-rate-details"; import { SHIPPING_ZONE_DETAILS } from "../elements/shipping/shipping-zone-details"; import { SHIPPING_ZONES_LIST } from "../elements/shipping/shipping-zones-list"; @@ -42,6 +43,8 @@ export function createShippingZone( export function createShippingRate(rateName, price, rateOption) { cy.get(rateOption) .click() + .get(SHARED_ELEMENTS.progressBar) + .should("not.be.visible") .get(SHIPPING_RATE_DETAILS.inputName) .type(rateName) .get(SHIPPING_RATE_DETAILS.priceInput) diff --git a/cypress/utils/ordersUtils.js b/cypress/utils/ordersUtils.js index a5eb9f3d7..4ebc19022 100644 --- a/cypress/utils/ordersUtils.js +++ b/cypress/utils/ordersUtils.js @@ -44,13 +44,13 @@ export function createCheckoutWithVoucher({ .its("body.data.checkoutAddPromoCode"); } -export function createReadyToFulfillOrder( +export function createReadyToFulfillOrder({ customerId, shippingMethodId, channelId, variantsList, address -) { +}) { let order; return orderRequest .createDraftOrder(customerId, shippingMethodId, channelId, address) @@ -62,6 +62,31 @@ export function createReadyToFulfillOrder( .then(() => orderRequest.completeOrder(order.id)); } +export function createFulfilledOrder({ + customerId, + shippingMethodId, + channelId, + variantsList, + address, + warehouse, + quantity = 1 +}) { + return createReadyToFulfillOrder({ + customerId, + shippingMethodId, + channelId, + variantsList, + address + }).then(({ order }) => { + orderRequest.fulfillOrder({ + orderId: order.id, + warehouse, + quantity, + linesId: order.lines + }); + }); +} + export function createOrder({ customerId, shippingMethodId, diff --git a/src/components/CardMenu/CardMenu.tsx b/src/components/CardMenu/CardMenu.tsx index 7376db274..886a71bc3 100644 --- a/src/components/CardMenu/CardMenu.tsx +++ b/src/components/CardMenu/CardMenu.tsx @@ -90,6 +90,7 @@ const CardMenu: React.FC = props => { return (
= props => { > {menuItems.map((menuItem, menuItemIndex) => ( handleMenuClick(menuItemIndex)} key={menuItem.label} diff --git a/src/orders/components/OrderDetailsPage/OrderDetailsPage.tsx b/src/orders/components/OrderDetailsPage/OrderDetailsPage.tsx index 28b7b5539..f7f3832ad 100644 --- a/src/orders/components/OrderDetailsPage/OrderDetailsPage.tsx +++ b/src/orders/components/OrderDetailsPage/OrderDetailsPage.tsx @@ -223,7 +223,7 @@ const OrderDetailsPage: React.FC = props => { )}
-
+
{!isOrderUnconfirmed ? ( = pr defaultMessage: "Cancel Fulfillment", description: "button" }), - onSelect: onOrderFulfillmentCancel + onSelect: onOrderFulfillmentCancel, + testId: "cancelFulfillmentButton" } ]} /> diff --git a/src/orders/components/OrderFulfillmentCancelDialog/OrderFulfillmentCancelDialog.tsx b/src/orders/components/OrderFulfillmentCancelDialog/OrderFulfillmentCancelDialog.tsx index a3acdc256..dcabffd4c 100644 --- a/src/orders/components/OrderFulfillmentCancelDialog/OrderFulfillmentCancelDialog.tsx +++ b/src/orders/components/OrderFulfillmentCancelDialog/OrderFulfillmentCancelDialog.tsx @@ -97,7 +97,10 @@ const OrderFulfillmentCancelDialog: React.FC -
+
= props => { )} {canRefund && ( -