diff --git a/cypress/apiRequests/Attribute.js b/cypress/apiRequests/Attribute.js
new file mode 100644
index 000000000..4ba3467f2
--- /dev/null
+++ b/cypress/apiRequests/Attribute.js
@@ -0,0 +1,49 @@
+class Attribute {
+ createAttribute(name) {
+ const mutation = `mutation{
+ attributeCreate(input:{
+ name:"${name}"
+ valueRequired:false
+ type:PRODUCT_TYPE
+ }){
+ attribute{
+ id
+ }
+ attributeErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ getAttributes(first, search) {
+ const mutation = `query{
+ attributes(first:${first}, filter:{
+ search:"${search}"
+ }){
+ edges{
+ node{
+ id
+ name
+ }
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ deleteAttribute(attributeId) {
+ const mutation = `mutation{
+ attributeDelete(id:"${attributeId}"){
+ attributeErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+}
+export default Attribute;
diff --git a/cypress/apiRequests/Category.js b/cypress/apiRequests/Category.js
new file mode 100644
index 000000000..0d76c7b3b
--- /dev/null
+++ b/cypress/apiRequests/Category.js
@@ -0,0 +1,43 @@
+class Category {
+ createCategory(name, slug = name) {
+ const mutation = `mutation{
+ categoryCreate(input:{name:"${name}", slug: "${slug}"}){
+ productErrors{
+ field
+ message
+ }
+ category{
+ id
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+ getCategories(first, search) {
+ const mutation = `query{
+ categories(first:${first}, filter:{
+ search:"${search}"
+ }){
+ edges{
+ node{
+ id
+ name
+ }
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+ deleteCategory(categoryId) {
+ const mutation = `mutation{
+ categoryDelete(id:"${categoryId}"){
+ productErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+}
+export default Category;
diff --git a/cypress/apiRequests/Channels.js b/cypress/apiRequests/Channels.js
new file mode 100644
index 000000000..2daa39a9e
--- /dev/null
+++ b/cypress/apiRequests/Channels.js
@@ -0,0 +1,53 @@
+class Channels {
+ createChannel(isActive, name, slug, currencyCode) {
+ const createChannelMutation = `mutation{
+ channelCreate(input: {
+ isActive: ${isActive}
+ name: "${name}"
+ slug: "${slug}"
+ currencyCode: "${currencyCode}"
+ }){
+ channel{
+ name
+ slug
+ }
+ channelErrors{
+ code
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(createChannelMutation);
+ }
+
+ getChannels() {
+ const getChannelsInfoQuery = `query{
+ channels{
+ name
+ id
+ isActive
+ slug
+ currencyCode
+ }
+ }
+ `;
+ return cy.sendRequestWithQuery(getChannelsInfoQuery);
+ }
+
+ deleteChannel(channelId, targetChennelId) {
+ const deleteChannelMutation = `mutation{
+ channelDelete(id: "${channelId}", input:{
+ targetChannel: "${targetChennelId}"
+ }){
+ channel{
+ name
+ }
+ channelErrors{
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(deleteChannelMutation);
+ }
+}
+export default Channels;
diff --git a/cypress/apiRequests/Product.js b/cypress/apiRequests/Product.js
new file mode 100644
index 000000000..e7e0c11d7
--- /dev/null
+++ b/cypress/apiRequests/Product.js
@@ -0,0 +1,192 @@
+class Product {
+ getFirstProducts(first, search) {
+ let filter = "";
+ if (search) {
+ filter = `, filter:{
+ search:"${search}"
+ }`;
+ }
+ const query = `query{
+ products(first:${first}${filter}){
+ edges{
+ node{
+ id
+ name
+ variants{
+ id
+ }
+ }
+ }
+ }
+ }
+ `;
+ return cy.sendRequestWithQuery(query);
+ }
+
+ updateChannelInProduct(
+ productId,
+ channelId,
+ isPublished,
+ isAvailableForPurchase
+ ) {
+ const mutation = `mutation{
+ productChannelListingUpdate(id:"${productId}",
+ input:{
+ addChannels:{
+ channelId:"${channelId}"
+ isPublished:${isPublished}
+ isAvailableForPurchase:${isAvailableForPurchase}
+ visibleInListings:true
+ }
+ }){
+ product{
+ id
+ name
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ updateChannelPriceInVariant(variantId, channelId) {
+ const mutation = `mutation{
+ productVariantChannelListingUpdate(id: "${variantId}", input:{
+ channelId: "${channelId}"
+ price: 10
+ costPrice: 10
+ }){
+ productChannelListingErrors{
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+ createProduct(attributeId, name, productType, category) {
+ const mutation = `mutation{
+ productCreate(input:{
+ attributes:[{
+ id:"${attributeId}"
+ }]
+ name:"${name}"
+ productType:"${productType}"
+ category:"${category}"
+ }){
+ product{
+ id
+ }
+ productErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ createVariant(
+ productId,
+ sku,
+ warehouseId,
+ quantity,
+ channelId,
+ price = 1,
+ costPrice = 1
+ ) {
+ let channelListings = "";
+ let stocks = "";
+ if (channelId) {
+ channelListings = `channelListings:{
+ channelId:"${channelId}"
+ price:"${price}"
+ costPrice:"${costPrice}"
+ }`;
+ }
+ if (warehouseId) {
+ stocks = `stocks:{
+ warehouse:"${warehouseId}"
+ quantity:${quantity}
+ }`;
+ }
+ const mutation = `mutation{
+ productVariantBulkCreate(product:"${productId}", variants:{
+ attributes:[]
+ sku:"${sku}"
+ ${channelListings}
+ ${stocks}
+ }){
+ productVariants{
+ id
+ name
+ }
+ bulkProductErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ createTypeProduct(name, attributeId, slug = name) {
+ const mutation = `mutation{
+ productTypeCreate(input:{
+ name:"${name}"
+ slug: "${slug}"
+ isShippingRequired:true
+ productAttributes:"${attributeId}"
+ }){
+ productErrors{
+ field
+ message
+ }
+ productType{
+ id
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ deleteProduct(productId) {
+ const mutation = `mutation{
+ productDelete(id:"${productId}"){
+ productErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+
+ getProductTypes(first, search) {
+ const query = `query{
+ productTypes(first:${first}, filter:{
+ search:"${search}"
+ }){
+ edges{
+ node{
+ id
+ name
+ }
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(query);
+ }
+
+ deleteProductType(productTypeId) {
+ const mutation = `mutation{
+ productTypeDelete(id:"${productTypeId}"){
+ productErrors{
+ field
+ message
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(mutation);
+ }
+}
+
+export default Product;
diff --git a/cypress/apiRequests/ShopInfo.js b/cypress/apiRequests/ShopInfo.js
new file mode 100644
index 000000000..17d5f8a9e
--- /dev/null
+++ b/cypress/apiRequests/ShopInfo.js
@@ -0,0 +1,13 @@
+class ShopInfo {
+ getShopInfo() {
+ const query = `query{
+ shop{
+ domain{
+ url
+ }
+ }
+ }`;
+ return cy.sendRequestWithQuery(query);
+ }
+}
+export default ShopInfo;
diff --git a/cypress/elements/catalog/product-selectors.js b/cypress/elements/catalog/product-selectors.js
index de68973b0..b61b38a11 100644
--- a/cypress/elements/catalog/product-selectors.js
+++ b/cypress/elements/catalog/product-selectors.js
@@ -1,5 +1,6 @@
/* eslint-disable sort-keys */
export const PRODUCTS_SELECTORS = {
+ productsList: "[data-test-id][data-test='id']",
products: "[data-test='submenu-item-label'][data-test-id='products']",
createProductBtn: "[data-test='add-product']",
productNameInput: "[name='name']",
@@ -11,5 +12,16 @@ export const PRODUCTS_SELECTORS = {
visibleRadioBtn: "[name='isPublished']",
saveBtn: "[data-test='button-bar-confirm']",
confirmationMsg: "[data-test='notification-success']",
- channelAvailabilityItem: "[data-test='channel-availability-item']"
+ channelAvailabilityItem: "[data-test='channel-availability-item']",
+ searchProducts: "[placeholder='Search Products...']",
+ availableManageButton:
+ "[data-test-id='channels-availiability-manage-button']",
+ channelsAvailabilityForm:
+ "[data-test-id='manage-products-channels-availiability-list']",
+ channelAvailabilityColumn:
+ "[data-test='availability'][data-test-availability='true']",
+ channelAvailabilityList: "ul[role='menu']",
+ goBackButton: "[data-test-id='app-header-back-button']",
+ assignedChannels: "[data-test='channel-availability-item']",
+ publishedRadioButton: "[role=radiogroup]"
};
diff --git a/cypress/elements/frontend-elements/search-selectors.js b/cypress/elements/frontend-elements/search-selectors.js
new file mode 100644
index 000000000..712a91ce9
--- /dev/null
+++ b/cypress/elements/frontend-elements/search-selectors.js
@@ -0,0 +1,5 @@
+export const SEARCH_SELECTORS = {
+ searchButton: "[data-test='menuSearchOverlayLink']",
+ searchInputField: "[placeholder='search']",
+ productItem: ".search__products__item"
+};
diff --git a/cypress/fixtures/addresses.json b/cypress/fixtures/addresses.json
new file mode 100644
index 000000000..5a346904f
--- /dev/null
+++ b/cypress/fixtures/addresses.json
@@ -0,0 +1,5 @@
+{
+ "plAddress":{
+ "currency": "PLN"
+ }
+}
\ No newline at end of file
diff --git a/cypress/integration/products.js b/cypress/integration/products.js
deleted file mode 100644
index 1d8e38ee8..000000000
--- a/cypress/integration/products.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { LEFT_MENU_SELECTORS } from "../elements/account/left-menu/left-menu-selectors";
-import { PRODUCTS_SELECTORS } from "../elements/catalog/product-selectors";
-
-//
-describe("Products", () => {
- beforeEach(() => {
- cy.clearSessionData().loginUserViaRequest();
- });
-
- it("should add new visible product", () => {
- cy.visit("/")
- .get(LEFT_MENU_SELECTORS.catalog)
- .click()
- .get(PRODUCTS_SELECTORS.products)
- .click()
- .get(PRODUCTS_SELECTORS.createProductBtn)
- .click()
- .get(PRODUCTS_SELECTORS.productNameInput)
- .click()
- .type("Visible test product")
- .get(PRODUCTS_SELECTORS.productTypeInput)
- .click()
- .get(PRODUCTS_SELECTORS.autocompleteDropdown) // trying to fill autocomplete before dropdown will cause error
- .get(PRODUCTS_SELECTORS.productTypeInput)
- .click()
- .type("Cushion")
- .get(PRODUCTS_SELECTORS.categoryItem)
- .should("have.length", 1)
- .get(PRODUCTS_SELECTORS.firstCategoryItem)
- .click()
- .get(PRODUCTS_SELECTORS.categoryInput)
- .click()
- .get(PRODUCTS_SELECTORS.categoryItem)
- .first()
- .click()
- .get(PRODUCTS_SELECTORS.channelAvailabilityItem)
- .first()
- .click()
- .get(PRODUCTS_SELECTORS.visibleRadioBtn)
- .first()
- .click()
- .get(PRODUCTS_SELECTORS.saveBtn)
- .click()
- .get(PRODUCTS_SELECTORS.confirmationMsg)
- .contains("Product created");
- });
-});
diff --git a/cypress/integration/products/products.js b/cypress/integration/products/products.js
new file mode 100644
index 000000000..9cb780cda
--- /dev/null
+++ b/cypress/integration/products/products.js
@@ -0,0 +1,109 @@
+import faker from "faker";
+
+import Channels from "../../apiRequests/Channels";
+import { LEFT_MENU_SELECTORS } from "../../elements/account/left-menu/left-menu-selectors";
+import { PRODUCTS_SELECTORS } from "../../elements/catalog/product-selectors";
+import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
+import { URL_LIST } from "../../url/url-list";
+import ChannelsUtils from "../../utils/channelsUtils";
+import ProductsUtils from "../../utils/productsUtils";
+
+//
+describe("Products", () => {
+ const channels = new Channels();
+ const channelsUtils = new ChannelsUtils();
+ const productsUtils = new ProductsUtils();
+
+ const startsWith = "Cy-";
+
+ before(() => {
+ cy.clearSessionData().loginUserViaRequest();
+ productsUtils.deleteProducts(startsWith);
+ channelsUtils.deleteChannels(startsWith);
+ });
+
+ beforeEach(() => {
+ cy.clearSessionData().loginUserViaRequest();
+ });
+
+ xit("should add new visible product", () => {
+ cy.visit("/")
+ .get(LEFT_MENU_SELECTORS.catalog)
+ .click()
+ .get(PRODUCTS_SELECTORS.products)
+ .click()
+ .get(PRODUCTS_SELECTORS.createProductBtn)
+ .click()
+ .get(PRODUCTS_SELECTORS.productNameInput)
+ .click()
+ .type("Visible test product")
+ .get(PRODUCTS_SELECTORS.productTypeInput)
+ .click()
+ .get(PRODUCTS_SELECTORS.autocompleteDropdown) // trying to fill autocomplete before dropdown will cause error
+ .get(PRODUCTS_SELECTORS.productTypeInput)
+ .click()
+ .type("Cushion")
+ .get(PRODUCTS_SELECTORS.categoryItem)
+ .should("have.length", 1)
+ .get(PRODUCTS_SELECTORS.firstCategoryItem)
+ .click()
+ .get(PRODUCTS_SELECTORS.categoryInput)
+ .click()
+ .get(PRODUCTS_SELECTORS.categoryItem)
+ .first()
+ .click()
+ .get(PRODUCTS_SELECTORS.channelAvailabilityItem)
+ .first()
+ .click()
+ .get(PRODUCTS_SELECTORS.visibleRadioBtn)
+ .first()
+ .click()
+ .get(PRODUCTS_SELECTORS.saveBtn)
+ .click()
+ .get(PRODUCTS_SELECTORS.confirmationMsg)
+ .contains("Product created");
+ });
+ it("should display correct availibility for product in channel", () => {
+ const name = `${startsWith}${faker.random.number()}`;
+ cy.fixture("addresses").then(json => {
+ channels.createChannel(true, name, name, json.plAddress.currency);
+ productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
+ const productTypeId = productsUtils.getProductTypeId();
+ const attributeId = productsUtils.getAttributeId();
+ const categoryId = productsUtils.getCategoryId();
+ productsUtils.createProduct(
+ name,
+ attributeId,
+ productTypeId,
+ categoryId
+ );
+ cy.visit(URL_LIST.products)
+ .get(PRODUCTS_SELECTORS.searchProducts)
+ .type(name)
+ .get(PRODUCTS_SELECTORS.productsList)
+ .contains(name)
+ .click()
+ .get(PRODUCTS_SELECTORS.availableManageButton)
+ .click()
+ .get(PRODUCTS_SELECTORS.channelsAvailabilityForm)
+ .contains(name)
+ .click()
+ .get(BUTTON_SELECTORS.submit)
+ .click()
+ .get(PRODUCTS_SELECTORS.saveBtn)
+ .click()
+ .get(PRODUCTS_SELECTORS.goBackButton)
+ .click()
+ .get(PRODUCTS_SELECTORS.searchProducts)
+ .type(name)
+ .get(PRODUCTS_SELECTORS.productsList)
+ .contains(name)
+ .parentsUntil("tbody")
+ .find(PRODUCTS_SELECTORS.channelAvailabilityColumn)
+ .click()
+ .get(PRODUCTS_SELECTORS.channelAvailabilityList)
+ .contains(name);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/products/publish.js b/cypress/integration/products/publish.js
new file mode 100644
index 000000000..ebd7588fc
--- /dev/null
+++ b/cypress/integration/products/publish.js
@@ -0,0 +1,141 @@
+import faker from "faker";
+
+import ShopInfo from "../../apiRequests/ShopInfo";
+import { PRODUCTS_SELECTORS } from "../../elements/catalog/product-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";
+
+//
+describe("Products", () => {
+ 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;
+
+ before(() => {
+ cy.clearSessionData().loginUserViaRequest();
+ productsUtils.deleteProducts(startsWith);
+ 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");
+ });
+ xit("should display on frontend only published products", () => {
+ const productName = `${startsWith}${faker.random.number()}`;
+ channelsUtils.getDefaultChannel().then(defaultChannel => {
+ productsUtils
+ .createProductInChannel(
+ productName,
+ productTypeId,
+ attributeId,
+ categoryId,
+ defaultChannel.id,
+ false,
+ false
+ )
+ .then(() => {
+ cy.visit(`${URL_LIST.products}${productsUtils.getCreatedProductId()}`)
+ .get(PRODUCTS_SELECTORS.assignedChannels)
+ .click()
+ .get(PRODUCTS_SELECTORS.publishedRadioButton)
+ .contains("Opublikowany")
+ .click()
+ .get(PRODUCTS_SELECTORS.saveBtn)
+ .click()
+ .waitForGraph("ProductChannelListingUpdate")
+ .get("@shopUrl")
+ .then(shopUrl => {
+ cy.visit(shopUrl);
+ searchSteps.searchFor(name);
+ cy.get(SEARCH_SELECTORS.productItem).contains(name);
+ });
+ });
+ });
+ });
+ it("shouldn't display not published product for unlogged user", () => {
+ const productName = `${startsWith}${faker.random.number()}`;
+ channelsUtils.getDefaultChannel().then(defaultChannel => {
+ productsUtils
+ .createProductInChannel(
+ productName,
+ productTypeId,
+ attributeId,
+ categoryId,
+ defaultChannel.id,
+ true,
+ false
+ )
+ .then(() => {
+ cy.visit(`${URL_LIST.products}${productsUtils.getCreatedProductId()}`)
+ .get(PRODUCTS_SELECTORS.assignedChannels)
+ .click()
+ .get(PRODUCTS_SELECTORS.publishedRadioButton)
+ .contains("Nie opublikowano")
+ .click()
+ .get(PRODUCTS_SELECTORS.saveBtn)
+ .click()
+ .waitForGraph("ProductChannelListingUpdate")
+ .get("@shopUrl")
+ .then(shopUrl => {
+ cy.visit(shopUrl);
+ searchSteps.searchFor(name);
+ cy.get(SEARCH_SELECTORS.productItem).should("not.exist");
+ });
+ });
+ });
+ });
+ xit("should display not published product for staff member", () => {
+ const productName = `${startsWith}${faker.random.number()}`;
+ channelsUtils.getDefaultChannel().then(defaultChannel => {
+ productsUtils
+ .createProductInChannel(
+ productName,
+ productTypeId,
+ attributeId,
+ categoryId,
+ defaultChannel.id,
+ true,
+ false
+ )
+ .then(() => {
+ cy.visit(`${URL_LIST.products}${productsUtils.getCreatedProductId()}`)
+ .get(PRODUCTS_SELECTORS.assignedChannels)
+ .click()
+ .get(PRODUCTS_SELECTORS.publishedRadioButton)
+ .contains("Nie opublikowano")
+ .click()
+ .get(PRODUCTS_SELECTORS.saveBtn)
+ .click()
+ .waitForGraph("ProductChannelListingUpdate")
+ .get("@shopUrl")
+ .then(shopUrl => {
+ cy.visit(shopUrl)
+ .loginInShop()
+ .then(() => {
+ searchSteps.searchFor(name);
+ cy.get(SEARCH_SELECTORS.productItem).contains(name);
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/cypress/steps/frontendSteps/searchSteps.js b/cypress/steps/frontendSteps/searchSteps.js
new file mode 100644
index 000000000..9c42e54fa
--- /dev/null
+++ b/cypress/steps/frontendSteps/searchSteps.js
@@ -0,0 +1,11 @@
+import { SEARCH_SELECTORS } from "../../elements/frontend-elements/search-selectors";
+
+class SearchSteps {
+ searchFor(query) {
+ cy.get(SEARCH_SELECTORS.searchButton)
+ .click()
+ .get(SEARCH_SELECTORS.searchInputField)
+ .type(query);
+ }
+}
+export default SearchSteps;
diff --git a/cypress/support/index.js b/cypress/support/index.js
index 531b8aab9..c09fd0ded 100644
--- a/cypress/support/index.js
+++ b/cypress/support/index.js
@@ -17,3 +17,38 @@ Cypress.Commands.add("clearSessionData", () => {
}
});
});
+
+Cypress.Commands.add("sendRequestWithQuery", query =>
+ cy.request({
+ method: "POST",
+ body: {
+ method: "POST",
+ url: Cypress.env("API_URI"),
+ query
+ },
+ headers: {
+ Authorization: `JWT ${window.sessionStorage.getItem("auth")}`
+ },
+ url: Cypress.env("API_URI")
+ })
+);
+
+Cypress.Commands.add("waitForGraph", operationName => {
+ const GRAPH_URL = "/graphql";
+ cy.intercept("POST", GRAPH_URL, req => {
+ req.statusCode = 200;
+ const requestBody = req.body;
+ if (Array.isArray(requestBody)) {
+ requestBody.forEach(element => {
+ if (element.operationName === operationName) {
+ req.alias = operationName;
+ }
+ });
+ } else {
+ if (requestBody.operationName === operationName) {
+ req.alias = operationName;
+ }
+ }
+ });
+ cy.wait(`@${operationName}`);
+});
diff --git a/cypress/support/user/index.js b/cypress/support/user/index.js
index 9edf99e27..1cdf56cf9 100644
--- a/cypress/support/user/index.js
+++ b/cypress/support/user/index.js
@@ -46,3 +46,23 @@ Cypress.Commands.add("loginUserViaRequest", () => {
window.sessionStorage.setItem("auth", resp.body.data.tokenCreate.token);
});
});
+
+Cypress.Commands.add("loginInShop", () => {
+ cy.request({
+ method: "POST",
+ url: Cypress.env("API_URI"),
+ body: [
+ {
+ operationName: "TokenAuth",
+ variables: {
+ email: Cypress.env("USER_NAME"),
+ password: Cypress.env("USER_PASSWORD")
+ },
+ query:
+ "mutation TokenAuth($email: String!, $password: String!) {\n tokenCreate(email: $email, password: $password) {\n token\n errors: accountErrors {\n code\n field\n message\n __typename\n }\n user {\n id\n __typename\n }\n __typename\n }\n}\n"
+ }
+ ]
+ }).then(resp => {
+ window.localStorage.setItem("token", resp.body[0].data.tokenCreate.token);
+ });
+});
diff --git a/cypress/url/url-list.js b/cypress/url/url-list.js
new file mode 100644
index 000000000..aa047845c
--- /dev/null
+++ b/cypress/url/url-list.js
@@ -0,0 +1,6 @@
+export const URL_LIST = {
+ dashbord: "/",
+ channels: "/channels/",
+ products: "/products/",
+ orders: "/orders/"
+};
diff --git a/cypress/utils/channelsUtils.js b/cypress/utils/channelsUtils.js
new file mode 100644
index 000000000..a536fb4f3
--- /dev/null
+++ b/cypress/utils/channelsUtils.js
@@ -0,0 +1,38 @@
+import Channels from "../apiRequests/Channels";
+
+class ChannelsUtils {
+ channels = new Channels();
+
+ deleteChannels(nameStartsWith) {
+ this.channels.getChannels().then(resp => {
+ const channelsArray = new Set(resp.body.data.channels);
+ if (channelsArray) {
+ channelsArray.forEach(element => {
+ if (element.name.startsWith(nameStartsWith)) {
+ const targetChannels = Array.from(channelsArray).filter(function(
+ channelElement
+ ) {
+ return (
+ element.currencyCode === channelElement.currencyCode &&
+ element.id !== channelElement.id
+ );
+ });
+ if (targetChannels[0]) {
+ this.channels.deleteChannel(element.id, targetChannels[0].id);
+ channelsArray.delete(element);
+ }
+ }
+ });
+ }
+ });
+ }
+ getDefaultChannel() {
+ return this.channels.getChannels().then(resp => {
+ const channelsArray = resp.body.data.channels;
+ return channelsArray.find(function(channelElement) {
+ return channelElement.slug === "default-channel";
+ });
+ });
+ }
+}
+export default ChannelsUtils;
diff --git a/cypress/utils/productsUtils.js b/cypress/utils/productsUtils.js
new file mode 100644
index 000000000..eda29a95b
--- /dev/null
+++ b/cypress/utils/productsUtils.js
@@ -0,0 +1,153 @@
+import Attribute from "../apiRequests/Attribute";
+import Category from "../apiRequests/Category";
+import Product from "../apiRequests/Product";
+
+class ProductsUtils {
+ createdVariantId;
+ createdProductId;
+ productTypeId;
+ attributeId;
+ categoryId;
+
+ updateChannelInProduct(productsList, channelId) {
+ const product = new Product();
+ productsList.forEach(productElement => {
+ product.updateChannelInProduct(productElement.node.id, channelId);
+ const variants = productElement.node.variants;
+ variants.forEach(variant => {
+ product.updateChannelPriceInVariant(variant.id, channelId);
+ });
+ });
+ }
+ createProduct(name, attributeId, productTypeId, categoryId) {
+ const product = new Product();
+ return product
+ .createProduct(attributeId, name, productTypeId, categoryId)
+ .then(createProductResp => {
+ this.createdProductId =
+ createProductResp.body.data.productCreate.product.id;
+ return product
+ .createVariant(this.createdProductId, name)
+ .then(createVariantResp => {
+ this.createdVariantId =
+ createVariantResp.body.data.productVariantBulkCreate.productVariants;
+ });
+ });
+ }
+ createProductInChannel(
+ name,
+ productTypeId,
+ attributeId,
+ categoryId,
+ channelId,
+ isPublished,
+ isAvailableForPurchase,
+ warehouseId,
+ quantityInWarehouse,
+ price
+ ) {
+ const product = new Product();
+ return product
+ .createProduct(attributeId, name, productTypeId, categoryId)
+ .then(createProductResp => {
+ this.createdProductId =
+ createProductResp.body.data.productCreate.product.id;
+ return product
+ .updateChannelInProduct(
+ this.createdProductId,
+ channelId,
+ isPublished,
+ isAvailableForPurchase
+ )
+ .then(() =>
+ product
+ .createVariant(
+ this.createdProductId,
+ name,
+ warehouseId,
+ quantityInWarehouse,
+ channelId,
+ price
+ )
+ .then(createVariantResp => {
+ this.createdVariantId =
+ createVariantResp.body.data.productVariantBulkCreate.productVariants;
+ })
+ );
+ });
+ }
+
+ createTypeAttributeAndCategoryForProduct(name) {
+ const attribute = new Attribute();
+ const category = new Category();
+ const product = new Product();
+ return attribute.createAttribute(name).then(createAttributeResp => {
+ this.attributeId =
+ createAttributeResp.body.data.attributeCreate.attribute.id;
+ return product
+ .createTypeProduct(name, this.attributeId)
+ .then(createTypeProductResp => {
+ this.productTypeId =
+ createTypeProductResp.body.data.productTypeCreate.productType.id;
+ return category.createCategory(name).then(categoryResp => {
+ this.categoryId = categoryResp.body.data.categoryCreate.category.id;
+ });
+ });
+ });
+ }
+
+ getCreatedVariants() {
+ return this.createdVariantId;
+ }
+ getProductTypeId() {
+ return this.productTypeId;
+ }
+ getAttributeId() {
+ return this.attributeId;
+ }
+ getCategoryId() {
+ return this.categoryId;
+ }
+ getCreatedProductId() {
+ return this.createdProductId;
+ }
+
+ deleteProducts(startsWith) {
+ const product = new Product();
+ const attribute = new Attribute();
+ const category = new Category();
+ product.getProductTypes(100, startsWith).then(resp => {
+ const productTypes = resp.body.data.productTypes.edges;
+ productTypes.forEach(productType => {
+ if (productType.node.name.includes(startsWith)) {
+ product.deleteProductType(productType.node.id);
+ }
+ });
+ });
+ attribute.getAttributes(100, startsWith).then(resp => {
+ const attributes = resp.body.data.attributes.edges;
+ attributes.forEach(attributeElement => {
+ if (attributeElement.node.name.includes(startsWith)) {
+ attribute.deleteAttribute(attributeElement.node.id);
+ }
+ });
+ });
+ category.getCategories(100, startsWith).then(resp => {
+ const categories = resp.body.data.categories.edges;
+ categories.forEach(categoryElement => {
+ if (categoryElement.node.name.includes(startsWith)) {
+ category.deleteCategory(categoryElement.node.id);
+ }
+ });
+ });
+ product.getFirstProducts(100, startsWith).then(getProductResp => {
+ const products = getProductResp.body.data.products.edges;
+ products.forEach(productElement => {
+ if (productElement.node.name.includes(startsWith)) {
+ product.deleteProducts(productElement.node.id);
+ }
+ });
+ });
+ }
+}
+export default ProductsUtils;