collections tests

This commit is contained in:
Karolina Rakoczy 2021-02-24 14:21:19 +01:00
commit 6e6b9956ef
28 changed files with 790 additions and 289 deletions

View file

@ -1,20 +1,20 @@
class Attribute {
createAttribute(name) {
const mutation = `mutation{
attributeCreate(input:{
name:"${name}"
valueRequired:false
type:PRODUCT_TYPE
}){
attribute{
id
attributeCreate(input:{
name:"${name}"
valueRequired:false
type:PRODUCT_TYPE
}){
attribute{
id
}
attributeErrors{
field
message
}
}
attributeErrors{
field
message
}
}
}`;
}`;
return cy.sendRequestWithQuery(mutation);
}

View file

@ -0,0 +1,37 @@
class Collections {
getCollections(search) {
const filter = search
? `, filter:{
search:""
}`
: "";
const query = `query{
collections(first:100 ${filter}){
edges{
node{
id
name
}
}
}
}`;
return cy
.sendRequestWithQuery(query)
.then(resp => resp.body.data.collections.edges);
}
deleteCollection(collectionId) {
const mutation = `mutation{
collectionDelete(id:"${collectionId}"){
collection{
id
}
collectionErrors{
field
message
}
}
}`;
return cy.sendRequestWithQuery(mutation);
}
}
export default Collections;

View file

@ -1,4 +1,7 @@
import Utils from "./utils/Utils";
class Product {
utils = new Utils();
getFirstProducts(first, search) {
const filter = search
? `, filter:{
@ -17,44 +20,50 @@ class Product {
}
}
}
}
`;
`;
return cy
.sendRequestWithQuery(query)
.then(resp => resp.body.data.products.edges);
}
updateChannelInProduct(productId, channelId) {
updateChannelInProduct({
productId,
channelId,
isPublished = true,
isAvailableForPurchase = true,
visibleInListings = true
}) {
const mutation = `mutation{
productChannelListingUpdate(id:"${productId}",
input:{
addChannels:{
channelId:"${channelId}"
isPublished:true
isAvailableForPurchase:true
productChannelListingUpdate(id:"${productId}",
input:{
addChannels:{
channelId:"${channelId}"
isPublished:${isPublished}
isAvailableForPurchase:${isAvailableForPurchase}
visibleInListings:${visibleInListings}
}
}){
product{
id
name
}
}
}){
product{
id
name
}
}
}`;
return cy.sendRequestWithQuery(mutation);
}`;
cy.sendRequestWithQuery(mutation);
}
updateChannelPriceInVariant(variantId, channelId) {
const mutation = `mutation{
productVariantChannelListingUpdate(id: "${variantId}", input:{
channelId: "${channelId}"
price: 10
costPrice: 10
}){
productChannelListingErrors{
message
}
}
}`;
productVariantChannelListingUpdate(id: "${variantId}", input: {
channelId: "${channelId}"
price: 10
costPrice: 10
}){
productChannelListingErrors{
message
}
}
} `;
return cy.sendRequestWithQuery(mutation);
}
createProduct(attributeId, name, productType, category) {
@ -88,27 +97,30 @@ class Product {
price = 1,
costPrice = 1
) {
const channelListings = channelId
? `channelListings:{
const channelListings = this.utils.getValueWithDefault(
channelId,
`channelListings:{
channelId:"${channelId}"
price:"${price}"
costPrice:"${costPrice}"
}`
: "";
const stocks = warehouseId
? `stocks:{
);
const stocks = this.utils.getValueWithDefault(
warehouseId,
`stocks:{
warehouse:"${warehouseId}"
quantity:${quantity}
}`
: "";
);
const mutation = `mutation{
productVariantBulkCreate(product:"${productId}", variants:{
attributes:[]
sku:"${sku}"
productVariantBulkCreate(product: "${productId}", variants: {
attributes: []
sku: "${sku}"
${channelListings}
${stocks}
}){
}) {
productVariants{
id
name
@ -124,33 +136,33 @@ class Product {
createTypeProduct(name, attributeId, slug = name) {
const mutation = `mutation{
productTypeCreate(input:{
name:"${name}"
productTypeCreate(input: {
name: "${name}"
slug: "${slug}"
isShippingRequired:true
productAttributes:"${attributeId}"
}){
productErrors{
field
message
}
productType{
id
}
}
}`;
isShippingRequired: true
productAttributes: "${attributeId}"
}){
productErrors{
field
message
}
productType{
id
}
}
} `;
return cy.sendRequestWithQuery(mutation);
}
deleteProduct(productId) {
const mutation = `mutation{
productDelete(id:"${productId}"){
productErrors{
field
message
}
}
}`;
productDelete(id: "${productId}"){
productErrors{
field
message
}
}
} `;
return cy.sendRequestWithQuery(mutation);
}

View file

@ -1,52 +0,0 @@
class Collections {
getCollection(collectionId, channelSlug) {
const operationName = "Collection";
const variables = {
attributes: {},
priceGte: null,
priceLte: null,
sortBy: null,
channel: channelSlug,
id: collectionId,
pageSize: 6
};
const query =
"query Collection($id: ID!, $channel: String!) {\n collection(id: $id, channel: $channel) {\n id\n slug\n name\n seoDescription\n seoTitle\n backgroundImage {\n url\n __typename\n }\n __typename\n }\n attributes(filter: {channel: $channel, inCollection: $id, filterableInStorefront: true}, first: 100) {\n edges {\n node {\n id\n name\n slug\n values {\n id\n name\n slug\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n}\n";
return cy.sendFrontShopRequest(operationName, query, variables);
}
getCollections(search) {
const filter = search
? `, filter:{
search:""
}`
: "";
const query = `query{
collections(first:100 ${filter}){
edges{
node{
id
name
}
}
}
}`;
return cy
.sendRequestWithQuery(query)
.then(resp => resp.body.data.collections.edges);
}
deleteCollection(collectionId) {
const mutation = `mutation{
collectionDelete(id:"${collectionId}"){
collection{
id
}
collectionErrors{
field
message
}
}
}`;
return cy.sendRequestWithQuery(mutation);
}
}
export default Collections;

View file

@ -0,0 +1,21 @@
class Collections {
getCollection(collectionId, channelSlug) {
const query = `query Collection{
collection(id: "${collectionId}", channel: "${channelSlug}") {
id
slug
name
products(first:100){
edges{
node{
id
name
}
}
}
}
}`;
return cy.sendFrontShopRequestWithQuery(query);
}
}
export default Collections;

View file

@ -0,0 +1,18 @@
class ProductDetails {
getProductDetails(productId, channelId) {
const query = `fragment BasicProductFields on Product {
id
name
}
query ProductDetails{
product(id: "${productId}", channel: "${channelId}") {
...BasicProductFields
isAvailable
isAvailableForPurchase
availableForPurchase
}
}`;
return cy.sendFrontShopRequestWithQuery(query);
}
}
export default ProductDetails;

View file

@ -0,0 +1,20 @@
class Search {
searchInShop(searchQuery) {
const query = `query SearchProducts {
products(channel: "default-channel", filter:{
search: "${searchQuery}"
}, first:10){
totalCount
edges{
node{
id
name
}
}
}
}`;
return cy.sendFrontShopRequestWithQuery(query);
}
}
export default Search;

View file

@ -0,0 +1,6 @@
class Utils {
getValueWithDefault(condition, value, defaultValue = "") {
return condition ? value : defaultValue;
}
}
export default Utils;

View file

@ -13,9 +13,20 @@ export const PRODUCTS_SELECTORS = {
saveBtn: "[data-test='button-bar-confirm']",
confirmationMsg: "[data-test='notification-success']",
channelAvailabilityItem: "[data-test='channel-availability-item']",
searchProducts: "[placeholder='Search Products...']",
availableManageButton:
"[data-test-id='channels-availiability-manage-button']",
channelsAvailabilityForm:
"[data-test-id='manage-products-channels-availiability-list']",
channelAvailabilityColumn:
"[data-test='availability'][data-test-availability='true']",
channelAvailabilityList: "ul[role='menu']",
goBackButton: "[data-test-id='app-header-back-button']",
assignedChannels: "[data-test='channel-availability-item']",
publishedRadioButtons: "[name*='isPublished']",
availableForPurchaseRadioButtons: "[name*='isAvailableForPurchase']",
radioButtonsValueTrue: "[value='true']",
radioButtonsValueFalse: "[value='false']",
visibleInListingsButton: "[name*='visibleInListings']",
emptyProductRow: "[class*='Skeleton']"
};

View file

@ -44,10 +44,10 @@ describe("Channels", () => {
it("should create new channel", () => {
const randomChannel = `${channelStartsWith} ${faker.random.number()}`;
cy.waitForGraph("Channels");
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.wait("Channels");
cy.waitForGraph("Channel");
cy.wait("@Channels");
cy.addAliasToGraphRequest("Channel");
channelsSteps.createChannelByView(randomChannel, currency);
// New channel should be visible in channels list
cy.wait("@Channel")
@ -65,7 +65,9 @@ describe("Channels", () => {
.click();
// new channel should be visible at product availability form
cy.visit(urlList.products).waitForGraph("InitialProductFilterData");
cy.addAliasToGraphRequest("InitialProductFilterData");
cy.visit(urlList.products);
cy.wait("@InitialProductFilterData");
cy.get(PRODUCTS_SELECTORS.productsList)
.first()
.click()
@ -106,15 +108,18 @@ describe("Channels", () => {
randomChannelToDelete,
currency
);
cy.visit(urlList.channels).waitForGraph("Channels");
cy.addAliasToGraphRequest("Channels");
cy.visit(urlList.channels);
cy.wait("@Channels");
cy.get(CHANNELS_SELECTORS.channelName)
.contains(randomChannelToDelete)
.parentsUntil(CHANNELS_SELECTORS.channelsTable)
.find("button")
.click()
.get(BUTTON_SELECTORS.submit)
.click()
.waitForGraph("Channels");
.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

@ -8,18 +8,26 @@ import ChannelsUtils from "../utils/channelsUtils";
import CollectionsUtils from "../utils/collectionsUtils";
import ProductsUtils from "../utils/productsUtils";
import ShippingUtils from "../utils/shippingUtils";
import StoreFrontCollectionUtils from "../utils/storeFront/collectionsUtils";
import StoreFrontProductUtils from "../utils/storeFront/storeFrontProductUtils";
describe("Collections", () => {
const productRequest = new Product();
const channelsUtils = new ChannelsUtils();
const productsUtils = new ProductsUtils();
const storeFrontProductUtils = new StoreFrontProductUtils();
const collectionsUtils = new CollectionsUtils();
const storeFrontCollectionUtils = new StoreFrontCollectionUtils();
const shippingUtils = new ShippingUtils();
const collectionsSteps = new CollectionsSteps();
const startsWith = "Cy-";
const name = `${startsWith}${faker.random.number()}`;
let attribute;
let productType;
let category;
let defaultChannel;
before(() => {
@ -35,19 +43,16 @@ describe("Collections", () => {
productsUtils.createTypeAttributeAndCategoryForProduct(name);
})
.then(() => {
const attribute = productsUtils.getAttribute();
const productType = productsUtils.getProductType();
const category = productsUtils.getCategory();
productsUtils.createProductInChannel(
attribute = productsUtils.getAttribute();
productType = productsUtils.getProductType();
category = productsUtils.getCategory();
productsUtils.createProductInChannel({
name,
defaultChannel.id,
null,
null,
productType.id,
attribute.id,
category.id,
1
);
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
});
});
@ -63,7 +68,7 @@ describe("Collections", () => {
.createCollection(collectionName, false, defaultChannel)
.then(collection => {
collectionsSteps.assignProductsToCollection(name);
collectionsUtils.isCollectionVisible(
storeFrontCollectionUtils.isCollectionVisible(
collection.id,
defaultChannel.slug
);
@ -79,55 +84,71 @@ describe("Collections", () => {
.createCollection(collectionName, true, defaultChannel)
.then(collection => {
collectionsSteps.assignProductsToCollection(name);
collectionsUtils.isCollectionVisible(
storeFrontCollectionUtils.isCollectionVisible(
collection.id,
defaultChannel.slug
);
})
.then(isVisible => expect(isVisible).to.equal(true));
});
xit("should not display unavailable in channel collections", () => {
channelsUtils.createChannel(true, name, name, "PLN").then(() => {
productRequest.updateChannelInProduct(
productsUtils.getCreatedProduct().id,
channelsUtils.getCreatedChannel().id
);
it("should not display unavailable in channel collections", () => {
const collectionName = `${startsWith}${faker.random.number()}`;
channelsUtils
.createChannel({ name: collectionName })
.then(() => {
productRequest.updateChannelInProduct(
productsUtils.getCreatedProduct().id,
channelsUtils.getCreatedChannel().id
);
})
.then(() => {
cy.visit(urlList.collections);
collectionsSteps.createCollection(
collectionName,
true,
channelsUtils.getCreatedChannel()
);
})
.then(collection => {
collectionsSteps.assignProductsToCollection(name);
storeFrontCollectionUtils.isCollectionVisible(
collection.id,
defaultChannel.slug
);
})
.then(isVisible => expect(isVisible).to.equal(false));
});
it("should display products hidden in listing, only in collection", () => {
const randomName = `${startsWith}${faker.random.number()}`;
const hiddenProductUtils = new ProductsUtils();
hiddenProductUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: false
});
cy.visit(urlList.collections);
collectionsSteps
.createCollection(collectionName, true, channelsUtils.getCreatedChannel())
.createCollection(randomName, true, defaultChannel)
.then(collection => {
collectionsSteps.assignProductsToCollection(name);
collectionsUtils.isCollectionVisible(
collectionsSteps.assignProductsToCollection(randomName);
storeFrontCollectionUtils.isProductInCollectionVisible(
collection.id,
defaultChannel.slug
);
})
.then(isVisible => expect(isVisible).to.equal(true));
});
xit("should display products hidden in listing, only in collection", () => {
productsUtils.createProductInChannel(
name,
defaultChannel.id,
null,
null,
productsUtils.getProductType().id,
productsUtils.getAttribute().id,
productsUtils.getCategory().id,
1
);
collectionsSteps
.createCollection(collectionName, true, defaultChannel)
.then(collection => {
collectionsSteps.assignProductsToCollection(name);
collectionsUtils.isProductInCollectionVisible(
collection.id,
defaultChannel.slug
defaultChannel.slug,
hiddenProductUtils.getCreatedProduct().id
);
})
.then(isVisible => {
expect(isVisible).to.equal(true);
// productsUtils.searchForProduct
storeFrontProductUtils.isProductVisibleInSearchResult(
hiddenProductUtils.getCreatedProduct().name,
defaultChannel.slug
);
})
.then(isVisible => {
expect(isVisible).to.equal(false);
});
});
});

View file

@ -11,7 +11,7 @@ import ProductsUtils from "../utils/productsUtils";
import ShippingUtils from "../utils/shippingUtils";
// <reference types="cypress" />
describe("User authorization", () => {
describe("Homepage analytics", () => {
const startsWith = "Cy-";
const customer = new Customer();
@ -48,12 +48,12 @@ describe("User authorization", () => {
)
.then(resp => {
customerId = resp.body.data.customerCreate.user.id;
shippingUtils.createShipping(
defaultChannel.id,
randomName,
addresses.plAddress,
shippingPrice
);
shippingUtils.createShipping({
channelId: defaultChannel.id,
name: randomName,
address: addresses.plAddress,
price: shippingPrice
});
})
.then(() => {
productsUtils.createTypeAttributeAndCategoryForProduct(randomName);
@ -63,16 +63,16 @@ describe("User authorization", () => {
const productType = productsUtils.getProductType();
const attribute = productsUtils.getAttribute();
const category = productsUtils.getCategory();
productsUtils.createProductInChannel(
randomName,
defaultChannel.id,
warehouse.id,
20,
productType.id,
attribute.id,
category.id,
productPrice
);
productsUtils.createProductInChannel({
name: randomName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
quantityInWarehouse: 20,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
price: productPrice
});
});
});
@ -154,16 +154,16 @@ describe("User authorization", () => {
const attribute = productsUtils.getAttribute();
const category = productsUtils.getCategory();
productsOutOfStockUtils.createProductInChannel(
productOutOfStockRandomName,
defaultChannel.id,
warehouse.id,
0,
productType.id,
attribute.id,
category.id,
productPrice
);
productsOutOfStockUtils.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;

View file

@ -0,0 +1,115 @@
import faker from "faker";
import ProductSteps from "../../../steps/productSteps";
import { productDetailsUrl } from "../../../url/urlList";
import ChannelsUtils from "../../../utils/channelsUtils";
import ProductsUtils from "../../../utils/productsUtils";
import ShippingUtils from "../../../utils/shippingUtils";
import StoreFrontProductUtils from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Products available in listings", () => {
const shippingUtils = new ShippingUtils();
const channelsUtils = new ChannelsUtils();
const productsUtils = new ProductsUtils();
const productSteps = new ProductSteps();
const frontShopProductUtils = new StoreFrontProductUtils();
const startsWith = "Cy-";
const name = `${startsWith}${faker.random.number()}`;
let productType;
let attribute;
let category;
let defaultChannel;
let warehouse;
before(() => {
cy.clearSessionData().loginUserViaRequest();
shippingUtils.deleteShipping(startsWith);
productsUtils.deleteProperProducts(startsWith);
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
cy.fixture("addresses");
})
.then(addressesFixture => {
shippingUtils.createShipping({
channelId: defaultChannel.id,
name,
address: addressesFixture.plAddress
});
})
.then(() => {
warehouse = shippingUtils.getWarehouse();
});
productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
productType = productsUtils.getProductType();
attribute = productsUtils.getAttribute();
category = productsUtils.getCategory();
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should update product to available for purchase", () => {
const productName = `${startsWith}${faker.random.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
isAvailableForPurchase: false
})
.then(() => {
const productUrl = productDetailsUrl(
productsUtils.getCreatedProduct().id
);
productSteps.updateProductIsAvailableForPurchase(productUrl, true);
})
.then(() => {
frontShopProductUtils.isProductAvailableForPurchase(
productsUtils.getCreatedProduct().id,
defaultChannel.slug,
productName
);
})
.then(isProductVisible => {
expect(isProductVisible).to.be.eq(true);
});
});
it("should update product to not available for purchase", () => {
const productName = `${startsWith}${faker.random.number()}`;
productsUtils
.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
warehouseId: warehouse.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
})
.then(() => {
const productUrl = productDetailsUrl(
productsUtils.getCreatedProduct().id
);
productSteps.updateProductIsAvailableForPurchase(productUrl, false);
})
.then(() => {
frontShopProductUtils.isProductAvailableForPurchase(
productsUtils.getCreatedProduct().id,
defaultChannel.slug,
productName
);
})
.then(isProductVisible => {
expect(isProductVisible).to.be.eq(false);
});
});
});

View file

@ -0,0 +1,108 @@
import faker from "faker";
import ProductSteps from "../../../steps/productSteps";
import { productDetailsUrl } from "../../../url/urlList";
import ChannelsUtils from "../../../utils/channelsUtils";
import ProductsUtils from "../../../utils/productsUtils";
import StoreFrontProductUtils from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Published products", () => {
const channelsUtils = new ChannelsUtils();
const productsUtils = new ProductsUtils();
const productSteps = new ProductSteps();
const frontShopProductUtils = new StoreFrontProductUtils();
const startsWith = "Cy-";
const name = `${startsWith}${faker.random.number()}`;
let productType;
let attribute;
let category;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProperProducts(startsWith);
productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
productType = productsUtils.getProductType();
attribute = productsUtils.getAttribute();
category = productsUtils.getCategory();
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should update product to published", () => {
const productName = `${startsWith}${faker.random.number()}`;
let defaultChannel;
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
isPublished: false,
isAvailableForPurchase: false
});
})
.then(() => {
const product = productsUtils.getCreatedProduct();
const productUrl = productDetailsUrl(product.id);
productSteps.updateProductPublish(productUrl, true);
frontShopProductUtils.isProductVisible(
product.id,
defaultChannel.slug,
productName
);
})
.then(isVisible => {
expect(isVisible).to.be.eq(true);
});
});
it("should update product to not published", () => {
const productName = `${startsWith}${faker.random.number()}`;
let defaultChannel;
let product;
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id
});
})
.then(() => {
product = productsUtils.getCreatedProduct();
const productUrl = productDetailsUrl(product.id);
productSteps.updateProductPublish(productUrl, false);
frontShopProductUtils.isProductVisible(
product.id,
defaultChannel.slug,
productName
);
})
.then(isVisible => {
expect(isVisible).to.be.eq(false);
cy.loginInShop();
})
.then(() => {
frontShopProductUtils.isProductVisible(
product.id,
defaultChannel.slug,
productName
);
})
.then(isVisible => {
expect(isVisible).to.be.eq(true);
});
});
});

View file

@ -0,0 +1,102 @@
import faker from "faker";
import ProductSteps from "../../../steps/productSteps";
import { productDetailsUrl } from "../../../url/urlList";
import ChannelsUtils from "../../../utils/channelsUtils";
import ProductsUtils from "../../../utils/productsUtils";
import StoreFrontProductUtils from "../../../utils/storeFront/storeFrontProductUtils";
// <reference types="cypress" />
describe("Products displayed in listings", () => {
const channelsUtils = new ChannelsUtils();
const productsUtils = new ProductsUtils();
const productSteps = new ProductSteps();
const frontShopProductUtils = new StoreFrontProductUtils();
const startsWith = "Cy-";
const name = `${startsWith}${faker.random.number()}`;
let productType;
let attribute;
let category;
before(() => {
cy.clearSessionData().loginUserViaRequest();
productsUtils.deleteProperProducts(startsWith);
productsUtils.createTypeAttributeAndCategoryForProduct(name).then(() => {
productType = productsUtils.getProductType();
attribute = productsUtils.getAttribute();
category = productsUtils.getCategory();
});
});
beforeEach(() => {
cy.clearSessionData().loginUserViaRequest();
});
it("should update product to visible in listings", () => {
const productName = `${startsWith}${faker.random.number()}`;
let defaultChannel;
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: false,
isAvailableForPurchase: false
});
})
.then(() => {
const product = productsUtils.getCreatedProduct();
const productUrl = productDetailsUrl(product.id);
productSteps.updateProductVisibleInListings(productUrl);
frontShopProductUtils.isProductVisibleInSearchResult(
productName,
defaultChannel.slug
);
})
.then(isProductVisible => {
expect(isProductVisible).to.be.eq(true);
});
});
it("should update product to not visible in listings", () => {
const productName = `${startsWith}${faker.random.number()}`;
let defaultChannel;
channelsUtils
.getDefaultChannel()
.then(channel => {
defaultChannel = channel;
productsUtils.createProductInChannel({
name: productName,
channelId: defaultChannel.id,
productTypeId: productType.id,
attributeId: attribute.id,
categoryId: category.id,
visibleInListings: true
});
})
.then(() => {
const product = productsUtils.getCreatedProduct();
const productUrl = productDetailsUrl(product.id);
productSteps.updateProductVisibleInListings(productUrl);
frontShopProductUtils
.isProductVisibleInSearchResult(productName, defaultChannel.slug)
.then(isProductVisible => {
expect(isProductVisible).to.be.eq(false);
});
cy.loginInShop();
})
.then(() => {
frontShopProductUtils.isProductVisibleInSearchResult(
productName,
defaultChannel.slug
);
})
.then(isProductVisible => {
expect(isProductVisible).to.be.eq(true);
});
});
});

View file

@ -1,7 +1,7 @@
// <reference types="cypress" />
import { LEFT_MENU_SELECTORS } from "../elements/account/left-menu/left-menu-selectors";
import { PRODUCTS_SELECTORS } from "../elements/catalog/product-selectors";
import { urlList } from "../url/urlList";
import { LEFT_MENU_SELECTORS } from "../../elements/account/left-menu/left-menu-selectors";
import { PRODUCTS_SELECTORS } from "../../elements/catalog/product-selectors";
import { urlList } from "../../url/urlList";
describe("Products", () => {
beforeEach(() => {

View file

@ -2,13 +2,11 @@ import { COLLECTION_SELECTORS } from "../elements/catalog/collection-selectors";
import { ASSIGN_PRODUCTS_SELECTORS } from "../elements/catalog/products/assign-products-selectors";
import { MENAGE_CHANNEL_AVAILABILITY_FORM } from "../elements/channels/menage-channel-availability-form";
import { BUTTON_SELECTORS } from "../elements/shared/button-selectors";
import CollectionsUtils from "../utils/collectionsUtils";
class CollectionsSteps {
createCollection(collectionName, isPublished, channel) {
const publishedSelector = isPublished
? MENAGE_CHANNEL_AVAILABILITY_FORM.radioButtonsValueTrue
: MENAGE_CHANNEL_AVAILABILITY_FORM.radioButtonsValueFalse;
const collectionsUtils = new CollectionsUtils();
cy.get(COLLECTION_SELECTORS.createCollectionButton)
.click()
@ -28,11 +26,12 @@ class CollectionsSteps {
.get(
`${MENAGE_CHANNEL_AVAILABILITY_FORM.publishedCheckbox}${publishedSelector}`
)
.click()
.waitForGraph("CreateCollection")
.get(COLLECTION_SELECTORS.saveButton)
.click();
return collectionsUtils.waitForCreateCollectionRequest();
cy.addAliasToGraphRequest("CreateCollection");
cy.get(COLLECTION_SELECTORS.saveButton).click();
return cy
.wait("@CreateCollection")
.its("response.body.data.collectionCreate.collection");
}
assignProductsToCollection(productName) {
cy.get(COLLECTION_SELECTORS.addProductButton)

View file

@ -1,12 +1,12 @@
import { HEADER_SELECTORS } from "../elements/header/header-selectors";
class HomePageSteps {
changeChannel(channelName) {
cy.get(HEADER_SELECTORS.channelSelect)
.click()
.get(HEADER_SELECTORS.channelSelectList)
cy.get(HEADER_SELECTORS.channelSelect).click();
cy.addAliasToGraphRequest("Home");
cy.get(HEADER_SELECTORS.channelSelectList)
.contains(channelName)
.click()
.waitForGraph("Home");
.click();
cy.wait("@Home");
}
}
export default HomePageSteps;

View file

@ -0,0 +1,37 @@
import { PRODUCTS_SELECTORS } from "../elements/catalog/product-selectors";
class ProductSteps {
valueTrue = PRODUCTS_SELECTORS.radioButtonsValueTrue;
valueFalse = PRODUCTS_SELECTORS.radioButtonsValueFalse;
updateProductIsAvailableForPurchase(productUrl, isAvailableForPurchase) {
const isAvailableForPurchaseSelector = isAvailableForPurchase
? this.valueTrue
: this.valueFalse;
const availableForPurchaseSelector = `${PRODUCTS_SELECTORS.availableForPurchaseRadioButtons}${isAvailableForPurchaseSelector}`;
this.updateProductMenageInChannel(productUrl, availableForPurchaseSelector);
}
updateProductPublish(productUrl, isPublished) {
const isPublishedSelector = isPublished ? this.valueTrue : this.valueFalse;
const publishedSelector = `${PRODUCTS_SELECTORS.publishedRadioButtons}${isPublishedSelector}`;
this.updateProductMenageInChannel(productUrl, publishedSelector);
}
updateProductVisibleInListings(productUrl) {
this.updateProductMenageInChannel(
productUrl,
PRODUCTS_SELECTORS.visibleInListingsButton
);
}
updateProductMenageInChannel(productUrl, menageSelector) {
cy.visit(productUrl)
.get(PRODUCTS_SELECTORS.assignedChannels)
.click()
.get(menageSelector)
.click();
cy.addAliasToGraphRequest("ProductChannelListingUpdate");
cy.get(PRODUCTS_SELECTORS.saveBtn)
.click()
.wait("@ProductChannelListingUpdate");
}
}
export default ProductSteps;

View file

@ -21,7 +21,7 @@ Cypress.Commands.add("clearSessionData", () => {
});
});
Cypress.Commands.add("waitForGraph", operationName => {
Cypress.Commands.add("addAliasToGraphRequest", operationName => {
cy.intercept("POST", urlList.apiUri, req => {
req.statusCode = 200;
const requestBody = req.body;
@ -39,7 +39,10 @@ Cypress.Commands.add("waitForGraph", operationName => {
});
});
Cypress.Commands.add("sendRequestWithQuery", query =>
Cypress.Commands.add("sendFrontShopRequestWithQuery", query =>
cy.sendRequestWithQuery(query, "token")
);
Cypress.Commands.add("sendRequestWithQuery", (query, authorization = "auth") =>
cy.request({
body: {
method: "POST",
@ -47,27 +50,9 @@ Cypress.Commands.add("sendRequestWithQuery", query =>
url: urlList.apiUri
},
headers: {
Authorization: `JWT ${window.sessionStorage.getItem("auth")}`
Authorization: `JWT ${window.sessionStorage.getItem(authorization)}`
},
method: "POST",
url: urlList.apiUri
})
);
Cypress.Commands.add(
"sendFrontShopRequest",
(operationName, query, variables) =>
cy.request({
method: "POST",
url: urlList.apiUri,
headers: {
authorization: `JWT ${window.localStorage.getItem("token")}`
},
body: [
{
operationName,
variables,
query
}
]
})
);

View file

@ -1,5 +1,4 @@
import { LOGIN_SELECTORS } from "../../elements/account/login-selectors";
import { urlList } from "../../url/urlList";
Cypress.Commands.add("loginUser", () =>
cy
@ -11,40 +10,32 @@ Cypress.Commands.add("loginUser", () =>
.click()
);
Cypress.Commands.add("loginUserViaRequest", () => {
const logInMutationQuery = `mutation TokenAuth($email: String!, $password: String!) {
tokenCreate(email: $email, password: $password) {
Cypress.Commands.add("loginInShop", () => {
cy.loginUserViaRequest("token");
});
Cypress.Commands.add("loginUserViaRequest", (authorization = "auth") => {
const mutation = `mutation TokenAuth{
tokenCreate(email: "${Cypress.env("USER_NAME")}", password: "${Cypress.env(
"USER_PASSWORD"
)}") {
token
errors: accountErrors {
code
field
message
__typename
}
user {
id
__typename
}
__typename
}
}`;
return cy
.request({
body: {
operationName: "TokenAuth",
query: logInMutationQuery,
variables: {
email: Cypress.env("USER_NAME"),
password: Cypress.env("USER_PASSWORD")
}
},
method: "POST",
url: urlList.apiUri
})
.then(resp => {
window.sessionStorage.setItem("auth", resp.body.data.tokenCreate.token);
});
return cy.sendRequestWithQuery(mutation, authorization).then(resp => {
window.sessionStorage.setItem(
authorization,
resp.body.data.tokenCreate.token
);
});
});
Cypress.Commands.add("loginInShop", () => {
cy.request({

View file

@ -8,3 +8,4 @@ export const urlList = {
warehouses: "warehouses/",
collections: "collections/"
};
export const productDetailsUrl = productId => `${urlList.products}${productId}`;

View file

@ -38,7 +38,7 @@ class ChannelsUtils {
}));
});
}
createChannel(isActive, name, slug, currencyCode) {
createChannel({ isActive = true, name, slug = name, currencyCode = "PLN" }) {
return this.channels
.createChannel(isActive, name, slug, currencyCode)
.then(
@ -46,7 +46,7 @@ class ChannelsUtils {
);
}
getCreatedChannel() {
return channel;
return this.createdChannel;
}
}
export default ChannelsUtils;

View file

@ -1,21 +1,8 @@
import Collections from "../apiRequests/frontShop/Collections";
import Collections from "../apiRequests/Collections";
class CollectionsUtils {
collectionsRequest = new Collections();
isCollectionVisible(collectionId, channelSlug) {
return this.collectionsRequest
.getCollection(collectionId, channelSlug)
.then(resp => {
const collection = resp.body[0].data.collection;
return collection !== null && collection.id === collectionId;
});
}
waitForCreateCollectionRequest() {
return cy
.wait(`@CreateCollection`)
.its("response.body.data.collectionCreate.collection");
}
deleteProperCollections(startsWith) {
cy.deleteProperElements(
this.collectionsRequest.deleteCollection,

View file

@ -13,19 +13,37 @@ class ProductsUtils {
attribute;
category;
createProductInChannel(
createProductWithVariant(name, attributeId, productTypeId, categoryId) {
return this.createProduct(
attributeId,
name,
productTypeId,
categoryId
).then(() => this.createVariant(this.product.id, name));
}
createProductInChannel({
name,
channelId,
warehouseId,
quantityInWarehouse,
warehouseId = null,
quantityInWarehouse = 10,
productTypeId,
attributeId,
categoryId,
price
) {
price = 1,
isPublished = true,
isAvailableForPurchase = true,
visibleInListings = true
}) {
return this.createProduct(attributeId, name, productTypeId, categoryId)
.then(() =>
this.productRequest.updateChannelInProduct(this.product.id, channelId)
this.productRequest.updateChannelInProduct({
productId: this.product.id,
channelId,
isPublished,
isAvailableForPurchase,
visibleInListings
})
)
.then(() => {
this.createVariant(
@ -92,7 +110,9 @@ class ProductsUtils {
resp.body.data.productVariantBulkCreate.productVariants)
);
}
getCreatedProduct() {
return this.product;
}
getCreatedVariants() {
return this.variants;
}

View file

@ -8,7 +8,7 @@ class ShippingUtils {
shippingZone;
warehouse;
createShipping(channelId, name, address, price) {
createShipping({ channelId, name, address, price = 1 }) {
return this.createShippingZone(name, address.country)
.then(() => this.createWarehouse(name, this.shippingZone.id, address))
.then(() => this.createShippingRate(name, this.shippingZone.id))

View file

@ -0,0 +1,23 @@
import Collections from "../../apiRequests/storeFront/Collections";
class CollectionsUtils {
collectionsRequest = new Collections();
isCollectionVisible(collectionId, channelSlug) {
return this.collectionsRequest
.getCollection(collectionId, channelSlug)
.then(resp => {
const collection = resp.body.data.collection;
return collection !== null && collection.id === collectionId;
});
}
isProductInCollectionVisible(collectionId, channelSlug, productId) {
return this.collectionsRequest
.getCollection(collectionId, channelSlug)
.then(resp => {
const product = resp.body.data.collection.products.edges[0].node;
return product !== null && product.id === productId;
});
}
}
export default CollectionsUtils;

View file

@ -0,0 +1,34 @@
import ProductDetails from "../../apiRequests/storeFront/ProductDetails";
import Search from "../../apiRequests/storeFront/Search";
class StoreFrontProductUtils {
isProductVisible(productId, channelSlug, name) {
const productDetails = new ProductDetails();
return productDetails
.getProductDetails(productId, channelSlug)
.then(productDetailsResp => {
const product = productDetailsResp.body.data.product;
return product !== null && product.name === name;
});
}
isProductAvailableForPurchase(productId, channelSlug) {
const productDetails = new ProductDetails();
return productDetails
.getProductDetails(productId, channelSlug)
.then(
productDetailsResp =>
productDetailsResp.body.data.product.isAvailableForPurchase
);
}
isProductVisibleInSearchResult(productName, channelSlug) {
const search = new Search();
return search
.searchInShop(productName, channelSlug)
.then(
resp =>
resp.body.data.products.totalCount !== 0 &&
resp.body.data.products.edges[0].node.name === productName
);
}
}
export default StoreFrontProductUtils;