Add tests for creating products without sku (#1550)
* create products without sku * update stories * update stories
This commit is contained in:
parent
241be6b6ee
commit
a311583647
9 changed files with 304 additions and 18 deletions
|
@ -23,5 +23,10 @@ export const PRODUCT_DETAILS = {
|
|||
uploadImageButton: '[data-test="button-upload-image"]',
|
||||
uploadSavedImagesButton: '[data-test="uploadImages"]',
|
||||
uploadMediaUrlButton: '[data-test="uploadMediaUrl"]',
|
||||
saveUploadUrlButton: '[data-test-id="upload-url-button"]'
|
||||
saveUploadUrlButton: '[data-test-id="upload-url-button"]',
|
||||
addWarehouseButton: '[data-test-id="add-warehouse"]',
|
||||
warehouseOption: "[role='menuitem']",
|
||||
stockInput: '[data-test-id="stock-input"]',
|
||||
costPriceInput: '[name*="costPrice"]',
|
||||
sellingPriceInput: '[name*="channel-price"]'
|
||||
};
|
||||
|
|
|
@ -9,5 +9,6 @@ export const VARIANTS_SELECTORS = {
|
|||
addWarehouseButton: "button[class*='MuiIconButton-colorPrimary']",
|
||||
warehouseOption: "[role='menuitem']",
|
||||
saveButton: "[data-test='button-bar-confirm']",
|
||||
skuInputInAddVariant: "[name='sku']"
|
||||
skuInputInAddVariant: "[name='sku']",
|
||||
stockInput: "[data-test-id='stock-input']"
|
||||
};
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
/// <reference types="cypress"/>
|
||||
/// <reference types="../../../support"/>
|
||||
|
||||
import faker from "faker";
|
||||
|
||||
import { PRODUCT_DETAILS } from "../../../elements/catalog/products/product-details";
|
||||
import { PRODUCTS_LIST } from "../../../elements/catalog/products/products-list";
|
||||
import { AVAILABLE_CHANNELS_FORM } from "../../../elements/channels/available-channels-form";
|
||||
import { BUTTON_SELECTORS } from "../../../elements/shared/button-selectors";
|
||||
import { urlList } from "../../../fixtures/urlList";
|
||||
import { ONE_PERMISSION_USERS } from "../../../fixtures/users";
|
||||
import {
|
||||
createProduct,
|
||||
updateChannelInProduct
|
||||
} from "../../../support/api/requests/Product";
|
||||
import { createTypeProduct } from "../../../support/api/requests/ProductType";
|
||||
import {
|
||||
deleteChannelsStartsWith,
|
||||
getDefaultChannel
|
||||
} from "../../../support/api/utils/channelsUtils";
|
||||
import { createWaitingForCaptureOrder } from "../../../support/api/utils/ordersUtils";
|
||||
import * as productUtils from "../../../support/api/utils/products/productsUtils";
|
||||
import * as shippingUtils from "../../../support/api/utils/shippingUtils";
|
||||
import { getProductVariants } from "../../../support/api/utils/storeFront/storeFrontProductUtils";
|
||||
import filterTests from "../../../support/filterTests";
|
||||
import {
|
||||
createFirstVariant,
|
||||
createVariant
|
||||
} from "../../../support/pages/catalog/products/VariantsPage";
|
||||
import { selectChannelInDetailsPages } from "../../../support/pages/channelsPage";
|
||||
|
||||
filterTests({ definedTags: ["all", "critical"], version: "3.1.0" }, () => {
|
||||
describe("Creating variants", () => {
|
||||
const startsWith = "CyCreateVariants-";
|
||||
const attributeValues = ["value1", "value2"];
|
||||
|
||||
let defaultChannel;
|
||||
let warehouse;
|
||||
let attribute;
|
||||
let productType;
|
||||
let simpleProductType;
|
||||
let category;
|
||||
let shippingMethod;
|
||||
let address;
|
||||
|
||||
before(() => {
|
||||
cy.clearSessionData().loginUserViaRequest();
|
||||
shippingUtils.deleteShippingStartsWith(startsWith);
|
||||
productUtils.deleteProductsStartsWith(startsWith);
|
||||
deleteChannelsStartsWith(startsWith);
|
||||
|
||||
const name = `${startsWith}${faker.datatype.number()}`;
|
||||
const simpleProductTypeName = `${startsWith}${faker.datatype.number()}`;
|
||||
getDefaultChannel()
|
||||
.then(channel => {
|
||||
defaultChannel = channel;
|
||||
cy.fixture("addresses");
|
||||
})
|
||||
.then(fixtureAddresses => {
|
||||
address = fixtureAddresses.plAddress;
|
||||
shippingUtils.createShipping({
|
||||
channelId: defaultChannel.id,
|
||||
name,
|
||||
address
|
||||
});
|
||||
})
|
||||
.then(
|
||||
({
|
||||
warehouse: warehouseResp,
|
||||
shippingMethod: shippingMethodResp
|
||||
}) => {
|
||||
warehouse = warehouseResp;
|
||||
shippingMethod = shippingMethodResp;
|
||||
}
|
||||
);
|
||||
productUtils
|
||||
.createTypeAttributeAndCategoryForProduct({ name, attributeValues })
|
||||
.then(
|
||||
({
|
||||
attribute: attributeResp,
|
||||
productType: productTypeResp,
|
||||
category: categoryResp
|
||||
}) => {
|
||||
attribute = attributeResp;
|
||||
productType = productTypeResp;
|
||||
category = categoryResp;
|
||||
createTypeProduct({
|
||||
name: simpleProductTypeName,
|
||||
attributeId: attribute.id,
|
||||
hasVariants: false
|
||||
});
|
||||
}
|
||||
)
|
||||
.then(type => {
|
||||
simpleProductType = type;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.clearSessionData().loginUserViaRequest(
|
||||
"auth",
|
||||
ONE_PERMISSION_USERS.product
|
||||
);
|
||||
});
|
||||
|
||||
it("should create variant without sku by variant creator", () => {
|
||||
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({
|
||||
warehouseId: warehouse.id,
|
||||
price,
|
||||
attribute: attributeValues[0]
|
||||
});
|
||||
getProductVariants(createdProduct.id, defaultChannel.slug);
|
||||
})
|
||||
.then(([variant]) => {
|
||||
expect(variant).to.have.property("name", attributeValues[0]);
|
||||
expect(variant).to.have.property("price", price);
|
||||
createWaitingForCaptureOrder({
|
||||
channelSlug: defaultChannel.slug,
|
||||
email: "example@example.com",
|
||||
variantsList: [variant],
|
||||
shippingMethodId: shippingMethod.id,
|
||||
address
|
||||
});
|
||||
})
|
||||
.then(({ order }) => {
|
||||
expect(order.id).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
it("should create variant without sku", () => {
|
||||
const name = `${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({
|
||||
warehouseName: warehouse.name,
|
||||
attributeName: variants[1].name,
|
||||
price: variants[1].price,
|
||||
channelName: defaultChannel.name
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
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);
|
||||
createWaitingForCaptureOrder({
|
||||
channelSlug: defaultChannel.slug,
|
||||
email: "example@example.com",
|
||||
variantsList: [secondVariant],
|
||||
shippingMethodId: shippingMethod.id,
|
||||
address
|
||||
});
|
||||
})
|
||||
.then(({ order }) => {
|
||||
expect(order.id).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
it("should create simple product without sku", () => {
|
||||
const name = `${startsWith}${faker.datatype.number()}`;
|
||||
cy.visit(urlList.products)
|
||||
.get(PRODUCTS_LIST.createProductBtn)
|
||||
.click()
|
||||
.get(PRODUCT_DETAILS.productNameInput)
|
||||
.type(name)
|
||||
.fillAutocompleteSelect(
|
||||
PRODUCT_DETAILS.productTypeInput,
|
||||
simpleProductType.name
|
||||
)
|
||||
.fillAutocompleteSelect(PRODUCT_DETAILS.categoryInput);
|
||||
selectChannelInDetailsPages(defaultChannel.name);
|
||||
cy.get(PRODUCT_DETAILS.addWarehouseButton).click();
|
||||
cy.contains(PRODUCT_DETAILS.warehouseOption, warehouse.name)
|
||||
.click()
|
||||
.get(PRODUCT_DETAILS.stockInput)
|
||||
.clearAndType(10)
|
||||
.get(PRODUCT_DETAILS.costPriceInput)
|
||||
.type(10)
|
||||
.get(PRODUCT_DETAILS.sellingPriceInput)
|
||||
.type(10)
|
||||
.get(AVAILABLE_CHANNELS_FORM.assignedChannels)
|
||||
.click()
|
||||
.get(
|
||||
`${AVAILABLE_CHANNELS_FORM.availableForPurchaseRadioButtons}${AVAILABLE_CHANNELS_FORM.radioButtonsValueTrue}`
|
||||
)
|
||||
.click()
|
||||
.get(
|
||||
`${AVAILABLE_CHANNELS_FORM.publishedRadioButtons}${AVAILABLE_CHANNELS_FORM.radioButtonsValueTrue}`
|
||||
)
|
||||
.click()
|
||||
.addAliasToGraphRequest("VariantCreate")
|
||||
.get(BUTTON_SELECTORS.confirm)
|
||||
.click()
|
||||
.confirmationMessageShouldDisappear()
|
||||
.wait("@VariantCreate")
|
||||
.then(({ response }) => {
|
||||
const variants = [
|
||||
response.body.data.productVariantCreate.productVariant
|
||||
];
|
||||
createWaitingForCaptureOrder({
|
||||
channelSlug: defaultChannel.slug,
|
||||
email: "example@example.com",
|
||||
variantsList: variants,
|
||||
shippingMethodId: shippingMethod.id,
|
||||
address
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -90,6 +90,23 @@ export function deleteProductType(productTypeId) {
|
|||
return cy.sendRequestWithQuery(mutation);
|
||||
}
|
||||
|
||||
export function productAttributeAssignmentUpdate({
|
||||
productTypeId,
|
||||
attributeId,
|
||||
variantSelection = true
|
||||
}) {
|
||||
const mutation = `mutation {
|
||||
productAttributeAssignmentUpdate(
|
||||
operations: {id: "${attributeId}", variantSelection: ${variantSelection}} productTypeId:"${productTypeId}") {
|
||||
errors {
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy.sendRequestWithQuery(mutation);
|
||||
}
|
||||
|
||||
export function getProductType(productTypeId) {
|
||||
const query = `query{
|
||||
productType(id:"${productTypeId}"){
|
||||
|
|
|
@ -22,6 +22,7 @@ export const getProductVariants = (productId, channelSlug) => {
|
|||
getProductDetails(productId, channelSlug).then(resp => {
|
||||
const variantsList = resp.body.data.product.variants;
|
||||
return variantsList.map(element => ({
|
||||
id: element.id,
|
||||
name: element.name,
|
||||
price: element.pricing.price.gross.amount
|
||||
}));
|
||||
|
|
|
@ -6,12 +6,18 @@ import { BUTTON_SELECTORS } from "../../../../elements/shared/button-selectors";
|
|||
import { selectChannelVariantInDetailsPage } from "../../channelsPage";
|
||||
import { fillUpPriceList } from "./priceListComponent";
|
||||
|
||||
export function variantsShouldBeVisible({ name, price }) {
|
||||
cy.contains(PRODUCT_DETAILS.variantRow, name).should("be.visible");
|
||||
export function variantsShouldBeVisible({ price }) {
|
||||
cy.get(PRODUCT_DETAILS.variantRow).should("be.visible");
|
||||
cy.contains(PRODUCT_DETAILS.variantPrice, price);
|
||||
}
|
||||
|
||||
export function createFirstVariant({ sku, warehouseId, price, attribute }) {
|
||||
export function createFirstVariant({
|
||||
sku,
|
||||
warehouseId,
|
||||
price,
|
||||
attribute,
|
||||
quantity = 1
|
||||
}) {
|
||||
cy.get(PRODUCT_DETAILS.addVariantsButton).click();
|
||||
cy.get(PRODUCT_DETAILS.addVariantsOptionDialog.optionMultiple).click();
|
||||
cy.get(BUTTON_SELECTORS.submit).click();
|
||||
|
@ -24,11 +30,14 @@ export function createFirstVariant({ sku, warehouseId, price, attribute }) {
|
|||
fillUpPriceList(price);
|
||||
cy.get(`[name*='${warehouseId}']`)
|
||||
.click()
|
||||
.get(VARIANTS_SELECTORS.stockInput)
|
||||
.type(quantity)
|
||||
.get(VARIANTS_SELECTORS.nextButton)
|
||||
.click()
|
||||
.get(VARIANTS_SELECTORS.skuInput)
|
||||
.type(sku)
|
||||
.addAliasToGraphRequest("ProductVariantBulkCreate")
|
||||
.click();
|
||||
if (sku) {
|
||||
cy.get(VARIANTS_SELECTORS.skuInput).type(sku);
|
||||
}
|
||||
cy.addAliasToGraphRequest("ProductVariantBulkCreate")
|
||||
.get(VARIANTS_SELECTORS.nextButton)
|
||||
.click()
|
||||
.waitForRequestAndCheckIfNoErrors("@ProductVariantBulkCreate")
|
||||
|
@ -43,7 +52,8 @@ export function createVariant({
|
|||
attributeName,
|
||||
price,
|
||||
costPrice = price,
|
||||
channelName
|
||||
channelName,
|
||||
quantity = 10
|
||||
}) {
|
||||
cy.get(PRODUCT_DETAILS.addVariantsButton)
|
||||
.click()
|
||||
|
@ -51,15 +61,18 @@ export function createVariant({
|
|||
.click()
|
||||
.get(VARIANTS_SELECTORS.attributeOption)
|
||||
.contains(attributeName)
|
||||
.click()
|
||||
.get(VARIANTS_SELECTORS.skuInputInAddVariant)
|
||||
.type(sku)
|
||||
.get(VARIANTS_SELECTORS.addWarehouseButton)
|
||||
.click();
|
||||
cy.contains(VARIANTS_SELECTORS.warehouseOption, warehouseName).click({
|
||||
force: true
|
||||
});
|
||||
cy.get(VARIANTS_SELECTORS.saveButton)
|
||||
if (sku) {
|
||||
cy.get(VARIANTS_SELECTORS.skuInputInAddVariant).type(sku);
|
||||
}
|
||||
cy.get(VARIANTS_SELECTORS.addWarehouseButton).click();
|
||||
cy.contains(VARIANTS_SELECTORS.warehouseOption, warehouseName)
|
||||
.click({
|
||||
force: true
|
||||
})
|
||||
.get(VARIANTS_SELECTORS.stockInput)
|
||||
.type(quantity)
|
||||
.get(VARIANTS_SELECTORS.saveButton)
|
||||
.click()
|
||||
.get(BUTTON_SELECTORS.back)
|
||||
.click()
|
||||
|
|
|
@ -375,6 +375,7 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
|||
</TableCell>
|
||||
<TableCell className={classes.colQuantity}>
|
||||
<TextField
|
||||
data-test-id="stock-input"
|
||||
disabled={disabled}
|
||||
fullWidth
|
||||
inputProps={{
|
||||
|
|
|
@ -203,6 +203,7 @@ const ProductVariantCreatorStock: React.FC<ProductVariantCreatorStockProps> = pr
|
|||
}
|
||||
</Typography>
|
||||
<TextField
|
||||
data-test-id="stock-input"
|
||||
fullWidth
|
||||
inputProps={{
|
||||
min: 0,
|
||||
|
|
|
@ -184251,6 +184251,7 @@ exports[`Storyshots Views / Products / Create multiple variants / prices and SKU
|
|||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
data-test-id="stock-input"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
|
||||
|
@ -184291,6 +184292,7 @@ exports[`Storyshots Views / Products / Create multiple variants / prices and SKU
|
|||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
data-test-id="stock-input"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
|
||||
|
@ -184331,6 +184333,7 @@ exports[`Storyshots Views / Products / Create multiple variants / prices and SKU
|
|||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
data-test-id="stock-input"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
|
||||
|
@ -185160,6 +185163,7 @@ exports[`Storyshots Views / Products / Create multiple variants / prices and SKU
|
|||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
|
||||
data-test-id="stock-input"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
|
||||
|
|
Loading…
Reference in a new issue