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