From e76c78a23bcc18c7d6a669bd8242693a5540539e Mon Sep 17 00:00:00 2001 From: Karolina Rakoczy Date: Mon, 12 Jul 2021 10:50:50 +0200 Subject: [PATCH] tests for shipping (#1173) * tests for shipping * fix typo Co-authored-by: Jakub Majorek * add data-test-id Co-authored-by: Jakub Majorek --- cypress/apiRequests/Product.js | 26 +- cypress/apiRequests/ShippingMethod.js | 25 +- cypress/apiRequests/StaffMembers.js | 73 ++++++ cypress/apiRequests/shopSettings.js | 16 ++ cypress/apiRequests/staffMember.js | 88 ------- cypress/apiRequests/utils/Utils.js | 6 + cypress/elements/shared/sharedElements.js | 8 +- .../shipping/shipping-rate-details.js | 13 +- .../shipping/shipping-zone-details.js | 2 + .../elements/shipping/shipping-zones-list.js | 4 +- cypress/fixtures/addresses.json | 14 ++ .../allEnv/checkout/stocksInCheckout.js | 26 ++ .../allEnv/configuration/shippingMethod.js | 224 ------------------ .../shippingMethods/channelsInShipping.js | 124 ++++++++++ .../shippingMethods/createShippingMethod.js | 141 +++++++++++ .../shippingMethods/postalCodes.js | 134 +++++++++++ .../shippingMethods/shippingWeight.js | 187 +++++++++++++++ .../allEnv/configuration/warehouse.js | 2 +- cypress/integration/allEnv/orders/orders.js | 2 +- .../integration/stagedOnly/staffMembers.js | 2 +- .../steps/catalog/products/productSteps.js | 2 +- cypress/steps/channelsSteps.js | 2 +- cypress/steps/shared/addressForm.js | 2 +- .../{autocompleteSelect.js => selects.js} | 8 + cypress/steps/shippingMethodSteps.js | 125 +++++++++- cypress/steps/user.js | 2 +- cypress/url/urlList.js | 5 + cypress/utils/ordersUtils.js | 20 +- cypress/utils/products/productsUtils.js | 6 +- cypress/utils/shippingUtils.js | 7 +- cypress/utils/users.js | 2 +- .../MultiAutocompleteSelectFieldContent.tsx | 6 +- .../ShippingWeightUnitForm.tsx | 2 +- .../ShippingZonePostalCodeRangeDialog.tsx | 1 + .../__snapshots__/Stories.test.ts.snap | 6 + 35 files changed, 960 insertions(+), 353 deletions(-) create mode 100644 cypress/apiRequests/shopSettings.js delete mode 100644 cypress/apiRequests/staffMember.js delete mode 100644 cypress/integration/allEnv/configuration/shippingMethod.js create mode 100644 cypress/integration/allEnv/configuration/shippingMethods/channelsInShipping.js create mode 100644 cypress/integration/allEnv/configuration/shippingMethods/createShippingMethod.js create mode 100644 cypress/integration/allEnv/configuration/shippingMethods/postalCodes.js create mode 100644 cypress/integration/allEnv/configuration/shippingMethods/shippingWeight.js rename cypress/steps/shared/{autocompleteSelect.js => selects.js} (73%) diff --git a/cypress/apiRequests/Product.js b/cypress/apiRequests/Product.js index 7dd85395d..5a4712901 100644 --- a/cypress/apiRequests/Product.js +++ b/cypress/apiRequests/Product.js @@ -1,5 +1,5 @@ import { stringify } from "../support/format/formatJson"; -import { getValueWithDefault } from "./utils/Utils"; +import { getValueWithDefault, getVariantsListIds } from "./utils/Utils"; export function getFirstProducts(first, search) { const filter = search @@ -143,7 +143,8 @@ export function createVariant({ attributeId, price = 1, costPrice = 1, - trackInventory = true + trackInventory = true, + weight = 1 }) { const channelListings = getValueWithDefault( channelId, @@ -168,6 +169,7 @@ export function createVariant({ id:"${attributeId}" values: ["value"] }] + weight: ${weight} sku: "${sku}" ${channelListings} trackInventory:${trackInventory} @@ -199,3 +201,23 @@ export function deleteProduct(productId) { } `; return cy.sendRequestWithQuery(mutation); } + +export function getVariants(variantsList) { + const variantsIds = getVariantsListIds(variantsList); + const query = `query{ + productVariants(first:100 ids:[${variantsIds}]){ + edges{ + node{ + stocks{ + warehouse{ + id + } + quantity + quantityAllocated + } + } + } + } + }`; + return cy.sendRequestWithQuery(query).its("body.data.productVariants"); +} diff --git a/cypress/apiRequests/ShippingMethod.js b/cypress/apiRequests/ShippingMethod.js index 91bc3c88c..8a4b78a6f 100644 --- a/cypress/apiRequests/ShippingMethod.js +++ b/cypress/apiRequests/ShippingMethod.js @@ -1,11 +1,28 @@ import { getValueWithDefault } from "./utils/Utils"; -export function createShippingRate({ name, shippingZoneId }) { +export function createShippingRate({ + name, + shippingZone, + type = "PRICE", + maxWeight, + minWeight +}) { + const maxOrderWeight = getValueWithDefault( + maxWeight, + `maximumOrderWeight: ${maxWeight}` + ); + const minOrderWeight = getValueWithDefault( + minWeight, + `minimumOrderWeight: ${minWeight}` + ); + const mutation = `mutation{ shippingPriceCreate(input:{ name: "${name}" - shippingZone: "${shippingZoneId}" - type: PRICE + shippingZone: "${shippingZone}" + type: ${type} + ${minOrderWeight} + ${maxOrderWeight} }){ shippingMethod{ id @@ -16,7 +33,7 @@ export function createShippingRate({ name, shippingZoneId }) { } } }`; - return cy.sendRequestWithQuery(mutation); + return cy.sendRequestWithQuery(mutation).its("body.data.shippingPriceCreate"); } export function createShippingZone(name, country, channelId) { diff --git a/cypress/apiRequests/StaffMembers.js b/cypress/apiRequests/StaffMembers.js index 73e9fa7c0..36554441f 100644 --- a/cypress/apiRequests/StaffMembers.js +++ b/cypress/apiRequests/StaffMembers.js @@ -1,3 +1,5 @@ +import { urlList } from "../url/urlList"; + export function getStaffMembersStartsWith(startsWith) { const query = `query{ staffUsers(first:100 filter:{ @@ -13,3 +15,74 @@ export function getStaffMembersStartsWith(startsWith) { }`; return cy.sendRequestWithQuery(query); } + +export function inviteStaffMember({ + email, + isActive = true, + firstName = "", + lastName = "", + permissionId +}) { + const mutation = `mutation createStaff{ + staffCreate(input:{ + firstName: "${firstName}" + lastName: "${lastName}" + email: "${email}", + isActive: ${isActive}, + addGroups:"${permissionId}" + redirectUrl: "${Cypress.config().baseUrl}${urlList.newPassword}" + }){ + user{ + id + } + errors{ + field + message + } + } + } + `; + return cy.sendRequestWithQuery(mutation).its("body.data.staffCreate"); +} + +export function updateStaffMember({ userId, isActive }) { + const mutation = `mutation{ + staffUpdate(id:"${userId}", input:{ + isActive:${isActive} + }){ + user{ + id + } + errors{ + field + message + } + } + }`; + return cy.sendRequestWithQuery(mutation).its("body.data.staffUpdate"); +} + +export function deleteStaffMember(staffId) { + const mutation = `mutation{ + staffDelete(id:"${staffId}"){ + errors{ + field + message + } + } + }`; + return cy.sendRequestWithQuery(mutation).its("body.data.staffDelete"); +} + +export function deleteStaffMembersStartsWith(startsWith) { + getStaffMembersStartsWith(startsWith).then(resp => { + if (resp.body.data.staffUsers) { + const staffMembers = resp.body.data.staffUsers.edges; + staffMembers.forEach(element => { + if (element.node.email.includes(startsWith)) { + deleteStaffMember(element.node.id); + } + }); + } + }); +} diff --git a/cypress/apiRequests/shopSettings.js b/cypress/apiRequests/shopSettings.js new file mode 100644 index 000000000..cb0d48bc8 --- /dev/null +++ b/cypress/apiRequests/shopSettings.js @@ -0,0 +1,16 @@ +export function updateShopWeightUnit(weightUnit) { + const mutation = `mutation{ + shopSettingsUpdate(input:{ + defaultWeightUnit: ${weightUnit} + }){ + errors{ + field + message + } + shop{ + defaultWeightUnit + } + } + }`; + return cy.sendRequestWithQuery(mutation).its("body.data.shopSettingsUpdate"); +} diff --git a/cypress/apiRequests/staffMember.js b/cypress/apiRequests/staffMember.js deleted file mode 100644 index 36554441f..000000000 --- a/cypress/apiRequests/staffMember.js +++ /dev/null @@ -1,88 +0,0 @@ -import { urlList } from "../url/urlList"; - -export function getStaffMembersStartsWith(startsWith) { - const query = `query{ - staffUsers(first:100 filter:{ - search:"${startsWith}" - }){ - edges{ - node{ - id - email - } - } - } - }`; - return cy.sendRequestWithQuery(query); -} - -export function inviteStaffMember({ - email, - isActive = true, - firstName = "", - lastName = "", - permissionId -}) { - const mutation = `mutation createStaff{ - staffCreate(input:{ - firstName: "${firstName}" - lastName: "${lastName}" - email: "${email}", - isActive: ${isActive}, - addGroups:"${permissionId}" - redirectUrl: "${Cypress.config().baseUrl}${urlList.newPassword}" - }){ - user{ - id - } - errors{ - field - message - } - } - } - `; - return cy.sendRequestWithQuery(mutation).its("body.data.staffCreate"); -} - -export function updateStaffMember({ userId, isActive }) { - const mutation = `mutation{ - staffUpdate(id:"${userId}", input:{ - isActive:${isActive} - }){ - user{ - id - } - errors{ - field - message - } - } - }`; - return cy.sendRequestWithQuery(mutation).its("body.data.staffUpdate"); -} - -export function deleteStaffMember(staffId) { - const mutation = `mutation{ - staffDelete(id:"${staffId}"){ - errors{ - field - message - } - } - }`; - return cy.sendRequestWithQuery(mutation).its("body.data.staffDelete"); -} - -export function deleteStaffMembersStartsWith(startsWith) { - getStaffMembersStartsWith(startsWith).then(resp => { - if (resp.body.data.staffUsers) { - const staffMembers = resp.body.data.staffUsers.edges; - staffMembers.forEach(element => { - if (element.node.email.includes(startsWith)) { - deleteStaffMember(element.node.id); - } - }); - } - }); -} diff --git a/cypress/apiRequests/utils/Utils.js b/cypress/apiRequests/utils/Utils.js index e199a0ca5..b28bfc34a 100644 --- a/cypress/apiRequests/utils/Utils.js +++ b/cypress/apiRequests/utils/Utils.js @@ -19,12 +19,18 @@ export function getDefaultAddress(address, addressType, withName = true) { } return `${addressType}:{${defaultAddress}}`; } + export function getVariantsLines(variantsList, quantity) { return variantsList.map( variant => `{quantity:${quantity} variantId:"${variant.id}"}` ); } + +export function getVariantsListIds(variantsList) { + return variantsList.map(variant => `"${variant.id}"`).join(); +} + export const getPaymentDataLine = paymentData => paymentData ? `, paymentData:"{\\"riskData\\":{\\"clientData\\":\\"${paymentData.clientData}\\"}, \\"paymentMethod\\":{\\"type\\":\\"scheme\\", \\"encryptedCardNumber\\":\\"${paymentData.encryptedCardNumber}\\", \\"encryptedExpiryMonth\\":\\"${paymentData.encryptedExpiryMonth}\\", \\"encryptedExpiryYear\\":\\"${paymentData.encryptedExpiryYear}\\", \\"encryptedSecurityCode\\":\\"${paymentData.encryptedSecurityCode}\\", \\"brand\\":\\"${paymentData.brand}\\"}}"` diff --git a/cypress/elements/shared/sharedElements.js b/cypress/elements/shared/sharedElements.js index 679757aba..6008293f4 100644 --- a/cypress/elements/shared/sharedElements.js +++ b/cypress/elements/shared/sharedElements.js @@ -3,8 +3,14 @@ export const SHARED_ELEMENTS = { progressBar: '[role="progressbar"]', skeleton: '[data-test-id="skeleton"]', table: 'table[class*="Table"]', - confirmationMsg: "[data-test='notification-success']" + notificationSuccess: '[data-test="notification-success"]', + confirmationMsg: "[data-test='notification-success']", + richTextEditor: { + empty: '[class*="codex-editor--empty"]' + } }; +export const selectorWithDataValue = value => `[data-value="${value}"]`; + export const getElementByDataTestId = dataTestId => `[data-test-id=${dataTestId}]`; diff --git a/cypress/elements/shipping/shipping-rate-details.js b/cypress/elements/shipping/shipping-rate-details.js index 07f4996f1..6a45cb456 100644 --- a/cypress/elements/shipping/shipping-rate-details.js +++ b/cypress/elements/shipping/shipping-rate-details.js @@ -1,4 +1,15 @@ export const SHIPPING_RATE_DETAILS = { inputName: "[name='name']", - priceInput: "[name='price']" + priceInput: "[name='price']", + includePostalCodesCheckbox: '[value="INCLUDE"]', + excludePostalCodesCheckbox: '[value="EXCLUDE"]', + addPostalCodesButton: '[data-test="add-postal-code-range"]', + postalCodesForm: { + min: '[name="min"]', + max: '[name="max"]' + }, + maxWeightInput: '[name="maxValue"]', + minWeightInput: '[name="minValue"]', + minDeliveryTimeInput: '[name="minDays"]', + maxDeliveryTimeInput: '[name="maxDays"]' }; diff --git a/cypress/elements/shipping/shipping-zone-details.js b/cypress/elements/shipping/shipping-zone-details.js index 249dac3ae..b5af07776 100644 --- a/cypress/elements/shipping/shipping-zone-details.js +++ b/cypress/elements/shipping/shipping-zone-details.js @@ -7,6 +7,8 @@ export const SHIPPING_ZONE_DETAILS = { addWeightRateButton: "[data-test-id='add-weight-rate']", nameInput: "[name='name']", shippingRatePriceTableCell: "[data-test-id='shipping-rate-price']", + autocompleteContentDialog: + "[data-test-id='multiautocomplete-select-content']", option: "[data-test='multiautocomplete-select-option']", warehouseSelector: "[placeholder*='Warehouse']", channelSelector: "[placeholder*='Channel']" diff --git a/cypress/elements/shipping/shipping-zones-list.js b/cypress/elements/shipping/shipping-zones-list.js index a61595a25..a95c278fa 100644 --- a/cypress/elements/shipping/shipping-zones-list.js +++ b/cypress/elements/shipping/shipping-zones-list.js @@ -1,3 +1,5 @@ export const SHIPPING_ZONES_LIST = { - addShippingZone: "[data-test-id='add-shipping-zone']" + addShippingZone: "[data-test-id='add-shipping-zone']", + unitSelect: "[id='mui-component-select-unit']", + saveUnit: '[data-test-id="saveUnit"]' }; diff --git a/cypress/fixtures/addresses.json b/cypress/fixtures/addresses.json index 023ec7cb5..ece8d029a 100644 --- a/cypress/fixtures/addresses.json +++ b/cypress/fixtures/addresses.json @@ -26,5 +26,19 @@ "phone": "+12025550189", "currency": "USD", "countryFullName": "United States of America" + }, + "secondUsAddress": { + "firstName": "test", + "lastName": "test", + "companyName": "Test2", + "streetAddress1": "Antonio Ridge", + "streetAddress2": "34930", + "city": "North Patrickfort", + "postalCode": "70958", + "country": "US", + "countryArea": "LA", + "phone": "2025550189", + "currency": "USD", + "countryFullName": "United States of America" } } \ No newline at end of file diff --git a/cypress/integration/allEnv/checkout/stocksInCheckout.js b/cypress/integration/allEnv/checkout/stocksInCheckout.js index 5920dd558..743025505 100644 --- a/cypress/integration/allEnv/checkout/stocksInCheckout.js +++ b/cypress/integration/allEnv/checkout/stocksInCheckout.js @@ -4,6 +4,7 @@ import { addProductsToCheckout, createCheckout } from "../../../apiRequests/Checkout"; +import { getVariants } from "../../../apiRequests/Product"; import { getDefaultChannel } from "../../../utils/channelsUtils"; import { createOrderWithNewProduct } from "../../../utils/ordersUtils"; import { @@ -80,6 +81,7 @@ describe("Products stocks in checkout", () => { expect(order, "order should be created").to.be.ok; }); }); + it("should not be possible to add product with quantity greater than stock", () => { const productName = `${startsWith}${faker.datatype.number()}`; let variants; @@ -133,4 +135,28 @@ describe("Products stocks in checkout", () => { expect(order, "order should be created").to.be.ok; }); }); + + it("should change product stock after purchase", () => { + const productName = `${startsWith}${faker.datatype.number()}`; + + createOrderWithNewProduct({ + attributeId: attribute.id, + categoryId: category.id, + productTypeId: productType.id, + channel: defaultChannel, + name: productName, + warehouseId: warehouse.id, + quantityInWarehouse: 10, + trackInventory: true, + shippingMethodId: shippingMethod.id, + address + }) + .then(({ variantsList }) => { + getVariants(variantsList); + }) + .then(variantsList => { + const variant = variantsList.edges[0]; + expect(variant.node.stocks[0].quantityAllocated).to.eq(1); + }); + }); }); diff --git a/cypress/integration/allEnv/configuration/shippingMethod.js b/cypress/integration/allEnv/configuration/shippingMethod.js deleted file mode 100644 index ae8e0b2a9..000000000 --- a/cypress/integration/allEnv/configuration/shippingMethod.js +++ /dev/null @@ -1,224 +0,0 @@ -// -import faker from "faker"; - -import { createChannel } from "../../../apiRequests/Channels"; -import { createCheckout } from "../../../apiRequests/Checkout"; -import { - addChannelToShippingMethod, - addChannelToShippingZone -} from "../../../apiRequests/ShippingMethod"; -import { createWarehouse } from "../../../apiRequests/Warehouse"; -import { ONE_PERMISSION_USERS } from "../../../Data/users"; -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 { - createShippingRate, - createShippingZone, - rateOptions -} from "../../../steps/shippingMethodSteps"; -import { getFormattedCurrencyAmount } from "../../../support/format/formatCurrencyAmount"; -import { urlList } from "../../../url/urlList"; -import * as channelsUtils from "../../../utils/channelsUtils"; -import * as productsUtils from "../../../utils/products/productsUtils"; -import * as shippingUtils from "../../../utils/shippingUtils"; -import { isShippingAvailableInCheckout } from "../../../utils/storeFront/checkoutUtils"; - -describe("Shipping methods", () => { - const startsWith = "CyShippingMethods-"; - const name = `${startsWith}${faker.datatype.number()}`; - const price = 8; - let defaultChannel; - let plAddress; - let variantsList; - let warehouse; - - before(() => { - cy.clearSessionData().loginUserViaRequest(); - productsUtils.deleteProductsStartsWith(startsWith); - shippingUtils.deleteShippingStartsWith(startsWith); - channelsUtils.deleteChannelsStartsWith(startsWith); - - channelsUtils - .getDefaultChannel() - .then(channel => { - defaultChannel = channel; - cy.fixture("addresses"); - }) - .then(addresses => { - plAddress = addresses.plAddress; - createWarehouse({ name, address: plAddress }); - }) - .then(warehouseResp => { - warehouse = warehouseResp; - productsUtils.createTypeAttributeAndCategoryForProduct(startsWith); - }) - .then( - ({ - productType: productTypeResp, - category: categoryResp, - attribute: attributeResp - }) => { - productsUtils.createProductInChannel({ - name, - channelId: defaultChannel.id, - productTypeId: productTypeResp.id, - attributeId: attributeResp.id, - categoryId: categoryResp.id, - warehouseId: warehouse.id, - quantityInWarehouse: 10 - }); - } - ) - .then(({ variantsList: variantsListResp }) => { - variantsList = variantsListResp; - }); - }); - - beforeEach(() => { - cy.clearSessionData().loginUserViaRequest(); - }); - - it("should display different price for each channel", () => { - const shippingName = `${startsWith}${faker.datatype.number()}`; - const defaultChannelPrice = 11; - const createdChannelPrice = 7; - const createdChannelCurrency = "PLN"; - - let shippingMethod; - let shippingZone; - let createdChannel; - - createChannel({ - name: shippingName, - currencyCode: createdChannelCurrency - }) - .then(channel => { - createdChannel = channel; - shippingUtils.createShipping({ - channelId: defaultChannel.id, - name: shippingName, - address: plAddress, - price: defaultChannelPrice - }); - }) - .then( - ({ - shippingMethod: shippingMethodResp, - shippingZone: shippingZoneResp - }) => { - shippingZone = shippingZoneResp; - shippingMethod = shippingMethodResp; - addChannelToShippingZone(shippingZone.id, createdChannel.id).then( - () => { - addChannelToShippingMethod( - shippingMethod.id, - createdChannel.id, - createdChannelPrice - ); - } - ); - } - ) - .then(() => { - cy.clearSessionData() - .loginUserViaRequest("auth", ONE_PERMISSION_USERS.shipping) - .visit(urlList.shippingMethods) - .get(SHARED_ELEMENTS.header) - .should("be.visible") - .get(SHARED_ELEMENTS.progressBar) - .should("not.exist"); - 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); - cy.getTextFromElement(SHIPPING_ZONE_DETAILS.shippingRatePriceTableCell) - .then(text => { - const expectedValue = getFormattedCurrencyAmount( - defaultChannelPrice, - defaultChannel.currencyCode - ); - expect(text).to.be.eq(expectedValue); - - selectChannelInHeader(createdChannel.name); - }) - .then(() => { - cy.getTextFromElement( - SHIPPING_ZONE_DETAILS.shippingRatePriceTableCell - ); - }) - .then(text => { - const expectedValue = getFormattedCurrencyAmount( - createdChannelPrice, - createdChannelCurrency - ); - expect(text).to.be.eq(expectedValue); - }); - }); - }); - it("should create price based shipping method", () => { - const shippingName = `${startsWith}${faker.datatype.number()}`; - cy.clearSessionData().loginUserViaRequest( - "auth", - ONE_PERMISSION_USERS.shipping - ); - cy.visit(urlList.shippingMethods); - createShippingZone( - shippingName, - warehouse.name, - plAddress.countryFullName, - defaultChannel.name - ); - createShippingRate(shippingName, price, rateOptions.PRICE_OPTION); - - createCheckout({ - channelSlug: defaultChannel.slug, - email: "test@example.com", - variantsList, - address: plAddress, - auth: "token" - }).then(({ checkout }) => { - const isShippingAvailable = isShippingAvailableInCheckout( - checkout, - shippingName - ); - expect(isShippingAvailable).to.be.true; - }); - }); - - it("should create weight based shipping method", () => { - const shippingName = `${startsWith}${faker.datatype.number()}`; - cy.clearSessionData().loginUserViaRequest( - "auth", - ONE_PERMISSION_USERS.shipping - ); - cy.visit(urlList.shippingMethods); - createShippingZone( - shippingName, - warehouse.name, - plAddress.countryFullName, - defaultChannel.name - ); - createShippingRate(shippingName, price, rateOptions.WEIGHT_OPTION); - createCheckout({ - channelSlug: defaultChannel.slug, - email: "test@example.com", - variantsList, - address: plAddress, - auth: "token" - }).then(({ checkout }) => { - const isShippingAvailable = isShippingAvailableInCheckout( - checkout, - shippingName - ); - expect(isShippingAvailable).to.be.true; - }); - }); -}); diff --git a/cypress/integration/allEnv/configuration/shippingMethods/channelsInShipping.js b/cypress/integration/allEnv/configuration/shippingMethods/channelsInShipping.js new file mode 100644 index 000000000..484c8dac8 --- /dev/null +++ b/cypress/integration/allEnv/configuration/shippingMethods/channelsInShipping.js @@ -0,0 +1,124 @@ +// +import faker from "faker"; + +import { createChannel } from "../../../../apiRequests/Channels"; +import { + addChannelToShippingMethod, + addChannelToShippingZone +} from "../../../../apiRequests/ShippingMethod"; +import { ONE_PERMISSION_USERS } from "../../../../Data/users"; +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 { getFormattedCurrencyAmount } from "../../../../support/format/formatCurrencyAmount"; +import { urlList } from "../../../../url/urlList"; +import * as channelsUtils from "../../../../utils/channelsUtils"; +import * as shippingUtils from "../../../../utils/shippingUtils"; + +describe("Channels in shippingMethod", () => { + const startsWith = "ChannelShippingMethod"; + let defaultChannel; + let plAddress; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + shippingUtils.deleteShippingStartsWith(startsWith); + channelsUtils.deleteChannelsStartsWith(startsWith); + + channelsUtils + .getDefaultChannel() + .then(channel => { + defaultChannel = channel; + cy.fixture("addresses"); + }) + .then(addresses => { + plAddress = addresses.plAddress; + }); + }); + + it("should display different price for each channel", () => { + const shippingName = `${startsWith}${faker.datatype.number()}`; + const defaultChannelPrice = 11; + const createdChannelPrice = 7; + const createdChannelCurrency = "PLN"; + + let shippingMethod; + let shippingZone; + let createdChannel; + + cy.clearSessionData().loginUserViaRequest(); + createChannel({ + name: shippingName, + currencyCode: createdChannelCurrency + }) + .then(channel => { + createdChannel = channel; + shippingUtils.createShipping({ + channelId: defaultChannel.id, + name: shippingName, + address: plAddress, + price: defaultChannelPrice + }); + }) + .then( + ({ + shippingMethod: shippingMethodResp, + shippingZone: shippingZoneResp + }) => { + shippingZone = shippingZoneResp; + shippingMethod = shippingMethodResp; + addChannelToShippingZone(shippingZone.id, createdChannel.id).then( + () => { + addChannelToShippingMethod( + shippingMethod.id, + createdChannel.id, + createdChannelPrice + ); + } + ); + } + ) + .then(() => { + cy.clearSessionData() + .loginUserViaRequest("auth", ONE_PERMISSION_USERS.shipping) + .visit(urlList.shippingMethods) + .get(SHARED_ELEMENTS.header) + .should("be.visible") + .get(SHARED_ELEMENTS.progressBar) + .should("not.exist"); + 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); + cy.getTextFromElement(SHIPPING_ZONE_DETAILS.shippingRatePriceTableCell) + .then(text => { + const expectedValue = getFormattedCurrencyAmount( + defaultChannelPrice, + defaultChannel.currencyCode + ); + expect(text).to.be.eq(expectedValue); + + selectChannelInHeader(createdChannel.name); + }) + .then(() => { + cy.getTextFromElement( + SHIPPING_ZONE_DETAILS.shippingRatePriceTableCell + ); + }) + .then(text => { + const expectedValue = getFormattedCurrencyAmount( + createdChannelPrice, + createdChannelCurrency + ); + expect(text).to.be.eq(expectedValue); + }); + }); + }); +}); diff --git a/cypress/integration/allEnv/configuration/shippingMethods/createShippingMethod.js b/cypress/integration/allEnv/configuration/shippingMethods/createShippingMethod.js new file mode 100644 index 000000000..d15e34939 --- /dev/null +++ b/cypress/integration/allEnv/configuration/shippingMethods/createShippingMethod.js @@ -0,0 +1,141 @@ +// +import faker from "faker"; + +import { createCheckout } from "../../../../apiRequests/Checkout"; +import { createWarehouse } from "../../../../apiRequests/Warehouse"; +import { ONE_PERMISSION_USERS } from "../../../../Data/users"; +import { + createShippingRate, + createShippingZone, + rateOptions +} from "../../../../steps/shippingMethodSteps"; +import { urlList } from "../../../../url/urlList"; +import * as channelsUtils from "../../../../utils/channelsUtils"; +import * as productsUtils from "../../../../utils/products/productsUtils"; +import * as shippingUtils from "../../../../utils/shippingUtils"; +import { isShippingAvailableInCheckout } from "../../../../utils/storeFront/checkoutUtils"; + +describe("Create shipping method", () => { + const startsWith = "CreateShippingMethods-"; + const name = `${startsWith}${faker.datatype.number()}`; + const price = 8; + const deliveryTime = { min: 2, max: 5 }; + let defaultChannel; + let plAddress; + let variantsList; + let warehouse; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + productsUtils.deleteProductsStartsWith(startsWith); + shippingUtils.deleteShippingStartsWith(startsWith); + + channelsUtils + .getDefaultChannel() + .then(channel => { + defaultChannel = channel; + cy.fixture("addresses"); + }) + .then(addresses => { + plAddress = addresses.plAddress; + createWarehouse({ name, address: plAddress }); + }) + .then(warehouseResp => { + warehouse = warehouseResp; + productsUtils.createTypeAttributeAndCategoryForProduct(startsWith); + }) + .then( + ({ + productType: productTypeResp, + category: categoryResp, + attribute: attributeResp + }) => { + productsUtils.createProductInChannel({ + name, + channelId: defaultChannel.id, + productTypeId: productTypeResp.id, + attributeId: attributeResp.id, + categoryId: categoryResp.id, + warehouseId: warehouse.id, + quantityInWarehouse: 10 + }); + } + ) + .then(({ variantsList: variantsListResp }) => { + variantsList = variantsListResp; + }); + }); + + beforeEach(() => { + cy.clearSessionData().loginUserViaRequest(); + }); + + it("should create price based shipping method", () => { + const shippingName = `${startsWith}${faker.datatype.number()}`; + cy.clearSessionData().loginUserViaRequest( + "auth", + ONE_PERMISSION_USERS.shipping + ); + cy.visit(urlList.shippingMethods); + createShippingZone( + shippingName, + warehouse.name, + plAddress.countryFullName, + defaultChannel.name + ); + createShippingRate({ + rateName: shippingName, + price, + rateOption: rateOptions.PRICE_OPTION, + deliveryTime + }); + + createCheckout({ + channelSlug: defaultChannel.slug, + email: "test@example.com", + variantsList, + address: plAddress, + auth: "token" + }).then(({ checkout }) => { + const isShippingAvailable = isShippingAvailableInCheckout( + checkout, + shippingName + ); + expect(isShippingAvailable).to.be.true; + }); + }); + + it("should create weight based shipping method", () => { + const shippingName = `${startsWith}${faker.datatype.number()}`; + cy.clearSessionData().loginUserViaRequest( + "auth", + ONE_PERMISSION_USERS.shipping + ); + cy.visit(urlList.shippingMethods); + createShippingZone( + shippingName, + warehouse.name, + plAddress.countryFullName, + defaultChannel.name + ); + createShippingRate({ + rateName: shippingName, + price, + rateOption: rateOptions.WEIGHT_OPTION, + deliveryTime + }); + createCheckout({ + channelSlug: defaultChannel.slug, + email: "test@example.com", + variantsList, + address: plAddress, + auth: "token" + }).then(({ checkout }) => { + const isShippingAvailable = isShippingAvailableInCheckout( + checkout, + shippingName + ); + expect(isShippingAvailable).to.be.true; + }); + }); +}); diff --git a/cypress/integration/allEnv/configuration/shippingMethods/postalCodes.js b/cypress/integration/allEnv/configuration/shippingMethods/postalCodes.js new file mode 100644 index 000000000..729c5029c --- /dev/null +++ b/cypress/integration/allEnv/configuration/shippingMethods/postalCodes.js @@ -0,0 +1,134 @@ +// +import faker from "faker"; + +import { createCheckout } from "../../../../apiRequests/Checkout"; +import { createShippingZone } from "../../../../apiRequests/ShippingMethod"; +import { createWarehouse } from "../../../../apiRequests/Warehouse"; +import { ONE_PERMISSION_USERS } from "../../../../Data/users"; +import { + createRateWithPostalCode, + postalCodesOptions +} from "../../../../steps/shippingMethodSteps"; +import { shippingZoneDetailsUrl } from "../../../../url/urlList"; +import { getDefaultChannel } from "../../../../utils/channelsUtils"; +import { + createProductInChannel, + createTypeAttributeAndCategoryForProduct, + deleteProductsStartsWith +} from "../../../../utils/products/productsUtils"; +import { deleteShippingStartsWith } from "../../../../utils/shippingUtils"; +import { isShippingAvailableInCheckout } from "../../../../utils/storeFront/checkoutUtils"; + +describe("Postal codes in shipping", () => { + const startsWith = "CyShippingMethods-"; + const name = `${startsWith}${faker.datatype.number()}`; + + const price = 10; + + let defaultChannel; + let usAddress; + let secondUsAddress; + let shippingZone; + let warehouse; + let variantsList; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + deleteShippingStartsWith(startsWith); + deleteProductsStartsWith(startsWith); + + getDefaultChannel() + .then(channel => { + defaultChannel = channel; + cy.fixture("addresses"); + }) + .then( + ({ + usAddress: usAddressResp, + secondUsAddress: secondUsAddressResp + }) => { + usAddress = usAddressResp; + secondUsAddress = secondUsAddressResp; + createShippingZone(name, "US", defaultChannel.id); + } + ) + .then(shippingZoneResp => { + shippingZone = shippingZoneResp; + createWarehouse({ + name, + shippingZone: shippingZone.id, + address: usAddress + }); + }) + .then(warehouseResp => { + warehouse = warehouseResp; + createTypeAttributeAndCategoryForProduct(name); + }) + .then(({ attribute, productType, category }) => { + createProductInChannel({ + name, + channelId: defaultChannel.id, + warehouseId: warehouse.id, + attributeId: attribute.id, + categoryId: category.id, + productTypeId: productType.id + }); + }) + .then(({ variantsList: variantsListResp }) => { + variantsList = variantsListResp; + }); + }); + + beforeEach(() => { + cy.clearSessionData() + .loginUserViaRequest("auth", ONE_PERMISSION_USERS.shipping) + .visit(shippingZoneDetailsUrl(shippingZone.id)); + }); + + it("Create shipping method with included postal codes", () => { + const rateName = `${startsWith}${faker.datatype.number()}`; + + createRateWithPostalCode({ + rateName, + price, + postalCodeOption: postalCodesOptions.INCLUDE_OPTION, + maxPostalCode: usAddress.postalCode, + minPostalCode: usAddress.postalCode + }); + isShippingAvailableForAddress(usAddress, rateName).then( + isAvailable => expect(isAvailable).to.be.true + ); + isShippingAvailableForAddress(secondUsAddress, rateName).then( + isAvailable => expect(isAvailable).to.be.false + ); + }); + + it("Create shipping method with excluded postal codes", () => { + const rateName = `${startsWith}${faker.datatype.number()}`; + + createRateWithPostalCode({ + rateName, + price, + postalCodeOption: postalCodesOptions.EXCLUDE_OPTION, + maxPostalCode: usAddress.postalCode, + minPostalCode: usAddress.postalCode + }); + isShippingAvailableForAddress(usAddress, rateName).then( + isAvailable => expect(isAvailable).to.be.false + ); + isShippingAvailableForAddress(secondUsAddress, rateName).then( + isAvailable => expect(isAvailable).to.be.true + ); + }); + + function isShippingAvailableForAddress(address, rateName) { + return createCheckout({ + address, + channelSlug: defaultChannel.slug, + email: "example@example.com", + variantsList + }).then(({ checkout }) => + isShippingAvailableInCheckout(checkout, rateName) + ); + } +}); diff --git a/cypress/integration/allEnv/configuration/shippingMethods/shippingWeight.js b/cypress/integration/allEnv/configuration/shippingMethods/shippingWeight.js new file mode 100644 index 000000000..1e972bae7 --- /dev/null +++ b/cypress/integration/allEnv/configuration/shippingMethods/shippingWeight.js @@ -0,0 +1,187 @@ +// +import faker from "faker"; + +import { createCheckout } from "../../../../apiRequests/Checkout"; +import { + createShippingRate as createShippingRateViaApi, + createShippingZone +} from "../../../../apiRequests/ShippingMethod"; +import { updateShopWeightUnit } from "../../../../apiRequests/shopSettings"; +import { createWarehouse } from "../../../../apiRequests/Warehouse"; +import { ONE_PERMISSION_USERS } from "../../../../Data/users"; +import { SHARED_ELEMENTS } from "../../../../elements/shared/sharedElements"; +import { SHIPPING_RATE_DETAILS } from "../../../../elements/shipping/shipping-rate-details"; +import { + changeWeightUnit, + createShippingRate, + rateOptions +} from "../../../../steps/shippingMethodSteps"; +import { + shippingZoneDetailsUrl, + urlList, + weightRateUrl +} from "../../../../url/urlList"; +import { getDefaultChannel } from "../../../../utils/channelsUtils"; +import { + createProductInChannel, + createTypeAttributeAndCategoryForProduct, + deleteProductsStartsWith +} from "../../../../utils/products/productsUtils"; +import { deleteShippingStartsWith } from "../../../../utils/shippingUtils"; +import { isShippingAvailableInCheckout } from "../../../../utils/storeFront/checkoutUtils"; + +describe("Shipping weight limits", () => { + const startsWith = "CyWeightRates-"; + const name = `${startsWith}${faker.datatype.number()}`; + + const price = 10; + + let defaultChannel; + let usAddress; + let shippingZone; + let warehouse; + let variantsList; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + deleteShippingStartsWith(startsWith); + deleteProductsStartsWith(startsWith); + + updateShopWeightUnit("KG"); + getDefaultChannel() + .then(channel => { + defaultChannel = channel; + cy.fixture("addresses"); + }) + .then(({ usAddress: usAddressResp }) => { + usAddress = usAddressResp; + createShippingZone(name, "US", defaultChannel.id); + }) + .then(shippingZoneResp => { + shippingZone = shippingZoneResp; + createWarehouse({ + name, + shippingZone: shippingZone.id, + address: usAddress + }); + }) + .then(warehouseResp => { + warehouse = warehouseResp; + createTypeAttributeAndCategoryForProduct(name); + }) + .then(({ attribute, productType, category }) => { + createProductInChannel({ + name, + channelId: defaultChannel.id, + warehouseId: warehouse.id, + attributeId: attribute.id, + categoryId: category.id, + productTypeId: productType.id, + weight: 10 + }); + }) + .then(({ variantsList: variantsListResp }) => { + variantsList = variantsListResp; + }); + }); + + beforeEach(() => { + cy.clearSessionData() + .loginUserViaRequest("auth", ONE_PERMISSION_USERS.shipping) + .visit(shippingZoneDetailsUrl(shippingZone.id)); + }); + + it("should be possible to buy product in a shipping weight limits", () => { + const rateName = `${startsWith}${faker.datatype.number()}`; + createShippingRate({ + rateName, + price, + rateOption: rateOptions.WEIGHT_OPTION, + weightLimits: { + max: 11, + min: 10 + } + }); + createCheckout({ + address: usAddress, + channelSlug: defaultChannel.slug, + email: "example@example.com", + variantsList + }).then(({ checkout }) => { + expect(isShippingAvailableInCheckout(checkout, rateName)).to.be.true; + }); + }); + + it("should not be possible to buy product not in a shipping weight limits", () => { + const rateName = `${startsWith}${faker.datatype.number()}`; + createShippingRate({ + rateName, + price, + rateOption: rateOptions.WEIGHT_OPTION, + weightLimits: { + max: 101, + min: 100 + } + }); + createCheckout({ + address: usAddress, + channelSlug: defaultChannel.slug, + email: "example@example.com", + variantsList + }).then(({ checkout }) => { + expect(isShippingAvailableInCheckout(checkout, rateName)).to.be.false; + }); + }); + + // Log in as user with shipping permissions after resolving SALEOR-3407 bug + it("should recalculate weight after changing shipping weight unit", () => { + const rateName = `${startsWith}${faker.datatype.number()}`; + const minWeightInKg = 1; + const maxWeightInKg = 10; + const minWeightInG = minWeightInKg * 1000; + const maxWeightInG = maxWeightInKg * 1000; + let shippingMethod; + + cy.clearSessionData().loginUserViaRequest(); + + createShippingRateViaApi({ + name: rateName, + shippingZone: shippingZone.id, + type: "WEIGHT", + maxWeight: maxWeightInKg, + minWeight: minWeightInKg + }) + .then(({ shippingMethod: shippingMethodResp }) => { + shippingMethod = shippingMethodResp; + cy.visit(urlList.shippingMethods) + .get(SHARED_ELEMENTS.progressBar) + .should("not.exist"); + changeWeightUnit("G"); + + cy.addAliasToGraphRequest("ShippingZone"); + cy.visit(weightRateUrl(shippingZone.id, shippingMethod.id)) + .wait("@ShippingZone") + .its("response.body"); + }) + .then(responseArray => { + const shippingMethods = responseArray.find( + element => element.data.shippingZone + ).data.shippingZone.shippingMethods; + const rate = shippingMethods.find( + element => element.id === shippingMethod.id + ); + expect(rate.minimumOrderWeight.unit).to.eq("G"); + cy.get(SHARED_ELEMENTS.progressBar) + .should("not.be.visible") + .get(SHIPPING_RATE_DETAILS.minWeightInput) + .invoke("val"); + }) + .then(actualMinWeight => { + expect(parseInt(actualMinWeight, 10)).to.eq(minWeightInG); + cy.get(SHIPPING_RATE_DETAILS.maxWeightInput).invoke("val"); + }) + .then(actualMaxWeight => { + expect(parseInt(actualMaxWeight, 10)).to.eq(maxWeightInG); + }); + }); +}); diff --git a/cypress/integration/allEnv/configuration/warehouse.js b/cypress/integration/allEnv/configuration/warehouse.js index 851992860..db2576cea 100644 --- a/cypress/integration/allEnv/configuration/warehouse.js +++ b/cypress/integration/allEnv/configuration/warehouse.js @@ -8,7 +8,7 @@ import { SHIPPING_ZONE_DETAILS } from "../../../elements/shipping/shipping-zone- import { WAREHOUSES_DETAILS } from "../../../elements/warehouses/warehouse-details"; import { WAREHOUSES_LIST } from "../../../elements/warehouses/warehouses-list"; import { fillUpBasicAddress } from "../../../steps/shared/addressForm"; -import { fillAutocompleteSelect } from "../../../steps/shared/autocompleteSelect"; +import { fillAutocompleteSelect } from "../../../steps/shared/selects"; import { shippingZoneDetailsUrl, urlList, diff --git a/cypress/integration/allEnv/orders/orders.js b/cypress/integration/allEnv/orders/orders.js index 815e4e486..c4b3028c0 100644 --- a/cypress/integration/allEnv/orders/orders.js +++ b/cypress/integration/allEnv/orders/orders.js @@ -13,7 +13,7 @@ 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 { fillAutocompleteSelect } from "../../../steps/shared/selects"; import { urlList } from "../../../url/urlList"; import { getDefaultChannel } from "../../../utils/channelsUtils"; import { diff --git a/cypress/integration/stagedOnly/staffMembers.js b/cypress/integration/stagedOnly/staffMembers.js index 501a0067c..b2f07bd3f 100644 --- a/cypress/integration/stagedOnly/staffMembers.js +++ b/cypress/integration/stagedOnly/staffMembers.js @@ -3,7 +3,7 @@ import faker from "faker"; import { deleteStaffMembersStartsWith, updateStaffMember -} from "../../apiRequests/staffMember"; +} from "../../apiRequests/StaffMembers"; import { LEFT_MENU_SELECTORS } from "../../elements/account/left-menu/left-menu-selectors"; import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors"; import { STAFF_MEMBER_DETAILS } from "../../elements/staffMembers/staffMemberDetails"; diff --git a/cypress/steps/catalog/products/productSteps.js b/cypress/steps/catalog/products/productSteps.js index e872cc097..a005ee49c 100644 --- a/cypress/steps/catalog/products/productSteps.js +++ b/cypress/steps/catalog/products/productSteps.js @@ -1,7 +1,7 @@ import { PRODUCT_DETAILS } from "../../../elements/catalog/products/product-details"; import { AVAILABLE_CHANNELS_FORM } from "../../../elements/channels/available-channels-form"; import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors"; -import { fillAutocompleteSelect } from "../../shared/autocompleteSelect"; +import { fillAutocompleteSelect } from "../../shared/selects"; import { addMetadataField } from "../metadataSteps"; import { editSeoSettings } from "../seoSteps"; diff --git a/cypress/steps/channelsSteps.js b/cypress/steps/channelsSteps.js index 286caf875..b5a27f687 100644 --- a/cypress/steps/channelsSteps.js +++ b/cypress/steps/channelsSteps.js @@ -5,7 +5,7 @@ import { CHANNELS_SELECTORS } from "../elements/channels/channels-selectors"; import { SELECT_CHANNELS_TO_ASSIGN } from "../elements/channels/select-channels-to-assign"; import { HEADER_SELECTORS } from "../elements/header/header-selectors"; import { BUTTON_SELECTORS } from "../elements/shared/button-selectors"; -import { fillAutocompleteSelect } from "./shared/autocompleteSelect"; +import { fillAutocompleteSelect } from "./shared/selects"; export function createChannelByView({ name, diff --git a/cypress/steps/shared/addressForm.js b/cypress/steps/shared/addressForm.js index 633fb12b4..779bf4b45 100644 --- a/cypress/steps/shared/addressForm.js +++ b/cypress/steps/shared/addressForm.js @@ -1,6 +1,6 @@ import { ADDRESS_SELECTORS } from "../../elements/shared/addressForm"; import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors"; -import { fillAutocompleteSelect } from "./autocompleteSelect"; +import { fillAutocompleteSelect } from "./selects"; export function fillUpAddressForm(address) { cy.get(ADDRESS_SELECTORS.firstName) diff --git a/cypress/steps/shared/autocompleteSelect.js b/cypress/steps/shared/selects.js similarity index 73% rename from cypress/steps/shared/autocompleteSelect.js rename to cypress/steps/shared/selects.js index 05a168c83..4c1c5cfb4 100644 --- a/cypress/steps/shared/autocompleteSelect.js +++ b/cypress/steps/shared/selects.js @@ -1,4 +1,5 @@ import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors"; +import { selectorWithDataValue } from "../../elements/shared/sharedElements"; export function fillAutocompleteSelect(selectSelector, option) { cy.get(selectSelector) @@ -20,3 +21,10 @@ export function fillAutocompleteSelect(selectSelector, option) { } return cy.get("@option"); } + +export function fillBaseSelect(selectSelector, value) { + cy.get(selectSelector) + .click() + .get(selectorWithDataValue(value)) + .click(); +} diff --git a/cypress/steps/shippingMethodSteps.js b/cypress/steps/shippingMethodSteps.js index 2905c79af..c68ac5f6b 100644 --- a/cypress/steps/shippingMethodSteps.js +++ b/cypress/steps/shippingMethodSteps.js @@ -3,6 +3,8 @@ 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"; +import { confirmationMessageShouldDisappear } from "./shared/confirmationMessage"; +import { fillBaseSelect } from "./shared/selects"; export function createShippingZone( shippingName, @@ -24,12 +26,21 @@ export function createShippingZone( .get(SHIPPING_ZONE_DETAILS.submitAssignCountry) .click() .get(BUTTON_SELECTORS.confirm) + .click(); + confirmationMessageShouldDisappear(); + cy.get(SHIPPING_ZONE_DETAILS.warehouseSelector) .click() + .get(SHIPPING_ZONE_DETAILS.autocompleteContentDialog) + .scrollTo("bottom") + // Remove this code between comments after fixing bug: SALEOR-3611 + .get(SHIPPING_ZONE_DETAILS.autocompleteContentDialog) + .should("not.exist") .get(SHIPPING_ZONE_DETAILS.warehouseSelector) .click() + // Remove this code between comments after fixing bug: SALEOR-3611 .get(SHIPPING_ZONE_DETAILS.option) .contains(warehouseName) - .click() + .click({ force: true }) .get(SHIPPING_ZONE_DETAILS.channelSelector) .click() .get(SHIPPING_ZONE_DETAILS.option) @@ -37,26 +48,120 @@ export function createShippingZone( .click(); cy.addAliasToGraphRequest("UpdateShippingZone"); cy.get(BUTTON_SELECTORS.confirm).click(); + confirmationMessageShouldDisappear(); cy.wait("@UpdateShippingZone"); } -export function createShippingRate(rateName, price, rateOption) { +export function changeWeightUnit(weightUnit) { + fillBaseSelect(SHIPPING_ZONES_LIST.unitSelect, weightUnit); + cy.addAliasToGraphRequest("UpdateDefaultWeightUnit"); + cy.get(SHIPPING_ZONES_LIST.saveUnit) + .click() + .get(SHARED_ELEMENTS.notificationSuccess) + .should("be.visible") + .wait("@UpdateDefaultWeightUnit") + .get(SHARED_ELEMENTS.notificationSuccess) + .should("not.exist"); +} + +export function createShippingRate({ + rateName, + price, + rateOption, + weightLimits, + deliveryTime +}) { + enterAndFillUpShippingRate({ + rateName, + price, + rateOption, + weightLimits, + deliveryTime + }); + saveRate(); +} + +export function enterAndFillUpShippingRate({ + rateName, + price, + rateOption, + weightLimits, + deliveryTime +}) { cy.get(rateOption) .click() .get(SHARED_ELEMENTS.progressBar) .should("not.be.visible") + .get(SHARED_ELEMENTS.richTextEditor.empty) + .should("exist") .get(SHIPPING_RATE_DETAILS.inputName) - .type(rateName) - .get(SHIPPING_RATE_DETAILS.priceInput) - .each($priceInput => { - cy.wrap($priceInput).type(price); - }); - cy.addAliasToGraphRequest("ShippingZone"); - cy.get(BUTTON_SELECTORS.confirm).click(); - cy.wait("@ShippingZone"); + .type(rateName); + if (deliveryTime) { + fillUpDeliveryTime(deliveryTime); + } + if (weightLimits) { + fillUpWeightLimits(weightLimits); + } + cy.get(SHIPPING_RATE_DETAILS.priceInput).each($priceInput => { + cy.wrap($priceInput).type(price); + }); +} + +export function createRateWithPostalCode({ + rateName, + price, + rateOption = rateOptions.PRICE_OPTION, + minPostalCode, + maxPostalCode, + postalCodeOption +}) { + enterAndFillUpShippingRate({ rateName, price, rateOption }); + cy.get(postalCodeOption) + .click() + .get(SHIPPING_RATE_DETAILS.addPostalCodesButton) + .click() + .get(SHIPPING_RATE_DETAILS.postalCodesForm.min) + .type(minPostalCode) + .get(SHIPPING_RATE_DETAILS.postalCodesForm.max) + .type(maxPostalCode) + .get(BUTTON_SELECTORS.submit) + .click(); + saveRate(); +} + +export function saveRate() { + cy.addAliasToGraphRequest("ShippingMethodChannelListingUpdate") + .addAliasToGraphRequest("ShippingZone") + .get(BUTTON_SELECTORS.confirm) + .click() + .get(SHARED_ELEMENTS.notificationSuccess) + .should("be.visible") + .wait(`@ShippingMethodChannelListingUpdate`) + .wait(`@ShippingZone`) + .get(SHARED_ELEMENTS.notificationSuccess) + .should("not.exist"); +} + +export function fillUpWeightLimits({ max, min }) { + cy.get(SHIPPING_RATE_DETAILS.minWeightInput) + .type(min) + .get(SHIPPING_RATE_DETAILS.maxWeightInput) + .type(max); +} + +export function fillUpDeliveryTime({ min, max }) { + cy.get(SHIPPING_RATE_DETAILS.minDeliveryTimeInput) + .type(min) + .get(SHIPPING_RATE_DETAILS.maxDeliveryTimeInput) + .type(max); } export const rateOptions = { PRICE_OPTION: SHIPPING_ZONE_DETAILS.addPriceRateButton, WEIGHT_OPTION: SHIPPING_ZONE_DETAILS.addWeightRateButton }; + +export const postalCodesOptions = { + INCLUDE_OPTION: SHIPPING_RATE_DETAILS.includePostalCodesCheckbox, + EXCLUDE_OPTION: SHIPPING_RATE_DETAILS.excludePostalCodesCheckbox +}; diff --git a/cypress/steps/user.js b/cypress/steps/user.js index cf3a02c46..adfd3dc6c 100644 --- a/cypress/steps/user.js +++ b/cypress/steps/user.js @@ -4,7 +4,7 @@ import { SHARED_ELEMENTS } from "../elements/shared/sharedElements"; import { INVITE_STAFF_MEMBER_FORM } from "../elements/staffMembers/inviteStaffMemberForm"; import { STAFF_MEMBER_DETAILS } from "../elements/staffMembers/staffMemberDetails"; import { userDetailsUrl } from "../url/urlList"; -import { fillAutocompleteSelect } from "./shared/autocompleteSelect"; +import { fillAutocompleteSelect } from "./shared/selects"; export function fillUpSetPassword(password) { cy.get(SET_PASSWORD.confirmPasswordInput) diff --git a/cypress/url/urlList.js b/cypress/url/urlList.js index b1cde33dc..8e02d49c3 100644 --- a/cypress/url/urlList.js +++ b/cypress/url/urlList.js @@ -14,9 +14,11 @@ export const urlList = { staffMembers: "staff/", newPassword: "new-password/", permissionsGroups: "permission-groups/", + weightRete: "weight/", attributes: "attributes/", productTypes: "product-types/" }; + export const productDetailsUrl = productId => `${urlList.products}${productId}`; export const userDetailsUrl = userId => `${urlList.staffMembers}${userId}`; @@ -30,6 +32,9 @@ export const permissionGroupDetails = permissionGroupId => export const shippingZoneDetailsUrl = shippingZoneId => `${urlList.shippingMethods}${shippingZoneId}`; +export const weightRateUrl = (shippingZoneId, weightRateId) => + `${urlList.shippingMethods}${shippingZoneId}/${urlList.weightRete}${weightRateId}`; + export const warehouseDetailsUrl = warehouseId => `${urlList.warehouses}${warehouseId}`; diff --git a/cypress/utils/ordersUtils.js b/cypress/utils/ordersUtils.js index 7e2f00c06..bd47f6fa4 100644 --- a/cypress/utils/ordersUtils.js +++ b/cypress/utils/ordersUtils.js @@ -165,6 +165,7 @@ export function createOrderWithNewProduct({ shippingMethodId, address }) { + let variantsList; return createProductInChannel({ attributeId, categoryId, @@ -174,13 +175,16 @@ export function createOrderWithNewProduct({ warehouseId, quantityInWarehouse, trackInventory - }).then(({ variantsList }) => - createWaitingForCaptureOrder({ - channelSlug: channel.slug, - email: "email@example.com", - variantsList, - shippingMethodId, - address + }) + .then(({ variantsList: variantsListResp }) => { + variantsList = variantsListResp; + createWaitingForCaptureOrder({ + channelSlug: channel.slug, + email: "email@example.com", + variantsList, + shippingMethodId, + address + }); }) - ); + .then(({ order, checkout }) => ({ order, checkout, variantsList })); } diff --git a/cypress/utils/products/productsUtils.js b/cypress/utils/products/productsUtils.js index 2f2893257..6a5f931d8 100644 --- a/cypress/utils/products/productsUtils.js +++ b/cypress/utils/products/productsUtils.js @@ -22,7 +22,8 @@ export function createProductInChannel({ visibleInListings = true, collectionId = null, description = null, - trackInventory = true + trackInventory = true, + weight = 1 }) { let product; let variantsList; @@ -54,7 +55,8 @@ export function createProductInChannel({ quantityInWarehouse, channelId, price, - trackInventory + trackInventory, + weight }); }) .then(variantsResp => { diff --git a/cypress/utils/shippingUtils.js b/cypress/utils/shippingUtils.js index b09ed06c1..922ad2b3a 100644 --- a/cypress/utils/shippingUtils.js +++ b/cypress/utils/shippingUtils.js @@ -24,9 +24,12 @@ export function createShipping({ }) .then(warehouseResp => { warehouse = warehouseResp; - createShippingRate({ name, shippingZoneId: shippingZone.id }); + shippingMethodRequest.createShippingRate({ + name, + shippingZone: shippingZone.id + }); }) - .then(sippingMethodResp => { + .then(({ shippingMethod: sippingMethodResp }) => { shippingMethod = sippingMethodResp; shippingMethodRequest.addChannelToShippingMethod( shippingMethod.id, diff --git a/cypress/utils/users.js b/cypress/utils/users.js index f7befc793..a7052a8cf 100644 --- a/cypress/utils/users.js +++ b/cypress/utils/users.js @@ -1,5 +1,5 @@ import { getPermissionsArray } from "../apiRequests/permissions"; -import { inviteStaffMember } from "../apiRequests/staffMember"; +import { inviteStaffMember } from "../apiRequests/StaffMembers"; export function inviteStaffMemberWithFirstPermission({ email, diff --git a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx index 945215dfe..abcb7c58b 100644 --- a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx +++ b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx @@ -203,7 +203,11 @@ const MultiAutocompleteSelectFieldContent: React.FC {hasValuesToDisplay && ( -
+
<> {add && ( = ({
- diff --git a/src/shipping/components/ShippingZonePostalCodeRangeDialog/ShippingZonePostalCodeRangeDialog.tsx b/src/shipping/components/ShippingZonePostalCodeRangeDialog/ShippingZonePostalCodeRangeDialog.tsx index 04b8db6a3..6736f43e5 100644 --- a/src/shipping/components/ShippingZonePostalCodeRangeDialog/ShippingZonePostalCodeRangeDialog.tsx +++ b/src/shipping/components/ShippingZonePostalCodeRangeDialog/ShippingZonePostalCodeRangeDialog.tsx @@ -93,6 +93,7 @@ const ShippingZonePostalCodeRangeDialog: React.FC