diff --git a/cypress/apiRequests/ShippingMethod.js b/cypress/apiRequests/ShippingMethod.js new file mode 100644 index 000000000..25c067a43 --- /dev/null +++ b/cypress/apiRequests/ShippingMethod.js @@ -0,0 +1,84 @@ +class ShippingMethod { + createShippingRate(name, shippingZone) { + const mutation = ` + mutation{ + shippingPriceCreate(input:{ + name: "${name}" + shippingZone: "${shippingZone}" + type: PRICE + }){ + shippingMethod{ + id + } + } + } + `; + return cy.sendRequestWithQuery(mutation); + } + + createShippingZone(name, country) { + const mutation = ` + mutation{ + shippingZoneCreate(input:{ + name: "${name}" + countries: "${country}" + }){ + shippingZone{ + id + } + } + } + `; + return cy.sendRequestWithQuery(mutation); + } + + addChannelToShippingMethod(shippingRateId, channelId, price) { + const mutation = ` + mutation{ + shippingMethodChannelListingUpdate(id:"${shippingRateId}", input:{ + addChannels: { + channelId:"${channelId}" + price: ${price} + } + }){ + shippingMethod{ + id + } + shippingErrors{ + code + message + } + } + } + `; + return cy.sendRequestWithQuery(mutation); + } + + deleteShippingZone(shippingZoneId) { + const mutation = `mutation{ + shippingZoneDelete(id:"${shippingZoneId}"){ + shippingErrors{ + message + } + } + } + `; + return cy.sendRequestWithQuery(mutation); + } + + getShippingZones() { + const query = `query{ + shippingZones(first:100){ + edges{ + node{ + name + id + } + } + } + } + `; + return cy.sendRequestWithQuery(query); + } +} +export default ShippingMethod; diff --git a/cypress/apiRequests/Warehouse.js b/cypress/apiRequests/Warehouse.js new file mode 100644 index 000000000..80df7f6f6 --- /dev/null +++ b/cypress/apiRequests/Warehouse.js @@ -0,0 +1,55 @@ +class Warehouse { + createWarehouse(name, shippingZone, address, slug = name) { + const mutation = `mutation{ + createWarehouse(input:{ + name:"${name}" + slug:"${slug}" + shippingZones:"${shippingZone}" + address:{ + streetAddress1: "${address.streetAddress1}" + streetAddress2: "${address.streetAddress2}" + city: "${address.city}" + postalCode: "${address.postalCode}" + country: ${address.country} + phone: "${address.phone}" + } + }){ + warehouseErrors{ + field + message + } + warehouse{ + id + } + } + }`; + return cy.sendRequestWithQuery(mutation); + } + getWarehouses(first, search) { + const query = `query{ + warehouses(first:${first}, filter:{ + search:"${search}" + }){ + edges{ + node{ + id + name + } + } + } + }`; + return cy.sendRequestWithQuery(query); + } + deleteWarehouse(warehouseId) { + const mutation = `mutation{ + deleteWarehouse(id:"${warehouseId}"){ + warehouseErrors{ + field + message + } + } + }`; + return cy.sendRequestWithQuery(mutation); + } +} +export default Warehouse; diff --git a/cypress/elements/frontend-elements/cart-selectors.js b/cypress/elements/frontend-elements/cart-selectors.js new file mode 100644 index 000000000..0209eba5c --- /dev/null +++ b/cypress/elements/frontend-elements/cart-selectors.js @@ -0,0 +1,3 @@ +export const CART_SELECTORS = { + productInCart: "[data-test='cartRow']" +}; diff --git a/cypress/elements/frontend-elements/product-details-selectors.js b/cypress/elements/frontend-elements/product-details-selectors.js new file mode 100644 index 000000000..9cda9b9f6 --- /dev/null +++ b/cypress/elements/frontend-elements/product-details-selectors.js @@ -0,0 +1,3 @@ +export const PRODUCTS_DETAILS_SELECTORS = { + addToCartButton: "[data-test='addProductToCartButton']" +}; diff --git a/cypress/integration/products/availableForPurchase.js b/cypress/integration/products/availableForPurchase.js new file mode 100644 index 000000000..1aa2c3685 --- /dev/null +++ b/cypress/integration/products/availableForPurchase.js @@ -0,0 +1,101 @@ +import faker from "faker"; + +import ShopInfo from "../../apiRequests/ShopInfo"; +import { PRODUCTS_SELECTORS } from "../../elements/catalog/product-selectors"; +import { CART_SELECTORS } from "../../elements/frontend-elements/cart-selectors"; +import { PRODUCTS_DETAILS_SELECTORS } from "../../elements/frontend-elements/product-details-selectors"; +import { SEARCH_SELECTORS } from "../../elements/frontend-elements/search-selectors"; +import SearchSteps from "../../steps/frontendSteps/searchSteps"; +import { URL_LIST } from "../../url/url-list"; +import ChannelsUtils from "../../utils/channelsUtils"; +import ProductsUtils from "../../utils/productsUtils"; +import ShippingUtils from "../../utils/shippingUtils"; + +// +describe("Products", () => { + const shippingUtils = new ShippingUtils(); + const channelsUtils = new ChannelsUtils(); + const productsUtils = new ProductsUtils(); + const searchSteps = new SearchSteps(); + + const shopInfo = new ShopInfo(); + + const startsWith = "Cy-"; + const name = `${startsWith}${faker.random.number()}`; + let productTypeId; + let attributeId; + let categoryId; + let defaultChannel; + let warehouseId; + + before(() => { + cy.clearSessionData().loginUserViaRequest(); + shippingUtils.deleteShipping(startsWith); + productsUtils.deleteProducts(startsWith); + + channelsUtils.findDefaultChannel().then(() => { + defaultChannel = channelsUtils.getDefaultChannel(); + cy.fixture("addresses").then(json => { + shippingUtils + .createShipping(defaultChannel, name, json.plAddress, 10) + .then(() => { + warehouseId = shippingUtils.getWarehouseId(); + }); + }); + }); + productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => { + productTypeId = productsUtils.getProductTypeId(); + attributeId = productsUtils.getAttributeId(); + categoryId = productsUtils.getCategoryId(); + }); + }); + + beforeEach(() => { + cy.clearSessionData().loginUserViaRequest(); + shopInfo + .getShopInfo() + .its("body.data.shop.domain.url") + .as("shopUrl"); + }); + + it("should be possible to add to cart available for purchase product", () => { + const productName = `${startsWith}${faker.random.number()}`; + productsUtils + .createProductInChannel( + productName, + productTypeId, + attributeId, + categoryId, + defaultChannel, + true, + false, + warehouseId, + 10, + 10 + ) + .then(() => { + const productUrl = `${URL_LIST.products}${productsUtils.getCreatedProductId}`; + cy.visit(productUrl) + .get(PRODUCTS_SELECTORS.assignedChannels) + .click() + .get(PRODUCTS_SELECTORS.publishedRadioButton) + .contains("Dostępne do zakupu") + .click() + .get(PRODUCTS_SELECTORS.saveBtn) + .click() + .waitForGraph("ProductChannelListingUpdate") + .get("@shopUrl") + .then(shopUrl => { + cy.visit(shopUrl); + searchSteps.searchFor(name); + cy.get(SEARCH_SELECTORS.productItem) + .contains(productName) + .click() + .get(PRODUCTS_DETAILS_SELECTORS.addToCartButton) + .click() + .get(CART_SELECTORS.productInCart) + .contains(productName); + }); + }); + }); +}); diff --git a/cypress/utils/channelsUtils.js b/cypress/utils/channelsUtils.js index a536fb4f3..7e1e58973 100644 --- a/cypress/utils/channelsUtils.js +++ b/cypress/utils/channelsUtils.js @@ -3,6 +3,8 @@ import Channels from "../apiRequests/Channels"; class ChannelsUtils { channels = new Channels(); + defaultChannel; + deleteChannels(nameStartsWith) { this.channels.getChannels().then(resp => { const channelsArray = new Set(resp.body.data.channels); @@ -26,13 +28,18 @@ class ChannelsUtils { } }); } - getDefaultChannel() { + findDefaultChannel() { return this.channels.getChannels().then(resp => { const channelsArray = resp.body.data.channels; - return channelsArray.find(function(channelElement) { + return (this.defaultChannel = channelsArray.find(function( + channelElement + ) { return channelElement.slug === "default-channel"; - }); + })); }); } + getDefaultChannel() { + return this.defaultChannel; + } } export default ChannelsUtils; diff --git a/cypress/utils/shippingUtils.js b/cypress/utils/shippingUtils.js new file mode 100644 index 000000000..5806ac82d --- /dev/null +++ b/cypress/utils/shippingUtils.js @@ -0,0 +1,71 @@ +import ShippingMethod from "../apiRequests/ShippingMethod"; +import Warehouse from "../apiRequests/Warehouse"; +class ShippingUtils { + shippingMethodId; + shippingZoneId; + warehouseId; + + createShipping(channelId, name, address, price) { + const shippingMethod = new ShippingMethod(); + const warehouse = new Warehouse(); + return shippingMethod + .createShippingZone(name, address.country) + .then(shippingZoneResp => { + this.shippingZoneId = + shippingZoneResp.body.data.shippingZoneCreate.shippingZone.id; + return warehouse + .createWarehouse(name, this.shippingZoneId, address) + .then(createWarehouseResp => { + this.warehouseId = + createWarehouseResp.body.data.createWarehouse.warehouse.id; + return shippingMethod + .createShippingRate(name, this.shippingZoneId) + .then(rateResp => { + this.shippingMethodId = + rateResp.body.data.shippingPriceCreate.shippingMethod.id; + return shippingMethod.addChannelToShippingMethod( + this.shippingMethodId, + channelId, + price + ); + }); + }); + }); + } + + getShippingMethodId() { + return this.shippingMethodId; + } + + getShippingZoneId() { + return this.shippingZoneId; + } + + getWarehouseId() { + return this.warehouseId; + } + + deleteShipping(startsWith) { + const shippingMethod = new ShippingMethod(); + const warehouse = new Warehouse(); + shippingMethod.getShippingZones().then(resp => { + if (resp.body.data.shippingZones) { + const shippingZone = resp.body.data.shippingZones.edges; + shippingZone.forEach(element => { + if (element.node.name.includes(startsWith)) { + shippingMethod.deleteShippingZone(element.node.id); + } + }); + } + }); + warehouse.getWarehouses(100, startsWith).then(resp => { + const warehouses = resp.body.data.warehouses.edges; + warehouses.forEach(warehouseElement => { + if (warehouseElement.node.name.includes(startsWith)) { + warehouse.deleteWarehouse(warehouseElement.node.id); + } + }); + }); + } +} +export default ShippingUtils;