From 925e723c355417684567a0bf8fdfe70f60b00243 Mon Sep 17 00:00:00 2001 From: Karolina Rakoczy Date: Fri, 26 Nov 2021 12:42:59 +0200 Subject: [PATCH] Add tests for creating preorders (#1563) * add test for creating preorder variant * all tests for creating & editing variants in preorder --- .../catalog/products/variants-selectors.js | 5 + cypress/fixtures/urlList.js | 4 + .../createAndEditVariantsInPreorder.js | 133 ++++++++++++++++++ cypress/support/api/requests/Product.js | 55 +++++++- .../api/utils/products/productsUtils.js | 8 +- cypress/support/formatData/formatDate.js | 8 ++ cypress/support/index.d.ts | 1 + .../pages/catalog/products/VariantsPage.js | 80 ++++++++--- 8 files changed, 270 insertions(+), 24 deletions(-) create mode 100644 cypress/integration/preorders/createAndEditVariantsInPreorder.js diff --git a/cypress/elements/catalog/products/variants-selectors.js b/cypress/elements/catalog/products/variants-selectors.js index 494a44742..68911eefc 100644 --- a/cypress/elements/catalog/products/variants-selectors.js +++ b/cypress/elements/catalog/products/variants-selectors.js @@ -10,5 +10,10 @@ export const VARIANTS_SELECTORS = { warehouseOption: "[role='menuitem']", saveButton: "[data-test='button-bar-confirm']", skuInputInAddVariant: "[name='sku']", + preorderCheckbox: "[name='isPreorder']", + setUpEndDateButton: "[name='hasPreorderEndDate']", + preorderEndDateInput: "[name='preorderEndDateTime:date']", + preorderEndTimeInput: "[name='preorderEndDateTime:time']", + globalThresholdInput: "[name='globalThreshold']", stockInput: "[data-test-id='stock-input']" }; diff --git a/cypress/fixtures/urlList.js b/cypress/fixtures/urlList.js index a45d1e332..a3a4be248 100644 --- a/cypress/fixtures/urlList.js +++ b/cypress/fixtures/urlList.js @@ -28,6 +28,7 @@ export const urlList = { translations: "translations/", variants: "variant/", vouchers: "discounts/vouchers/", + variant: "variant/", warehouses: "warehouses/", weightRete: "weight/" }; @@ -80,5 +81,8 @@ export const saleDetailsUrl = saleId => `${urlList.sales}${saleId}`; export const voucherDetailsUrl = voucherId => `${urlList.vouchers}${voucherId}`; +export const variantDetailsUrl = (productId, variantId) => + `${urlList.products}${productId}/${urlList.variant}${variantId}`; + export const stripeConfirmationUrl = id => `https://api.stripe.com/v1/payment_intents/${id}/confirm`; diff --git a/cypress/integration/preorders/createAndEditVariantsInPreorder.js b/cypress/integration/preorders/createAndEditVariantsInPreorder.js new file mode 100644 index 000000000..e0c963f2c --- /dev/null +++ b/cypress/integration/preorders/createAndEditVariantsInPreorder.js @@ -0,0 +1,133 @@ +/// +/// + +import { PRODUCT_DETAILS } from "../../elements/catalog/products/product-details"; +import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors"; +import { productDetailsUrl, variantDetailsUrl } from "../../fixtures/urlList"; +import { + activatePreorderOnVariant, + deactivatePreorderOnVariant, + getVariant +} from "../../support/api/requests/Product"; +import { createWaitingForCaptureOrder } from "../../support/api/utils/ordersUtils"; +import { createProductWithShipping } from "../../support/api/utils/products/productsUtils"; +import filterTests from "../../support/filterTests"; +import { formatDate, formatTime } from "../../support/formatData/formatDate"; +import { + enablePreorderWithThreshold, + fillUpVariantAttributeAndSku, + saveVariant, + selectChannelForVariantAndFillUpPrices, + setUpPreorderEndDate +} from "../../support/pages/catalog/products/VariantsPage"; + +filterTests({ definedTags: ["all"], version: "3.1.0" }, () => { + describe("Creating variants", () => { + const startsWith = "CreatePreOrder"; + const attributeValues = ["value1", "value2", "value3"]; + const threshold = 100; + const futureDate = new Date().setDate(new Date().getDate() + 14); + const endDate = formatDate(futureDate); + const endTime = formatTime(futureDate); + + let defaultChannel; + let product; + let variantsList; + let checkoutData; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + createProductWithShipping({ name: startsWith, attributeValues }).then( + resp => { + checkoutData = { + address: resp.address, + channelSlug: resp.defaultChannel.slug, + email: "example@example.com", + shippingMethodId: resp.shippingMethod.id + }; + defaultChannel = resp.defaultChannel; + product = resp.product; + variantsList = resp.variantsList; + } + ); + }); + + beforeEach(() => { + cy.clearSessionData().loginUserViaRequest(); + }); + + it("should create variant in preorder", () => { + let variant; + + cy.visit(productDetailsUrl(product.id)) + .get(PRODUCT_DETAILS.addVariantsButton) + .click(); + fillUpVariantAttributeAndSku({ + attributeName: attributeValues[1], + sku: attributeValues[1] + }); + enablePreorderWithThreshold(threshold); + setUpPreorderEndDate(endDate, endTime); + saveVariant() + .then(({ response }) => { + variant = response.body.data.productVariantCreate.productVariant; + cy.get(BUTTON_SELECTORS.back).click(); + selectChannelForVariantAndFillUpPrices({ + channelName: defaultChannel.name, + attributeName: attributeValues[1], + price: 10 + }); + }) + .then(() => { + checkoutData.variantsList = [variant]; + createWaitingForCaptureOrder(checkoutData); + }) + .then(({ order }) => { + expect(order.id).to.be.ok; + getVariant(variant.id, defaultChannel.slug); + }) + .then(({ preorder }) => { + const respEndDate = new Date(preorder.endDate); + + expect(preorder.globalThreshold).to.eq(threshold); + expect(preorder.globalSoldUnits).to.eq(1); + expect(endDate).to.eq(formatDate(respEndDate)); + expect(endTime).to.eq(formatTime(respEndDate)); + }); + }); + + it("should enable preorder on active variant", () => { + const variant = variantsList[0]; + checkoutData.variantsList = [variant]; + + deactivatePreorderOnVariant(variant.id); + cy.visit(variantDetailsUrl(product.id, variant.id)); + enablePreorderWithThreshold(threshold); + saveVariant("VariantUpdate"); + createWaitingForCaptureOrder(checkoutData) + .then(({ order }) => { + expect(order.id).to.be.ok; + getVariant(variant.id, defaultChannel.slug); + }) + .then(({ preorder }) => { + expect(preorder.globalThreshold).to.eq(threshold); + expect(preorder.globalSoldUnits).to.eq(1); + }); + }); + + it("should set end date on preorder variant", () => { + const variant = variantsList[0]; + checkoutData.variantsList = [variant]; + + activatePreorderOnVariant(variant.id); + cy.visit(variantDetailsUrl(product.id, variant.id)); + setUpPreorderEndDate(endDate, endTime); + saveVariant("VariantUpdate"); + getVariant(variant.id, defaultChannel.slug).then(({ preorder }) => { + const respEndDate = new Date(preorder.endDate); + expect(endDate).to.eq(formatDate(respEndDate)); + expect(endTime).to.eq(formatTime(respEndDate)); + }); + }); + }); +}); diff --git a/cypress/support/api/requests/Product.js b/cypress/support/api/requests/Product.js index 3467caa16..c021a95b6 100644 --- a/cypress/support/api/requests/Product.js +++ b/cypress/support/api/requests/Product.js @@ -1,9 +1,6 @@ import { stringify } from "../.././formatData/formatJson"; -import { - getValuesInArray, - getValueWithDefault, - getVariantsListIds -} from "./utils/Utils"; +import { returnValueDependsOnShopVersion } from "../../formatData/dataDependingOnVersion"; +import { getValueWithDefault, getVariantsListIds } from "./utils/Utils"; export function getFirstProducts(first, search) { const filter = search @@ -241,10 +238,20 @@ export function getVariants(variantsList) { } export function getVariant(id, channel, auth = "auth") { + const preorder = returnValueDependsOnShopVersion( + "3.1", + `preorder{ + globalThreshold + globalSoldUnits + endDate + }` + ); + const query = `query{ productVariant(id:"${id}" channel:"${channel}"){ id name + ${preorder} sku pricing{ onSale @@ -268,3 +275,41 @@ export function getVariant(id, channel, auth = "auth") { }`; return cy.sendRequestWithQuery(query, auth).its("body.data.productVariant"); } + +export function deactivatePreorderOnVariant(variantId) { + const mutation = `mutation{ + productVariantPreorderDeactivate(id:"${variantId}"){ + errors{ + field + message + } + } + }`; + return cy + .sendRequestWithQuery(mutation) + .its("body.data.productVariantPreorderDeactivate"); +} + +export function activatePreorderOnVariant(variantId, threshold, endDate) { + const thresholdLine = getValueWithDefault( + threshold, + `globalThreshold:${threshold}` + ); + const endDateLine = getValueWithDefault(threshold, `endDate:${endDate}`); + const mutation = `mutation{ + productVariantUpdate(id:"${variantId}", input:{ + preorder:{ + ${thresholdLine} + ${endDateLine} + } + }){ + errors{ + field + message + } + } + }`; + return cy + .sendRequestWithQuery(mutation) + .its("body.data.productVariantUpdate"); +} diff --git a/cypress/support/api/utils/products/productsUtils.js b/cypress/support/api/utils/products/productsUtils.js index 28f689315..f9059c270 100644 --- a/cypress/support/api/utils/products/productsUtils.js +++ b/cypress/support/api/utils/products/productsUtils.js @@ -12,7 +12,7 @@ import { import { deleteAttributesStartsWith } from "../attributes/attributeUtils"; import { deleteCollectionsStartsWith } from "../catalog/collectionsUtils"; import { getDefaultChannel } from "../channelsUtils"; -import { createShipping } from "../shippingUtils"; +import { createShipping, deleteShippingStartsWith } from "../shippingUtils"; export function createProductInChannel({ name, @@ -116,6 +116,7 @@ export function deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({ name, description = name, warehouseId, + attributeValues = ["value"], sku = name, productPrice = 10 }) { @@ -132,7 +133,7 @@ export function deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({ }) .then(collectionResp => { collection = collectionResp; - createTypeAttributeAndCategoryForProduct({ name }); + createTypeAttributeAndCategoryForProduct({ name, attributeValues }); }) .then(({ attribute: attributeResp, category, productType }) => { attribute = attributeResp; @@ -154,6 +155,7 @@ export function deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({ export function createProductWithShipping({ name, + attributeValues = ["value"], sku = name, productPrice = 10, shippingPrice = 10 @@ -164,6 +166,7 @@ export function createProductWithShipping({ let defaultChannel; let shippingZone; + deleteShippingStartsWith(name); return cy .fixture("addresses") .then(addresses => { @@ -191,6 +194,7 @@ export function createProductWithShipping({ deleteProductsAndCreateNewOneWithNewDataAndDefaultChannel({ name, warehouseId: warehouse.id, + attributeValues, sku, productPrice }); diff --git a/cypress/support/formatData/formatDate.js b/cypress/support/formatData/formatDate.js index 324d7261a..1140a381a 100644 --- a/cypress/support/formatData/formatDate.js +++ b/cypress/support/formatData/formatDate.js @@ -10,3 +10,11 @@ function getPeriodValue(date, option) { const formatter = new Intl.DateTimeFormat("en-us", option); return formatter.format(date); } + +export function formatTime(date) { + const formatter = new Intl.DateTimeFormat([], { + hour: "numeric", + minute: "numeric" + }); + return formatter.format(date); +} diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts index 56916ff8d..1db07d05b 100644 --- a/cypress/support/index.d.ts +++ b/cypress/support/index.d.ts @@ -48,5 +48,6 @@ declare namespace Cypress { createNewOption(selectSelector: string, newOption: string): Chainable; findElementOnTable(elementName: string): Chainable; searchInTable(query: string): Chainable; + waitForRequestAndCheckIfNoErrors(alias: string): Chainable; } } diff --git a/cypress/support/pages/catalog/products/VariantsPage.js b/cypress/support/pages/catalog/products/VariantsPage.js index ae4077e47..53729e8e1 100644 --- a/cypress/support/pages/catalog/products/VariantsPage.js +++ b/cypress/support/pages/catalog/products/VariantsPage.js @@ -55,28 +55,50 @@ export function createVariant({ channelName, quantity = 10 }) { - cy.get(PRODUCT_DETAILS.addVariantsButton) + cy.get(PRODUCT_DETAILS.addVariantsButton).click(); + fillUpGeneralVariantInputs({ attributeName, warehouseName, sku }); + cy.get(VARIANTS_SELECTORS.saveButton) .click() - .get(VARIANTS_SELECTORS.attributeSelector) + .get(BUTTON_SELECTORS.back) + .click(); + selectChannelForVariantAndFillUpPrices({ + channelName, + attributeName, + price, + costPrice + }); +} + +export function fillUpGeneralVariantInputs({ + attributeName, + warehouseName, + sku +}) { + fillUpVariantAttributeAndSku({ attributeName, sku }); + cy.get(VARIANTS_SELECTORS.addWarehouseButton).click(); + cy.contains(VARIANTS_SELECTORS.warehouseOption, warehouseName).click({ + force: true + }); + cy.get(VARIANTS_SELECTORS.stockInput).type(quantity); +} + +export function fillUpVariantAttributeAndSku({ attributeName, sku }) { + cy.get(VARIANTS_SELECTORS.attributeSelector) .click() .get(VARIANTS_SELECTORS.attributeOption) .contains(attributeName) - .click(); - if (sku) { - cy.get(VARIANTS_SELECTORS.skuInputInAddVariant).type(sku); - } - cy.get(VARIANTS_SELECTORS.addWarehouseButton).click(); - cy.contains(VARIANTS_SELECTORS.warehouseOption, warehouseName) - .click({ - force: true - }) - .get(VARIANTS_SELECTORS.stockInput) - .type(quantity) - .get(VARIANTS_SELECTORS.saveButton) .click() - .get(BUTTON_SELECTORS.back) - .click() - .addAliasToGraphRequest("ProductChannelListingUpdate"); + .get(VARIANTS_SELECTORS.skuInputInAddVariant) + .type(sku); +} + +export function selectChannelForVariantAndFillUpPrices({ + channelName, + attributeName, + price, + costPrice = price +}) { + cy.addAliasToGraphRequest("ProductChannelListingUpdate"); selectChannelVariantInDetailsPage(channelName, attributeName); cy.get(BUTTON_SELECTORS.confirm) .click() @@ -97,3 +119,27 @@ export function createVariant({ .get(AVAILABLE_CHANNELS_FORM.menageChannelsButton) .should("be.visible"); } + +export function enablePreorderWithThreshold(threshold) { + cy.get(VARIANTS_SELECTORS.preorderCheckbox) + .click() + .get(VARIANTS_SELECTORS.globalThresholdInput) + .type(threshold); +} + +export function setUpPreorderEndDate(endDate, endTime) { + cy.get(VARIANTS_SELECTORS.setUpEndDateButton) + .click() + .get(VARIANTS_SELECTORS.preorderEndDateInput) + .type(endDate) + .get(VARIANTS_SELECTORS.preorderEndTimeInput) + .type(endTime); +} + +export function saveVariant(waitForAlias = "VariantCreate") { + return cy + .addAliasToGraphRequest(waitForAlias) + .get(BUTTON_SELECTORS.confirm) + .click() + .waitForRequestAndCheckIfNoErrors(`@${waitForAlias}`); +}