* add tags

* edit e2e.yaml

* fix test for customer registration

* add empty lines
This commit is contained in:
Karolina Rakoczy 2021-07-23 12:46:44 +03:00 committed by GitHub
parent b024a0fde6
commit 1f01a09e87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
96 changed files with 5612 additions and 5425 deletions

View file

@ -63,7 +63,7 @@ jobs:
start: npx local-web-server --spa index.html
wait-on: http://localhost:9000/
wait-on-timeout: 120
spec: cypress/integration/allEnv/**/*.js
command: npm run cy:run:allEnv
- uses: actions/upload-artifact@v1
if: ${{ failure() }}
with:

View file

@ -5,8 +5,7 @@ export const SHARED_ELEMENTS = {
skeleton: '[data-test-id="skeleton"]',
table: 'table[class*="Table"]',
tableRow: '[data-test="id"]',
confirmationMsg: "[data-test='notification-success']",
notificationSuccess: '[data-test="notification-success"]',
notificationSuccess: '[data-test="notification"][data-test-type="success"]',
dialog: '[role="dialog"]',
searchInput: '[data-test-id="searchInput"]',
selectOption: '[data-test="selectFieldOption"]',

View file

@ -0,0 +1,182 @@
import faker from "faker";
import {
addShippingMethod,
completeCheckout,
createCheckout
} from "../apiRequests/Checkout";
import { getOrder } from "../apiRequests/Order";
import filterTests from "../support/filterTests";
import { getDefaultChannel } from "../utils/channelsUtils";
import { addAdyenPayment } from "../utils/ordersUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../utils/shippingUtils";
filterTests(["stagedOnly"], () => {
describe("Adyen payments", () => {
const startsWith = "CyChannelInDraftOrders-";
const name = startsWith + faker.datatype.number();
const email = `CyChannelInDraftOrders@example.com`;
let address;
let defaultChannel;
let warehouse;
let shippingMethod;
let variantsList;
let checkout;
let paymentCards;
let cardData;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
cy.fixture("cards").then(cardsResp => {
paymentCards = cardsResp;
cardData = {
clientData: paymentCards.clientData,
encryptedExpiryMonth: paymentCards.encryptedExpiryMonth,
encryptedExpiryYear: paymentCards.encryptedExpiryYear,
encryptedSecurityCode: paymentCards.encryptedSecurityCodes.matches
};
});
cy.fixture("addresses")
.then(addresses => {
address = addresses.usAddress;
getDefaultChannel();
})
.then(channelResp => {
defaultChannel = channelResp;
createShipping({
channelId: channelResp.id,
name,
address,
price: 10
});
})
.then(
({
warehouse: warehouseResp,
shippingZone: shippingZoneResp,
shippingMethod: shippingMethodResp
}) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
}
);
createTypeAttributeAndCategoryForProduct(name)
.then(({ productType, attribute, category }) => {
createProductInChannel({
name,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(({ variantsList: variants }) => (variantsList = variants));
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
createCheckout({
channelSlug: defaultChannel.slug,
email,
variantsList,
address,
billingAddress: address,
auth: "token"
})
.then(({ checkout: checkoutResp }) => {
checkout = checkoutResp;
addShippingMethod(checkout.id, shippingMethod.id);
})
.then(({ checkout: checkoutResp }) => {
addAdyenPayment(checkout.id, checkoutResp.totalPrice.gross.amount);
});
});
it("should purchase products with simple card", () => {
const simpleCard = cardData;
simpleCard.encryptedCardNumber =
paymentCards.cards.simpleCard.encryptedCardNumber;
simpleCard.brand = paymentCards.cards.simpleCard.brand;
completeCheckout(checkout.id, simpleCard)
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
expect(order.paymentStatus).to.eq("FULLY_CHARGED");
});
});
it("should purchase product with 3D secure 2 Auth", () => {
const threeDSecureCard = cardData;
threeDSecureCard.encryptedCardNumber =
paymentCards.cards.threeDSecureTwoAuth.encryptedCardNumber;
threeDSecureCard.brand = paymentCards.cards.threeDSecureTwoAuth.brand;
completeCheckout(checkout.id, threeDSecureCard)
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
expect(order.paymentStatus).to.eq("FULLY_CHARGED");
});
});
it("should purchase product with 3D secure 1 Auth", () => {
const threeDSecureCardOneAuth = cardData;
threeDSecureCardOneAuth.encryptedCardNumber =
paymentCards.cards.threeDSecureOneAuth.encryptedCardNumber;
threeDSecureCardOneAuth.brand =
paymentCards.cards.threeDSecureOneAuth.brand;
completeCheckout(checkout.id, threeDSecureCardOneAuth)
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
expect(order.paymentStatus).to.eq("FULLY_CHARGED");
});
});
it("should fail with unknown security number", () => {
const simpleCard = cardData;
simpleCard.encryptedCardNumber =
paymentCards.cards.simpleCard.encryptedCardNumber;
simpleCard.brand = paymentCards.cards.simpleCard.brand;
simpleCard.encryptedSecurityCode =
paymentCards.encryptedSecurityCodes.unknown;
completeCheckout(checkout.id, simpleCard).then(({ checkoutErrors }) => {
expect(checkoutErrors).to.have.length(1);
});
});
it("should fail with timeout in 3D authorization", () => {
const errorCard = cardData;
errorCard.encryptedCardNumber =
paymentCards.cards.errorCard.encryptedCardNumber;
errorCard.brand = paymentCards.cards.errorCard.brand;
completeCheckout(checkout.id, errorCard).then(({ checkoutErrors }) => {
expect(checkoutErrors).to.have.length(1);
});
});
it("should fail with closed account", () => {
const closeAccount = cardData;
closeAccount.encryptedCardNumber =
paymentCards.cards.closeAccount.encryptedCardNumber;
closeAccount.brand = paymentCards.cards.closeAccount.brand;
completeCheckout(checkout.id, closeAccount).then(({ checkoutErrors }) => {
expect(checkoutErrors).to.have.length(1);
});
});
});
});

View file

@ -1,104 +0,0 @@
import faker from "faker";
import { createApp, getApp } from "../../apiRequests/Apps";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import { APP_DETAILS } from "../../elements/apps/appDetails";
import { APPS_LIST } from "../../elements/apps/appsList";
import { WEBHOOK_DETAILS } from "../../elements/apps/webhookDetails";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import { appDetailsUrl, urlList } from "../../url/urlList";
import { deleteAppsStartsWith } from "../../utils/appUtils";
describe("Tests for apps", () => {
const startsWith = "Apps";
const name = `${startsWith}${faker.datatype.number()}`;
let createdApp;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAppsStartsWith(startsWith);
createApp(name, "MANAGE_APPS").then(app => {
createdApp = app;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest("auth", ONE_PERMISSION_USERS.app);
});
it("should create app", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.apps)
.get(APPS_LIST.createLocalAppButton)
.click()
.get(APP_DETAILS.nameInput)
.type(randomName)
.get(APP_DETAILS.manageAppsPermissionCheckbox)
.click()
.addAliasToGraphRequest("AppCreate")
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.wait("@AppCreate")
.its("response.body.data.appCreate.app")
.then(app => {
getApp(app.id);
})
.then(app => {
expect(app.name).to.eq(randomName);
const token = app.tokens.find(element => element.name === "Default");
expect(token).to.be.ok;
});
});
it("should create webhook", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
const targetUrl = `http://example.${randomName}`;
cy.visit(appDetailsUrl(createdApp.id))
.get(APP_DETAILS.createWebhookButton)
.click()
.get(WEBHOOK_DETAILS.nameInput)
.type(randomName)
.get(WEBHOOK_DETAILS.targetUrlInput)
.type(targetUrl)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getApp(createdApp.id).then(({ webhooks }) => {
expect(webhooks[0].name).to.eq(randomName);
expect(webhooks[0].targetUrl).to.eq(targetUrl);
});
});
it("should create token", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
let expectedToken;
cy.visit(appDetailsUrl(createdApp.id))
.get(APP_DETAILS.createTokenButton)
.click()
.get(APP_DETAILS.createTokenForm.tokenDialog)
.find(APP_DETAILS.createTokenForm.nameInput)
.type(randomName)
.get(BUTTON_SELECTORS.submit)
.click()
.get(APP_DETAILS.createTokenForm.tokenToCopy)
.invoke("text")
.then(text => {
expectedToken = text;
cy.get(APP_DETAILS.createTokenForm.doneButton).click();
getApp(createdApp.id);
})
.then(app => {
const token = app.tokens.find(element => element.name === randomName);
const tokenLastFourDigits = expectedToken.slice(
expectedToken.length - 4
);
expect(token.authToken).to.eq(tokenLastFourDigits);
});
});
});

View file

@ -1,136 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { getCategory } from "../../apiRequests/Category";
import { CATEGORIES_LIST } from "../../elements/catalog/categories/categories-list";
import { CATEGORY_DETAILS } from "../../elements/catalog/categories/category-details";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { createCategory } from "../../steps/categoriesSteps";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessages";
import { categoryDetails, urlList } from "../../url/urlList";
import { deleteCategoriesStartsWith } from "../../utils/categoryUtils";
import * as channelsUtils from "../../utils/channelsUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import { deleteShippingStartsWith } from "../../utils/shippingUtils";
describe("Categories", () => {
const startsWith = "CyCollections";
const name = `${startsWith}${faker.datatype.number()}`;
let attribute;
let category;
let productType;
let product;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
deleteCategoriesStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
channelsUtils.deleteChannelsStartsWith(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createTypeAttributeAndCategoryForProduct(name);
})
.then(
({
category: categoryResp,
attribute: attributeResp,
productType: productTypeResp
}) => {
category = categoryResp;
attribute = attributeResp;
productType = productTypeResp;
productsUtils.createProductInChannel({
name,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
}
)
.then(({ product: productResp }) => (product = productResp));
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create category", () => {
const categoryName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.categories)
.get(CATEGORIES_LIST.addCategoryButton)
.click();
createCategory({ name: categoryName, description: categoryName })
.its("response.body.data.categoryCreate.category")
.then(newCategory => {
getCategory(newCategory.id);
})
.then(newCategory => {
expect(newCategory.name).to.eq(categoryName);
// Uncomment this expect after fixing bug SALEOR-3728
// expect(newCategory.description).to.eq(categoryName);
});
});
it("should add subcategory", () => {
const categoryName = `${startsWith}${faker.datatype.number()}`;
cy.visit(categoryDetails(category.id))
.get(CATEGORY_DETAILS.createSubcategoryButton)
.click();
createCategory({ name: categoryName, description: categoryName })
.visit(categoryDetails(category.id))
.contains(CATEGORY_DETAILS.categoryChildrenRow, categoryName)
.should("be.visible");
getCategory(category.id).then(categoryResp => {
expect(categoryResp.children.edges[0].node.name).to.eq(categoryName);
});
});
it("should add product to category", () => {
cy.visit(categoryDetails(category.id))
.get(CATEGORY_DETAILS.productsTab)
.click()
.get(CATEGORY_DETAILS.addProducts)
.click()
.url()
.should("include", urlList.addProduct);
});
it("should remove product from category", () => {
cy.visit(categoryDetails(category.id))
.get(CATEGORY_DETAILS.productsTab)
.click();
cy.contains(CATEGORY_DETAILS.productRow, product.name)
.find(BUTTON_SELECTORS.checkbox)
.click()
.get(BUTTON_SELECTORS.deleteIcon)
.click()
.addAliasToGraphRequest("productBulkDelete")
.get(BUTTON_SELECTORS.submit)
.click();
confirmationMessageShouldDisappear();
cy.contains(CATEGORY_DETAILS.productRow, product.name)
.should("not.exist")
.wait("@productBulkDelete");
getCategory(category.id).then(categoryResp => {
expect(categoryResp.products).to.be.null;
});
});
it("should enter category details page", () => {
cy.visit(urlList.categories)
.get(SHARED_ELEMENTS.searchInput)
.type(category.name);
cy.contains(SHARED_ELEMENTS.tableRow, category.name).click();
cy.contains(SHARED_ELEMENTS.header, category.name).should("be.visible");
});
});

View file

@ -1,118 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../../apiRequests/Channels";
import {
addProductsToCheckout,
addShippingMethod,
createCheckout
} from "../../../apiRequests/Checkout";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Products without shipment option", () => {
const startsWith = "WithoutShipmentCheckout-";
const name = `${startsWith}${faker.datatype.number()}`;
const nameProdWithoutShipping = `${startsWith}${faker.datatype.number()}`;
let channel;
let address;
let warehouse;
let shippingMethod;
let productWithShipping;
let productWithoutShipping;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
createChannel({
name
})
.then(channelResp => {
channel = channelResp;
cy.fixture("addresses");
})
.then(({ usAddress }) => {
address = usAddress;
createShipping({
channelId: channel.id,
name,
address,
minProductPrice: 100
});
})
.then(
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
createTypeAttributeAndCategoryForProduct(name);
}
)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
createProductInChannel({
attributeId: attributeResp.id,
categoryId: categoryResp.id,
channelId: channel.id,
name,
productTypeId: productTypeResp.id,
warehouseId: warehouse.id
}).then(({ variantsList }) => (productWithShipping = variantsList));
createProductInChannel({
attributeId: attributeResp.id,
categoryId: categoryResp.id,
channelId: channel.id,
name: nameProdWithoutShipping,
productTypeId: productTypeResp.id,
warehouseId: warehouse.id
}).then(
({ variantsList }) => (productWithoutShipping = variantsList)
);
}
);
});
it("should be not possible to buy product without shipping option", () => {
createCheckout({
channelSlug: channel.slug,
email: "example@example.com",
variantsList: productWithoutShipping,
address,
auth: "token"
})
.then(({ checkout }) => {
expect(
checkout.availableShippingMethods,
"expect no available shipping"
).to.have.length(0);
addProductsToCheckout(checkout.id, productWithShipping, 1);
})
.then(({ checkout }) => {
expect(
checkout.availableShippingMethods,
"expect no available shipping"
).to.have.length(0);
addShippingMethod(checkout.id, shippingMethod.id);
})
.then(({ errors }) => {
expect(errors[0].field, "expect error in shipping method").to.be.eq(
"shippingMethod"
);
});
});
});

View file

@ -1,162 +0,0 @@
import faker from "faker";
import {
addProductsToCheckout,
createCheckout
} from "../../../apiRequests/Checkout";
import { getVariants } from "../../../apiRequests/Product";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import { createOrderWithNewProduct } from "../../../utils/ordersUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Products stocks in checkout", () => {
const startsWith = "CyStocksCheckout-";
const name = `${startsWith}${faker.datatype.number()}`;
let defaultChannel;
let address;
let warehouse;
let attribute;
let category;
let productType;
let shippingMethod;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
cy.fixture("addresses")
.then(addresses => {
address = addresses.usAddress;
getDefaultChannel();
})
.then(channel => {
defaultChannel = channel;
createShipping({
channelId: defaultChannel.id,
name,
address
});
})
.then(
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
createTypeAttributeAndCategoryForProduct(name);
}
)
.then(
({
attribute: attributeResp,
category: categoryResp,
productType: productTypeResp
}) => {
attribute = attributeResp;
category = categoryResp;
productType = productTypeResp;
}
);
});
it("should create checkout with last product in stock", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
createOrderWithNewProduct({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channel: defaultChannel,
name: productName,
warehouseId: warehouse.id,
shippingMethodId: shippingMethod.id,
address
}).then(({ order }) => {
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;
createProductInChannel({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channelId: defaultChannel.id,
name: productName,
warehouseId: warehouse.id,
quantityInWarehouse: 1
})
.then(({ variantsList }) => {
variants = variantsList;
createCheckout({
channelSlug: defaultChannel.slug,
address,
billingAddress: address,
email: "email@example.com",
variantsList,
auth: "token"
});
})
.then(({ checkout: checkout }) => {
addProductsToCheckout(checkout.id, variants, 2);
})
.then(({ errors }) => {
expect(
errors[0],
"should return error on field quantity"
).to.have.property("field", "quantity");
});
});
it("should buy product with no quantity if tracking is not set", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
createOrderWithNewProduct({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channel: defaultChannel,
name: productName,
warehouseId: warehouse.id,
quantityInWarehouse: 0,
trackInventory: false,
shippingMethodId: shippingMethod.id,
address
}).then(({ order }) => {
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);
});
});
});

View file

@ -1,68 +0,0 @@
import faker from "faker";
import { createCheckout } from "../../../apiRequests/Checkout";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Warehouses in checkout", () => {
const startsWith = `CyWarehouseCheckout`;
let defaultChannel;
let usAddress;
let plAddress;
let warehouse;
it("should not be possible to buy product for country not listed in warehouse", () => {
cy.clearSessionData().loginUserViaRequest();
deleteShippingStartsWith(startsWith);
deleteProductsStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
cy.fixture("addresses")
.then(addresses => {
usAddress = addresses.usAddress;
plAddress = addresses.plAddress;
getDefaultChannel();
})
.then(channelResp => {
defaultChannel = channelResp;
createShipping({
channelId: defaultChannel.id,
name,
address: usAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
createTypeAttributeAndCategoryForProduct(name);
})
.then(({ attribute, productType, category }) => {
createProductInChannel({
name,
attributeId: attribute.id,
categoryId: category.id,
channelId: defaultChannel.id,
productTypeId: productType.id,
warehouseId: warehouse.id,
quantityInWarehouse: 100
});
})
.then(({ variantsList }) => {
createCheckout({
channelSlug: defaultChannel.slug,
email: "example@example.com",
variantsList,
address: plAddress
});
})
.then(({ errors }) => {
expect(errors[0]).to.have.property("field", "quantity");
});
});
});

View file

@ -1,178 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import { updateChannelInProduct } from "../../apiRequests/Product";
import { getCollection } from "../../apiRequests/storeFront/Collections";
import { searchInShop } from "../../apiRequests/storeFront/Search";
import {
assignProductsToCollection,
createCollection
} from "../../steps/collectionsSteps";
import { urlList } from "../../url/urlList";
import * as channelsUtils from "../../utils/channelsUtils";
import { deleteCollectionsStartsWith } from "../../utils/collectionsUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import { deleteShippingStartsWith } from "../../utils/shippingUtils";
import {
isCollectionVisible,
isProductInCollectionVisible
} from "../../utils/storeFront/collectionsUtils";
import { isProductVisibleInSearchResult } from "../../utils/storeFront/storeFrontProductUtils";
describe("Collections", () => {
const startsWith = "CyCollections-";
const name = `${startsWith}${faker.datatype.number()}`;
let attribute;
let productType;
let category;
let product;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
deleteCollectionsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
channelsUtils.deleteChannelsStartsWith(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createTypeAttributeAndCategoryForProduct(name);
})
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
attribute = attributeResp;
productType = productTypeResp;
category = categoryResp;
productsUtils.createProductInChannel({
name,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
}
)
.then(({ product: productResp }) => (product = productResp));
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should not display hidden collections", () => {
const collectionName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
let collection;
createCollection(collectionName, false, defaultChannel)
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(name);
})
.then(() => {
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isCollectionVisible(resp, collection.id);
expect(isVisible).to.equal(false);
});
});
it("should display collections", () => {
const collectionName = `${startsWith}${faker.datatype.number()}`;
let collection;
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
createCollection(collectionName, true, defaultChannel)
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(name);
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isCollectionVisible(resp, collection.id);
expect(isVisible).to.equal(true);
});
});
it("should not display collection not set as available in channel", () => {
const collectionName = `${startsWith}${faker.datatype.number()}`;
let collection;
let channel;
createChannel({ name: collectionName })
.then(channelResp => {
channel = channelResp;
updateChannelInProduct(product.id, channel.id);
})
.then(() => {
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
createCollection(collectionName, true, channel);
})
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(name);
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isCollectionVisible(resp, collection.id);
expect(isVisible).to.equal(false);
});
});
it("should display products hidden in listing", () => {
// Products "hidden in listings" are not displayed in Category listings or search results,
// but are listed on Collections
const randomName = `${startsWith}${faker.datatype.number()}`;
let collection;
let createdProduct;
productsUtils
.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: false
})
.then(({ product: productResp }) => (createdProduct = productResp));
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
createCollection(randomName, true, defaultChannel)
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(randomName);
})
.then(() => {
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductInCollectionVisible(resp, createdProduct.id);
expect(isVisible).to.equal(true);
})
.then(() => {
searchInShop(createdProduct.name);
})
.then(resp => {
const isVisible = isProductVisibleInSearchResult(
resp,
createdProduct.name
);
expect(isVisible).to.equal(false);
});
});
});

View file

@ -1,120 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { getAttribute } from "../../../../apiRequests/Attribute";
import { ATTRIBUTES_LIST } from "../../../../elements/attribute/attributes_list";
import { createAttributeWithInputType } from "../../../../steps/attributesSteps";
import { urlList } from "../../../../url/urlList";
import { deleteAttributesStartsWith } from "../../../../utils/attributes/attributeUtils";
import { expectCorrectDataInAttribute } from "../../../../utils/attributes/checkAttributeData";
describe("Create attribute with type", () => {
const startsWith = "AttrCreate";
const attributesTypes = [
"DROPDOWN",
"MULTISELECT",
"FILE",
"RICH_TEXT",
"BOOLEAN"
];
const attributeReferenceType = ["PRODUCT", "PAGE"];
const attributeNumericType = [
{ unitSystem: "IMPERIAL", unitsOf: "DISTANCE", unit: "FT" },
{ unitSystem: "METRIC", unitsOf: "VOLUME", unit: "CUBIC_CENTIMETER" },
{ unitSystem: "without selecting unit" }
];
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAttributesStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.attributes)
.get(ATTRIBUTES_LIST.createAttributeButton)
.click();
});
attributesTypes.forEach(attributeType => {
it(`should create ${attributeType} attribute`, () => {
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({ name: attributeName, attributeType })
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType
});
});
});
});
attributeReferenceType.forEach(entityType => {
it(`should create reference ${entityType} attribute`, () => {
const attributeType = "REFERENCE";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
entityType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
entityType
});
});
});
});
attributeNumericType.forEach(numericSystemType => {
it(`should create numeric attribute - ${numericSystemType.unitSystem}`, () => {
const attributeType = "NUMERIC";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
numericSystemType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
unit: numericSystemType.unit
});
});
});
});
it("should create attribute without required value", () => {
const attributeType = "BOOLEAN";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
valueRequired: false
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
valueRequired: false
});
});
});
});

View file

@ -1,120 +0,0 @@
import faker from "faker";
import { getAttribute } from "../../../../apiRequests/Attribute";
import { ATTRIBUTES_DETAILS } from "../../../../elements/attribute/attributes_details";
import { ATTRIBUTES_LIST } from "../../../../elements/attribute/attributes_list";
import { createAttributeWithInputType } from "../../../../steps/attributesSteps";
import { urlList } from "../../../../url/urlList";
import { deleteAttributesStartsWith } from "../../../../utils/attributes/attributeUtils";
import { expectCorrectDataInAttribute } from "../../../../utils/attributes/checkAttributeData";
describe("Create content attribute", () => {
const startsWith = "AttrCont";
const attributesTypes = [
"DROPDOWN",
"MULTISELECT",
"FILE",
"RICH_TEXT",
"BOOLEAN"
];
const attributeReferenceType = ["PRODUCT", "PAGE"];
const attributeNumericType = [
{ unitSystem: "IMPERIAL", unitsOf: "DISTANCE", unit: "FT" },
{ unitSystem: "METRIC", unitsOf: "VOLUME", unit: "CUBIC_CENTIMETER" },
{ unitSystem: "without selecting unit" }
];
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAttributesStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.attributes)
.get(ATTRIBUTES_LIST.createAttributeButton)
.click()
.get(ATTRIBUTES_DETAILS.pageTypeAttributeCheckbox)
.click();
});
attributesTypes.forEach(attributeType => {
it(`should create ${attributeType} attribute`, () => {
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({ name: attributeName, attributeType })
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType
});
});
});
});
attributeReferenceType.forEach(entityType => {
it(`should create reference ${entityType} attribute`, () => {
const attributeType = "REFERENCE";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
entityType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
entityType
});
});
});
});
attributeNumericType.forEach(numericSystemType => {
it(`should create numeric attribute - ${numericSystemType.unitSystem}`, () => {
const attributeType = "NUMERIC";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
numericSystemType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
unit: numericSystemType.unit
});
});
});
});
it("should create attribute without required value", () => {
const attributeType = "BOOLEAN";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
valueRequired: false
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
valueRequired: false
});
});
});
});

View file

@ -1,160 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../../apiRequests/Channels";
import {
createShippingZone,
getShippingZone
} from "../../../apiRequests/ShippingMethod";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list";
import { ADD_CHANNEL_FORM_SELECTORS } from "../../../elements/channels/add-channel-form-selectors";
import { AVAILABLE_CHANNELS_FORM } from "../../../elements/channels/available-channels-form";
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 { createChannelByView } from "../../../steps/channelsSteps";
import { waitForProgressBarToNotExist } from "../../../steps/shared/progressBar";
import { urlList } from "../../../url/urlList";
import { deleteChannelsStartsWith } from "../../../utils/channelsUtils";
import { deleteShippingStartsWith } from "../../../utils/shippingUtils";
describe("Channels", () => {
const channelStartsWith = `CyChannels`;
const randomName = `${channelStartsWith} ${faker.datatype.number()}`;
const currency = "PLN";
let shippingZone;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteChannelsStartsWith(channelStartsWith);
deleteShippingStartsWith(channelStartsWith);
createShippingZone(randomName, "US").then(shippingZoneResp => {
shippingZone = shippingZoneResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.channel
);
});
it("should create new channel", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
cy.wait("@Channels");
createChannelByView({ name: randomChannel, currency });
cy.wait("@Channel");
// New channel should be visible in channels list
cy.get(ADD_CHANNEL_FORM_SELECTORS.backToChannelsList)
.click()
.get(CHANNELS_SELECTORS.channelsTable)
.contains(randomChannel);
// new channel should be visible in channel selector
cy.visit(urlList.homePage)
.get(HEADER_SELECTORS.channelSelect)
.click()
.get(HEADER_SELECTORS.channelSelectList)
.contains(randomChannel)
.click();
// new channel should be visible at product availability form
cy.clearSessionData().loginUserViaRequest();
cy.addAliasToGraphRequest("InitialProductFilterAttributes");
cy.visit(urlList.products);
cy.wait("@InitialProductFilterAttributes");
waitForProgressBarToNotExist();
cy.get(PRODUCTS_LIST.emptyProductRow).should("not.exist");
cy.get(PRODUCTS_LIST.productsList)
.first()
.click()
.get(AVAILABLE_CHANNELS_FORM.menageChannelsButton)
.click()
.get(SELECT_CHANNELS_TO_ASSIGN.listOfChannels)
.contains(randomChannel);
});
it("should create channel with shippingZone", () => {
// remove login after fixing SALEOR-3162
cy.clearSessionData().loginUserViaRequest();
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
cy.wait("@Channels");
createChannelByView({
name: randomChannel,
currency,
shippingZone: shippingZone.name
});
cy.wait("@Channel");
getShippingZone(shippingZone.id).then(shippingZoneResp => {
const assignedChannel = shippingZoneResp.channels.find(
channel => channel.name === randomChannel
);
expect(assignedChannel).to.be.ok;
});
});
it("should validate slug name", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
createChannel({
isActive: false,
name: randomChannel,
slug: randomChannel,
currencyCode: currency
});
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
createChannelByView({ name: randomChannel, currency });
cy.get(ADD_CHANNEL_FORM_SELECTORS.slugValidationMessage).should(
"be.visible"
);
});
it("should validate duplicated currency", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
createChannelByView({
name: randomChannel,
currency: "notExistingCurrency"
});
cy.get(ADD_CHANNEL_FORM_SELECTORS.currencyValidationMessage).should(
"be.visible"
);
});
it("should delete channel", () => {
const randomChannelToDelete = `${channelStartsWith} ${faker.datatype.number()}`;
createChannel({
isActive: false,
name: randomChannelToDelete,
slug: randomChannelToDelete,
currencyCode: currency
});
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
cy.wait("@Channels");
cy.contains(CHANNELS_SELECTORS.channelName, randomChannelToDelete)
.parentsUntil(CHANNELS_SELECTORS.channelsTable)
.find("button")
.click();
cy.addAliasToGraphRequest("Channels");
cy.get(BUTTON_SELECTORS.submit).click();
cy.wait("@Channels");
cy.get(CHANNELS_SELECTORS.channelName)
.contains(randomChannelToDelete)
.should("not.exist");
});
});

View file

@ -1,63 +0,0 @@
import faker from "faker";
import { getCustomer } from "../../../apiRequests/Customer";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { CUSTOMER_DETAILS } from "../../../elements/customer/customer-details";
import { CUSTOMERS_LIST } from "../../../elements/customer/customers-list";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { fillUpAddressForm } from "../../../steps/shared/addressForm";
import { confirmationMessageShouldDisappear } from "../../../steps/shared/confirmationMessage";
import { urlList } from "../../../url/urlList";
describe("Tests for customer", () => {
const channelStartsWith = `Customers`;
it("should create customer", () => {
const randomName = `${channelStartsWith}${faker.datatype.number()}`;
const email = `${randomName}@example.com`;
const note = faker.lorem.paragraph();
let address;
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.user)
.visit(urlList.customers)
.get(CUSTOMERS_LIST.createCustomerButton)
.click()
.get(SHARED_ELEMENTS.progressBar)
.should("not.be.visible")
.get(CUSTOMER_DETAILS.nameInput)
.type(randomName)
.get(CUSTOMER_DETAILS.lastNameInput)
.type(randomName)
.get(CUSTOMER_DETAILS.emailInput)
.type(email)
.fixture("addresses")
.then(({ usAddress }) => {
address = usAddress;
fillUpAddressForm(address);
})
.get(CUSTOMER_DETAILS.noteInput)
.type(note)
.addAliasToGraphRequest("CreateCustomer")
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.wait("@CreateCustomer")
.its("response.body.data.customerCreate.user")
.then(customer => {
getCustomer(customer.id);
})
.then(customer => {
chai
.softExpect(customer.firstName, "Expect correct first name")
.to.eq(randomName);
chai
.softExpect(customer.lastName, "Expect correct last name")
.to.eq(randomName);
chai.softExpect(customer.email, "Expect correct email").to.eq(email);
chai.softExpect(customer.note, "Expect correct note").to.eq(note);
cy.expectCorrectFullAddress(customer.addresses[0], address);
});
});
});

View file

@ -1,148 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { activateChannel, createChannel } from "../../../apiRequests/Channels";
import { createCheckout } from "../../../apiRequests/Checkout";
import { getProductDetails } from "../../../apiRequests/storeFront/ProductDetails";
import { CHANNEL_FORM_SELECTORS } from "../../../elements/channels/channel-form-selectors";
import { DRAFT_ORDER_SELECTORS } from "../../../elements/orders/draft-order-selectors";
import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors";
import { urlList } from "../../../url/urlList";
import {
deleteChannelsStartsWith,
getDefaultChannel
} from "../../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
import { isProductVisible } from "../../../utils/storeFront/storeFrontProductUtils";
describe("Tests on inactive channel", () => {
const channelStartsWith = `InactiveChannel`;
const randomName = `${channelStartsWith}${faker.datatype.number()}`;
const currency = "PLN";
let address;
let defaultChannel;
let newChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteChannelsStartsWith(channelStartsWith);
deleteProductsStartsWith(channelStartsWith);
cy.fixture("addresses").then(({ plAddress }) => {
address = plAddress;
});
getDefaultChannel().then(channel => (defaultChannel = channel));
createChannel({
isActive: false,
name: randomName,
slug: randomName,
currencyCode: currency
}).then(channel => {
newChannel = channel;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should not be possible to add products to order with inactive channel", () => {
cy.visit(urlList.orders)
.get(ORDERS_SELECTORS.createOrder)
.click()
.get(CHANNEL_FORM_SELECTORS.channelSelect)
.click()
.get(CHANNEL_FORM_SELECTORS.channelOption)
.contains(newChannel.name)
.click()
.get(CHANNEL_FORM_SELECTORS.confirmButton)
.click();
cy.location()
.should(loc => {
const urlRegex = new RegExp(`${urlList.orders}.+`, "g");
expect(loc.pathname).to.match(urlRegex);
})
.get(DRAFT_ORDER_SELECTORS.addProducts)
.should("not.exist");
});
it("should not be possible to create checkout with inactive channel", () => {
const randomChannel = `${channelStartsWith}${faker.datatype.number()}`;
createTypeAttributeAndCategoryForProduct(randomChannel)
.then(({ productType, attribute, category }) => {
createProductInChannel({
name: randomChannel,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(({ variantsList }) => {
createCheckout({
channelSlug: newChannel.slug,
email: "example@example.com",
variantsList,
address
});
})
.then(({ errors }) => {
expect(
errors[0],
"checkout shouldn't be created with error in field channel"
).to.have.property("field", "channel");
});
});
it("products in inactive channel should not be displayed", () => {
const randomChannel = `${channelStartsWith}${faker.datatype.number()}`;
let channel;
let product;
createChannel({
isActive: false,
name: randomChannel,
slug: randomChannel,
currencyCode: currency
})
.then(channelResp => {
channel = channelResp;
createTypeAttributeAndCategoryForProduct(randomChannel);
})
.then(({ productType, attribute, category }) => {
createProductInChannel({
name: randomChannel,
channelId: channel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(({ product: productResp }) => {
product = productResp;
getProductDetails(product.id, channel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, randomChannel);
expect(
isVisible,
"product with inactive channel shouldn't be visible"
).to.be.eq(false);
activateChannel(channel.id);
})
.then(() => {
getProductDetails(product.id, channel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, randomChannel);
expect(
isVisible,
"product with active channel should be visible"
).to.be.eq(true);
});
});
});

View file

@ -1,66 +0,0 @@
import faker from "faker";
import {
createMenu as createMenuViaApi,
getMenu
} from "../../../apiRequests/Menu";
import {
createMenu,
createNewMenuItem,
MENU_ITEM_TYPES
} from "../../../steps/navigationSteps";
import { deleteMenusStartsWith } from "../../../utils/navigationUtils";
describe("Tests for menu navigation", () => {
const startsWith = "Navigation";
const randomName = `${startsWith}${faker.datatype.number()}`;
let menu;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteMenusStartsWith(startsWith);
createMenuViaApi(randomName).then(
({ menu: menuResp }) => (menu = menuResp)
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create a menu", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createMenu(name)
.then(menuResp => {
getMenu(menuResp.id);
})
.then(menuResp => {
expect(menuResp.name).to.eq(name);
});
});
["category", "collection", "page"].forEach(itemType => {
it(`should add new ${itemType} item to menu`, () => {
const itemName = `${startsWith}${faker.datatype.number()}`;
let selectedItem;
createNewMenuItem({
menuId: menu.id,
name: itemName,
menuItemType: MENU_ITEM_TYPES[itemType]
})
.then(selectedItemResp => {
selectedItem = selectedItemResp;
getMenu(menu.id);
})
.then(({ items }) => {
const item = items.find(element => element.name === itemName);
const itemOfType = item[itemType];
const name = itemType !== "page" ? "name" : "title";
expect(itemOfType[name]).to.eq(selectedItem);
});
});
});
});

View file

@ -1,148 +0,0 @@
import faker from "faker";
import {
createPermissionGroup,
getPermissionGroup
} from "../../../apiRequests/PermissionGroup.js";
import { getStaffMembersStartsWith } from "../../../apiRequests/StaffMembers";
import { TEST_ADMIN_USER } from "../../../Data/users.js";
import { PERMISSION_GROUP_DETAILS } from "../../../elements/permissionGroup/permissionGroupDetails";
import { PERMISSION_GROUP_LIST } from "../../../elements/permissionGroup/permissionGroupsList";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { waitForProgressBarToNotExist } from "../../../steps/shared/progressBar.js";
import {
permissionGroupDetails,
staffMemberDetailsUrl,
urlList
} from "../../../url/urlList";
import { deletePermissionGroupsStartsWith } from "../../../utils/permissionGroupUtils.js";
describe("Permissions groups", () => {
const startsWith = "CyPermissions-";
before(() => {
cy.clearSessionData().loginUserViaRequest();
deletePermissionGroupsStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.permissionsGroups)
.get(PERMISSION_GROUP_LIST.createPermissionButton)
.click()
.get(PERMISSION_GROUP_DETAILS.nameInput)
.type(permissionName)
.get(PERMISSION_GROUP_DETAILS.productsPermissionCheckbox)
.click()
.get(
PERMISSION_GROUP_DETAILS.productsTypesAndAttributesPermissionCheckbox
)
.click()
.get(BUTTON_SELECTORS.confirm)
.click()
.get(PERMISSION_GROUP_DETAILS.assignMemberButton)
.should("be.visible")
.get(BUTTON_SELECTORS.back)
.click();
waitForProgressBarToNotExist();
cy.contains(
PERMISSION_GROUP_LIST.permissionGroupRow,
permissionName
).should("be.visible");
});
it("should delete permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
let staffMember;
getStaffMembersStartsWith(TEST_ADMIN_USER.email)
.its("body.data.staffUsers.edges")
.then(staffMemberResp => {
staffMember = staffMemberResp[0].node;
createPermissionGroup({
name: permissionName,
userIdsArray: `["${staffMember.id}"]`,
permissionsArray: "[MANAGE_PRODUCTS]"
});
cy.visit(urlList.permissionsGroups);
cy.contains(PERMISSION_GROUP_LIST.permissionGroupRow, permissionName)
.should("be.visible")
.find(BUTTON_SELECTORS.deleteIcon)
.click()
.get(BUTTON_SELECTORS.submit)
.click();
cy.contains(PERMISSION_GROUP_LIST.permissionGroupRow, permissionName)
.should("not.exist")
.visit(staffMemberDetailsUrl(staffMember.id));
cy.get(SHARED_ELEMENTS.header).should("be.visible");
cy.contains(permissionName).should("not.exist");
});
});
it("should add user to permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
createPermissionGroup({
name: permissionName,
permissionsArray: "[MANAGE_PRODUCTS]"
})
.then(({ group }) => {
cy.visit(permissionGroupDetails(group.id))
.get(PERMISSION_GROUP_DETAILS.assignMemberButton)
.click()
.get(PERMISSION_GROUP_DETAILS.searchField)
.type(TEST_ADMIN_USER.email);
cy.contains(
PERMISSION_GROUP_DETAILS.userRow,
`${TEST_ADMIN_USER.name} ${TEST_ADMIN_USER.lastName}`
)
.should("have.length", 1)
.find(BUTTON_SELECTORS.checkbox)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.addAliasToGraphRequest("PermissionGroupUpdate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@PermissionGroupUpdate");
getPermissionGroup(group.id);
})
.then(resp => {
expect(resp.users).to.have.length(1);
expect(resp.users[0].email).to.be.eq(TEST_ADMIN_USER.email);
});
});
it("should remove user from permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
let staffMember;
getStaffMembersStartsWith(TEST_ADMIN_USER.email)
.its("body.data.staffUsers.edges")
.then(staffMemberResp => {
staffMember = staffMemberResp[0].node;
createPermissionGroup({
name: permissionName,
userIdsArray: `["${staffMember.id}"]`,
permissionsArray: "[MANAGE_PRODUCTS]"
});
})
.then(({ group }) => {
cy.visit(permissionGroupDetails(group.id))
.get(PERMISSION_GROUP_DETAILS.removeUserButton)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.addAliasToGraphRequest("PermissionGroupUpdate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@PermissionGroupUpdate");
cy.visit(staffMemberDetailsUrl(staffMember.id));
cy.get(SHARED_ELEMENTS.header).should("be.visible");
cy.contains(permissionName).should("not.exist");
});
});
});

View file

@ -1,103 +0,0 @@
import faker from "faker";
import { createAttribute } from "../../../apiRequests/Attribute";
import {
createTypeProduct,
getProductType
} from "../../../apiRequests/productType";
import { PRODUCT_TYPE_DETAILS } from "../../../elements/productTypes/productTypeDetails";
import { createProductType } from "../../../steps/productTypeSteps";
import { assignElements } from "../../../steps/shared/assignElements";
import { confirmationMessageShouldDisappear } from "../../../steps/shared/confirmationMessage";
import { visitAndWaitForProgressBarToDisappear } from "../../../steps/shared/progressBar";
import { productTypeDetailsUrl, urlList } from "../../../url/urlList";
import { deleteProductsStartsWith } from "../../../utils/products/productsUtils";
describe("Tests for product types", () => {
const startsWith = "ProductType";
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
createAttribute({ name: startsWith });
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.productTypes)
.softExpectSkeletonIsVisible();
});
it("Create product type without shipping required", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createProductType(name, false)
.then(productType => {
getProductType(productType.id);
})
.then(productType => {
expect(productType.name).to.be.eq(name);
expect(productType.isShippingRequired).to.be.false;
});
});
it("Create product type with shipping required", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const shippingWeight = 10;
createProductType(name, shippingWeight)
.then(productType => {
getProductType(productType.id);
})
.then(productType => {
expect(productType.name).to.be.eq(name);
expect(productType.isShippingRequired).to.be.true;
expect(productType.weight.value).to.eq(shippingWeight);
});
});
it("Update product type with product attribute", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({ name })
.then(productType => {
visitAndWaitForProgressBarToDisappear(
productTypeDetailsUrl(productType.id)
)
.get(PRODUCT_TYPE_DETAILS.assignProductAttributeButton)
.click();
cy.addAliasToGraphRequest("AssignProductAttribute");
assignElements(startsWith, false);
confirmationMessageShouldDisappear();
cy.wait("@AssignProductAttribute");
getProductType(productType.id);
})
.then(productType => {
expect(productType.productAttributes[0].name).to.eq(startsWith);
});
});
it("Update product type with variant attribute", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({ name, hasVariants: false })
.then(productType => {
visitAndWaitForProgressBarToDisappear(
productTypeDetailsUrl(productType.id)
)
.get(PRODUCT_TYPE_DETAILS.hasVariantsButton)
.click()
.get(PRODUCT_TYPE_DETAILS.assignVariantAttributeButton)
.click();
cy.addAliasToGraphRequest("AssignProductAttribute");
assignElements(startsWith, false);
confirmationMessageShouldDisappear();
cy.wait("@AssignProductAttribute");
getProductType(productType.id);
})
.then(productType => {
expect(productType.variantAttributes[0].name).to.eq(startsWith);
});
});
});

View file

@ -1,124 +0,0 @@
// <reference types="cypress" />
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 { waitForProgressBarToNotExist } from "../../../../steps/shared/progressBar";
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");
waitForProgressBarToNotExist();
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);
});
});
});
});

View file

@ -1,141 +0,0 @@
// <reference types="cypress" />
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).softExpectSkeletonIsVisible();
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).softExpectSkeletonIsVisible();
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;
});
});
});

View file

@ -1,134 +0,0 @@
// <reference types="cypress" />
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)
);
}
});

View file

@ -1,187 +0,0 @@
// <reference types="cypress" />
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);
});
});
});

View file

@ -1,78 +0,0 @@
import faker from "faker";
import {
getShopInfo,
updateShopAddress
} from "../../../apiRequests/shopSettings";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SITE_SETTINGS_DETAILS } from "../../../elements/siteSettings/site-settings-details";
import { fillUpBasicAddress } from "../../../steps/shared/addressForm";
import { confirmationMessageShouldDisappear } from "../../../steps/shared/confirmationMessage";
import { urlList } from "../../../url/urlList";
describe("Tests for site settings", () => {
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
cy.fixture("addresses").then(({ usAddress, plAddress }) => {
address = usAddress;
updateShopAddress(plAddress);
});
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.siteSettings);
});
it("should change store name", () => {
const name = `Cypress-${faker.datatype.number()}`;
cy.get(SITE_SETTINGS_DETAILS.nameInput)
.clearAndType(name)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getShopInfo().then(shopInfo => {
expect(shopInfo.name).to.eq(name);
});
});
it("should change site url", () => {
const url = `http://cypress${faker.datatype.number()}.saleor.com`;
cy.get(SITE_SETTINGS_DETAILS.urlInput)
.clearAndType(url)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getShopInfo().then(shopInfo => {
expect(shopInfo.domain.host).to.eq(url);
});
});
it("should change store description", () => {
const description = faker.lorem.sentence();
cy.get(SITE_SETTINGS_DETAILS.descriptionInput)
.clearAndType(description)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getShopInfo().then(shopInfo => {
expect(shopInfo.description).to.eq(description);
});
});
it("should change store address", () => {
fillUpBasicAddress(address);
cy.get(BUTTON_SELECTORS.confirm).click();
confirmationMessageShouldDisappear();
getShopInfo().then(({ companyAddress }) => {
expect(companyAddress.companyName).to.eq(address.companyName);
cy.expectCorrectBasicAddress(companyAddress, address);
});
});
});

View file

@ -1,112 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createShippingZone } from "../../../apiRequests/ShippingMethod";
import { createWarehouse, getWarehouse } from "../../../apiRequests/Warehouse";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHIPPING_ZONE_DETAILS } from "../../../elements/shipping/shipping-zone-details";
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/selects";
import {
shippingZoneDetailsUrl,
urlList,
warehouseDetailsUrl
} from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import { deleteShippingStartsWith } from "../../../utils/shippingUtils";
describe("Warehouse settings", () => {
const startsWith = "CyWarehouse";
let usAddress;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteShippingStartsWith(startsWith);
cy.fixture("addresses").then(addresses => {
usAddress = addresses.usAddress;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create warehouse", () => {
const name = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.warehouses)
.get(WAREHOUSES_LIST.createNewButton)
.click();
cy.get(WAREHOUSES_DETAILS.nameInput).type(name);
fillUpBasicAddress(usAddress);
cy.addAliasToGraphRequest("WarehouseCreate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@WarehouseCreate")
.its("response.body.data.createWarehouse.warehouse")
.then(warehouse => {
getWarehouse(warehouse.id);
})
.then(warehouse => {
const addressResp = warehouse.address;
chai.softExpect(warehouse.name).to.be.eq(name);
cy.expectCorrectBasicAddress(addressResp, usAddress);
});
});
it("should add warehouse to shipping zone", () => {
const name = `${startsWith}${faker.datatype.number()}`;
let defaultChannel;
let warehouse;
let shippingZone;
getDefaultChannel()
.then(channelResp => {
defaultChannel = channelResp;
createWarehouse({
name,
address: usAddress
});
})
.then(warehouseResp => {
warehouse = warehouseResp;
createShippingZone(name, "US", defaultChannel.id);
})
.then(shippingZoneResp => {
shippingZone = shippingZoneResp;
cy.visit(shippingZoneDetailsUrl(shippingZone.id));
fillAutocompleteSelect(
SHIPPING_ZONE_DETAILS.warehouseSelector,
warehouse.name
);
cy.addAliasToGraphRequest("UpdateShippingZone")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@UpdateShippingZone");
getWarehouse(warehouse.id);
})
.then(warehouseResp => {
expect(warehouseResp.shippingZones.edges[0].node.id).to.be.eq(
shippingZone.id
);
});
});
it("should delete warehouse", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createWarehouse({
name,
address: usAddress
}).then(warehouse => {
cy.visit(warehouseDetailsUrl(warehouse.id))
.get(BUTTON_SELECTORS.deleteButton)
.click()
.addAliasToGraphRequest("WarehouseDelete")
.get(BUTTON_SELECTORS.submit)
.click()
.wait("@WarehouseDelete");
getWarehouse(warehouse.id).should("be.null");
});
});
});

View file

@ -1,55 +0,0 @@
import faker from "faker";
import { customerRegistration } from "../../apiRequests/Customer";
import { CUSTOMER_DETAILS } from "../../elements/customers/customer-details";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import { customerDetailsUrl } from "../../url/urlList";
import { getDefaultChannel } from "../../utils/channelsUtils";
describe("Tests for customer registration", () => {
const startsWith = "Registration";
const email = `${startsWith}${faker.datatype.number()}@example.com`;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
getDefaultChannel().then(channel => {
defaultChannel = channel;
});
});
it("shouldn't register customer with duplicated email", () => {
const duplicatedEmail = Cypress.env("USER_NAME");
customerRegistration({
duplicatedEmail,
channel: defaultChannel.slug
}).then(({ user, errors }) => {
expect(errors[0].field).to.eq("email");
expect(user).to.not.be.ok;
});
});
it("should activate customer from dashboard", () => {
customerRegistration({ email, channel: defaultChannel.slug })
.then(({ user }) => {
cy.visit(customerDetailsUrl(user.id))
.get(CUSTOMER_DETAILS.isActiveCheckbox)
.click()
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.clearSessionData()
.loginUserViaRequest("token", {
email,
password: Cypress.env("USER_PASSWORD")
})
.its("body.data.tokenCreate");
})
.then(({ token, errors }) => {
expect(errors.length).to.eq(0);
expect(token).to.be.ok;
});
});
});

View file

@ -1,198 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../../apiRequests/Channels";
import { updateChannelInProduct } from "../../../apiRequests/Product";
import {
assignProducts,
createSale,
discountOptions
} from "../../../steps/discounts/salesSteps";
import { urlList } from "../../../url/urlList";
import * as channelsUtils from "../../../utils/channelsUtils";
import { deleteSalesStartsWith } from "../../../utils/discounts/salesUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
import { getProductPrice } from "../../../utils/storeFront/storeFrontProductUtils";
describe("Sales discounts", () => {
const startsWith = "CySales-";
let productType;
let attribute;
let category;
let defaultChannel;
let warehouse;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
deleteSalesStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
channelsUtils.getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addresses => {
createShipping({
channelId: defaultChannel.id,
name,
address: addresses.plAddress,
price: 100
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create percentage discount", () => {
const saleName = `${startsWith}${faker.datatype.number()}`;
const discountValue = 50;
const productPrice = 100;
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
/* Uncomment after fixing SALEOR-3367 bug
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
*/
cy.visit(urlList.sales);
cy.softExpectSkeletonIsVisible();
const product = productResp;
createSale({
saleName,
channelName: defaultChannel.name,
discountValue,
discountOption: discountOptions.PERCENTAGE
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => {
const expectedPrice = (productPrice * discountValue) / 100;
expect(expectedPrice).to.be.eq(price);
});
});
it("should create fixed price discount", () => {
const saleName = `${startsWith}${faker.datatype.number()}`;
const discountValue = 50;
const productPrice = 100;
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
/* Uncomment after fixing SALEOR-3367 bug
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
*/
cy.visit(urlList.sales);
cy.softExpectSkeletonIsVisible();
const product = productResp;
createSale({
saleName,
channelName: defaultChannel.name,
discountValue,
discountOption: discountOptions.FIXED
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => {
const expectedPrice = productPrice - discountValue;
expect(expectedPrice).to.be.eq(price);
});
});
it("should not displayed discount not assign to channel", () => {
const saleName = `${startsWith}${faker.datatype.number()}`;
let channel;
let product;
const discountValue = 50;
const productPrice = 100;
createChannel({ name: saleName }).then(
channelResp => (channel = channelResp)
);
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
product = productResp;
updateChannelInProduct({
productId: product.id,
channelId: channel.id
});
})
.then(() => {
/* Uncomment after fixing SALEOR-3367 bug
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
*/
cy.visit(urlList.sales);
cy.softExpectSkeletonIsVisible();
createSale({
saleName,
channelName: channel.name,
discountValue
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => expect(price).to.equal(productPrice));
});
});

View file

@ -1,177 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../../apiRequests/Channels";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import {
createVoucher,
discountOptions
} from "../../../steps/discounts/vouchersSteps";
import { urlList } from "../../../url/urlList";
import * as channelsUtils from "../../../utils/channelsUtils";
import { deleteVouchersStartsWith } from "../../../utils/discounts/vouchersUtils";
import { createCheckoutWithVoucher } from "../../../utils/ordersUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Vouchers discounts", () => {
const startsWith = "CyVou-";
const productPrice = 100;
const shippingPrice = 100;
let defaultChannel;
let createdChannel;
let productType;
let attribute;
let category;
let shippingMethod;
let variants;
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
deleteVouchersStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
channelsUtils.getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addresses => {
address = addresses.plAddress;
createShipping({
channelId: defaultChannel.id,
name,
address,
price: shippingPrice
});
})
.then(({ shippingMethod: shippingMethodResp, warehouse: warehouse }) => {
shippingMethod = shippingMethodResp;
productsUtils.createProductInChannel({
name,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
})
.then(({ variantsList: variantsResp }) => {
variants = variantsResp;
createChannel({ name });
})
.then(channel => {
createdChannel = channel;
});
});
it("should create percentage voucher", () => {
const voucherValue = 50;
loginAndCreateCheckoutForVoucherWithDiscount(
discountOptions.PERCENTAGE,
voucherValue
).then(amount => {
const expectedAmount =
(productPrice * voucherValue) / 100 + shippingPrice;
expect(amount).to.be.eq(expectedAmount);
});
});
it("should create fixed price voucher", () => {
const voucherValue = 50;
loginAndCreateCheckoutForVoucherWithDiscount(
discountOptions.FIXED,
voucherValue
).then(amount => {
const expectedAmount = productPrice + shippingPrice - voucherValue;
expect(amount).to.be.eq(expectedAmount);
});
});
it("should create free shipping voucher", () => {
loginAndCreateCheckoutForVoucherWithDiscount(
discountOptions.SHIPPING,
null
).then(amount => {
const expectedAmount = productPrice;
expect(amount).to.be.eq(expectedAmount);
});
});
it("should create voucher not available for selected channel", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
const voucherValue = 50;
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.vouchers);
cy.softExpectSkeletonIsVisible();
createVoucher({
voucherCode: randomName,
voucherValue,
discountOption: discountOptions.PERCENTAGE,
channelName: createdChannel.name
});
createCheckoutForCreatedVoucher(randomName).then(resp => {
const errorField = resp.checkoutErrors[0].field;
expect(errorField).to.be.eq("promoCode");
});
});
function createCheckoutForCreatedVoucher(voucherCode) {
return createCheckoutWithVoucher({
channelSlug: defaultChannel.slug,
variantsList: variants,
address,
shippingMethodId: shippingMethod.id,
voucherCode,
auth: "token"
});
}
function loginAndCreateCheckoutForVoucherWithDiscount(
discount,
voucherValue
) {
const voucherCode = `${startsWith}${faker.datatype.number()}`;
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
.visit(urlList.vouchers);
cy.softExpectSkeletonIsVisible();
createVoucher({
voucherCode,
voucherValue,
discountOption: discount,
channelName: defaultChannel.name
});
return createCheckoutForCreatedVoucher(voucherCode).its(
"checkout.totalPrice.gross.amount"
);
}
});

View file

@ -1,19 +0,0 @@
import { TEST_ADMIN_USER, USER_WITHOUT_NAME } from "../../../Data/users";
import { expectWelcomeMessageIncludes } from "../../../steps/homePageSteps";
import { urlList } from "../../../url/urlList";
describe("Displaying welcome message on home page", () => {
it("should display user name on home page", () => {
cy.loginUserViaRequest();
cy.visit(urlList.homePage);
expectWelcomeMessageIncludes(
`${TEST_ADMIN_USER.name} ${TEST_ADMIN_USER.lastName}`
);
});
it("should display user email on home page", () => {
cy.loginUserViaRequest("auth", USER_WITHOUT_NAME);
cy.visit(urlList.homePage);
expectWelcomeMessageIncludes(`${USER_WITHOUT_NAME.email}`);
});
});

View file

@ -1,251 +0,0 @@
import faker from "faker";
import {
createCustomer,
deleteCustomersStartsWith
} from "../../../apiRequests/Customer";
import { HOMEPAGE_SELECTORS } from "../../../elements/homePage/homePage-selectors";
import { changeChannel } from "../../../steps/homePageSteps";
import { urlList } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import * as homePageUtils from "../../../utils/homePageUtils";
import {
createReadyToFulfillOrder,
createWaitingForCaptureOrder
} from "../../../utils/ordersUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import * as shippingUtils from "../../../utils/shippingUtils";
// <reference types="cypress" />
describe("Homepage analytics", () => {
const startsWith = "CyHomeAnalytics";
let customerId;
let defaultChannel;
let createdVariants;
let productType;
let attribute;
let category;
let warehouse;
let shippingMethod;
let addresses;
const productPrice = 22;
const shippingPrice = 12;
const randomName = startsWith + faker.datatype.number();
const randomEmail = `${startsWith}${randomName}@example.com`;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
deleteCustomersStartsWith(startsWith);
shippingUtils.deleteShippingStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addressesFixture => (addresses = addressesFixture))
.then(() => createCustomer(randomEmail, randomName, addresses.plAddress))
.then(resp => {
customerId = resp.body.data.customerCreate.user.id;
shippingUtils.createShipping({
channelId: defaultChannel.id,
name: randomName,
address: addresses.plAddress,
price: shippingPrice
});
})
.then(
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
}
)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 20,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
}
)
.then(({ variantsList: variantsResp }) => {
createdVariants = variantsResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should all elements be visible on the dashboard", () => {
cy.visit(urlList.homePage)
.softAssertVisibility(HOMEPAGE_SELECTORS.sales)
.softAssertVisibility(HOMEPAGE_SELECTORS.orders)
.softAssertVisibility(HOMEPAGE_SELECTORS.activity)
.softAssertVisibility(HOMEPAGE_SELECTORS.topProducts)
.softAssertVisibility(HOMEPAGE_SELECTORS.ordersReadyToFulfill)
.softAssertVisibility(HOMEPAGE_SELECTORS.paymentsWaitingForCapture)
.softAssertVisibility(HOMEPAGE_SELECTORS.productsOutOfStock);
});
it("should correct amount of ready to fullfil orders be displayed", () => {
homePageUtils
.getOrdersReadyToFulfill(defaultChannel.slug)
.as("ordersReadyToFulfill");
createReadyToFulfillOrder({
customerId,
shippingMethodId: shippingMethod.id,
channelId: defaultChannel.id,
variantsList: createdVariants,
address: addresses.plAddress
});
cy.get("@ordersReadyToFulfill").then(ordersReadyToFulfillBefore => {
const allOrdersReadyToFulfill = ordersReadyToFulfillBefore + 1;
const notANumberRegex = "\\D*";
const ordersReadyToFulfillRegexp = new RegExp(
`${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(
HOMEPAGE_SELECTORS.ordersReadyToFulfill,
ordersReadyToFulfillRegexp
).should("be.visible");
});
});
it("should correct amount of payments waiting for capture be displayed", () => {
homePageUtils
.getOrdersReadyForCapture(defaultChannel.slug)
.as("ordersReadyForCapture");
createWaitingForCaptureOrder({
channelSlug: defaultChannel.slug,
email: randomEmail,
variantsList: createdVariants,
shippingMethodId: shippingMethod.id,
address: addresses.plAddress
});
cy.get("@ordersReadyForCapture").then(ordersReadyForCaptureBefore => {
const allOrdersReadyForCapture = ordersReadyForCaptureBefore + 1;
const notANumberRegex = "\\D*";
const ordersReadyForCaptureRegexp = new RegExp(
`${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(
HOMEPAGE_SELECTORS.ordersReadyForCapture,
ordersReadyForCaptureRegexp
).should("be.visible");
});
});
it("should correct amount of products out of stock be displayed", () => {
homePageUtils
.getProductsOutOfStock(defaultChannel.slug)
.as("productsOutOfStock");
const productOutOfStockRandomName = startsWith + faker.datatype.number();
productsUtils.createProductInChannel({
name: productOutOfStockRandomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 0,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
cy.get("@productsOutOfStock").then(productsOutOfStockBefore => {
const allProductsOutOfStock = productsOutOfStockBefore + 1;
const notANumberRegex = "\\D*";
const productsOutOfStockRegexp = new RegExp(
`${notANumberRegex}${allProductsOutOfStock}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(
HOMEPAGE_SELECTORS.productsOutOfStock,
productsOutOfStockRegexp
).should("be.visible");
});
});
it("should correct amount of sales be displayed", () => {
homePageUtils.getSalesAmount(defaultChannel.slug).as("salesAmount");
createReadyToFulfillOrder({
customerId,
shippingMethodId: shippingMethod.id,
channelId: defaultChannel.id,
variantsList: createdVariants,
address: addresses.plAddress
});
cy.get("@salesAmount").then(salesAmount => {
const totalAmount = salesAmount + productPrice;
const totalAmountString = totalAmount.toFixed(2);
const totalAmountIntegerValue = totalAmountString.split(".")[0];
const totalAmountDecimalValue = totalAmountString.split(".")[1];
const decimalSeparator = "[,.]";
const totalAmountIntegerWithThousandsSeparator = new Intl.NumberFormat(
"en"
)
.format(totalAmountIntegerValue)
.replaceAll(",", "[,.]*");
const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`;
const notANumberRegex = "\\D*";
const salesAmountRegexp = new RegExp(
`${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(HOMEPAGE_SELECTORS.sales, salesAmountRegexp).should(
"be.visible"
);
});
});
it("should correct amount of orders be displayed", () => {
homePageUtils.getTodaysOrders(defaultChannel.slug).as("todaysOrders");
createReadyToFulfillOrder({
customerId,
shippingMethodId: shippingMethod.id,
channelId: defaultChannel.id,
variantsList: createdVariants,
address: addresses.plAddress
});
cy.get("@todaysOrders").then(ordersBefore => {
const allOrders = ordersBefore + 1;
const notANumberRegex = "\\D*";
const ordersRegexp = new RegExp(
`${notANumberRegex}${allOrders}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(HOMEPAGE_SELECTORS.orders, ordersRegexp).should("be.visible");
});
});
});

View file

@ -1,39 +0,0 @@
// <reference types="cypress" />
import { LOGIN_SELECTORS } from "../../elements/account/login-selectors";
import { urlList } from "../../url/urlList";
describe("User authorization", () => {
beforeEach(() => {
cy.clearSessionData();
});
it("should successfully log in an user", () => {
cy.visit(urlList.homePage);
cy.loginUser();
cy.get(LOGIN_SELECTORS.welcomePage);
});
it("should fail for wrong password", () => {
cy.visit(urlList.homePage)
.get(LOGIN_SELECTORS.emailAddressInput)
.type("admin@example.com")
.get(LOGIN_SELECTORS.emailPasswordInput)
.type("wrong-password")
.get(LOGIN_SELECTORS.signInButton)
.click()
.get(LOGIN_SELECTORS.warningCredentialMessage);
});
it("should successfully log out an user", () => {
cy.window().then(win => {
win.sessionStorage.clear();
});
cy.visit(urlList.homePage);
cy.loginUser();
cy.get(LOGIN_SELECTORS.userMenu)
.click()
.get(LOGIN_SELECTORS.accountSettings)
.click();
cy.location("pathname").should("contains", "/staff/");
});
});

View file

@ -1,100 +0,0 @@
import faker from "faker";
import {
updateMetadata,
updatePrivateMetadata
} from "../../apiRequests/Metadata";
import { createDraftOrder, getOrder } from "../../apiRequests/Order";
import { getProductMetadata } from "../../apiRequests/storeFront/ProductDetails";
import { getDefaultChannel } from "../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct
} from "../../utils/products/productsUtils";
describe("Test for metadata", () => {
const startsWith = "Metadata";
const name = `${startsWith}${faker.datatype.number()}`;
const metadata = { key: "metadataKey", value: "metadataValue" };
let channel;
let product;
before(() => {
cy.clearSessionData().loginUserViaRequest();
getDefaultChannel()
.then(channelResp => {
channel = channelResp;
createTypeAttributeAndCategoryForProduct(name);
})
.then(({ attribute, category, productType }) => {
createProductInChannel({
attributeId: attribute.id,
categoryId: category.id,
channelId: channel.id,
name,
productTypeId: productType.id
});
})
.then(({ product: productResp }) => {
product = productResp;
});
});
it("should create metadata for product", () => {
cy.clearSessionData().loginUserViaRequest();
updateMetadata(product.id, metadata.key, metadata.value);
updatePrivateMetadata(product.id, metadata.key, metadata.value)
.then(() => {
getProductMetadata({
productId: product.id,
channelSlug: channel.slug,
auth: "auth",
withPrivateMetadata: true
}).its("data");
})
.then(({ product: productResp }) => {
expect(productResp.metadata[0].key).to.eq(metadata.key);
expect(productResp.metadata[0].value).to.eq(metadata.value);
expect(productResp.privateMetadata[0].key).to.eq(metadata.key);
expect(productResp.privateMetadata[0].value).to.eq(metadata.value);
getProductMetadata({
productId: product.id,
channelSlug: channel.slug,
auth: "token",
withPrivateMetadata: true
});
})
.then(({ errors }) => {
expect(errors[0].extensions.exception.code).to.eq("PermissionDenied");
getProductMetadata({
productId: product.id,
channelSlug: channel.slug,
auth: "token",
withPrivateMetadata: false
}).its("data");
})
.then(({ product: productResp }) => {
expect(productResp.metadata[0].key).to.eq(metadata.key);
expect(productResp.metadata[0].value).to.eq(metadata.value);
});
});
it("should create metadata for order", () => {
let order;
cy.clearSessionData().loginUserViaRequest();
createDraftOrder({ channelId: channel.id })
.then(orderResp => {
order = orderResp;
updateMetadata(order.id, metadata.key, metadata.value);
updatePrivateMetadata(order.id, metadata.key, metadata.value);
})
.then(() => {
getOrder(order.id);
})
.then(orderResp => {
expect(orderResp.metadata[0].key).to.eq(metadata.key);
expect(orderResp.metadata[0].value).to.eq(metadata.value);
expect(orderResp.privateMetadata[0].key).to.eq(metadata.key);
expect(orderResp.privateMetadata[0].value).to.eq(metadata.value);
});
});
});

View file

@ -1,45 +0,0 @@
import { PERMISSIONS_OPTIONS } from "../../Data/permissionsUsers";
import * as permissionsSteps from "../../steps/permissions";
describe("Navigation for users with different permissions", () => {
Object.keys(PERMISSIONS_OPTIONS).forEach(key => {
it(`should navigate as an user with ${key} permission`, () => {
const permissionOption = PERMISSIONS_OPTIONS[key];
const permissions = permissionOption.permissions;
cy.clearSessionData();
permissionsSteps.navigateToAllAvailablePageAndCheckIfDisplayed(
permissionOption
);
if (key === "all") {
return;
}
permissionsSteps
.getDisplayedSelectors()
.then(selectors => {
permissionsSteps.expectAllSelectorsPermitted(permissions, selectors);
})
.then(() => {
if (!permissions) {
return;
}
permissions.forEach(permission => {
if (permission.parent) {
cy.get(permission.parent.parentMenuSelector)
.click()
.then(() => {
permissionsSteps.getDisplayedSelectors(
permission.parent.parentSelectors
);
})
.then(parentSelectors => {
permissionsSteps.expectAllSelectorsPermitted(
permissions,
parentSelectors
);
});
}
});
});
});
});
});

View file

@ -1,98 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../../apiRequests/Channels";
import { CHANNEL_FORM_SELECTORS } from "../../../elements/channels/channel-form-selectors";
import { HEADER_SELECTORS } from "../../../elements/header/header-selectors";
import { DRAFT_ORDER_SELECTORS } from "../../../elements/orders/draft-order-selectors";
import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors";
import {
selectChannelInHeader,
selectChannelInPicker
} from "../../../steps/channelsSteps";
import { urlList } from "../../../url/urlList";
import * as channelsUtils from "../../../utils/channelsUtils";
describe("Channels in draft orders", () => {
const startsWith = "CyChannelInDraftOrders-";
const randomName = startsWith + faker.datatype.number();
let defaultChannel;
let otherChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
createChannel({ name: randomName });
})
.then(channelResp => {
otherChannel = channelResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("Draft order channel should be taken from global channel picker", () => {
let channelName;
cy.visit(urlList.homePage);
cy.getTextFromElement(HEADER_SELECTORS.channelSelect).then(
channelInHeader => {
channelName = channelInHeader;
}
);
cy.visit(urlList.orders)
.get(ORDERS_SELECTORS.createOrder)
.click();
cy.getTextFromElement(CHANNEL_FORM_SELECTORS.channelSelect).then(
selectedChannelName => {
expect(channelName).to.contains(selectedChannelName);
}
);
cy.get(CHANNEL_FORM_SELECTORS.confirmButton).click();
cy.getTextFromElement(DRAFT_ORDER_SELECTORS.salesChannel).then(
channelNameInDraftOrder => {
expect(channelName).to.contains(channelNameInDraftOrder);
}
);
});
it("Draft order channel should be taken from global channel picker when changed", () => {
cy.visit(urlList.homePage);
selectChannelInHeader(otherChannel.name);
cy.visit(urlList.orders);
cy.get(ORDERS_SELECTORS.createOrder).click();
cy.getTextFromElement(CHANNEL_FORM_SELECTORS.channelSelect).then(
channelInSelect => {
expect(channelInSelect).to.be.eq(otherChannel.name);
}
);
cy.get(CHANNEL_FORM_SELECTORS.confirmButton).click();
cy.getTextFromElement(DRAFT_ORDER_SELECTORS.salesChannel).then(
channelInDraftOrder => {
expect(channelInDraftOrder).to.be.eq(otherChannel.name);
}
);
});
it("should create draft order with chosen channel", () => {
cy.visit(urlList.homePage);
selectChannelInHeader(defaultChannel.name);
cy.visit(urlList.orders);
cy.get(ORDERS_SELECTORS.createOrder).click();
cy.getTextFromElement(CHANNEL_FORM_SELECTORS.channelSelect).then(
channelInSelect => {
expect(channelInSelect).to.be.eq(defaultChannel.name);
}
);
selectChannelInPicker(otherChannel.name);
cy.getTextFromElement(DRAFT_ORDER_SELECTORS.salesChannel).then(
channelInDraftOrder => {
expect(channelInDraftOrder).to.be.eq(otherChannel.name);
}
);
});
});

View file

@ -1,102 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import {
createCustomer,
deleteCustomersStartsWith
} from "../../../apiRequests/Customer";
import { DRAFT_ORDERS_LIST_SELECTORS } from "../../../elements/orders/draft-orders-list-selectors";
import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors";
import { selectChannelInPicker } from "../../../steps/channelsSteps";
import { finalizeDraftOrder } from "../../../steps/draftOrderSteps";
import { urlList } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Draft orders", () => {
const startsWith = "CyDraftOrders-";
const randomName = startsWith + faker.datatype.number();
let defaultChannel;
let warehouse;
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteCustomersStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
})
.then(() => {
cy.fixture("addresses");
})
.then(addresses => {
address = addresses.plAddress;
createCustomer(
`${randomName}@example.com`,
randomName,
addresses.plAddress,
true
);
createShipping({
channelId: defaultChannel.id,
name: randomName,
address: addresses.plAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
})
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productTypeResp.id,
attributeId: attributeResp.id,
categoryId: categoryResp.id
});
}
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should move draft order to orders", () => {
cy.visit(urlList.orders);
cy.softExpectSkeletonIsVisible();
cy.get(ORDERS_SELECTORS.createOrder).click();
selectChannelInPicker(defaultChannel.name);
finalizeDraftOrder(randomName, address).then(draftOrderNumber => {
cy.visit(urlList.orders);
cy.contains(ORDERS_SELECTORS.orderRow, draftOrderNumber).should(
$order => {
expect($order).to.be.visible;
}
);
cy.visit(urlList.draftOrders);
cy.contains(
DRAFT_ORDERS_LIST_SELECTORS.draftOrderRow,
draftOrderNumber
).should($draftOrder => {
expect($draftOrder).to.not.exist;
});
});
});
});

View file

@ -1,200 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import {
createCustomer,
deleteCustomersStartsWith
} from "../../../apiRequests/Customer";
import { getOrder } from "../../../apiRequests/Order";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { ORDER_REFUND } from "../../../elements/orders/order-refund";
import { ORDERS_SELECTORS } from "../../../elements/orders/orders-selectors";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { selectChannelInPicker } from "../../../steps/channelsSteps";
import { finalizeDraftOrder } from "../../../steps/draftOrderSteps";
import { fillAutocompleteSelect } from "../../../steps/shared/selects";
import { urlList } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import {
createFulfilledOrder,
createOrder,
createReadyToFulfillOrder
} from "../../../utils/ordersUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Orders", () => {
const startsWith = "CyOrders-";
const randomName = startsWith + faker.datatype.number();
let customer;
let defaultChannel;
let warehouse;
let shippingMethod;
let variantsList;
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteCustomersStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
})
.then(() => {
cy.fixture("addresses");
})
.then(addresses => {
address = addresses.plAddress;
createCustomer(`${randomName}@example.com`, randomName, address, true);
})
.then(customerResp => {
customer = customerResp.body.data.customerCreate.user;
createShipping({
channelId: defaultChannel.id,
name: randomName,
address
});
})
.then(
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
shippingMethod = shippingMethodResp;
warehouse = warehouseResp;
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
}
)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productTypeResp.id,
attributeId: attributeResp.id,
categoryId: categoryResp.id
});
}
)
.then(({ variantsList: variantsResp }) => {
variantsList = variantsResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.order
);
});
it("should create order with selected channel", () => {
// Remove login as admin after fixing SALEOR-3154
cy.clearSessionData().loginUserViaRequest();
cy.visit(urlList.orders)
.get(ORDERS_SELECTORS.createOrder)
.click();
selectChannelInPicker(defaultChannel.name);
finalizeDraftOrder(randomName, address).then(draftOrderNumber => {
cy.visit(urlList.orders);
cy.contains(ORDERS_SELECTORS.orderRow, draftOrderNumber).click();
cy.contains(ORDERS_SELECTORS.salesChannel, defaultChannel.name).should(
"be.visible"
);
});
});
// This test will pass after fixing SALEOR-3154
it("should not be possible to change channel in order", () => {
createOrder({
customerId: customer.id,
channelId: defaultChannel.id,
shippingMethodId: shippingMethod.id,
variantsList,
address
}).then(order => {
cy.visit(urlList.orders);
cy.contains(ORDERS_SELECTORS.orderRow, order.number).click();
cy.get(ORDERS_SELECTORS.salesChannel)
.find("[button]")
.should("not.exist");
});
});
it("should cancel fulfillment", () => {
let order;
createFulfilledOrder({
customerId: customer.id,
channelId: defaultChannel.id,
shippingMethodId: shippingMethod.id,
variantsList,
address,
warehouse: warehouse.id
})
.then(({ order: orderResp }) => {
order = orderResp;
cy.visit(urlList.orders);
cy.softExpectSkeletonIsVisible();
cy.contains(ORDERS_SELECTORS.orderRow, order.number).click();
cy.get(SHARED_ELEMENTS.skeleton)
.should("not.exist")
.get(ORDERS_SELECTORS.orderFulfillmentFrame)
.find(BUTTON_SELECTORS.showMoreButton)
.click()
.get(ORDERS_SELECTORS.cancelFulfillment)
.click();
})
.then(() => {
fillAutocompleteSelect(
ORDERS_SELECTORS.cancelFulfillmentSelectField,
warehouse.name
);
cy.addAliasToGraphRequest("OrderFulfillmentCancel");
cy.get(BUTTON_SELECTORS.submit).click();
cy.wait("@OrderFulfillmentCancel");
getOrder(order.id);
})
.then(orderResp => {
expect(orderResp.status).to.be.eq("UNFULFILLED");
});
});
it("should make a refund", () => {
let order;
createReadyToFulfillOrder({
customerId: customer.id,
channelId: defaultChannel.id,
shippingMethodId: shippingMethod.id,
variantsList,
address
})
.then(({ order: orderResp }) => {
order = orderResp;
cy.visit(urlList.orders);
cy.softExpectSkeletonIsVisible();
cy.contains(ORDERS_SELECTORS.orderRow, order.number).click();
cy.get(ORDERS_SELECTORS.refundButton)
.click()
.get(ORDER_REFUND.productsQuantityInput)
.type("1")
.addAliasToGraphRequest("OrderFulfillmentRefundProducts");
cy.get(BUTTON_SELECTORS.submit)
.click()
.wait("@OrderFulfillmentRefundProducts");
getOrder(order.id);
})
.then(orderResp => {
expect(orderResp.paymentStatus).to.be.eq("FULLY_REFUNDED");
});
});
});

View file

@ -1,61 +0,0 @@
import faker from "faker";
import { createAttribute } from "../../../apiRequests/Attribute";
import { createPageType, getPageType } from "../../../apiRequests/PageTypes";
import { PAGE_TYPE_DETAILS } from "../../../elements/pageTypes/pageTypeDetails";
import { PAGE_TYPES_LIST } from "../../../elements/pageTypes/pageTypesList";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { assignElements } from "../../../steps/shared/assignElements";
import { confirmationMessageShouldDisappear } from "../../../steps/shared/confirmationMessage";
import { pageTypeDetailsUrl, urlList } from "../../../url/urlList";
describe("Tests for page types", () => {
const startsWith = "PageTypes";
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create page type", () => {
const randomName = startsWith + faker.datatype.number();
cy.visit(urlList.pageTypes)
.get(PAGE_TYPES_LIST.createPageTypeButton)
.click()
.get(PAGE_TYPE_DETAILS.nameInput)
.type(randomName)
.addAliasToGraphRequest("PageTypeCreate")
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.wait("@PageTypeCreate")
.its("response.body.data.pageTypeCreate.pageType")
.then(pageType => {
getPageType(pageType.id);
})
.then(pageType => {
expect(pageType.name).to.eq(randomName);
});
});
it("should assign attribute", () => {
const randomName = startsWith + faker.datatype.number();
createAttribute({ name: randomName, type: "PAGE_TYPE" });
createPageType(randomName)
.then(({ pageType }) => {
cy.visit(pageTypeDetailsUrl(pageType.id))
.get(SHARED_ELEMENTS.progressBar)
.should("be.not.visible")
.get(PAGE_TYPE_DETAILS.assignAttributesButton)
.click();
assignElements(randomName, false);
confirmationMessageShouldDisappear();
getPageType(pageType.id);
})
.then(pageType => {
expect(pageType.attributes[0].name).to.eq(randomName);
});
});
});

View file

@ -1,233 +0,0 @@
import faker from "faker";
import { createAttribute } from "../../../apiRequests/Attribute";
import { createCategory } from "../../../apiRequests/Category";
import {
checkoutShippingAddressUpdate,
checkoutShippingMethodUpdate,
checkoutVariantsUpdate,
completeCheckout,
createCheckout
} from "../../../apiRequests/Checkout";
import { getOrder } from "../../../apiRequests/Order";
import { createTypeProduct } from "../../../apiRequests/productType";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import {
addPayment,
createAndCompleteCheckoutWithoutShipping,
createWaitingForCaptureOrder
} from "../../../utils/ordersUtils";
import {
createProductInChannel,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
describe("Purchase products with all products types", () => {
const startsWith = `CyPurchaseByType`;
const name = `${startsWith}${faker.datatype.number()}`;
const email = `${startsWith}@example.com`;
const testsMessage = "Check order status";
const { softExpect } = chai;
let defaultChannel;
let address;
let warehouse;
let attribute;
let category;
let shippingMethod;
let createProductData;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
getDefaultChannel().then(channelResp => (defaultChannel = channelResp));
cy.fixture("addresses")
.then(addresses => {
address = addresses.usAddress;
createShipping({
channelId: defaultChannel.id,
name,
address,
price: 10
});
})
.then(
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
}
);
createAttribute({ name })
.then(attributeResp => {
attribute = attributeResp;
createCategory(name);
})
.then(categoryResp => {
category = categoryResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
createProductData = {
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 10,
attributeId: attribute.id,
categoryId: category.id,
price: 10
};
});
it("should purchase digital product", () => {
const digitalName = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({
name: digitalName,
attributeId: attribute.id,
shippable: false
})
.then(productType => {
createProductData.name = digitalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
createAndCompleteCheckoutWithoutShipping({
channelSlug: defaultChannel.slug,
email,
billingAddress: address,
variantsList,
auth: "token"
});
})
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
softExpect(
order.isShippingRequired,
"Check if is shipping required in order"
).to.eq(false);
expect(order.status, testsMessage).to.be.eq("UNFULFILLED");
});
});
it("should purchase physical product", () => {
const physicalName = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({
name: physicalName,
attributeId: attribute.id,
shippable: true
})
.then(productType => {
createProductData.name = physicalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
createWaitingForCaptureOrder({
channelSlug: defaultChannel.slug,
email,
variantsList,
shippingMethodId: shippingMethod.id,
address
});
})
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
softExpect(
order.isShippingRequired,
"Check if is shipping required in order"
).to.eq(true);
expect(order.status, testsMessage).to.be.eq("UNFULFILLED");
});
});
it("should purchase multiple products with all product types", () => {
const physicalName = `${startsWith}${faker.datatype.number()}`;
const digitalName = `${startsWith}${faker.datatype.number()}`;
let digitalProductVariantsList;
let checkout;
createTypeProduct({
name: digitalName,
attributeId: attribute.id,
shippable: false
})
.then(productType => {
createProductData.name = digitalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
digitalProductVariantsList = variantsList;
createCheckout({
channelSlug: defaultChannel.slug,
email,
variantsList: digitalProductVariantsList,
billingAddress: address,
auth: "token"
});
})
.then(({ checkout: checkoutResp }) => {
checkout = checkoutResp;
addPayment(checkout.id);
})
.then(() => {
createTypeProduct({
name: physicalName,
attributeId: attribute.id,
shippable: true
});
})
.then(productType => {
createProductData.name = physicalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
checkoutVariantsUpdate(checkout.id, variantsList);
})
.then(() => {
checkoutShippingMethodUpdate(checkout.id, shippingMethod.id);
})
.then(({ checkoutErrors }) => {
expect(
checkoutErrors,
"Should be not possible to add shipping method without shipping address"
).to.have.lengthOf(1);
checkoutShippingAddressUpdate(checkout.id, address);
})
.then(() => {
addPayment(checkout.id);
})
.then(({ paymentErrors }) => {
expect(
paymentErrors,
"Should be not possible to add payment without shipping"
).to.have.lengthOf(1);
checkoutShippingMethodUpdate(checkout.id, shippingMethod.id);
})
.then(() => {
addPayment(checkout.id);
})
.then(() => {
completeCheckout(checkout.id);
})
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
softExpect(
order.isShippingRequired,
"Check if is shipping required in order"
).to.eq(true);
expect(order.status, testsMessage).to.be.eq("UNFULFILLED");
});
});
});

View file

@ -1,141 +0,0 @@
// <reference types="cypress" />
import faker from "faker";
import { createAttribute } from "../../../apiRequests/Attribute";
import { createTypeProduct } from "../../../apiRequests/productType";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { PRODUCT_DETAILS } from "../../../elements/catalog/products/product-details";
import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { metadataForms } from "../../../steps/catalog/metadataSteps";
import {
fillUpPriceList,
priceInputLists
} from "../../../steps/catalog/products/priceList";
import { fillUpCommonFieldsForAllProductTypes } from "../../../steps/catalog/products/productSteps";
import { selectChannelInDetailsPages } from "../../../steps/channelsSteps";
import { urlList } from "../../../url/urlList";
import {
expectCorrectProductInformation,
expectCorrectProductVariantInformation
} from "../../../utils/products/checkProductInfo";
import * as productUtils from "../../../utils/products/productsUtils";
describe("Create product", () => {
const startsWith = "CyCreateProduct-";
const name = `${startsWith}${faker.datatype.number()}`;
const generalInfo = {
name: `${startsWith}${faker.datatype.number()}`,
description: faker.lorem.sentence(),
rating: 2
};
const seo = {
title: "testTitle",
description: generalInfo.description
};
const metadata = {
public: {
metadataForm: metadataForms.public,
name: "metadataName",
value: "metadataValue"
},
private: {
metadataForm: metadataForms.private,
name: "privateMetadataName",
value: "privateMetadataValue"
}
};
let attribute;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productUtils.deleteProductsStartsWith(startsWith);
createAttribute({ name }).then(attributeResp => {
attribute = attributeResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create product with variants", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
seo.slug = randomName;
const productData = {
generalInfo,
seo,
metadata,
productOrganization: { productType: randomName },
attribute
};
createTpeAndFillUpProductFields(randomName, true, productData).then(
productOrgResp => (productData.productOrganization = productOrgResp)
);
cy.addAliasToGraphRequest("ProductDetails");
cy.get(BUTTON_SELECTORS.confirm).click();
cy.wait("@ProductDetails");
cy.get(SHARED_ELEMENTS.confirmationMsg).should("be.visible");
cy.get("@ProductDetails")
.its("response.body")
.then(resp => {
const productResp = resp.find(element => element.data.product).data
.product;
expectCorrectProductInformation(productResp, productData);
});
});
it("should create product without variants", () => {
const prices = { sellingPrice: 6, costPrice: 3 };
const randomName = `${startsWith}${faker.datatype.number()}`;
seo.slug = randomName;
const productData = {
generalInfo,
seo,
metadata,
productOrganization: { productType: randomName },
attribute
};
createTpeAndFillUpProductFields(randomName, false, productData).then(
productOrgResp => (productData.productOrganization = productOrgResp)
);
selectChannelInDetailsPages();
fillUpPriceList(prices.sellingPrice);
fillUpPriceList(prices.costPrice, priceInputLists.costPrice);
cy.get(PRODUCT_DETAILS.skuInput).type(randomName);
cy.addAliasToGraphRequest("ProductDetails");
cy.get(BUTTON_SELECTORS.confirm).click();
cy.wait("@ProductDetails");
cy.get(SHARED_ELEMENTS.confirmationMsg).should("be.visible");
cy.get("@ProductDetails")
.its("response.body")
.then(resp => {
const productResp = resp.find(element => element.data.product).data
.product;
expectCorrectProductInformation(productResp, productData);
expectCorrectProductVariantInformation(
productResp.variants,
randomName,
prices
);
});
});
function createTpeAndFillUpProductFields(
randomName,
hasVariants,
productData
) {
createTypeProduct({
name: randomName,
attributeId: attribute.id,
hasVariants
});
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.product)
.visit(urlList.products)
.get(PRODUCTS_LIST.createProductBtn)
.click();
return fillUpCommonFieldsForAllProductTypes(productData);
}
});

View file

@ -1,117 +0,0 @@
import faker from "faker";
import { getProductDetails } from "../../../../apiRequests/storeFront/ProductDetails";
import { ONE_PERMISSION_USERS } from "../../../../Data/users";
import { updateProductIsAvailableForPurchase } from "../../../../steps/catalog/products/productSteps";
import { productDetailsUrl } from "../../../../url/urlList";
import { getDefaultChannel } from "../../../../utils/channelsUtils";
import * as productsUtils from "../../../../utils/products/productsUtils";
import * as shippingUtils from "../../../../utils/shippingUtils";
import { isProductAvailableForPurchase } from "../../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Products available in listings", () => {
const startsWith = "CyAvailForPurchase-";
const name = `${startsWith}${faker.datatype.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
let warehouse;
before(() => {
cy.clearSessionData().loginUserViaRequest();
shippingUtils.deleteShippingStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addressesFixture => {
shippingUtils.createShipping({
channelId: defaultChannel.id,
name,
address: addressesFixture.plAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
});
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
}
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should update product to available for purchase", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
let product;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
isAvailableForPurchase: false
})
.then(({ product: productResp }) => {
product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductIsAvailableForPurchase(productUrl, true);
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
expect(isProductAvailableForPurchase(resp)).to.be.eq(true);
});
});
it("should update product to not available for purchase", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
let product;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
})
.then(({ product: productResp }) => {
product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductIsAvailableForPurchase(productUrl, false);
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
expect(isProductAvailableForPurchase(resp)).to.be.eq(false);
});
});
});

View file

@ -1,105 +0,0 @@
import faker from "faker";
import { getProductDetails } from "../../../../apiRequests/storeFront/ProductDetails";
import { ONE_PERMISSION_USERS } from "../../../../Data/users";
import { updateProductPublish } from "../../../../steps/catalog/products/productSteps";
import { productDetailsUrl } from "../../../../url/urlList";
import { getDefaultChannel } from "../../../../utils/channelsUtils";
import * as productsUtils from "../../../../utils/products/productsUtils";
import { isProductVisible } from "../../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Published products", () => {
const startsWith = "CyPublishedProducts-";
const name = `${startsWith}${faker.datatype.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should update product to published", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
isPublished: false,
isAvailableForPurchase: false
})
.then(({ product: productResp }) => {
const product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductPublish(productUrl, true);
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, productName);
expect(isVisible).to.be.eq(true);
});
});
it("should update product to not published", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
let product;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
})
.then(({ product: productResp }) => {
product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductPublish(productUrl, false);
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, productName);
expect(isVisible).to.be.eq(false);
cy.loginInShop();
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, productName);
expect(isVisible).to.be.eq(true);
});
});
});

View file

@ -1,114 +0,0 @@
import faker from "faker";
import { searchInShop } from "../../../../apiRequests/storeFront/Search";
import { ONE_PERMISSION_USERS } from "../../../../Data/users";
import { updateProductVisibleInListings } from "../../../../steps/catalog/products/productSteps";
import { productDetailsUrl } from "../../../../url/urlList";
import { getDefaultChannel } from "../../../../utils/channelsUtils";
import * as productsUtils from "../../../../utils/products/productsUtils";
import { isProductVisibleInSearchResult } from "../../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Products displayed in listings", () => {
const startsWith = "CyVisibleInListings-";
const name = `${startsWith}${faker.datatype.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should update product to visible in listings", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: false,
isAvailableForPurchase: false
})
.then(({ product: productResp }) => {
const product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductVisibleInListings(productUrl);
searchInShop(productName);
})
.then(resp => {
const isProductVisible = isProductVisibleInSearchResult(
resp,
productName
);
expect(isProductVisible).to.be.eq(true);
});
});
it("should update product to not visible in listings", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: true
})
.then(({ product: productResp }) => {
const product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductVisibleInListings(productUrl);
searchInShop(productName).then(resp => {
const isProductVisible = isProductVisibleInSearchResult(
resp,
productName
);
expect(isProductVisible).to.be.eq(false);
});
cy.loginInShop();
})
.then(() => {
searchInShop(productName);
})
.then(resp => {
const isProductVisible = isProductVisibleInSearchResult(
resp,
productName
);
expect(isProductVisible).to.be.eq(true);
});
});
});

View file

@ -1,120 +0,0 @@
import faker from "faker";
import { createCollection } from "../../../../apiRequests/Collections";
import { updateProduct } from "../../../../apiRequests/Product";
import { PRODUCTS_LIST } from "../../../../elements/catalog/products/products-list";
import {
selectChannel,
selectFilterOption,
selectProductsOutOfStock
} from "../../../../steps/catalog/products/productsListSteps";
import { waitForProgressBarToNotExist } from "../../../../steps/shared/progressBar";
import { urlList } from "../../../../url/urlList";
import { getDefaultChannel } from "../../../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../../utils/shippingUtils";
describe("Filtering products", () => {
const startsWith = "CyFilterProducts-";
const name = `${startsWith}${faker.datatype.number()}`;
const stockQuantity = 747;
const price = 342;
let attribute;
let productType;
let category;
let warehouse;
let channel;
let collection;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteShippingStartsWith(startsWith);
deleteProductsStartsWith(startsWith);
createTypeAttributeAndCategoryForProduct(name).then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
attribute = attributeResp;
productType = productTypeResp;
category = categoryResp;
}
);
createCollection(name).then(
collectionResp => (collection = collectionResp)
);
getDefaultChannel()
.then(channelResp => {
channel = channelResp;
cy.fixture("addresses");
})
.then(addresses => {
createShipping({
channelId: channel.id,
name,
address: addresses.plAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
createProductInChannel({
name,
channelId: channel.id,
warehouseId: warehouse.id,
quantityInWarehouse: stockQuantity,
price,
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id
});
})
.then(({ product: product }) => {
updateProduct(product.id, { collections: [collection.id] });
});
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.products);
});
const filterProductsBy = ["category", "collection", "productType"];
filterProductsBy.forEach(filterBy => {
it(`should filter products by ${filterBy}`, () => {
cy.softExpectSkeletonIsVisible();
waitForProgressBarToNotExist();
selectFilterOption(filterBy, name);
cy.getTextFromElement(PRODUCTS_LIST.productsNames).then(product => {
expect(product).to.includes(name);
});
});
});
it("should filter products out of stock", () => {
cy.softExpectSkeletonIsVisible();
const productOutOfStock = `${startsWith}${faker.datatype.number()}`;
createProductInChannel({
name: productOutOfStock,
channelId: channel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 0,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price
});
waitForProgressBarToNotExist();
selectChannel(channel.slug);
selectProductsOutOfStock();
cy.getTextFromElement(PRODUCTS_LIST.productsNames).then(product => {
expect(product).to.includes(productOutOfStock);
});
});
});

View file

@ -1,61 +0,0 @@
import { PRODUCTS_LIST } from "../../../../elements/catalog/products/products-list";
import { BUTTON_SELECTORS } from "../../../../elements/shared/button-selectors";
import {
getDisplayedColumnArray,
isNumberOfProductsSameAsInSelectResultsOnPage
} from "../../../../steps/catalog/products/productsListSteps";
import { waitForProgressBarToNotExist } from "../../../../steps/shared/progressBar";
import { urlList } from "../../../../url/urlList";
describe("Products", () => {
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
cy.visit(urlList.products);
});
it("Should go to the next page", () => {
cy.softExpectSkeletonIsVisible();
cy.get(PRODUCTS_LIST.productsList)
.should("be.visible")
.get(PRODUCTS_LIST.emptyProductRow)
.should("not.exist")
.get(PRODUCTS_LIST.previousPagePagination)
.should("be.disabled");
let firstPageProducts;
getDisplayedColumnArray("name").then(
productsList => (firstPageProducts = productsList)
);
cy.addAliasToGraphRequest("ProductList");
cy.get(PRODUCTS_LIST.nextPageButton).click();
waitForProgressBarToNotExist();
cy.wait("@ProductList");
getDisplayedColumnArray("name").then(productList => {
expect(productList).to.not.equal(firstPageProducts);
});
cy.get(PRODUCTS_LIST.previousPagePagination).then($button => {
expect($button).to.be.enabled;
});
});
it("should displayed correct number of results per page", () => {
cy.softExpectSkeletonIsVisible();
isNumberOfProductsSameAsInSelectResultsOnPage().then(
isTheSame =>
expect(isTheSame, "check if number of displayed products is correct").to
.be.true
);
cy.get(PRODUCTS_LIST.resultsOnPageSelect)
.click()
.get(
`${PRODUCTS_LIST.rowNumberOption}${BUTTON_SELECTORS.notSelectedOption}`
)
.first()
.click();
waitForProgressBarToNotExist();
isNumberOfProductsSameAsInSelectResultsOnPage().then(
isTheSame =>
expect(
isTheSame,
"check if number of displayed products is correct, after changing results number in table footer"
).to.be.true
);
});
});

View file

@ -1,28 +0,0 @@
import { PRODUCTS_LIST } from "../../../../elements/catalog/products/products-list";
import { SHARED_ELEMENTS } from "../../../../elements/shared/sharedElements";
import { waitForProgressBarToNotExist } from "../../../../steps/shared/progressBar";
import { urlList } from "../../../../url/urlList";
import { expectProductsSortedBy } from "../../../../utils/products/productsListUtils";
describe("Sorting products", () => {
const sortByList = ["name", "type"];
sortByList.forEach(sortBy => {
it(`Sorting by ${sortBy}`, () => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.products);
cy.softExpectSkeletonIsVisible();
cy.get(SHARED_ELEMENTS.header).should("be.visible");
if (sortBy !== "name") {
cy.get(PRODUCTS_LIST.tableHeaders[sortBy]).click();
waitForProgressBarToNotExist();
}
expectProductsSortedBy(sortBy);
cy.addAliasToGraphRequest("ProductList")
.get(PRODUCTS_LIST.tableHeaders[sortBy])
.click();
waitForProgressBarToNotExist().wait("@ProductList");
expectProductsSortedBy(sortBy, false);
});
});
});

View file

@ -1,206 +0,0 @@
import faker from "faker";
import { createChannel } from "../../../apiRequests/Channels";
import {
createProduct,
updateChannelInProduct
} from "../../../apiRequests/Product";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import {
createFirstVariant,
createVariant,
variantsShouldBeVisible
} from "../../../steps/catalog/products/VariantsSteps";
import { selectChannelInHeader } from "../../../steps/channelsSteps";
import { urlList } from "../../../url/urlList";
import {
deleteChannelsStartsWith,
getDefaultChannel
} from "../../../utils/channelsUtils";
import * as productUtils from "../../../utils/products/productsUtils";
import * as shippingUtils from "../../../utils/shippingUtils";
import { getProductVariants } from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Creating variants", () => {
const startsWith = "CyCreateVariants-";
const attributeValues = ["value1", "value2"];
let defaultChannel;
let warehouse;
let attribute;
let productType;
let category;
let newChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
shippingUtils.deleteShippingStartsWith(startsWith);
productUtils.deleteProductsStartsWith(startsWith);
deleteChannelsStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(fixtureAddresses =>
shippingUtils.createShipping({
channelId: defaultChannel.id,
name,
address: fixtureAddresses.plAddress
})
)
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
createChannel({ isActive: true, name, currencyCode: "PLN" });
})
.then(resp => (newChannel = resp));
productUtils
.createTypeAttributeAndCategoryForProduct(name, attributeValues)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
attribute = attributeResp;
productType = productTypeResp;
category = categoryResp;
}
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should create variant visible on frontend", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const price = 10;
let createdProduct;
createProduct({
attributeId: attribute.id,
name,
productTypeId: productType.id,
categoryId: category.id
})
.then(resp => {
createdProduct = resp;
updateChannelInProduct({
productId: createdProduct.id,
channelId: defaultChannel.id
});
cy.visit(`${urlList.products}${createdProduct.id}`);
createFirstVariant({
sku: name,
warehouseId: warehouse.id,
price,
attribute: attributeValues[0]
});
selectChannelInHeader(defaultChannel.name);
variantsShouldBeVisible({ name, price });
getProductVariants(createdProduct.id, defaultChannel.slug);
})
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", price);
});
});
it("should create several variants", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const secondVariantSku = `${startsWith}${faker.datatype.number()}`;
const variants = [{ price: 7 }, { name: attributeValues[1], price: 16 }];
let createdProduct;
productUtils
.createProductInChannel({
name,
attributeId: attribute.id,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
categoryId: category.id,
price: variants[0].price
})
.then(({ product: productResp }) => {
createdProduct = productResp;
cy.visit(`${urlList.products}${createdProduct.id}`);
createVariant({
sku: secondVariantSku,
warehouseName: warehouse.name,
attributeName: variants[1].name,
price: variants[1].price,
channelName: defaultChannel.name
});
})
.then(() => {
selectChannelInHeader(defaultChannel.name);
variantsShouldBeVisible({
name: variants[1].name,
price: variants[1].price
});
getProductVariants(createdProduct.id, defaultChannel.slug);
})
.then(([firstVariant, secondVariant]) => {
expect(firstVariant).to.have.property("price", variants[0].price);
expect(secondVariant).to.have.property("name", variants[1].name);
expect(secondVariant).to.have.property("price", variants[1].price);
});
});
it("should create variant for many channels", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const variantsPrice = 10;
let createdProduct;
createProduct({
attributeId: attribute.id,
name,
productTypeId: productType.id,
categoryId: category.id
})
.then(productResp => {
createdProduct = productResp;
updateChannelInProduct({
productId: createdProduct.id,
channelId: defaultChannel.id
});
})
.then(() => {
updateChannelInProduct({
productId: createdProduct.id,
channelId: newChannel.id
});
})
.then(() => {
cy.visit(`${urlList.products}${createdProduct.id}`);
createFirstVariant({
sku: name,
warehouseId: warehouse.id,
price: variantsPrice,
attribute: attributeValues[0]
});
selectChannelInHeader(defaultChannel.name);
variantsShouldBeVisible({ name, price: variantsPrice });
selectChannelInHeader(newChannel.name);
variantsShouldBeVisible({ name, price: variantsPrice });
getProductVariants(createdProduct.id, defaultChannel.slug);
})
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", variantsPrice);
getProductVariants(createdProduct.id, newChannel.slug);
})
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", variantsPrice);
});
});
});

View file

@ -1,151 +0,0 @@
import faker from "faker";
import { createCategory } from "../../../apiRequests/Category";
import { createCollection } from "../../../apiRequests/Collections";
import { getProductDetails } from "../../../apiRequests/storeFront/ProductDetails";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { PRODUCT_DETAILS } from "../../../elements/catalog/products/product-details";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { metadataForms } from "../../../steps/catalog/metadataSteps";
import { fillUpCommonFieldsForAllProductTypes } from "../../../steps/catalog/products/productSteps";
import { productDetailsUrl } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import { deleteCollectionsStartsWith } from "../../../utils/collectionsUtils";
import { expectCorrectProductInformation } from "../../../utils/products/checkProductInfo";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
describe("Update products", () => {
const startsWith = "CyUpdateProducts-";
const name = `${startsWith}${faker.datatype.number()}`;
const description = faker.lorem.sentences(2);
let defaultChannel;
let collection;
let product;
let attribute;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteCollectionsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
createCollection(name);
})
.then(collectionResp => {
collection = collectionResp;
createTypeAttributeAndCategoryForProduct(name);
})
.then(({ attribute: attributeResp, category, productType }) => {
attribute = attributeResp;
createProductInChannel({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channelId: defaultChannel.id,
name,
collectionId: collection.id,
description
});
})
.then(({ product: productResp }) => {
product = productResp;
});
});
it("Should update product", () => {
const updatedName = `${startsWith}${faker.random.number()}`;
let updatedCategory;
let updatedCollection;
createCategory(updatedName)
.then(categoryResp => {
updatedCategory = categoryResp;
createCollection(updatedName);
})
.then(collectionResp => {
updatedCollection = collectionResp;
const productData = {
generalInfo: {
name: updatedName,
description: faker.lorem.sentence(),
rating: 3
},
seo: {
slug: updatedName,
title: "newTitle",
description: "New description."
},
metadata: {
private: {
metadataForm: metadataForms.private,
name: "newPrivate",
value: "value1"
},
public: {
metadataForm: metadataForms.public,
name: "newPublic",
value: "value2"
}
},
productOrganization: {
category: updatedCategory.name,
collection: updatedCollection.name
}
};
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.product)
.visit(productDetailsUrl(product.id))
.get(PRODUCT_DETAILS.collectionRemoveButtons)
.click();
fillUpCommonFieldsForAllProductTypes(productData, false);
cy.addAliasToGraphRequest("UpdatePrivateMetadata");
cy.addAliasToGraphRequest("UpdateMetadata");
cy.addAliasToGraphRequest("ProductUpdate");
cy.get(BUTTON_SELECTORS.confirm).click();
cy.get(SHARED_ELEMENTS.confirmationMsg)
.should("be.visible")
.then(() => {
cy.wait("@ProductUpdate");
cy.wait("@UpdateMetadata");
cy.wait("@UpdatePrivateMetadata");
productData.productOrganization.productType = name;
productData.attribute = attribute;
cy.loginUserViaRequest("token");
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug, "auth").its(
"body.data.product"
);
})
.then(resp => {
expectCorrectProductInformation(resp, productData);
});
});
});
it("should delete product", () => {
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.product)
.visit(productDetailsUrl(product.id))
.addAliasToGraphRequest("ProductDelete")
.get(BUTTON_SELECTORS.deleteButton)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.wait("@ProductDelete")
.loginUserViaRequest("token")
.then(() => {
getProductDetails(product.id, defaultChannel.slug).its("body.data");
})
.then(
productResp =>
expect(productResp.product, "Check if product exist").to.be.null
);
});
});

110
cypress/integration/apps.js Normal file
View file

@ -0,0 +1,110 @@
import faker from "faker";
import { createApp, getApp } from "../apiRequests/Apps";
import { ONE_PERMISSION_USERS } from "../Data/users";
import { APP_DETAILS } from "../elements/apps/appDetails";
import { APPS_LIST } from "../elements/apps/appsList";
import { WEBHOOK_DETAILS } from "../elements/apps/webhookDetails";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import { confirmationMessageShouldDisappear } from "../steps/shared/confirmationMessage";
import filterTests from "../support/filterTests";
import { appDetailsUrl, urlList } from "../url/urlList";
import { deleteAppsStartsWith } from "../utils/appUtils";
filterTests(["all"], () => {
describe("Tests for apps", () => {
const startsWith = "Apps";
const name = `${startsWith}${faker.datatype.number()}`;
let createdApp;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAppsStartsWith(startsWith);
createApp(name, "MANAGE_APPS").then(app => {
createdApp = app;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.app
);
});
it("should create app", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.apps)
.get(APPS_LIST.createLocalAppButton)
.click()
.get(APP_DETAILS.nameInput)
.type(randomName)
.get(APP_DETAILS.manageAppsPermissionCheckbox)
.click()
.addAliasToGraphRequest("AppCreate")
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.wait("@AppCreate")
.its("response.body.data.appCreate.app")
.then(app => {
getApp(app.id);
})
.then(app => {
expect(app.name).to.eq(randomName);
const token = app.tokens.find(element => element.name === "Default");
expect(token).to.be.ok;
});
});
it("should create webhook", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
const targetUrl = `http://example.${randomName}`;
cy.visit(appDetailsUrl(createdApp.id))
.get(APP_DETAILS.createWebhookButton)
.click()
.get(WEBHOOK_DETAILS.nameInput)
.type(randomName)
.get(WEBHOOK_DETAILS.targetUrlInput)
.type(targetUrl)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getApp(createdApp.id).then(({ webhooks }) => {
expect(webhooks[0].name).to.eq(randomName);
expect(webhooks[0].targetUrl).to.eq(targetUrl);
});
});
it("should create token", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
let expectedToken;
cy.visit(appDetailsUrl(createdApp.id))
.get(APP_DETAILS.createTokenButton)
.click()
.get(APP_DETAILS.createTokenForm.tokenDialog)
.find(APP_DETAILS.createTokenForm.nameInput)
.type(randomName)
.get(BUTTON_SELECTORS.submit)
.click()
.get(APP_DETAILS.createTokenForm.tokenToCopy)
.invoke("text")
.then(text => {
expectedToken = text;
cy.get(APP_DETAILS.createTokenForm.doneButton).click();
getApp(createdApp.id);
})
.then(app => {
const token = app.tokens.find(element => element.name === randomName);
const tokenLastFourDigits = expectedToken.slice(
expectedToken.length - 4
);
expect(token.authToken).to.eq(tokenLastFourDigits);
});
});
});
});

View file

@ -0,0 +1,139 @@
// <reference types="cypress" />
import faker from "faker";
import { getCategory } from "../apiRequests/Category";
import { CATEGORIES_LIST } from "../elements/catalog/categories/categories-list";
import { CATEGORY_DETAILS } from "../elements/catalog/categories/category-details";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../elements/shared/sharedElements";
import { createCategory } from "../steps/categoriesSteps";
import { confirmationMessageShouldDisappear } from "../steps/shared/confirmationMessages";
import filterTests from "../support/filterTests";
import { categoryDetails, urlList } from "../url/urlList";
import { deleteCategoriesStartsWith } from "../utils/categoryUtils";
import * as channelsUtils from "../utils/channelsUtils";
import * as productsUtils from "../utils/products/productsUtils";
import { deleteShippingStartsWith } from "../utils/shippingUtils";
filterTests(["all"], () => {
describe("Categories", () => {
const startsWith = "CyCollections";
const name = `${startsWith}${faker.datatype.number()}`;
let attribute;
let category;
let productType;
let product;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
deleteCategoriesStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
channelsUtils.deleteChannelsStartsWith(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createTypeAttributeAndCategoryForProduct(name);
})
.then(
({
category: categoryResp,
attribute: attributeResp,
productType: productTypeResp
}) => {
category = categoryResp;
attribute = attributeResp;
productType = productTypeResp;
productsUtils.createProductInChannel({
name,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
}
)
.then(({ product: productResp }) => (product = productResp));
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create category", () => {
const categoryName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.categories)
.get(CATEGORIES_LIST.addCategoryButton)
.click();
createCategory({ name: categoryName, description: categoryName })
.its("response.body.data.categoryCreate.category")
.then(newCategory => {
getCategory(newCategory.id);
})
.then(newCategory => {
expect(newCategory.name).to.eq(categoryName);
// Uncomment this expect after fixing bug SALEOR-3728
// expect(newCategory.description).to.eq(categoryName);
});
});
it("should add subcategory", () => {
const categoryName = `${startsWith}${faker.datatype.number()}`;
cy.visit(categoryDetails(category.id))
.get(CATEGORY_DETAILS.createSubcategoryButton)
.click();
createCategory({ name: categoryName, description: categoryName })
.visit(categoryDetails(category.id))
.contains(CATEGORY_DETAILS.categoryChildrenRow, categoryName)
.should("be.visible");
getCategory(category.id).then(categoryResp => {
expect(categoryResp.children.edges[0].node.name).to.eq(categoryName);
});
});
it("should add product to category", () => {
cy.visit(categoryDetails(category.id))
.get(CATEGORY_DETAILS.productsTab)
.click()
.get(CATEGORY_DETAILS.addProducts)
.click()
.url()
.should("include", urlList.addProduct);
});
it("should remove product from category", () => {
cy.visit(categoryDetails(category.id))
.get(CATEGORY_DETAILS.productsTab)
.click();
cy.contains(CATEGORY_DETAILS.productRow, product.name)
.find(BUTTON_SELECTORS.checkbox)
.click()
.get(BUTTON_SELECTORS.deleteIcon)
.click()
.addAliasToGraphRequest("productBulkDelete")
.get(BUTTON_SELECTORS.submit)
.click();
confirmationMessageShouldDisappear();
cy.contains(CATEGORY_DETAILS.productRow, product.name)
.should("not.exist")
.wait("@productBulkDelete");
getCategory(category.id).then(categoryResp => {
expect(categoryResp.products).to.be.null;
});
});
it("should enter category details page", () => {
cy.visit(urlList.categories)
.get(SHARED_ELEMENTS.searchInput)
.type(category.name);
cy.contains(SHARED_ELEMENTS.tableRow, category.name).click();
cy.contains(SHARED_ELEMENTS.header, category.name).should("be.visible");
});
});
});

View file

@ -0,0 +1,124 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import {
addProductsToCheckout,
addShippingMethod,
createCheckout
} from "../../apiRequests/Checkout";
import filterTests from "../../support/filterTests";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Products without shipment option", () => {
const startsWith = "WithoutShipmentCheckout-";
const name = `${startsWith}${faker.datatype.number()}`;
const nameProdWithoutShipping = `${startsWith}${faker.datatype.number()}`;
let channel;
let address;
let warehouse;
let shippingMethod;
let productWithShipping;
let productWithoutShipping;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
createChannel({
name
})
.then(channelResp => {
channel = channelResp;
cy.fixture("addresses");
})
.then(({ usAddress }) => {
address = usAddress;
createShipping({
channelId: channel.id,
name,
address,
minProductPrice: 100
});
})
.then(
({
warehouse: warehouseResp,
shippingMethod: shippingMethodResp
}) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
createTypeAttributeAndCategoryForProduct(name);
}
)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
createProductInChannel({
attributeId: attributeResp.id,
categoryId: categoryResp.id,
channelId: channel.id,
name,
productTypeId: productTypeResp.id,
warehouseId: warehouse.id
}).then(({ variantsList }) => (productWithShipping = variantsList));
createProductInChannel({
attributeId: attributeResp.id,
categoryId: categoryResp.id,
channelId: channel.id,
name: nameProdWithoutShipping,
productTypeId: productTypeResp.id,
warehouseId: warehouse.id
}).then(
({ variantsList }) => (productWithoutShipping = variantsList)
);
}
);
});
it("should be not possible to buy product without shipping option", () => {
createCheckout({
channelSlug: channel.slug,
email: "example@example.com",
variantsList: productWithoutShipping,
address,
auth: "token"
})
.then(({ checkout }) => {
expect(
checkout.availableShippingMethods,
"expect no available shipping"
).to.have.length(0);
addProductsToCheckout(checkout.id, productWithShipping, 1);
})
.then(({ checkout }) => {
expect(
checkout.availableShippingMethods,
"expect no available shipping"
).to.have.length(0);
addShippingMethod(checkout.id, shippingMethod.id);
})
.then(({ errors }) => {
expect(errors[0].field, "expect error in shipping method").to.be.eq(
"shippingMethod"
);
});
});
});
});

View file

@ -0,0 +1,240 @@
import faker from "faker";
import { createAttribute } from "../../apiRequests/Attribute";
import { createCategory } from "../../apiRequests/Category";
import {
checkoutShippingAddressUpdate,
checkoutShippingMethodUpdate,
checkoutVariantsUpdate,
completeCheckout,
createCheckout
} from "../../apiRequests/Checkout";
import { getOrder } from "../../apiRequests/Order";
import { createTypeProduct } from "../../apiRequests/productType";
import filterTests from "../../support/filterTests";
import { getDefaultChannel } from "../../utils/channelsUtils";
import {
addPayment,
createAndCompleteCheckoutWithoutShipping,
createWaitingForCaptureOrder
} from "../../utils/ordersUtils";
import {
createProductInChannel,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all", "critical"], () => {
describe("Purchase products with all products types", () => {
const startsWith = `CyPurchaseByType`;
const name = `${startsWith}${faker.datatype.number()}`;
const email = `${startsWith}@example.com`;
const testsMessage = "Check order status";
const { softExpect } = chai;
let defaultChannel;
let address;
let warehouse;
let attribute;
let category;
let shippingMethod;
let createProductData;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
getDefaultChannel().then(channelResp => (defaultChannel = channelResp));
cy.fixture("addresses")
.then(addresses => {
address = addresses.usAddress;
createShipping({
channelId: defaultChannel.id,
name,
address,
price: 10
});
})
.then(
({
warehouse: warehouseResp,
shippingMethod: shippingMethodResp
}) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
}
);
createAttribute({ name })
.then(attributeResp => {
attribute = attributeResp;
createCategory(name);
})
.then(categoryResp => {
category = categoryResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
createProductData = {
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 10,
attributeId: attribute.id,
categoryId: category.id,
price: 10
};
});
it("should purchase digital product", () => {
const digitalName = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({
name: digitalName,
attributeId: attribute.id,
shippable: false
})
.then(productType => {
createProductData.name = digitalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
createAndCompleteCheckoutWithoutShipping({
channelSlug: defaultChannel.slug,
email,
billingAddress: address,
variantsList,
auth: "token"
});
})
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
softExpect(
order.isShippingRequired,
"Check if is shipping required in order"
).to.eq(false);
expect(order.status, testsMessage).to.be.eq("UNFULFILLED");
});
});
it("should purchase physical product", () => {
const physicalName = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({
name: physicalName,
attributeId: attribute.id,
shippable: true
})
.then(productType => {
createProductData.name = physicalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
createWaitingForCaptureOrder({
channelSlug: defaultChannel.slug,
email,
variantsList,
shippingMethodId: shippingMethod.id,
address
});
})
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
softExpect(
order.isShippingRequired,
"Check if is shipping required in order"
).to.eq(true);
expect(order.status, testsMessage).to.be.eq("UNFULFILLED");
});
});
it("should purchase multiple products with all product types", () => {
const physicalName = `${startsWith}${faker.datatype.number()}`;
const digitalName = `${startsWith}${faker.datatype.number()}`;
let digitalProductVariantsList;
let checkout;
createTypeProduct({
name: digitalName,
attributeId: attribute.id,
shippable: false
})
.then(productType => {
createProductData.name = digitalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
digitalProductVariantsList = variantsList;
createCheckout({
channelSlug: defaultChannel.slug,
email,
variantsList: digitalProductVariantsList,
billingAddress: address,
auth: "token"
});
})
.then(({ checkout: checkoutResp }) => {
checkout = checkoutResp;
addPayment(checkout.id);
})
.then(() => {
createTypeProduct({
name: physicalName,
attributeId: attribute.id,
shippable: true
});
})
.then(productType => {
createProductData.name = physicalName;
createProductData.productTypeId = productType.id;
createProductInChannel(createProductData);
})
.then(({ variantsList }) => {
checkoutVariantsUpdate(checkout.id, variantsList);
})
.then(() => {
checkoutShippingMethodUpdate(checkout.id, shippingMethod.id);
})
.then(({ checkoutErrors }) => {
expect(
checkoutErrors,
"Should be not possible to add shipping method without shipping address"
).to.have.lengthOf(1);
checkoutShippingAddressUpdate(checkout.id, address);
})
.then(() => {
addPayment(checkout.id);
})
.then(({ paymentErrors }) => {
expect(
paymentErrors,
"Should be not possible to add payment without shipping"
).to.have.lengthOf(1);
checkoutShippingMethodUpdate(checkout.id, shippingMethod.id);
})
.then(() => {
addPayment(checkout.id);
})
.then(() => {
completeCheckout(checkout.id);
})
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
softExpect(
order.isShippingRequired,
"Check if is shipping required in order"
).to.eq(true);
expect(order.status, testsMessage).to.be.eq("UNFULFILLED");
});
});
});
});

View file

@ -0,0 +1,168 @@
import faker from "faker";
import {
addProductsToCheckout,
createCheckout
} from "../../apiRequests/Checkout";
import { getVariants } from "../../apiRequests/Product";
import filterTests from "../../support/filterTests";
import { getDefaultChannel } from "../../utils/channelsUtils";
import { createOrderWithNewProduct } from "../../utils/ordersUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all", "critical"], () => {
describe("Products stocks in checkout", () => {
const startsWith = "CyStocksCheckout-";
const name = `${startsWith}${faker.datatype.number()}`;
let defaultChannel;
let address;
let warehouse;
let attribute;
let category;
let productType;
let shippingMethod;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
cy.fixture("addresses")
.then(addresses => {
address = addresses.usAddress;
getDefaultChannel();
})
.then(channel => {
defaultChannel = channel;
createShipping({
channelId: defaultChannel.id,
name,
address
});
})
.then(
({
warehouse: warehouseResp,
shippingMethod: shippingMethodResp
}) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
createTypeAttributeAndCategoryForProduct(name);
}
)
.then(
({
attribute: attributeResp,
category: categoryResp,
productType: productTypeResp
}) => {
attribute = attributeResp;
category = categoryResp;
productType = productTypeResp;
}
);
});
it("should create checkout with last product in stock", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
createOrderWithNewProduct({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channel: defaultChannel,
name: productName,
warehouseId: warehouse.id,
shippingMethodId: shippingMethod.id,
address
}).then(({ order }) => {
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;
createProductInChannel({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channelId: defaultChannel.id,
name: productName,
warehouseId: warehouse.id,
quantityInWarehouse: 1
})
.then(({ variantsList }) => {
variants = variantsList;
createCheckout({
channelSlug: defaultChannel.slug,
address,
billingAddress: address,
email: "email@example.com",
variantsList,
auth: "token"
});
})
.then(({ checkout: checkout }) => {
addProductsToCheckout(checkout.id, variants, 2);
})
.then(({ errors }) => {
expect(
errors[0],
"should return error on field quantity"
).to.have.property("field", "quantity");
});
});
it("should buy product with no quantity if tracking is not set", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
createOrderWithNewProduct({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channel: defaultChannel,
name: productName,
warehouseId: warehouse.id,
quantityInWarehouse: 0,
trackInventory: false,
shippingMethodId: shippingMethod.id,
address
}).then(({ order }) => {
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);
});
});
});
});

View file

@ -0,0 +1,71 @@
import faker from "faker";
import { createCheckout } from "../../apiRequests/Checkout";
import filterTests from "../../support/filterTests";
import { getDefaultChannel } from "../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Warehouses in checkout", () => {
const startsWith = `CyWarehouseCheckout`;
let defaultChannel;
let usAddress;
let plAddress;
let warehouse;
it("should not be possible to buy product for country not listed in warehouse", () => {
cy.clearSessionData().loginUserViaRequest();
deleteShippingStartsWith(startsWith);
deleteProductsStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
cy.fixture("addresses")
.then(addresses => {
usAddress = addresses.usAddress;
plAddress = addresses.plAddress;
getDefaultChannel();
})
.then(channelResp => {
defaultChannel = channelResp;
createShipping({
channelId: defaultChannel.id,
name,
address: usAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
createTypeAttributeAndCategoryForProduct(name);
})
.then(({ attribute, productType, category }) => {
createProductInChannel({
name,
attributeId: attribute.id,
categoryId: category.id,
channelId: defaultChannel.id,
productTypeId: productType.id,
warehouseId: warehouse.id,
quantityInWarehouse: 100
});
})
.then(({ variantsList }) => {
createCheckout({
channelSlug: defaultChannel.slug,
email: "example@example.com",
variantsList,
address: plAddress
});
})
.then(({ errors }) => {
expect(errors[0]).to.have.property("field", "quantity");
});
});
});
});

View file

@ -0,0 +1,184 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../apiRequests/Channels";
import { updateChannelInProduct } from "../apiRequests/Product";
import { getCollection } from "../apiRequests/storeFront/Collections";
import { searchInShop } from "../apiRequests/storeFront/Search";
import {
assignProductsToCollection,
createCollection
} from "../steps/collectionsSteps";
import filterTests from "../support/filterTests";
import { urlList } from "../url/urlList";
import * as channelsUtils from "../utils/channelsUtils";
import { deleteCollectionsStartsWith } from "../utils/collectionsUtils";
import * as productsUtils from "../utils/products/productsUtils";
import { deleteShippingStartsWith } from "../utils/shippingUtils";
import {
isCollectionVisible,
isProductInCollectionVisible
} from "../utils/storeFront/collectionsUtils";
import { isProductVisibleInSearchResult } from "../utils/storeFront/storeFrontProductUtils";
filterTests(["all"], () => {
describe("Collections", () => {
const startsWith = "CyCollections-";
const name = `${startsWith}${faker.datatype.number()}`;
let attribute;
let productType;
let category;
let product;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
deleteCollectionsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
channelsUtils.deleteChannelsStartsWith(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createTypeAttributeAndCategoryForProduct(name);
})
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
attribute = attributeResp;
productType = productTypeResp;
category = categoryResp;
productsUtils.createProductInChannel({
name,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
}
)
.then(({ product: productResp }) => (product = productResp));
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should not display hidden collections", () => {
const collectionName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
let collection;
createCollection(collectionName, false, defaultChannel)
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(name);
})
.then(() => {
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isCollectionVisible(resp, collection.id);
expect(isVisible).to.equal(false);
});
});
it("should display collections", () => {
const collectionName = `${startsWith}${faker.datatype.number()}`;
let collection;
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
createCollection(collectionName, true, defaultChannel)
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(name);
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isCollectionVisible(resp, collection.id);
expect(isVisible).to.equal(true);
});
});
it("should not display collection not set as available in channel", () => {
const collectionName = `${startsWith}${faker.datatype.number()}`;
let collection;
let channel;
createChannel({ name: collectionName })
.then(channelResp => {
channel = channelResp;
updateChannelInProduct(product.id, channel.id);
})
.then(() => {
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
createCollection(collectionName, true, channel);
})
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(name);
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isCollectionVisible(resp, collection.id);
expect(isVisible).to.equal(false);
});
});
it("should display products hidden in listing", () => {
// Products "hidden in listings" are not displayed in Category listings or search results,
// but are listed on Collections
const randomName = `${startsWith}${faker.datatype.number()}`;
let collection;
let createdProduct;
productsUtils
.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: false
})
.then(({ product: productResp }) => (createdProduct = productResp));
cy.visit(urlList.collections);
cy.softExpectSkeletonIsVisible();
createCollection(randomName, true, defaultChannel)
.then(collectionResp => {
collection = collectionResp;
assignProductsToCollection(randomName);
})
.then(() => {
getCollection(collection.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductInCollectionVisible(
resp,
createdProduct.id
);
expect(isVisible).to.equal(true);
})
.then(() => {
searchInShop(createdProduct.name);
})
.then(resp => {
const isVisible = isProductVisibleInSearchResult(
resp,
createdProduct.name
);
expect(isVisible).to.equal(false);
});
});
});
});

View file

@ -0,0 +1,123 @@
// <reference types="cypress" />
import faker from "faker";
import { getAttribute } from "../../../apiRequests/Attribute";
import { ATTRIBUTES_LIST } from "../../../elements/attribute/attributes_list";
import { createAttributeWithInputType } from "../../../steps/attributesSteps";
import filterTests from "../../../support/filterTests";
import { urlList } from "../../../url/urlList";
import { deleteAttributesStartsWith } from "../../../utils/attributes/attributeUtils";
import { expectCorrectDataInAttribute } from "../../../utils/attributes/checkAttributeData";
filterTests(["all"], () => {
describe("Create attribute with type", () => {
const startsWith = "AttrCreate";
const attributesTypes = [
"DROPDOWN",
"MULTISELECT",
"FILE",
"RICH_TEXT",
"BOOLEAN"
];
const attributeReferenceType = ["PRODUCT", "PAGE"];
const attributeNumericType = [
{ unitSystem: "IMPERIAL", unitsOf: "DISTANCE", unit: "FT" },
{ unitSystem: "METRIC", unitsOf: "VOLUME", unit: "CUBIC_CENTIMETER" },
{ unitSystem: "without selecting unit" }
];
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAttributesStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.attributes)
.get(ATTRIBUTES_LIST.createAttributeButton)
.click();
});
attributesTypes.forEach(attributeType => {
it(`should create ${attributeType} attribute`, () => {
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({ name: attributeName, attributeType })
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType
});
});
});
});
attributeReferenceType.forEach(entityType => {
it(`should create reference ${entityType} attribute`, () => {
const attributeType = "REFERENCE";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
entityType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
entityType
});
});
});
});
attributeNumericType.forEach(numericSystemType => {
it(`should create numeric attribute - ${numericSystemType.unitSystem}`, () => {
const attributeType = "NUMERIC";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
numericSystemType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
unit: numericSystemType.unit
});
});
});
});
it("should create attribute without required value", () => {
const attributeType = "BOOLEAN";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
valueRequired: false
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
valueRequired: false
});
});
});
});
});

View file

@ -0,0 +1,123 @@
import faker from "faker";
import { getAttribute } from "../../../apiRequests/Attribute";
import { ATTRIBUTES_DETAILS } from "../../../elements/attribute/attributes_details";
import { ATTRIBUTES_LIST } from "../../../elements/attribute/attributes_list";
import { createAttributeWithInputType } from "../../../steps/attributesSteps";
import filterTests from "../../../support/filterTests";
import { urlList } from "../../../url/urlList";
import { deleteAttributesStartsWith } from "../../../utils/attributes/attributeUtils";
import { expectCorrectDataInAttribute } from "../../../utils/attributes/checkAttributeData";
filterTests(["all"], () => {
describe("Create content attribute", () => {
const startsWith = "AttrCont";
const attributesTypes = [
"DROPDOWN",
"MULTISELECT",
"FILE",
"RICH_TEXT",
"BOOLEAN"
];
const attributeReferenceType = ["PRODUCT", "PAGE"];
const attributeNumericType = [
{ unitSystem: "IMPERIAL", unitsOf: "DISTANCE", unit: "FT" },
{ unitSystem: "METRIC", unitsOf: "VOLUME", unit: "CUBIC_CENTIMETER" },
{ unitSystem: "without selecting unit" }
];
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteAttributesStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.attributes)
.get(ATTRIBUTES_LIST.createAttributeButton)
.click()
.get(ATTRIBUTES_DETAILS.pageTypeAttributeCheckbox)
.click();
});
attributesTypes.forEach(attributeType => {
it(`should create ${attributeType} attribute`, () => {
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({ name: attributeName, attributeType })
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType
});
});
});
});
attributeReferenceType.forEach(entityType => {
it(`should create reference ${entityType} attribute`, () => {
const attributeType = "REFERENCE";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
entityType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
entityType
});
});
});
});
attributeNumericType.forEach(numericSystemType => {
it(`should create numeric attribute - ${numericSystemType.unitSystem}`, () => {
const attributeType = "NUMERIC";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
numericSystemType
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
unit: numericSystemType.unit
});
});
});
});
it("should create attribute without required value", () => {
const attributeType = "BOOLEAN";
const attributeName = `${startsWith}${faker.datatype.number()}`;
createAttributeWithInputType({
name: attributeName,
attributeType,
valueRequired: false
})
.then(({ attribute }) => {
getAttribute(attribute.id);
})
.then(attribute => {
expectCorrectDataInAttribute(attribute, {
attributeName,
attributeType,
valueRequired: false
});
});
});
});
});

View file

@ -0,0 +1,163 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import {
createShippingZone,
getShippingZone
} from "../../apiRequests/ShippingMethod";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import { PRODUCTS_LIST } from "../../elements/catalog/products/products-list";
import { ADD_CHANNEL_FORM_SELECTORS } from "../../elements/channels/add-channel-form-selectors";
import { AVAILABLE_CHANNELS_FORM } from "../../elements/channels/available-channels-form";
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 { createChannelByView } from "../../steps/channelsSteps";
import { waitForProgressBarToNotExist } from "../../steps/shared/progressBar";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import { deleteChannelsStartsWith } from "../../utils/channelsUtils";
import { deleteShippingStartsWith } from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Channels", () => {
const channelStartsWith = `CyChannels`;
const randomName = `${channelStartsWith} ${faker.datatype.number()}`;
const currency = "PLN";
let shippingZone;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteChannelsStartsWith(channelStartsWith);
deleteShippingStartsWith(channelStartsWith);
createShippingZone(randomName, "US").then(shippingZoneResp => {
shippingZone = shippingZoneResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.channel
);
});
it("should create new channel", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
cy.wait("@Channels");
createChannelByView({ name: randomChannel, currency });
cy.wait("@Channel");
// New channel should be visible in channels list
cy.get(ADD_CHANNEL_FORM_SELECTORS.backToChannelsList)
.click()
.get(CHANNELS_SELECTORS.channelsTable)
.contains(randomChannel);
// new channel should be visible in channel selector
cy.visit(urlList.homePage)
.get(HEADER_SELECTORS.channelSelect)
.click()
.get(HEADER_SELECTORS.channelSelectList)
.contains(randomChannel)
.click();
// new channel should be visible at product availability form
cy.clearSessionData().loginUserViaRequest();
cy.addAliasToGraphRequest("InitialProductFilterAttributes");
cy.visit(urlList.products);
cy.wait("@InitialProductFilterAttributes");
waitForProgressBarToNotExist();
cy.get(PRODUCTS_LIST.emptyProductRow).should("not.exist");
cy.get(PRODUCTS_LIST.productsList)
.first()
.click()
.get(AVAILABLE_CHANNELS_FORM.menageChannelsButton)
.click()
.get(SELECT_CHANNELS_TO_ASSIGN.listOfChannels)
.contains(randomChannel);
});
it("should create channel with shippingZone", () => {
// remove login after fixing SALEOR-3162
cy.clearSessionData().loginUserViaRequest();
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
cy.wait("@Channels");
createChannelByView({
name: randomChannel,
currency,
shippingZone: shippingZone.name
});
cy.wait("@Channel");
getShippingZone(shippingZone.id).then(shippingZoneResp => {
const assignedChannel = shippingZoneResp.channels.find(
channel => channel.name === randomChannel
);
expect(assignedChannel).to.be.ok;
});
});
it("should validate slug name", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
createChannel({
isActive: false,
name: randomChannel,
slug: randomChannel,
currencyCode: currency
});
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
createChannelByView({ name: randomChannel, currency });
cy.get(ADD_CHANNEL_FORM_SELECTORS.slugValidationMessage).should(
"be.visible"
);
});
it("should validate duplicated currency", () => {
const randomChannel = `${channelStartsWith} ${faker.datatype.number()}`;
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
createChannelByView({
name: randomChannel,
currency: "notExistingCurrency"
});
cy.get(ADD_CHANNEL_FORM_SELECTORS.currencyValidationMessage).should(
"be.visible"
);
});
it("should delete channel", () => {
const randomChannelToDelete = `${channelStartsWith} ${faker.datatype.number()}`;
createChannel({
isActive: false,
name: randomChannelToDelete,
slug: randomChannelToDelete,
currencyCode: currency
});
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.softExpectSkeletonIsVisible();
cy.wait("@Channels");
cy.contains(CHANNELS_SELECTORS.channelName, randomChannelToDelete)
.parentsUntil(CHANNELS_SELECTORS.channelsTable)
.find("button")
.click();
cy.addAliasToGraphRequest("Channels");
cy.get(BUTTON_SELECTORS.submit).click();
cy.wait("@Channels");
cy.get(CHANNELS_SELECTORS.channelName)
.contains(randomChannelToDelete)
.should("not.exist");
});
});
});

View file

@ -0,0 +1,66 @@
import faker from "faker";
import { getCustomer } from "../../apiRequests/Customer";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import { CUSTOMER_DETAILS } from "../../elements/customer/customer-details";
import { CUSTOMERS_LIST } from "../../elements/customer/customers-list";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { fillUpAddressForm } from "../../steps/shared/addressForm";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
filterTests(["all"], () => {
describe("Tests for customer", () => {
const channelStartsWith = `Customers`;
it("should create customer", () => {
const randomName = `${channelStartsWith}${faker.datatype.number()}`;
const email = `${randomName}@example.com`;
const note = faker.lorem.paragraph();
let address;
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.user)
.visit(urlList.customers)
.get(CUSTOMERS_LIST.createCustomerButton)
.click()
.get(SHARED_ELEMENTS.progressBar)
.should("not.be.visible")
.get(CUSTOMER_DETAILS.nameInput)
.type(randomName)
.get(CUSTOMER_DETAILS.lastNameInput)
.type(randomName)
.get(CUSTOMER_DETAILS.emailInput)
.type(email)
.fixture("addresses")
.then(({ usAddress }) => {
address = usAddress;
fillUpAddressForm(address);
})
.get(CUSTOMER_DETAILS.noteInput)
.type(note)
.addAliasToGraphRequest("CreateCustomer")
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.wait("@CreateCustomer")
.its("response.body.data.customerCreate.user")
.then(customer => {
getCustomer(customer.id);
})
.then(customer => {
chai
.softExpect(customer.firstName, "Expect correct first name")
.to.eq(randomName);
chai
.softExpect(customer.lastName, "Expect correct last name")
.to.eq(randomName);
chai.softExpect(customer.email, "Expect correct email").to.eq(email);
chai.softExpect(customer.note, "Expect correct note").to.eq(note);
cy.expectCorrectFullAddress(customer.addresses[0], address);
});
});
});
});

View file

@ -0,0 +1,151 @@
// <reference types="cypress" />
import faker from "faker";
import { activateChannel, createChannel } from "../../apiRequests/Channels";
import { createCheckout } from "../../apiRequests/Checkout";
import { getProductDetails } from "../../apiRequests/storeFront/ProductDetails";
import { CHANNEL_FORM_SELECTORS } from "../../elements/channels/channel-form-selectors";
import { DRAFT_ORDER_SELECTORS } from "../../elements/orders/draft-order-selectors";
import { ORDERS_SELECTORS } from "../../elements/orders/orders-selectors";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import {
deleteChannelsStartsWith,
getDefaultChannel
} from "../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
import { isProductVisible } from "../../utils/storeFront/storeFrontProductUtils";
filterTests(["all"], () => {
describe("Tests on inactive channel", () => {
const channelStartsWith = `InactiveChannel`;
const randomName = `${channelStartsWith}${faker.datatype.number()}`;
const currency = "PLN";
let address;
let defaultChannel;
let newChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteChannelsStartsWith(channelStartsWith);
deleteProductsStartsWith(channelStartsWith);
cy.fixture("addresses").then(({ plAddress }) => {
address = plAddress;
});
getDefaultChannel().then(channel => (defaultChannel = channel));
createChannel({
isActive: false,
name: randomName,
slug: randomName,
currencyCode: currency
}).then(channel => {
newChannel = channel;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should not be possible to add products to order with inactive channel", () => {
cy.visit(urlList.orders)
.get(ORDERS_SELECTORS.createOrder)
.click()
.get(CHANNEL_FORM_SELECTORS.channelSelect)
.click()
.get(CHANNEL_FORM_SELECTORS.channelOption)
.contains(newChannel.name)
.click()
.get(CHANNEL_FORM_SELECTORS.confirmButton)
.click();
cy.location()
.should(loc => {
const urlRegex = new RegExp(`${urlList.orders}.+`, "g");
expect(loc.pathname).to.match(urlRegex);
})
.get(DRAFT_ORDER_SELECTORS.addProducts)
.should("not.exist");
});
it("should not be possible to create checkout with inactive channel", () => {
const randomChannel = `${channelStartsWith}${faker.datatype.number()}`;
createTypeAttributeAndCategoryForProduct(randomChannel)
.then(({ productType, attribute, category }) => {
createProductInChannel({
name: randomChannel,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(({ variantsList }) => {
createCheckout({
channelSlug: newChannel.slug,
email: "example@example.com",
variantsList,
address
});
})
.then(({ errors }) => {
expect(
errors[0],
"checkout shouldn't be created with error in field channel"
).to.have.property("field", "channel");
});
});
it("products in inactive channel should not be displayed", () => {
const randomChannel = `${channelStartsWith}${faker.datatype.number()}`;
let channel;
let product;
createChannel({
isActive: false,
name: randomChannel,
slug: randomChannel,
currencyCode: currency
})
.then(channelResp => {
channel = channelResp;
createTypeAttributeAndCategoryForProduct(randomChannel);
})
.then(({ productType, attribute, category }) => {
createProductInChannel({
name: randomChannel,
channelId: channel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(({ product: productResp }) => {
product = productResp;
getProductDetails(product.id, channel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, randomChannel);
expect(
isVisible,
"product with inactive channel shouldn't be visible"
).to.be.eq(false);
activateChannel(channel.id);
})
.then(() => {
getProductDetails(product.id, channel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, randomChannel);
expect(
isVisible,
"product with active channel should be visible"
).to.be.eq(true);
});
});
});
});

View file

@ -0,0 +1,69 @@
import faker from "faker";
import {
createMenu as createMenuViaApi,
getMenu
} from "../../apiRequests/Menu";
import {
createMenu,
createNewMenuItem,
MENU_ITEM_TYPES
} from "../../steps/navigationSteps";
import filterTests from "../../support/filterTests";
import { deleteMenusStartsWith } from "../../utils/navigationUtils";
filterTests(["all"], () => {
describe("Tests for menu navigation", () => {
const startsWith = "Navigation";
const randomName = `${startsWith}${faker.datatype.number()}`;
let menu;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteMenusStartsWith(startsWith);
createMenuViaApi(randomName).then(
({ menu: menuResp }) => (menu = menuResp)
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create a menu", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createMenu(name)
.then(menuResp => {
getMenu(menuResp.id);
})
.then(menuResp => {
expect(menuResp.name).to.eq(name);
});
});
["category", "collection", "page"].forEach(itemType => {
it(`should add new ${itemType} item to menu`, () => {
const itemName = `${startsWith}${faker.datatype.number()}`;
let selectedItem;
createNewMenuItem({
menuId: menu.id,
name: itemName,
menuItemType: MENU_ITEM_TYPES[itemType]
})
.then(selectedItemResp => {
selectedItem = selectedItemResp;
getMenu(menu.id);
})
.then(({ items }) => {
const item = items.find(element => element.name === itemName);
const itemOfType = item[itemType];
const name = itemType !== "page" ? "name" : "title";
expect(itemOfType[name]).to.eq(selectedItem);
});
});
});
});
});

View file

@ -0,0 +1,151 @@
import faker from "faker";
import {
createPermissionGroup,
getPermissionGroup
} from "../../apiRequests/PermissionGroup.js";
import { getStaffMembersStartsWith } from "../../apiRequests/StaffMembers";
import { TEST_ADMIN_USER } from "../../Data/users.js";
import { PERMISSION_GROUP_DETAILS } from "../../elements/permissionGroup/permissionGroupDetails";
import { PERMISSION_GROUP_LIST } from "../../elements/permissionGroup/permissionGroupsList";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { waitForProgressBarToNotExist } from "../../steps/shared/progressBar.js";
import filterTests from "../../support/filterTests.js";
import {
permissionGroupDetails,
staffMemberDetailsUrl,
urlList
} from "../../url/urlList";
import { deletePermissionGroupsStartsWith } from "../../utils/permissionGroupUtils.js";
filterTests(["all"], () => {
describe("Permissions groups", () => {
const startsWith = "CyPermissions-";
before(() => {
cy.clearSessionData().loginUserViaRequest();
deletePermissionGroupsStartsWith(startsWith);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.permissionsGroups)
.get(PERMISSION_GROUP_LIST.createPermissionButton)
.click()
.get(PERMISSION_GROUP_DETAILS.nameInput)
.type(permissionName)
.get(PERMISSION_GROUP_DETAILS.productsPermissionCheckbox)
.click()
.get(
PERMISSION_GROUP_DETAILS.productsTypesAndAttributesPermissionCheckbox
)
.click()
.get(BUTTON_SELECTORS.confirm)
.click()
.get(PERMISSION_GROUP_DETAILS.assignMemberButton)
.should("be.visible")
.get(BUTTON_SELECTORS.back)
.click();
waitForProgressBarToNotExist();
cy.contains(
PERMISSION_GROUP_LIST.permissionGroupRow,
permissionName
).should("be.visible");
});
it("should delete permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
let staffMember;
getStaffMembersStartsWith(TEST_ADMIN_USER.email)
.its("body.data.staffUsers.edges")
.then(staffMemberResp => {
staffMember = staffMemberResp[0].node;
createPermissionGroup({
name: permissionName,
userIdsArray: `["${staffMember.id}"]`,
permissionsArray: "[MANAGE_PRODUCTS]"
});
cy.visit(urlList.permissionsGroups);
cy.contains(PERMISSION_GROUP_LIST.permissionGroupRow, permissionName)
.should("be.visible")
.find(BUTTON_SELECTORS.deleteIcon)
.click()
.get(BUTTON_SELECTORS.submit)
.click();
cy.contains(PERMISSION_GROUP_LIST.permissionGroupRow, permissionName)
.should("not.exist")
.visit(staffMemberDetailsUrl(staffMember.id));
cy.get(SHARED_ELEMENTS.header).should("be.visible");
cy.contains(permissionName).should("not.exist");
});
});
it("should add user to permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
createPermissionGroup({
name: permissionName,
permissionsArray: "[MANAGE_PRODUCTS]"
})
.then(({ group }) => {
cy.visit(permissionGroupDetails(group.id))
.get(PERMISSION_GROUP_DETAILS.assignMemberButton)
.click()
.get(PERMISSION_GROUP_DETAILS.searchField)
.type(TEST_ADMIN_USER.email);
cy.contains(
PERMISSION_GROUP_DETAILS.userRow,
`${TEST_ADMIN_USER.name} ${TEST_ADMIN_USER.lastName}`
)
.should("have.length", 1)
.find(BUTTON_SELECTORS.checkbox)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.addAliasToGraphRequest("PermissionGroupUpdate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@PermissionGroupUpdate");
getPermissionGroup(group.id);
})
.then(resp => {
expect(resp.users).to.have.length(1);
expect(resp.users[0].email).to.be.eq(TEST_ADMIN_USER.email);
});
});
it("should remove user from permission group", () => {
const permissionName = `${startsWith}${faker.datatype.number()}`;
let staffMember;
getStaffMembersStartsWith(TEST_ADMIN_USER.email)
.its("body.data.staffUsers.edges")
.then(staffMemberResp => {
staffMember = staffMemberResp[0].node;
createPermissionGroup({
name: permissionName,
userIdsArray: `["${staffMember.id}"]`,
permissionsArray: "[MANAGE_PRODUCTS]"
});
})
.then(({ group }) => {
cy.visit(permissionGroupDetails(group.id))
.get(PERMISSION_GROUP_DETAILS.removeUserButton)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.addAliasToGraphRequest("PermissionGroupUpdate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@PermissionGroupUpdate");
cy.visit(staffMemberDetailsUrl(staffMember.id));
cy.get(SHARED_ELEMENTS.header).should("be.visible");
cy.contains(permissionName).should("not.exist");
});
});
});
});

View file

@ -0,0 +1,106 @@
import faker from "faker";
import { createAttribute } from "../../apiRequests/Attribute";
import {
createTypeProduct,
getProductType
} from "../../apiRequests/productType";
import { PRODUCT_TYPE_DETAILS } from "../../elements/productTypes/productTypeDetails";
import { createProductType } from "../../steps/productTypeSteps";
import { assignElements } from "../../steps/shared/assignElements";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import { visitAndWaitForProgressBarToDisappear } from "../../steps/shared/progressBar";
import filterTests from "../../support/filterTests";
import { productTypeDetailsUrl, urlList } from "../../url/urlList";
import { deleteProductsStartsWith } from "../../utils/products/productsUtils";
filterTests(["all"], () => {
describe("Tests for product types", () => {
const startsWith = "ProductType";
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
createAttribute({ name: startsWith });
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.productTypes)
.softExpectSkeletonIsVisible();
});
it("Create product type without shipping required", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createProductType(name, false)
.then(productType => {
getProductType(productType.id);
})
.then(productType => {
expect(productType.name).to.be.eq(name);
expect(productType.isShippingRequired).to.be.false;
});
});
it("Create product type with shipping required", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const shippingWeight = 10;
createProductType(name, shippingWeight)
.then(productType => {
getProductType(productType.id);
})
.then(productType => {
expect(productType.name).to.be.eq(name);
expect(productType.isShippingRequired).to.be.true;
expect(productType.weight.value).to.eq(shippingWeight);
});
});
it("Update product type with product attribute", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({ name })
.then(productType => {
visitAndWaitForProgressBarToDisappear(
productTypeDetailsUrl(productType.id)
)
.get(PRODUCT_TYPE_DETAILS.assignProductAttributeButton)
.click();
cy.addAliasToGraphRequest("AssignProductAttribute");
assignElements(startsWith, false);
confirmationMessageShouldDisappear();
cy.wait("@AssignProductAttribute");
getProductType(productType.id);
})
.then(productType => {
expect(productType.productAttributes[0].name).to.eq(startsWith);
});
});
it("Update product type with variant attribute", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createTypeProduct({ name, hasVariants: false })
.then(productType => {
visitAndWaitForProgressBarToDisappear(
productTypeDetailsUrl(productType.id)
)
.get(PRODUCT_TYPE_DETAILS.hasVariantsButton)
.click()
.get(PRODUCT_TYPE_DETAILS.assignVariantAttributeButton)
.click();
cy.addAliasToGraphRequest("AssignProductAttribute");
assignElements(startsWith, false);
confirmationMessageShouldDisappear();
cy.wait("@AssignProductAttribute");
getProductType(productType.id);
})
.then(productType => {
expect(productType.variantAttributes[0].name).to.eq(startsWith);
});
});
});
});

View file

@ -0,0 +1,129 @@
// <reference types="cypress" />
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 { waitForProgressBarToNotExist } from "../../../steps/shared/progressBar";
import filterTests from "../../../support/filterTests";
import { getFormattedCurrencyAmount } from "../../../support/format/formatCurrencyAmount";
import { urlList } from "../../../url/urlList";
import * as channelsUtils from "../../../utils/channelsUtils";
import * as shippingUtils from "../../../utils/shippingUtils";
filterTests(["all"], () => {
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");
waitForProgressBarToNotExist();
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);
});
});
});
});
});

View file

@ -0,0 +1,144 @@
// <reference types="cypress" />
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 filterTests from "../../../support/filterTests";
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";
filterTests(["all"], () => {
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).softExpectSkeletonIsVisible();
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).softExpectSkeletonIsVisible();
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;
});
});
});
});

View file

@ -0,0 +1,137 @@
// <reference types="cypress" />
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 filterTests from "../../../support/filterTests";
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";
filterTests(["all"], () => {
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)
);
}
});
});

View file

@ -0,0 +1,190 @@
// <reference types="cypress" />
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 filterTests from "../../../support/filterTests";
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";
filterTests(["all"], () => {
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);
});
});
});
});

View file

@ -0,0 +1,78 @@
import faker from "faker";
import { getShopInfo, updateShopAddress } from "../../apiRequests/shopSettings";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SITE_SETTINGS_DETAILS } from "../../elements/siteSettings/site-settings-details";
import { fillUpBasicAddress } from "../../steps/shared/addressForm";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
filterTests(["all"], () => {
describe("Tests for site settings", () => {
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
cy.fixture("addresses").then(({ usAddress, plAddress }) => {
address = usAddress;
updateShopAddress(plAddress);
});
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.siteSettings);
});
it("should change store name", () => {
const name = `Cypress-${faker.datatype.number()}`;
cy.get(SITE_SETTINGS_DETAILS.nameInput)
.clearAndType(name)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getShopInfo().then(shopInfo => {
expect(shopInfo.name).to.eq(name);
});
});
it("should change site url", () => {
const url = `http://cypress${faker.datatype.number()}.saleor.com`;
cy.get(SITE_SETTINGS_DETAILS.urlInput)
.clearAndType(url)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getShopInfo().then(shopInfo => {
expect(shopInfo.domain.host).to.eq(url);
});
});
it("should change store description", () => {
const description = faker.lorem.sentence();
cy.get(SITE_SETTINGS_DETAILS.descriptionInput)
.clearAndType(description)
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
getShopInfo().then(shopInfo => {
expect(shopInfo.description).to.eq(description);
});
});
it("should change store address", () => {
fillUpBasicAddress(address);
cy.get(BUTTON_SELECTORS.confirm).click();
confirmationMessageShouldDisappear();
getShopInfo().then(({ companyAddress }) => {
expect(companyAddress.companyName).to.eq(address.companyName);
cy.expectCorrectBasicAddress(companyAddress, address);
});
});
});
});

View file

@ -0,0 +1,115 @@
// <reference types="cypress" />
import faker from "faker";
import { createShippingZone } from "../../apiRequests/ShippingMethod";
import { createWarehouse, getWarehouse } from "../../apiRequests/Warehouse";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHIPPING_ZONE_DETAILS } from "../../elements/shipping/shipping-zone-details";
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/selects";
import filterTests from "../../support/filterTests";
import {
shippingZoneDetailsUrl,
urlList,
warehouseDetailsUrl
} from "../../url/urlList";
import { getDefaultChannel } from "../../utils/channelsUtils";
import { deleteShippingStartsWith } from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Warehouse settings", () => {
const startsWith = "CyWarehouse";
let usAddress;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteShippingStartsWith(startsWith);
cy.fixture("addresses").then(addresses => {
usAddress = addresses.usAddress;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create warehouse", () => {
const name = `${startsWith}${faker.datatype.number()}`;
cy.visit(urlList.warehouses)
.get(WAREHOUSES_LIST.createNewButton)
.click();
cy.get(WAREHOUSES_DETAILS.nameInput).type(name);
fillUpBasicAddress(usAddress);
cy.addAliasToGraphRequest("WarehouseCreate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@WarehouseCreate")
.its("response.body.data.createWarehouse.warehouse")
.then(warehouse => {
getWarehouse(warehouse.id);
})
.then(warehouse => {
const addressResp = warehouse.address;
chai.softExpect(warehouse.name).to.be.eq(name);
cy.expectCorrectBasicAddress(addressResp, usAddress);
});
});
it("should add warehouse to shipping zone", () => {
const name = `${startsWith}${faker.datatype.number()}`;
let defaultChannel;
let warehouse;
let shippingZone;
getDefaultChannel()
.then(channelResp => {
defaultChannel = channelResp;
createWarehouse({
name,
address: usAddress
});
})
.then(warehouseResp => {
warehouse = warehouseResp;
createShippingZone(name, "US", defaultChannel.id);
})
.then(shippingZoneResp => {
shippingZone = shippingZoneResp;
cy.visit(shippingZoneDetailsUrl(shippingZone.id));
fillAutocompleteSelect(
SHIPPING_ZONE_DETAILS.warehouseSelector,
warehouse.name
);
cy.addAliasToGraphRequest("UpdateShippingZone")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@UpdateShippingZone");
getWarehouse(warehouse.id);
})
.then(warehouseResp => {
expect(warehouseResp.shippingZones.edges[0].node.id).to.be.eq(
shippingZone.id
);
});
});
it("should delete warehouse", () => {
const name = `${startsWith}${faker.datatype.number()}`;
createWarehouse({
name,
address: usAddress
}).then(warehouse => {
cy.visit(warehouseDetailsUrl(warehouse.id))
.get(BUTTON_SELECTORS.deleteButton)
.click()
.addAliasToGraphRequest("WarehouseDelete")
.get(BUTTON_SELECTORS.submit)
.click()
.wait("@WarehouseDelete");
getWarehouse(warehouse.id).should("be.null");
});
});
});
});

View file

@ -0,0 +1,85 @@
import faker from "faker";
import { confirmAccount, customerRegistration } from "../apiRequests/Customer";
import { CUSTOMER_DETAILS } from "../elements/customers/customer-details";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import { confirmationMessageShouldDisappear } from "../steps/shared/confirmationMessage";
import filterTests from "../support/filterTests";
import { customerDetailsUrl } from "../url/urlList";
import { getDefaultChannel } from "../utils/channelsUtils";
import { getMailActivationLinkForUser } from "../utils/users";
describe("Tests for customer registration", () => {
const startsWith = "Registration";
const email = `${startsWith}${faker.datatype.number()}@example.com`;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
getDefaultChannel().then(channel => {
defaultChannel = channel;
});
});
filterTests(["stagedOnly"], () => {
it("should register customer", () => {
const email = `${startsWith}${faker.datatype.number()}@example.com`;
customerRegistration({ email, channel: defaultChannel.slug });
getMailActivationLinkForUser(email)
.then(urlLink => {
const tokenRegex = /token=(.*)/;
const token = urlLink.match(tokenRegex)[1];
cy.clearSessionData();
confirmAccount(email, token);
})
.then(() => {
cy.loginUserViaRequest("token", {
email,
password: Cypress.env("USER_PASSWORD")
}).its("body.data.tokenCreate");
})
.then(({ errors, token }) => {
expect(errors.length).to.eq(0);
expect(token).to.be.ok;
});
});
});
filterTests(["all"], () => {
it("shouldn't register customer with duplicated email", () => {
const duplicatedEmail = Cypress.env("USER_NAME");
customerRegistration({
duplicatedEmail,
channel: defaultChannel.slug
}).then(({ user, errors }) => {
expect(errors[0].field).to.eq("email");
expect(user).to.not.be.ok;
});
});
it("should activate customer from dashboard", () => {
customerRegistration({ email, channel: defaultChannel.slug })
.then(({ user }) => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(customerDetailsUrl(user.id))
.get(CUSTOMER_DETAILS.isActiveCheckbox)
.click()
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.clearSessionData()
.loginUserViaRequest("token", {
email,
password: Cypress.env("USER_PASSWORD")
})
.its("body.data.tokenCreate");
})
.then(({ token, errors }) => {
expect(errors.length).to.eq(0);
expect(token).to.be.ok;
});
});
});
});

View file

@ -0,0 +1,201 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import { updateChannelInProduct } from "../../apiRequests/Product";
import {
assignProducts,
createSale,
discountOptions
} from "../../steps/discounts/salesSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import * as channelsUtils from "../../utils/channelsUtils";
import { deleteSalesStartsWith } from "../../utils/discounts/salesUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
import { getProductPrice } from "../../utils/storeFront/storeFrontProductUtils";
filterTests(["all"], () => {
describe("Sales discounts", () => {
const startsWith = "CySales-";
let productType;
let attribute;
let category;
let defaultChannel;
let warehouse;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
deleteSalesStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
channelsUtils.getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addresses => {
createShipping({
channelId: defaultChannel.id,
name,
address: addresses.plAddress,
price: 100
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create percentage discount", () => {
const saleName = `${startsWith}${faker.datatype.number()}`;
const discountValue = 50;
const productPrice = 100;
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
/* Uncomment after fixing SALEOR-3367 bug
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
*/
cy.visit(urlList.sales);
cy.softExpectSkeletonIsVisible();
const product = productResp;
createSale({
saleName,
channelName: defaultChannel.name,
discountValue,
discountOption: discountOptions.PERCENTAGE
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => {
const expectedPrice = (productPrice * discountValue) / 100;
expect(expectedPrice).to.be.eq(price);
});
});
it("should create fixed price discount", () => {
const saleName = `${startsWith}${faker.datatype.number()}`;
const discountValue = 50;
const productPrice = 100;
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
/* Uncomment after fixing SALEOR-3367 bug
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
*/
cy.visit(urlList.sales);
cy.softExpectSkeletonIsVisible();
const product = productResp;
createSale({
saleName,
channelName: defaultChannel.name,
discountValue,
discountOption: discountOptions.FIXED
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => {
const expectedPrice = productPrice - discountValue;
expect(expectedPrice).to.be.eq(price);
});
});
it("should not displayed discount not assign to channel", () => {
const saleName = `${startsWith}${faker.datatype.number()}`;
let channel;
let product;
const discountValue = 50;
const productPrice = 100;
createChannel({ name: saleName }).then(
channelResp => (channel = channelResp)
);
productsUtils
.createProductInChannel({
name: saleName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
})
.then(({ product: productResp }) => {
product = productResp;
updateChannelInProduct({
productId: product.id,
channelId: channel.id
});
})
.then(() => {
/* Uncomment after fixing SALEOR-3367 bug
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
*/
cy.visit(urlList.sales);
cy.softExpectSkeletonIsVisible();
createSale({
saleName,
channelName: channel.name,
discountValue
});
assignProducts(product.name);
getProductPrice(product.id, defaultChannel.slug);
})
.then(price => expect(price).to.equal(productPrice));
});
});
});

View file

@ -0,0 +1,182 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import {
createVoucher,
discountOptions
} from "../../steps/discounts/vouchersSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import * as channelsUtils from "../../utils/channelsUtils";
import { deleteVouchersStartsWith } from "../../utils/discounts/vouchersUtils";
import { createCheckoutWithVoucher } from "../../utils/ordersUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Vouchers discounts", () => {
const startsWith = "CyVou-";
const productPrice = 100;
const shippingPrice = 100;
let defaultChannel;
let createdChannel;
let productType;
let attribute;
let category;
let shippingMethod;
let variants;
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
deleteVouchersStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
channelsUtils.getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addresses => {
address = addresses.plAddress;
createShipping({
channelId: defaultChannel.id,
name,
address,
price: shippingPrice
});
})
.then(
({ shippingMethod: shippingMethodResp, warehouse: warehouse }) => {
shippingMethod = shippingMethodResp;
productsUtils.createProductInChannel({
name,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
}
)
.then(({ variantsList: variantsResp }) => {
variants = variantsResp;
createChannel({ name });
})
.then(channel => {
createdChannel = channel;
});
});
it("should create percentage voucher", () => {
const voucherValue = 50;
loginAndCreateCheckoutForVoucherWithDiscount(
discountOptions.PERCENTAGE,
voucherValue
).then(amount => {
const expectedAmount =
(productPrice * voucherValue) / 100 + shippingPrice;
expect(amount).to.be.eq(expectedAmount);
});
});
it("should create fixed price voucher", () => {
const voucherValue = 50;
loginAndCreateCheckoutForVoucherWithDiscount(
discountOptions.FIXED,
voucherValue
).then(amount => {
const expectedAmount = productPrice + shippingPrice - voucherValue;
expect(amount).to.be.eq(expectedAmount);
});
});
it("should create free shipping voucher", () => {
loginAndCreateCheckoutForVoucherWithDiscount(
discountOptions.SHIPPING,
null
).then(amount => {
const expectedAmount = productPrice;
expect(amount).to.be.eq(expectedAmount);
});
});
it("should create voucher not available for selected channel", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
const voucherValue = 50;
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.vouchers);
cy.softExpectSkeletonIsVisible();
createVoucher({
voucherCode: randomName,
voucherValue,
discountOption: discountOptions.PERCENTAGE,
channelName: createdChannel.name
});
createCheckoutForCreatedVoucher(randomName).then(resp => {
const errorField = resp.checkoutErrors[0].field;
expect(errorField).to.be.eq("promoCode");
});
});
function createCheckoutForCreatedVoucher(voucherCode) {
return createCheckoutWithVoucher({
channelSlug: defaultChannel.slug,
variantsList: variants,
address,
shippingMethodId: shippingMethod.id,
voucherCode,
auth: "token"
});
}
function loginAndCreateCheckoutForVoucherWithDiscount(
discount,
voucherValue
) {
const voucherCode = `${startsWith}${faker.datatype.number()}`;
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.discount)
.visit(urlList.vouchers);
cy.softExpectSkeletonIsVisible();
createVoucher({
voucherCode,
voucherValue,
discountOption: discount,
channelName: defaultChannel.name
});
return createCheckoutForCreatedVoucher(voucherCode).its(
"checkout.totalPrice.gross.amount"
);
}
});
});

View file

@ -0,0 +1,22 @@
import { TEST_ADMIN_USER, USER_WITHOUT_NAME } from "../../Data/users";
import { expectWelcomeMessageIncludes } from "../../steps/homePageSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
filterTests(["all"], () => {
describe("Displaying welcome message on home page", () => {
it("should display user name on home page", () => {
cy.loginUserViaRequest();
cy.visit(urlList.homePage);
expectWelcomeMessageIncludes(
`${TEST_ADMIN_USER.name} ${TEST_ADMIN_USER.lastName}`
);
});
it("should display user email on home page", () => {
cy.loginUserViaRequest("auth", USER_WITHOUT_NAME);
cy.visit(urlList.homePage);
expectWelcomeMessageIncludes(`${USER_WITHOUT_NAME.email}`);
});
});
});

View file

@ -0,0 +1,262 @@
import faker from "faker";
import {
createCustomer,
deleteCustomersStartsWith
} from "../../apiRequests/Customer";
import { HOMEPAGE_SELECTORS } from "../../elements/homePage/homePage-selectors";
import { changeChannel } from "../../steps/homePageSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import { getDefaultChannel } from "../../utils/channelsUtils";
import * as homePageUtils from "../../utils/homePageUtils";
import {
createReadyToFulfillOrder,
createWaitingForCaptureOrder
} from "../../utils/ordersUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import * as shippingUtils from "../../utils/shippingUtils";
// <reference types="cypress" />
filterTests(["all", "critical"], () => {
describe("Homepage analytics", () => {
const startsWith = "CyHomeAnalytics";
let customerId;
let defaultChannel;
let createdVariants;
let productType;
let attribute;
let category;
let warehouse;
let shippingMethod;
let addresses;
const productPrice = 22;
const shippingPrice = 12;
const randomName = startsWith + faker.datatype.number();
const randomEmail = `${startsWith}${randomName}@example.com`;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
deleteCustomersStartsWith(startsWith);
shippingUtils.deleteShippingStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addressesFixture => (addresses = addressesFixture))
.then(() =>
createCustomer(randomEmail, randomName, addresses.plAddress)
)
.then(resp => {
customerId = resp.body.data.customerCreate.user.id;
shippingUtils.createShipping({
channelId: defaultChannel.id,
name: randomName,
address: addresses.plAddress,
price: shippingPrice
});
})
.then(
({
warehouse: warehouseResp,
shippingMethod: shippingMethodResp
}) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
}
)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 20,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
}
)
.then(({ variantsList: variantsResp }) => {
createdVariants = variantsResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should all elements be visible on the dashboard", () => {
cy.visit(urlList.homePage)
.softAssertVisibility(HOMEPAGE_SELECTORS.sales)
.softAssertVisibility(HOMEPAGE_SELECTORS.orders)
.softAssertVisibility(HOMEPAGE_SELECTORS.activity)
.softAssertVisibility(HOMEPAGE_SELECTORS.topProducts)
.softAssertVisibility(HOMEPAGE_SELECTORS.ordersReadyToFulfill)
.softAssertVisibility(HOMEPAGE_SELECTORS.paymentsWaitingForCapture)
.softAssertVisibility(HOMEPAGE_SELECTORS.productsOutOfStock);
});
it("should correct amount of ready to fullfil orders be displayed", () => {
homePageUtils
.getOrdersReadyToFulfill(defaultChannel.slug)
.as("ordersReadyToFulfill");
createReadyToFulfillOrder({
customerId,
shippingMethodId: shippingMethod.id,
channelId: defaultChannel.id,
variantsList: createdVariants,
address: addresses.plAddress
});
cy.get("@ordersReadyToFulfill").then(ordersReadyToFulfillBefore => {
const allOrdersReadyToFulfill = ordersReadyToFulfillBefore + 1;
const notANumberRegex = "\\D*";
const ordersReadyToFulfillRegexp = new RegExp(
`${notANumberRegex}${allOrdersReadyToFulfill}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(
HOMEPAGE_SELECTORS.ordersReadyToFulfill,
ordersReadyToFulfillRegexp
).should("be.visible");
});
});
it("should correct amount of payments waiting for capture be displayed", () => {
homePageUtils
.getOrdersReadyForCapture(defaultChannel.slug)
.as("ordersReadyForCapture");
createWaitingForCaptureOrder({
channelSlug: defaultChannel.slug,
email: randomEmail,
variantsList: createdVariants,
shippingMethodId: shippingMethod.id,
address: addresses.plAddress
});
cy.get("@ordersReadyForCapture").then(ordersReadyForCaptureBefore => {
const allOrdersReadyForCapture = ordersReadyForCaptureBefore + 1;
const notANumberRegex = "\\D*";
const ordersReadyForCaptureRegexp = new RegExp(
`${notANumberRegex}${allOrdersReadyForCapture}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(
HOMEPAGE_SELECTORS.ordersReadyForCapture,
ordersReadyForCaptureRegexp
).should("be.visible");
});
});
it("should correct amount of products out of stock be displayed", () => {
homePageUtils
.getProductsOutOfStock(defaultChannel.slug)
.as("productsOutOfStock");
const productOutOfStockRandomName = startsWith + faker.datatype.number();
productsUtils.createProductInChannel({
name: productOutOfStockRandomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 0,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
cy.get("@productsOutOfStock").then(productsOutOfStockBefore => {
const allProductsOutOfStock = productsOutOfStockBefore + 1;
const notANumberRegex = "\\D*";
const productsOutOfStockRegexp = new RegExp(
`${notANumberRegex}${allProductsOutOfStock}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(
HOMEPAGE_SELECTORS.productsOutOfStock,
productsOutOfStockRegexp
).should("be.visible");
});
});
it("should correct amount of sales be displayed", () => {
homePageUtils.getSalesAmount(defaultChannel.slug).as("salesAmount");
createReadyToFulfillOrder({
customerId,
shippingMethodId: shippingMethod.id,
channelId: defaultChannel.id,
variantsList: createdVariants,
address: addresses.plAddress
});
cy.get("@salesAmount").then(salesAmount => {
const totalAmount = salesAmount + productPrice;
const totalAmountString = totalAmount.toFixed(2);
const totalAmountIntegerValue = totalAmountString.split(".")[0];
const totalAmountDecimalValue = totalAmountString.split(".")[1];
const decimalSeparator = "[,.]";
const totalAmountIntegerWithThousandsSeparator = new Intl.NumberFormat(
"en"
)
.format(totalAmountIntegerValue)
.replaceAll(",", "[,.]*");
const totalAmountWithSeparators = `${totalAmountIntegerWithThousandsSeparator}${decimalSeparator}${totalAmountDecimalValue}`;
const notANumberRegex = "\\D*";
const salesAmountRegexp = new RegExp(
`${notANumberRegex}${totalAmountWithSeparators}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(HOMEPAGE_SELECTORS.sales, salesAmountRegexp).should(
"be.visible"
);
});
});
it("should correct amount of orders be displayed", () => {
homePageUtils.getTodaysOrders(defaultChannel.slug).as("todaysOrders");
createReadyToFulfillOrder({
customerId,
shippingMethodId: shippingMethod.id,
channelId: defaultChannel.id,
variantsList: createdVariants,
address: addresses.plAddress
});
cy.get("@todaysOrders").then(ordersBefore => {
const allOrders = ordersBefore + 1;
const notANumberRegex = "\\D*";
const ordersRegexp = new RegExp(
`${notANumberRegex}${allOrders}${notANumberRegex}`
);
cy.visit(urlList.homePage);
changeChannel(defaultChannel.name);
cy.contains(HOMEPAGE_SELECTORS.orders, ordersRegexp).should(
"be.visible"
);
});
});
});
});

View file

@ -0,0 +1,42 @@
// <reference types="cypress" />
import { LOGIN_SELECTORS } from "../elements/account/login-selectors";
import filterTests from "../support/filterTests";
import { urlList } from "../url/urlList";
filterTests(["all"], () => {
describe("User authorization", () => {
beforeEach(() => {
cy.clearSessionData();
});
it("should successfully log in an user", () => {
cy.visit(urlList.homePage);
cy.loginUser();
cy.get(LOGIN_SELECTORS.welcomePage);
});
it("should fail for wrong password", () => {
cy.visit(urlList.homePage)
.get(LOGIN_SELECTORS.emailAddressInput)
.type("admin@example.com")
.get(LOGIN_SELECTORS.emailPasswordInput)
.type("wrong-password")
.get(LOGIN_SELECTORS.signInButton)
.click()
.get(LOGIN_SELECTORS.warningCredentialMessage);
});
it("should successfully log out an user", () => {
cy.window().then(win => {
win.sessionStorage.clear();
});
cy.visit(urlList.homePage);
cy.loginUser();
cy.get(LOGIN_SELECTORS.userMenu)
.click()
.get(LOGIN_SELECTORS.accountSettings)
.click();
cy.location("pathname").should("contains", "/staff/");
});
});
});

View file

@ -0,0 +1,100 @@
import faker from "faker";
import { updateMetadata, updatePrivateMetadata } from "../apiRequests/Metadata";
import { createDraftOrder, getOrder } from "../apiRequests/Order";
import { getProductMetadata } from "../apiRequests/storeFront/ProductDetails";
import filterTests from "../support/filterTests";
import { getDefaultChannel } from "../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct
} from "../utils/products/productsUtils";
filterTests(["all"], () => {
describe("Test for metadata", () => {
const startsWith = "Metadata";
const name = `${startsWith}${faker.datatype.number()}`;
const metadata = { key: "metadataKey", value: "metadataValue" };
let channel;
let product;
before(() => {
cy.clearSessionData().loginUserViaRequest();
getDefaultChannel()
.then(channelResp => {
channel = channelResp;
createTypeAttributeAndCategoryForProduct(name);
})
.then(({ attribute, category, productType }) => {
createProductInChannel({
attributeId: attribute.id,
categoryId: category.id,
channelId: channel.id,
name,
productTypeId: productType.id
});
})
.then(({ product: productResp }) => {
product = productResp;
});
});
it("should create metadata for product", () => {
cy.clearSessionData().loginUserViaRequest();
updateMetadata(product.id, metadata.key, metadata.value);
updatePrivateMetadata(product.id, metadata.key, metadata.value)
.then(() => {
getProductMetadata({
productId: product.id,
channelSlug: channel.slug,
auth: "auth",
withPrivateMetadata: true
}).its("data");
})
.then(({ product: productResp }) => {
expect(productResp.metadata[0].key).to.eq(metadata.key);
expect(productResp.metadata[0].value).to.eq(metadata.value);
expect(productResp.privateMetadata[0].key).to.eq(metadata.key);
expect(productResp.privateMetadata[0].value).to.eq(metadata.value);
getProductMetadata({
productId: product.id,
channelSlug: channel.slug,
auth: "token",
withPrivateMetadata: true
});
})
.then(({ errors }) => {
expect(errors[0].extensions.exception.code).to.eq("PermissionDenied");
getProductMetadata({
productId: product.id,
channelSlug: channel.slug,
auth: "token",
withPrivateMetadata: false
}).its("data");
})
.then(({ product: productResp }) => {
expect(productResp.metadata[0].key).to.eq(metadata.key);
expect(productResp.metadata[0].value).to.eq(metadata.value);
});
});
it("should create metadata for order", () => {
let order;
cy.clearSessionData().loginUserViaRequest();
createDraftOrder({ channelId: channel.id })
.then(orderResp => {
order = orderResp;
updateMetadata(order.id, metadata.key, metadata.value);
updatePrivateMetadata(order.id, metadata.key, metadata.value);
})
.then(() => {
getOrder(order.id);
})
.then(orderResp => {
expect(orderResp.metadata[0].key).to.eq(metadata.key);
expect(orderResp.metadata[0].value).to.eq(metadata.value);
expect(orderResp.privateMetadata[0].key).to.eq(metadata.key);
expect(orderResp.privateMetadata[0].value).to.eq(metadata.value);
});
});
});
});

View file

@ -0,0 +1,52 @@
import { PERMISSIONS_OPTIONS } from "../Data/permissionsUsers";
import * as permissionsSteps from "../steps/permissions";
import filterTests from "../support/filterTests";
describe("Navigation for users with different permissions", () => {
Object.keys(PERMISSIONS_OPTIONS).forEach(key => {
const tags = key === "all" ? ["critical", "all"] : ["all"];
filterTests(tags, () => {
it(`should navigate as an user with ${key} permission`, () => {
const permissionOption = PERMISSIONS_OPTIONS[key];
const permissions = permissionOption.permissions;
cy.clearSessionData();
permissionsSteps.navigateToAllAvailablePageAndCheckIfDisplayed(
permissionOption
);
if (key === "all") {
return;
}
permissionsSteps
.getDisplayedSelectors()
.then(selectors => {
permissionsSteps.expectAllSelectorsPermitted(
permissions,
selectors
);
})
.then(() => {
if (!permissions) {
return;
}
permissions.forEach(permission => {
if (permission.parent) {
cy.get(permission.parent.parentMenuSelector)
.click()
.then(() => {
permissionsSteps.getDisplayedSelectors(
permission.parent.parentSelectors
);
})
.then(parentSelectors => {
permissionsSteps.expectAllSelectorsPermitted(
permissions,
parentSelectors
);
});
}
});
});
});
});
});
});

View file

@ -0,0 +1,101 @@
// <reference types="cypress" />
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import { CHANNEL_FORM_SELECTORS } from "../../elements/channels/channel-form-selectors";
import { HEADER_SELECTORS } from "../../elements/header/header-selectors";
import { DRAFT_ORDER_SELECTORS } from "../../elements/orders/draft-order-selectors";
import { ORDERS_SELECTORS } from "../../elements/orders/orders-selectors";
import {
selectChannelInHeader,
selectChannelInPicker
} from "../../steps/channelsSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import * as channelsUtils from "../../utils/channelsUtils";
filterTests(["all"], () => {
describe("Channels in draft orders", () => {
const startsWith = "CyChannelInDraftOrders-";
const randomName = startsWith + faker.datatype.number();
let defaultChannel;
let otherChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
channelsUtils.deleteChannelsStartsWith(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
createChannel({ name: randomName });
})
.then(channelResp => {
otherChannel = channelResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("Draft order channel should be taken from global channel picker", () => {
let channelName;
cy.visit(urlList.homePage);
cy.getTextFromElement(HEADER_SELECTORS.channelSelect).then(
channelInHeader => {
channelName = channelInHeader;
}
);
cy.visit(urlList.orders)
.get(ORDERS_SELECTORS.createOrder)
.click();
cy.getTextFromElement(CHANNEL_FORM_SELECTORS.channelSelect).then(
selectedChannelName => {
expect(channelName).to.contains(selectedChannelName);
}
);
cy.get(CHANNEL_FORM_SELECTORS.confirmButton).click();
cy.getTextFromElement(DRAFT_ORDER_SELECTORS.salesChannel).then(
channelNameInDraftOrder => {
expect(channelName).to.contains(channelNameInDraftOrder);
}
);
});
it("Draft order channel should be taken from global channel picker when changed", () => {
cy.visit(urlList.homePage);
selectChannelInHeader(otherChannel.name);
cy.visit(urlList.orders);
cy.get(ORDERS_SELECTORS.createOrder).click();
cy.getTextFromElement(CHANNEL_FORM_SELECTORS.channelSelect).then(
channelInSelect => {
expect(channelInSelect).to.be.eq(otherChannel.name);
}
);
cy.get(CHANNEL_FORM_SELECTORS.confirmButton).click();
cy.getTextFromElement(DRAFT_ORDER_SELECTORS.salesChannel).then(
channelInDraftOrder => {
expect(channelInDraftOrder).to.be.eq(otherChannel.name);
}
);
});
it("should create draft order with chosen channel", () => {
cy.visit(urlList.homePage);
selectChannelInHeader(defaultChannel.name);
cy.visit(urlList.orders);
cy.get(ORDERS_SELECTORS.createOrder).click();
cy.getTextFromElement(CHANNEL_FORM_SELECTORS.channelSelect).then(
channelInSelect => {
expect(channelInSelect).to.be.eq(defaultChannel.name);
}
);
selectChannelInPicker(otherChannel.name);
cy.getTextFromElement(DRAFT_ORDER_SELECTORS.salesChannel).then(
channelInDraftOrder => {
expect(channelInDraftOrder).to.be.eq(otherChannel.name);
}
);
});
});
});

View file

@ -0,0 +1,105 @@
// <reference types="cypress" />
import faker from "faker";
import {
createCustomer,
deleteCustomersStartsWith
} from "../../apiRequests/Customer";
import { DRAFT_ORDERS_LIST_SELECTORS } from "../../elements/orders/draft-orders-list-selectors";
import { ORDERS_SELECTORS } from "../../elements/orders/orders-selectors";
import { selectChannelInPicker } from "../../steps/channelsSteps";
import { finalizeDraftOrder } from "../../steps/draftOrderSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import { getDefaultChannel } from "../../utils/channelsUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Draft orders", () => {
const startsWith = "CyDraftOrders-";
const randomName = startsWith + faker.datatype.number();
let defaultChannel;
let warehouse;
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteCustomersStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
})
.then(() => {
cy.fixture("addresses");
})
.then(addresses => {
address = addresses.plAddress;
createCustomer(
`${randomName}@example.com`,
randomName,
addresses.plAddress,
true
);
createShipping({
channelId: defaultChannel.id,
name: randomName,
address: addresses.plAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
})
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productTypeResp.id,
attributeId: attributeResp.id,
categoryId: categoryResp.id
});
}
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should move draft order to orders", () => {
cy.visit(urlList.orders);
cy.softExpectSkeletonIsVisible();
cy.get(ORDERS_SELECTORS.createOrder).click();
selectChannelInPicker(defaultChannel.name);
finalizeDraftOrder(randomName, address).then(draftOrderNumber => {
cy.visit(urlList.orders);
cy.contains(ORDERS_SELECTORS.orderRow, draftOrderNumber).should(
$order => {
expect($order).to.be.visible;
}
);
cy.visit(urlList.draftOrders);
cy.contains(
DRAFT_ORDERS_LIST_SELECTORS.draftOrderRow,
draftOrderNumber
).should($draftOrder => {
expect($draftOrder).to.not.exist;
});
});
});
});
});

View file

@ -0,0 +1,211 @@
// <reference types="cypress" />
import faker from "faker";
import {
createCustomer,
deleteCustomersStartsWith
} from "../../apiRequests/Customer";
import { getOrder } from "../../apiRequests/Order";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import { ORDER_REFUND } from "../../elements/orders/order-refund";
import { ORDERS_SELECTORS } from "../../elements/orders/orders-selectors";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { selectChannelInPicker } from "../../steps/channelsSteps";
import { finalizeDraftOrder } from "../../steps/draftOrderSteps";
import { fillAutocompleteSelect } from "../../steps/shared/selects";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import { getDefaultChannel } from "../../utils/channelsUtils";
import {
createFulfilledOrder,
createOrder,
createReadyToFulfillOrder
} from "../../utils/ordersUtils";
import * as productsUtils from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Orders", () => {
const startsWith = "CyOrders-";
const randomName = startsWith + faker.datatype.number();
let customer;
let defaultChannel;
let warehouse;
let shippingMethod;
let variantsList;
let address;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteCustomersStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
})
.then(() => {
cy.fixture("addresses");
})
.then(addresses => {
address = addresses.plAddress;
createCustomer(
`${randomName}@example.com`,
randomName,
address,
true
);
})
.then(customerResp => {
customer = customerResp.body.data.customerCreate.user;
createShipping({
channelId: defaultChannel.id,
name: randomName,
address
});
})
.then(
({
warehouse: warehouseResp,
shippingMethod: shippingMethodResp
}) => {
shippingMethod = shippingMethodResp;
warehouse = warehouseResp;
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
}
)
.then(
({
productType: productTypeResp,
attribute: attributeResp,
category: categoryResp
}) => {
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productTypeResp.id,
attributeId: attributeResp.id,
categoryId: categoryResp.id
});
}
)
.then(({ variantsList: variantsResp }) => {
variantsList = variantsResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.order
);
});
it("should create order with selected channel", () => {
// Remove login as admin after fixing SALEOR-3154
cy.clearSessionData().loginUserViaRequest();
cy.visit(urlList.orders)
.get(ORDERS_SELECTORS.createOrder)
.click();
selectChannelInPicker(defaultChannel.name);
finalizeDraftOrder(randomName, address).then(draftOrderNumber => {
cy.visit(urlList.orders);
cy.contains(ORDERS_SELECTORS.orderRow, draftOrderNumber).click();
cy.contains(ORDERS_SELECTORS.salesChannel, defaultChannel.name).should(
"be.visible"
);
});
});
// This test will pass after fixing SALEOR-3154
it("should not be possible to change channel in order", () => {
createOrder({
customerId: customer.id,
channelId: defaultChannel.id,
shippingMethodId: shippingMethod.id,
variantsList,
address
}).then(order => {
cy.visit(urlList.orders);
cy.contains(ORDERS_SELECTORS.orderRow, order.number).click();
cy.get(ORDERS_SELECTORS.salesChannel)
.find("[button]")
.should("not.exist");
});
});
it("should cancel fulfillment", () => {
let order;
createFulfilledOrder({
customerId: customer.id,
channelId: defaultChannel.id,
shippingMethodId: shippingMethod.id,
variantsList,
address,
warehouse: warehouse.id
})
.then(({ order: orderResp }) => {
order = orderResp;
cy.visit(urlList.orders);
cy.softExpectSkeletonIsVisible();
cy.contains(ORDERS_SELECTORS.orderRow, order.number).click();
cy.get(SHARED_ELEMENTS.skeleton)
.should("not.exist")
.get(ORDERS_SELECTORS.orderFulfillmentFrame)
.find(BUTTON_SELECTORS.showMoreButton)
.click()
.get(ORDERS_SELECTORS.cancelFulfillment)
.click();
})
.then(() => {
fillAutocompleteSelect(
ORDERS_SELECTORS.cancelFulfillmentSelectField,
warehouse.name
);
cy.addAliasToGraphRequest("OrderFulfillmentCancel");
cy.get(BUTTON_SELECTORS.submit).click();
cy.wait("@OrderFulfillmentCancel");
getOrder(order.id);
})
.then(orderResp => {
expect(orderResp.status).to.be.eq("UNFULFILLED");
});
});
it("should make a refund", () => {
let order;
createReadyToFulfillOrder({
customerId: customer.id,
channelId: defaultChannel.id,
shippingMethodId: shippingMethod.id,
variantsList,
address
})
.then(({ order: orderResp }) => {
order = orderResp;
cy.visit(urlList.orders);
cy.softExpectSkeletonIsVisible();
cy.contains(ORDERS_SELECTORS.orderRow, order.number).click();
cy.get(ORDERS_SELECTORS.refundButton)
.click()
.get(ORDER_REFUND.productsQuantityInput)
.type("1")
.addAliasToGraphRequest("OrderFulfillmentRefundProducts");
cy.get(BUTTON_SELECTORS.submit)
.click()
.wait("@OrderFulfillmentRefundProducts");
getOrder(order.id);
})
.then(orderResp => {
expect(orderResp.paymentStatus).to.be.eq("FULLY_REFUNDED");
});
});
});
});

View file

@ -0,0 +1,64 @@
import faker from "faker";
import { createAttribute } from "../../apiRequests/Attribute";
import { createPageType, getPageType } from "../../apiRequests/PageTypes";
import { PAGE_TYPE_DETAILS } from "../../elements/pageTypes/pageTypeDetails";
import { PAGE_TYPES_LIST } from "../../elements/pageTypes/pageTypesList";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { assignElements } from "../../steps/shared/assignElements";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import filterTests from "../../support/filterTests";
import { pageTypeDetailsUrl, urlList } from "../../url/urlList";
filterTests(["all"], () => {
describe("Tests for page types", () => {
const startsWith = "PageTypes";
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create page type", () => {
const randomName = startsWith + faker.datatype.number();
cy.visit(urlList.pageTypes)
.get(PAGE_TYPES_LIST.createPageTypeButton)
.click()
.get(PAGE_TYPE_DETAILS.nameInput)
.type(randomName)
.addAliasToGraphRequest("PageTypeCreate")
.get(BUTTON_SELECTORS.confirm)
.click();
confirmationMessageShouldDisappear();
cy.wait("@PageTypeCreate")
.its("response.body.data.pageTypeCreate.pageType")
.then(pageType => {
getPageType(pageType.id);
})
.then(pageType => {
expect(pageType.name).to.eq(randomName);
});
});
it("should assign attribute", () => {
const randomName = startsWith + faker.datatype.number();
createAttribute({ name: randomName, type: "PAGE_TYPE" });
createPageType(randomName)
.then(({ pageType }) => {
cy.visit(pageTypeDetailsUrl(pageType.id))
.get(SHARED_ELEMENTS.progressBar)
.should("be.not.visible")
.get(PAGE_TYPE_DETAILS.assignAttributesButton)
.click();
assignElements(randomName, false);
confirmationMessageShouldDisappear();
getPageType(pageType.id);
})
.then(pageType => {
expect(pageType.attributes[0].name).to.eq(randomName);
});
});
});
});

View file

@ -0,0 +1,145 @@
// <reference types="cypress" />
import faker from "faker";
import { createAttribute } from "../../apiRequests/Attribute";
import { createTypeProduct } from "../../apiRequests/productType";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import { PRODUCT_DETAILS } from "../../elements/catalog/products/product-details";
import { PRODUCTS_LIST } from "../../elements/catalog/products/products-list";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { metadataForms } from "../../steps/catalog/metadataSteps";
import {
fillUpPriceList,
priceInputLists
} from "../../steps/catalog/products/priceList";
import { fillUpCommonFieldsForAllProductTypes } from "../../steps/catalog/products/productSteps";
import { selectChannelInDetailsPages } from "../../steps/channelsSteps";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import {
expectCorrectProductInformation,
expectCorrectProductVariantInformation
} from "../../utils/products/checkProductInfo";
import * as productUtils from "../../utils/products/productsUtils";
filterTests(["all", "critical"], () => {
describe("Create product", () => {
const startsWith = "CyCreateProduct-";
const name = `${startsWith}${faker.datatype.number()}`;
const generalInfo = {
name: `${startsWith}${faker.datatype.number()}`,
description: faker.lorem.sentence(),
rating: 2
};
const seo = {
title: "testTitle",
description: generalInfo.description
};
const metadata = {
public: {
metadataForm: metadataForms.public,
name: "metadataName",
value: "metadataValue"
},
private: {
metadataForm: metadataForms.private,
name: "privateMetadataName",
value: "privateMetadataValue"
}
};
let attribute;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productUtils.deleteProductsStartsWith(startsWith);
createAttribute({ name }).then(attributeResp => {
attribute = attributeResp;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should create product with variants", () => {
const randomName = `${startsWith}${faker.datatype.number()}`;
seo.slug = randomName;
const productData = {
generalInfo,
seo,
metadata,
productOrganization: { productType: randomName },
attribute
};
createTpeAndFillUpProductFields(randomName, true, productData).then(
productOrgResp => (productData.productOrganization = productOrgResp)
);
cy.addAliasToGraphRequest("ProductDetails");
cy.get(BUTTON_SELECTORS.confirm).click();
confirmationMessageShouldDisappear();
cy.wait("@ProductDetails");
cy.get("@ProductDetails")
.its("response.body")
.then(resp => {
const productResp = resp.find(element => element.data.product).data
.product;
expectCorrectProductInformation(productResp, productData);
});
});
it("should create product without variants", () => {
const prices = { sellingPrice: 6, costPrice: 3 };
const randomName = `${startsWith}${faker.datatype.number()}`;
seo.slug = randomName;
const productData = {
generalInfo,
seo,
metadata,
productOrganization: { productType: randomName },
attribute
};
createTpeAndFillUpProductFields(randomName, false, productData).then(
productOrgResp => (productData.productOrganization = productOrgResp)
);
selectChannelInDetailsPages();
fillUpPriceList(prices.sellingPrice);
fillUpPriceList(prices.costPrice, priceInputLists.costPrice);
cy.get(PRODUCT_DETAILS.skuInput).type(randomName);
cy.addAliasToGraphRequest("ProductDetails");
cy.get(BUTTON_SELECTORS.confirm).click();
confirmationMessageShouldDisappear();
cy.wait("@ProductDetails");
cy.get("@ProductDetails")
.its("response.body")
.then(resp => {
const productResp = resp.find(element => element.data.product).data
.product;
expectCorrectProductInformation(productResp, productData);
expectCorrectProductVariantInformation(
productResp.variants,
randomName,
prices
);
});
});
function createTpeAndFillUpProductFields(
randomName,
hasVariants,
productData
) {
createTypeProduct({
name: randomName,
attributeId: attribute.id,
hasVariants
});
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.product)
.visit(urlList.products)
.get(PRODUCTS_LIST.createProductBtn)
.click();
return fillUpCommonFieldsForAllProductTypes(productData);
}
});
});

View file

@ -0,0 +1,121 @@
import faker from "faker";
import { getProductDetails } from "../../../apiRequests/storeFront/ProductDetails";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { updateProductIsAvailableForPurchase } from "../../../steps/catalog/products/productSteps";
import filterTests from "../../../support/filterTests";
import { productDetailsUrl } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import * as shippingUtils from "../../../utils/shippingUtils";
import { isProductAvailableForPurchase } from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
filterTests(["all"], () => {
describe("Products available in listings", () => {
const startsWith = "CyAvailForPurchase-";
const name = `${startsWith}${faker.datatype.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
let warehouse;
before(() => {
cy.clearSessionData().loginUserViaRequest();
shippingUtils.deleteShippingStartsWith(startsWith);
productsUtils.deleteProductsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addressesFixture => {
shippingUtils.createShipping({
channelId: defaultChannel.id,
name,
address: addressesFixture.plAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
});
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
}
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should update product to available for purchase", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
let product;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
isAvailableForPurchase: false
})
.then(({ product: productResp }) => {
product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductIsAvailableForPurchase(productUrl, true);
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
expect(isProductAvailableForPurchase(resp)).to.be.eq(true);
});
});
it("should update product to not available for purchase", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
let product;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
})
.then(({ product: productResp }) => {
product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductIsAvailableForPurchase(productUrl, false);
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
expect(isProductAvailableForPurchase(resp)).to.be.eq(false);
});
});
});
});

View file

@ -0,0 +1,109 @@
import faker from "faker";
import { getProductDetails } from "../../../apiRequests/storeFront/ProductDetails";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { updateProductPublish } from "../../../steps/catalog/products/productSteps";
import filterTests from "../../../support/filterTests";
import { productDetailsUrl } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import { isProductVisible } from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
filterTests(["all"], () => {
describe("Published products", () => {
const startsWith = "CyPublishedProducts-";
const name = `${startsWith}${faker.datatype.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should update product to published", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
isPublished: false,
isAvailableForPurchase: false
})
.then(({ product: productResp }) => {
const product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductPublish(productUrl, true);
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, productName);
expect(isVisible).to.be.eq(true);
});
});
it("should update product to not published", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
let product;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
})
.then(({ product: productResp }) => {
product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductPublish(productUrl, false);
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, productName);
expect(isVisible).to.be.eq(false);
cy.loginInShop();
})
.then(() => {
getProductDetails(product.id, defaultChannel.slug);
})
.then(resp => {
const isVisible = isProductVisible(resp, productName);
expect(isVisible).to.be.eq(true);
});
});
});
});

View file

@ -0,0 +1,118 @@
import faker from "faker";
import { searchInShop } from "../../../apiRequests/storeFront/Search";
import { ONE_PERMISSION_USERS } from "../../../Data/users";
import { updateProductVisibleInListings } from "../../../steps/catalog/products/productSteps";
import filterTests from "../../../support/filterTests";
import { productDetailsUrl } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import * as productsUtils from "../../../utils/products/productsUtils";
import { isProductVisibleInSearchResult } from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
filterTests(["all"], () => {
describe("Products displayed in listings", () => {
const startsWith = "CyVisibleInListings-";
const name = `${startsWith}${faker.datatype.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProductsStartsWith(startsWith);
productsUtils
.createTypeAttributeAndCategoryForProduct(name)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
productType = productTypeResp;
attribute = attributeResp;
category = categoryResp;
getDefaultChannel();
}
)
.then(channel => {
defaultChannel = channel;
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should update product to visible in listings", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: false,
isAvailableForPurchase: false
})
.then(({ product: productResp }) => {
const product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductVisibleInListings(productUrl);
searchInShop(productName);
})
.then(resp => {
const isProductVisible = isProductVisibleInSearchResult(
resp,
productName
);
expect(isProductVisible).to.be.eq(true);
});
});
it("should update product to not visible in listings", () => {
const productName = `${startsWith}${faker.datatype.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: true
})
.then(({ product: productResp }) => {
const product = productResp;
const productUrl = productDetailsUrl(product.id);
updateProductVisibleInListings(productUrl);
searchInShop(productName).then(resp => {
const isProductVisible = isProductVisibleInSearchResult(
resp,
productName
);
expect(isProductVisible).to.be.eq(false);
});
cy.loginInShop();
})
.then(() => {
searchInShop(productName);
})
.then(resp => {
const isProductVisible = isProductVisibleInSearchResult(
resp,
productName
);
expect(isProductVisible).to.be.eq(true);
});
});
});
});

View file

@ -0,0 +1,123 @@
import faker from "faker";
import { createCollection } from "../../../apiRequests/Collections";
import { updateProduct } from "../../../apiRequests/Product";
import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list";
import {
selectChannel,
selectFilterOption,
selectProductsOutOfStock
} from "../../../steps/catalog/products/productsListSteps";
import { waitForProgressBarToNotExist } from "../../../steps/shared/progressBar";
import filterTests from "../../../support/filterTests";
import { urlList } from "../../../url/urlList";
import { getDefaultChannel } from "../../../utils/channelsUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../../utils/shippingUtils";
filterTests(["all"], () => {
describe("Filtering products", () => {
const startsWith = "CyFilterProducts-";
const name = `${startsWith}${faker.datatype.number()}`;
const stockQuantity = 747;
const price = 342;
let attribute;
let productType;
let category;
let warehouse;
let channel;
let collection;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteShippingStartsWith(startsWith);
deleteProductsStartsWith(startsWith);
createTypeAttributeAndCategoryForProduct(name).then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
attribute = attributeResp;
productType = productTypeResp;
category = categoryResp;
}
);
createCollection(name).then(
collectionResp => (collection = collectionResp)
);
getDefaultChannel()
.then(channelResp => {
channel = channelResp;
cy.fixture("addresses");
})
.then(addresses => {
createShipping({
channelId: channel.id,
name,
address: addresses.plAddress
});
})
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
createProductInChannel({
name,
channelId: channel.id,
warehouseId: warehouse.id,
quantityInWarehouse: stockQuantity,
price,
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id
});
})
.then(({ product: product }) => {
updateProduct(product.id, { collections: [collection.id] });
});
});
beforeEach(() => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.products);
});
const filterProductsBy = ["category", "collection", "productType"];
filterProductsBy.forEach(filterBy => {
it(`should filter products by ${filterBy}`, () => {
cy.softExpectSkeletonIsVisible();
waitForProgressBarToNotExist();
selectFilterOption(filterBy, name);
cy.getTextFromElement(PRODUCTS_LIST.productsNames).then(product => {
expect(product).to.includes(name);
});
});
});
it("should filter products out of stock", () => {
cy.softExpectSkeletonIsVisible();
const productOutOfStock = `${startsWith}${faker.datatype.number()}`;
createProductInChannel({
name: productOutOfStock,
channelId: channel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 0,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price
});
waitForProgressBarToNotExist();
selectChannel(channel.slug);
selectProductsOutOfStock();
cy.getTextFromElement(PRODUCTS_LIST.productsNames).then(product => {
expect(product).to.includes(productOutOfStock);
});
});
});
});

View file

@ -0,0 +1,64 @@
import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list";
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
import {
getDisplayedColumnArray,
isNumberOfProductsSameAsInSelectResultsOnPage
} from "../../../steps/catalog/products/productsListSteps";
import { waitForProgressBarToNotExist } from "../../../steps/shared/progressBar";
import filterTests from "../../../support/filterTests";
import { urlList } from "../../../url/urlList";
filterTests(["all"], () => {
describe("Products", () => {
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
cy.visit(urlList.products);
});
it("Should go to the next page", () => {
cy.softExpectSkeletonIsVisible();
cy.get(PRODUCTS_LIST.productsList)
.should("be.visible")
.get(PRODUCTS_LIST.emptyProductRow)
.should("not.exist")
.get(PRODUCTS_LIST.previousPagePagination)
.should("be.disabled");
let firstPageProducts;
getDisplayedColumnArray("name").then(
productsList => (firstPageProducts = productsList)
);
cy.addAliasToGraphRequest("ProductList");
cy.get(PRODUCTS_LIST.nextPageButton).click();
waitForProgressBarToNotExist();
cy.wait("@ProductList");
getDisplayedColumnArray("name").then(productList => {
expect(productList).to.not.equal(firstPageProducts);
});
cy.get(PRODUCTS_LIST.previousPagePagination).then($button => {
expect($button).to.be.enabled;
});
});
it("should displayed correct number of results per page", () => {
cy.softExpectSkeletonIsVisible();
isNumberOfProductsSameAsInSelectResultsOnPage().then(
isTheSame =>
expect(isTheSame, "check if number of displayed products is correct")
.to.be.true
);
cy.get(PRODUCTS_LIST.resultsOnPageSelect)
.click()
.get(
`${PRODUCTS_LIST.rowNumberOption}${BUTTON_SELECTORS.notSelectedOption}`
)
.first()
.click();
waitForProgressBarToNotExist();
isNumberOfProductsSameAsInSelectResultsOnPage().then(
isTheSame =>
expect(
isTheSame,
"check if number of displayed products is correct, after changing results number in table footer"
).to.be.true
);
});
});
});

View file

@ -0,0 +1,31 @@
import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list";
import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
import { waitForProgressBarToNotExist } from "../../../steps/shared/progressBar";
import filterTests from "../../../support/filterTests";
import { urlList } from "../../../url/urlList";
import { expectProductsSortedBy } from "../../../utils/products/productsListUtils";
filterTests(["all"], () => {
describe("Sorting products", () => {
const sortByList = ["name", "type"];
sortByList.forEach(sortBy => {
it(`Sorting by ${sortBy}`, () => {
cy.clearSessionData()
.loginUserViaRequest()
.visit(urlList.products);
cy.softExpectSkeletonIsVisible();
cy.get(SHARED_ELEMENTS.header).should("be.visible");
if (sortBy !== "name") {
cy.get(PRODUCTS_LIST.tableHeaders[sortBy]).click();
waitForProgressBarToNotExist();
}
expectProductsSortedBy(sortBy);
cy.addAliasToGraphRequest("ProductList")
.get(PRODUCTS_LIST.tableHeaders[sortBy])
.click();
waitForProgressBarToNotExist().wait("@ProductList");
expectProductsSortedBy(sortBy, false);
});
});
});
});

View file

@ -0,0 +1,209 @@
import faker from "faker";
import { createChannel } from "../../apiRequests/Channels";
import {
createProduct,
updateChannelInProduct
} from "../../apiRequests/Product";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import {
createFirstVariant,
createVariant,
variantsShouldBeVisible
} from "../../steps/catalog/products/VariantsSteps";
import { selectChannelInHeader } from "../../steps/channelsSteps";
import filterTests from "../../support/filterTests";
import { urlList } from "../../url/urlList";
import {
deleteChannelsStartsWith,
getDefaultChannel
} from "../../utils/channelsUtils";
import * as productUtils from "../../utils/products/productsUtils";
import * as shippingUtils from "../../utils/shippingUtils";
import { getProductVariants } from "../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
filterTests(["all", "critical"], () => {
describe("Creating variants", () => {
const startsWith = "CyCreateVariants-";
const attributeValues = ["value1", "value2"];
let defaultChannel;
let warehouse;
let attribute;
let productType;
let category;
let newChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
shippingUtils.deleteShippingStartsWith(startsWith);
productUtils.deleteProductsStartsWith(startsWith);
deleteChannelsStartsWith(startsWith);
const name = `${startsWith}${faker.datatype.number()}`;
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(fixtureAddresses =>
shippingUtils.createShipping({
channelId: defaultChannel.id,
name,
address: fixtureAddresses.plAddress
})
)
.then(({ warehouse: warehouseResp }) => {
warehouse = warehouseResp;
createChannel({ isActive: true, name, currencyCode: "PLN" });
})
.then(resp => (newChannel = resp));
productUtils
.createTypeAttributeAndCategoryForProduct(name, attributeValues)
.then(
({
attribute: attributeResp,
productType: productTypeResp,
category: categoryResp
}) => {
attribute = attributeResp;
productType = productTypeResp;
category = categoryResp;
}
);
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest(
"auth",
ONE_PERMISSION_USERS.product
);
});
it("should create variant visible on frontend", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const price = 10;
let createdProduct;
createProduct({
attributeId: attribute.id,
name,
productTypeId: productType.id,
categoryId: category.id
})
.then(resp => {
createdProduct = resp;
updateChannelInProduct({
productId: createdProduct.id,
channelId: defaultChannel.id
});
cy.visit(`${urlList.products}${createdProduct.id}`);
createFirstVariant({
sku: name,
warehouseId: warehouse.id,
price,
attribute: attributeValues[0]
});
selectChannelInHeader(defaultChannel.name);
variantsShouldBeVisible({ name, price });
getProductVariants(createdProduct.id, defaultChannel.slug);
})
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", price);
});
});
it("should create several variants", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const secondVariantSku = `${startsWith}${faker.datatype.number()}`;
const variants = [{ price: 7 }, { name: attributeValues[1], price: 16 }];
let createdProduct;
productUtils
.createProductInChannel({
name,
attributeId: attribute.id,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
categoryId: category.id,
price: variants[0].price
})
.then(({ product: productResp }) => {
createdProduct = productResp;
cy.visit(`${urlList.products}${createdProduct.id}`);
createVariant({
sku: secondVariantSku,
warehouseName: warehouse.name,
attributeName: variants[1].name,
price: variants[1].price,
channelName: defaultChannel.name
});
})
.then(() => {
selectChannelInHeader(defaultChannel.name);
variantsShouldBeVisible({
name: variants[1].name,
price: variants[1].price
});
getProductVariants(createdProduct.id, defaultChannel.slug);
})
.then(([firstVariant, secondVariant]) => {
expect(firstVariant).to.have.property("price", variants[0].price);
expect(secondVariant).to.have.property("name", variants[1].name);
expect(secondVariant).to.have.property("price", variants[1].price);
});
});
it("should create variant for many channels", () => {
const name = `${startsWith}${faker.datatype.number()}`;
const variantsPrice = 10;
let createdProduct;
createProduct({
attributeId: attribute.id,
name,
productTypeId: productType.id,
categoryId: category.id
})
.then(productResp => {
createdProduct = productResp;
updateChannelInProduct({
productId: createdProduct.id,
channelId: defaultChannel.id
});
})
.then(() => {
updateChannelInProduct({
productId: createdProduct.id,
channelId: newChannel.id
});
})
.then(() => {
cy.visit(`${urlList.products}${createdProduct.id}`);
createFirstVariant({
sku: name,
warehouseId: warehouse.id,
price: variantsPrice,
attribute: attributeValues[0]
});
selectChannelInHeader(defaultChannel.name);
variantsShouldBeVisible({ name, price: variantsPrice });
selectChannelInHeader(newChannel.name);
variantsShouldBeVisible({ name, price: variantsPrice });
getProductVariants(createdProduct.id, defaultChannel.slug);
})
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", variantsPrice);
getProductVariants(createdProduct.id, newChannel.slug);
})
.then(([variant]) => {
expect(variant).to.have.property("name", attributeValues[0]);
expect(variant).to.have.property("price", variantsPrice);
});
});
});
});

View file

@ -0,0 +1,152 @@
import faker from "faker";
import { createCategory } from "../../apiRequests/Category";
import { createCollection } from "../../apiRequests/Collections";
import { getProductDetails } from "../../apiRequests/storeFront/ProductDetails";
import { ONE_PERMISSION_USERS } from "../../Data/users";
import { PRODUCT_DETAILS } from "../../elements/catalog/products/product-details";
import { BUTTON_SELECTORS } from "../../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
import { metadataForms } from "../../steps/catalog/metadataSteps";
import { fillUpCommonFieldsForAllProductTypes } from "../../steps/catalog/products/productSteps";
import { confirmationMessageShouldDisappear } from "../../steps/shared/confirmationMessage";
import filterTests from "../../support/filterTests";
import { productDetailsUrl } from "../../url/urlList";
import { getDefaultChannel } from "../../utils/channelsUtils";
import { deleteCollectionsStartsWith } from "../../utils/collectionsUtils";
import { expectCorrectProductInformation } from "../../utils/products/checkProductInfo";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
filterTests(["all"], () => {
describe("Update products", () => {
const startsWith = "CyUpdateProducts-";
const name = `${startsWith}${faker.datatype.number()}`;
const description = faker.lorem.sentences(2);
let defaultChannel;
let collection;
let product;
let attribute;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteCollectionsStartsWith(startsWith);
getDefaultChannel()
.then(channel => {
defaultChannel = channel;
createCollection(name);
})
.then(collectionResp => {
collection = collectionResp;
createTypeAttributeAndCategoryForProduct(name);
})
.then(({ attribute: attributeResp, category, productType }) => {
attribute = attributeResp;
createProductInChannel({
attributeId: attribute.id,
categoryId: category.id,
productTypeId: productType.id,
channelId: defaultChannel.id,
name,
collectionId: collection.id,
description
});
})
.then(({ product: productResp }) => {
product = productResp;
});
});
it("Should update product", () => {
const updatedName = `${startsWith}${faker.random.number()}`;
let updatedCategory;
let updatedCollection;
createCategory(updatedName)
.then(categoryResp => {
updatedCategory = categoryResp;
createCollection(updatedName);
})
.then(collectionResp => {
updatedCollection = collectionResp;
const productData = {
generalInfo: {
name: updatedName,
description: faker.lorem.sentence(),
rating: 3
},
seo: {
slug: updatedName,
title: "newTitle",
description: "New description."
},
metadata: {
private: {
metadataForm: metadataForms.private,
name: "newPrivate",
value: "value1"
},
public: {
metadataForm: metadataForms.public,
name: "newPublic",
value: "value2"
}
},
productOrganization: {
category: updatedCategory.name,
collection: updatedCollection.name
}
};
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.product)
.visit(productDetailsUrl(product.id))
.get(PRODUCT_DETAILS.collectionRemoveButtons)
.click();
fillUpCommonFieldsForAllProductTypes(productData, false);
cy.addAliasToGraphRequest("UpdatePrivateMetadata");
cy.addAliasToGraphRequest("UpdateMetadata");
cy.addAliasToGraphRequest("ProductUpdate");
cy.get(BUTTON_SELECTORS.confirm).click();
confirmationMessageShouldDisappear();
cy.wait("@ProductUpdate");
cy.wait("@UpdateMetadata");
cy.wait("@UpdatePrivateMetadata");
productData.productOrganization.productType = name;
productData.attribute = attribute;
cy.loginUserViaRequest("token")
.then(() => {
getProductDetails(product.id, defaultChannel.slug, "auth").its(
"body.data.product"
);
})
.then(resp => {
expectCorrectProductInformation(resp, productData);
});
});
});
it("should delete product", () => {
cy.clearSessionData()
.loginUserViaRequest("auth", ONE_PERMISSION_USERS.product)
.visit(productDetailsUrl(product.id))
.addAliasToGraphRequest("ProductDelete")
.get(BUTTON_SELECTORS.deleteButton)
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.wait("@ProductDelete")
.loginUserViaRequest("token")
.then(() => {
getProductDetails(product.id, defaultChannel.slug).its("body.data");
})
.then(
productResp =>
expect(productResp.product, "Check if product exist").to.be.null
);
});
});
});

View file

@ -0,0 +1,115 @@
import faker from "faker";
import {
deleteStaffMembersStartsWith,
updateStaffMember
} 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";
import { STAFF_MEMBERS_LIST } from "../elements/staffMembers/staffMembersList";
import { expectWelcomeMessageIncludes } from "../steps/homePageSteps";
import { getDisplayedSelectors } from "../steps/permissions";
import {
fillUpSetPassword,
fillUpUserDetails,
updateUserActiveFlag
} from "../steps/user";
import filterTests from "../support/filterTests";
import { urlList, userDetailsUrl } from "../url/urlList";
import {
getMailActivationLinkForUser,
inviteStaffMemberWithFirstPermission
} from "../utils/users";
filterTests(["stagedOnly"], () => {
describe("Staff members", () => {
const startsWith = "StaffMembers";
const password = Cypress.env("USER_PASSWORD");
const lastName = faker.name.lastName();
const email = `${startsWith}${lastName}@example.com`;
let user;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteStaffMembersStartsWith(startsWith);
inviteStaffMemberWithFirstPermission({ email })
.then(({ user: userResp }) => {
user = userResp;
getMailActivationLinkForUser(email);
})
.then(urlLink => {
cy.clearSessionData().visit(urlLink);
fillUpSetPassword(password);
cy.clearSessionData();
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should invite user", () => {
const firstName = faker.name.firstName();
const emailInvite = `${startsWith}${firstName}@example.com`;
cy.visit(urlList.staffMembers)
.softExpectSkeletonIsVisible()
.get(STAFF_MEMBERS_LIST.inviteStaffMemberButton)
.click();
fillUpUserDetails(firstName, lastName, emailInvite);
getMailActivationLinkForUser(emailInvite).then(urlLink => {
cy.clearSessionData().visit(urlLink);
fillUpSetPassword(password);
expectWelcomeMessageIncludes(`${firstName} ${lastName}`);
});
});
it("should deactivate user", () => {
updateStaffMember({ userId: user.id, isActive: true });
updateUserActiveFlag(user.id);
cy.clearSessionData()
.loginUserViaRequest("auth", { email, password })
.its("body.data.tokenCreate")
.then(tokenCreate => {
chai
.softExpect(
tokenCreate.errors[0].code,
"logging in should return error"
)
.to.be.eq("INVALID_CREDENTIALS");
expect(tokenCreate.token).to.be.not.ok;
});
});
it("should activate user", () => {
updateStaffMember({ userId: user.id, isActive: false });
updateUserActiveFlag(user.id);
cy.clearSessionData()
.loginUserViaRequest("auth", { email, password })
.visit(urlList.homePage);
expectWelcomeMessageIncludes(email);
});
it("should remove user permissions", () => {
cy.visit(userDetailsUrl(user.id))
.get(STAFF_MEMBER_DETAILS.removePermissionButton)
.click()
.addAliasToGraphRequest("StaffMemberUpdate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@StaffMemberUpdate")
.clearSessionData()
.loginUserViaRequest("auth", { email, password })
.visit(urlList.homePage);
expectWelcomeMessageIncludes(email);
getDisplayedSelectors().then(displayedSelectors => {
expect(Object.values(displayedSelectors)).to.have.length(1);
expect(Object.values(displayedSelectors)[0]).to.eq(
LEFT_MENU_SELECTORS.home
);
});
});
});
});

View file

@ -1,173 +0,0 @@
import faker from "faker";
import {
addShippingMethod,
completeCheckout,
completeCheckoutWithAdyen,
createCheckout
} from "../../apiRequests/Checkout";
import { getOrder } from "../../apiRequests/Order";
import { getDefaultChannel } from "../../utils/channelsUtils";
import { addAdyenPayment } from "../../utils/ordersUtils";
import {
createProductInChannel,
createTypeAttributeAndCategoryForProduct,
deleteProductsStartsWith
} from "../../utils/products/productsUtils";
import {
createShipping,
deleteShippingStartsWith
} from "../../utils/shippingUtils";
describe("Adyen payments", () => {
const startsWith = "CyChannelInDraftOrders-";
const name = startsWith + faker.datatype.number();
const email = `CyChannelInDraftOrders@example.com`;
let address;
let defaultChannel;
let warehouse;
let shippingMethod;
let variantsList;
let checkout;
let paymentCards;
let cardData;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteProductsStartsWith(startsWith);
deleteShippingStartsWith(startsWith);
cy.fixture("cards").then(cardsResp => {
paymentCards = cardsResp;
cardData = {
clientData: paymentCards.clientData,
encryptedExpiryMonth: paymentCards.encryptedExpiryMonth,
encryptedExpiryYear: paymentCards.encryptedExpiryYear,
encryptedSecurityCode: paymentCards.encryptedSecurityCodes.matches
};
});
cy.fixture("addresses")
.then(addresses => {
address = addresses.usAddress;
getDefaultChannel();
})
.then(channelResp => {
defaultChannel = channelResp;
createShipping({
channelId: channelResp.id,
name,
address,
price: 10
});
})
.then(
({
warehouse: warehouseResp,
shippingZone: shippingZoneResp,
shippingMethod: shippingMethodResp
}) => {
warehouse = warehouseResp;
shippingMethod = shippingMethodResp;
}
);
createTypeAttributeAndCategoryForProduct(name)
.then(({ productType, attribute, category }) => {
createProductInChannel({
name,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(({ variantsList: variants }) => (variantsList = variants));
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
createCheckout({
channelSlug: defaultChannel.slug,
email,
variantsList,
address,
billingAddress: address,
auth: "token"
})
.then(({ checkout: checkoutResp }) => {
checkout = checkoutResp;
addShippingMethod(checkout.id, shippingMethod.id);
})
.then(({ checkout: checkoutResp }) => {
addAdyenPayment(checkout.id, checkoutResp.totalPrice.gross.amount);
});
});
it("should purchase products with simple card", () => {
const simpleCard = cardData;
simpleCard.encryptedCardNumber =
paymentCards.cards.simpleCard.encryptedCardNumber;
simpleCard.brand = paymentCards.cards.simpleCard.brand;
completeCheckout(checkout.id, simpleCard)
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
expect(order.paymentStatus).to.eq("FULLY_CHARGED");
});
});
it("should purchase product with 3D secure 2 Auth", () => {
const threeDSecureCard = cardData;
threeDSecureCard.encryptedCardNumber =
paymentCards.cards.threeDSecureTwoAuth.encryptedCardNumber;
threeDSecureCard.brand = paymentCards.cards.threeDSecureTwoAuth.brand;
completeCheckout(checkout.id, threeDSecureCard)
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
expect(order.paymentStatus).to.eq("FULLY_CHARGED");
});
});
it("should purchase product with 3D secure 1 Auth", () => {
const threeDSecureCardOneAuth = cardData;
threeDSecureCardOneAuth.encryptedCardNumber =
paymentCards.cards.threeDSecureOneAuth.encryptedCardNumber;
threeDSecureCardOneAuth.brand =
paymentCards.cards.threeDSecureOneAuth.brand;
completeCheckout(checkout.id, threeDSecureCardOneAuth)
.then(({ order }) => {
getOrder(order.id);
})
.then(order => {
expect(order.paymentStatus).to.eq("FULLY_CHARGED");
});
});
it("should fail with unknown security number", () => {
const simpleCard = cardData;
simpleCard.encryptedCardNumber =
paymentCards.cards.simpleCard.encryptedCardNumber;
simpleCard.brand = paymentCards.cards.simpleCard.brand;
simpleCard.encryptedSecurityCode =
paymentCards.encryptedSecurityCodes.unknown;
completeCheckout(checkout.id, simpleCard).then(({ checkoutErrors }) => {
expect(checkoutErrors).to.have.length(1);
});
});
it("should fail with timeout in 3D authorization", () => {
const errorCard = cardData;
errorCard.encryptedCardNumber =
paymentCards.cards.errorCard.encryptedCardNumber;
errorCard.brand = paymentCards.cards.errorCard.brand;
completeCheckout(checkout.id, errorCard).then(({ checkoutErrors }) => {
expect(checkoutErrors).to.have.length(1);
});
});
it("should fail with closed account", () => {
const closeAccount = cardData;
closeAccount.encryptedCardNumber =
paymentCards.cards.closeAccount.encryptedCardNumber;
closeAccount.brand = paymentCards.cards.closeAccount.brand;
completeCheckout(checkout.id, closeAccount).then(({ checkoutErrors }) => {
expect(checkoutErrors).to.have.length(1);
});
});
});

View file

@ -1,40 +0,0 @@
import faker from "faker";
import {
confirmAccount,
customerRegistration
} from "../../apiRequests/Customer";
import { getDefaultChannel } from "../../utils/channelsUtils";
import { getMailActivationLinkForUser } from "../../utils/users";
describe("Tests for customer registration with email", () => {
const startsWith = "RegistrationEmail";
let defaultChannel;
before(() => {
cy.clearSessionData().loginUserViaRequest();
getDefaultChannel().then(channel => (defaultChannel = channel));
});
it("should register customer", () => {
const email = `${startsWith}${faker.datatype.number()}@example.com`;
customerRegistration({ email, channel: defaultChannel.slug });
getMailActivationLinkForUser(email)
.then(urlLink => {
const tokenRegex = /token=(.*)/;
const token = urlLink.match(tokenRegex)[1];
cy.clearSessionData();
confirmAccount(email, token);
})
.then(() => {
cy.loginUserViaRequest("token", {
email,
password: Cypress.env("USER_PASSWORD")
}).its("body.data.tokenCreate");
})
.then(({ errors, token }) => {
expect(errors.length).to.eq(0);
expect(token).to.be.ok;
});
});
});

View file

@ -1,112 +0,0 @@
import faker from "faker";
import {
deleteStaffMembersStartsWith,
updateStaffMember
} 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";
import { STAFF_MEMBERS_LIST } from "../../elements/staffMembers/staffMembersList";
import { expectWelcomeMessageIncludes } from "../../steps/homePageSteps";
import { getDisplayedSelectors } from "../../steps/permissions";
import {
fillUpSetPassword,
fillUpUserDetails,
updateUserActiveFlag
} from "../../steps/user";
import { urlList, userDetailsUrl } from "../../url/urlList";
import {
getMailActivationLinkForUser,
inviteStaffMemberWithFirstPermission
} from "../../utils/users";
describe("Staff members", () => {
const startsWith = "StaffMembers";
const password = Cypress.env("USER_PASSWORD");
const lastName = faker.name.lastName();
const email = `${startsWith}${lastName}@example.com`;
let user;
before(() => {
cy.clearSessionData().loginUserViaRequest();
deleteStaffMembersStartsWith(startsWith);
inviteStaffMemberWithFirstPermission({ email })
.then(({ user: userResp }) => {
user = userResp;
getMailActivationLinkForUser(email);
})
.then(urlLink => {
cy.clearSessionData().visit(urlLink);
fillUpSetPassword(password);
cy.clearSessionData();
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should invite user", () => {
const firstName = faker.name.firstName();
const emailInvite = `${startsWith}${firstName}@example.com`;
cy.visit(urlList.staffMembers)
.softExpectSkeletonIsVisible()
.get(STAFF_MEMBERS_LIST.inviteStaffMemberButton)
.click();
fillUpUserDetails(firstName, lastName, emailInvite);
getMailActivationLinkForUser(emailInvite).then(urlLink => {
cy.clearSessionData().visit(urlLink);
fillUpSetPassword(password);
expectWelcomeMessageIncludes(`${firstName} ${lastName}`);
});
});
it("should deactivate user", () => {
updateStaffMember({ userId: user.id, isActive: true });
updateUserActiveFlag(user.id);
cy.clearSessionData()
.loginUserViaRequest("auth", { email, password })
.its("body.data.tokenCreate")
.then(tokenCreate => {
chai
.softExpect(
tokenCreate.errors[0].code,
"logging in should return error"
)
.to.be.eq("INVALID_CREDENTIALS");
expect(tokenCreate.token).to.be.not.ok;
});
});
it("should activate user", () => {
updateStaffMember({ userId: user.id, isActive: false });
updateUserActiveFlag(user.id);
cy.clearSessionData()
.loginUserViaRequest("auth", { email, password })
.visit(urlList.homePage);
expectWelcomeMessageIncludes(email);
});
it("should remove user permissions", () => {
cy.visit(userDetailsUrl(user.id))
.get(STAFF_MEMBER_DETAILS.removePermissionButton)
.click()
.addAliasToGraphRequest("StaffMemberUpdate")
.get(BUTTON_SELECTORS.confirm)
.click()
.wait("@StaffMemberUpdate")
.clearSessionData()
.loginUserViaRequest("auth", { email, password })
.visit(urlList.homePage);
expectWelcomeMessageIncludes(email);
getDisplayedSelectors().then(displayedSelectors => {
expect(Object.values(displayedSelectors)).to.have.length(1);
expect(Object.values(displayedSelectors)[0]).to.eq(
LEFT_MENU_SELECTORS.home
);
});
});
});

View file

@ -4,6 +4,7 @@ import { SELECT_CHANNELS_TO_ASSIGN } from "../elements/channels/select-channels-
import { ASSIGN_ELEMENTS_SELECTORS } from "../elements/shared/assign-elements-selectors";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import { SHARED_ELEMENTS } from "../elements/shared/sharedElements";
import { confirmationMessageShouldDisappear } from "./shared/confirmationMessage";
export function createCollection(collectionName, isPublished, channel) {
const publishedSelector = isPublished
@ -29,11 +30,12 @@ export function createCollection(collectionName, isPublished, channel) {
.click();
cy.addAliasToGraphRequest("CreateCollection");
cy.get(COLLECTION_SELECTORS.saveButton).click();
cy.get(SHARED_ELEMENTS.confirmationMsg).should("be.visible");
confirmationMessageShouldDisappear();
return cy
.wait("@CreateCollection")
.its("response.body.data.collectionCreate.collection");
}
export function assignProductsToCollection(productName) {
cy.get(COLLECTION_SELECTORS.addProductButton)
.click()

View file

@ -1,8 +1,8 @@
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
export function confirmationMessageShouldDisappear() {
cy.get(SHARED_ELEMENTS.confirmationMsg)
cy.get(SHARED_ELEMENTS.notificationSuccess)
.should("be.visible")
.get(SHARED_ELEMENTS.confirmationMsg)
.get(SHARED_ELEMENTS.notificationSuccess)
.should("not.exist");
}

View file

@ -1,8 +1,8 @@
import { SHARED_ELEMENTS } from "../../elements/shared/sharedElements";
export function confirmationMessageShouldDisappear() {
cy.get(SHARED_ELEMENTS.confirmationMsg)
cy.get(SHARED_ELEMENTS.notificationSuccess)
.should("be.visible")
.get(SHARED_ELEMENTS.confirmationMsg)
.get(SHARED_ELEMENTS.notificationSuccess)
.should("not.exist");
}

View file

@ -0,0 +1,24 @@
// / <reference types="Cypress" />
/**
* Filter Cypress tests based on a given tag or tags. If no tags are present, run tests.
*
* @param {[string]} definedTags An array of tags
* @param {Function} runTest All tests captured within a Cypress run
* @example npm run open --env tags=api
*/
const filterTests = (definedTags, runTest) => {
if (Cypress.env("tags")) {
const tags = Cypress.env("tags").split("/");
const found = definedTags.some($definedTag => tags.includes($definedTag));
if (found) {
runTest();
}
} else {
runTest();
}
};
export default filterTests;

View file

@ -248,7 +248,8 @@
"cy:run": "cypress run",
"cy:run:record": "npm run cy:run -- --record",
"cy:open": "cypress open",
"cy:run:allEnv": "cypress run --spec 'cypress/integration/stagedOnly/*'",
"cy:run:critical": "cypress run --env tags=critical --spec 'cypress/integration/navigation.js','cypress/integration/products/*.js','cypress/integration/checkout/*.js'",
"cy:run:allEnv": "cypress run --env tags=all",
"test:e2e:run": "start-server-and-test start http://localhost:9000 cy:run",
"test:e2e:run:record": "start-server-and-test start http://localhost:9000 cy:run:record",
"test:e2e:dev": "start-server-and-test start http://localhost:9000 cy:open",