Fix tests for SKU (#2924)
* add tests update and tc ids * move test to proper file and refactor * update before for createProductWithoutSku * update before for updatingProductsWithoutSku * add function for create simple product
This commit is contained in:
parent
c60f6f870c
commit
7545bc152b
6 changed files with 262 additions and 132 deletions
|
@ -10,15 +10,24 @@ import { urlList } from "../../../fixtures/urlList";
|
|||
import { ONE_PERMISSION_USERS } from "../../../fixtures/users";
|
||||
import { updateVariantWarehouse } from "../../../support/api/requests/Product";
|
||||
import { createTypeProduct } from "../../../support/api/requests/ProductType";
|
||||
import {
|
||||
deleteChannelsStartsWith,
|
||||
getDefaultChannel,
|
||||
} from "../../../support/api/utils/channelsUtils";
|
||||
import { deleteChannelsStartsWith } 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 { enterVariantEditPage } from "../../../support/pages/catalog/products/productDetailsPage";
|
||||
import { selectChannelsForVariant } from "../../../support/pages/catalog/products/VariantsPage";
|
||||
import { getProductVariants } from "../../../support/api/utils/storeFront/storeFrontProductUtils";
|
||||
import { deleteWarehouseStartsWith } from "../../../support/api/utils/warehouseUtils";
|
||||
import {
|
||||
fillUpPriceList,
|
||||
priceInputLists,
|
||||
} from "../../../support/pages/catalog/products/priceListComponent";
|
||||
import {
|
||||
enterVariantEditPage,
|
||||
fillUpProductTypeDialog,
|
||||
} from "../../../support/pages/catalog/products/productDetailsPage";
|
||||
import {
|
||||
createVariant,
|
||||
selectChannelsForVariant,
|
||||
} from "../../../support/pages/catalog/products/VariantsPage";
|
||||
import { selectChannelInDetailsPages } from "../../../support/pages/channelsPage";
|
||||
|
||||
describe("Creating variants", () => {
|
||||
|
@ -39,28 +48,24 @@ describe("Creating variants", () => {
|
|||
shippingUtils.deleteShippingStartsWith(startsWith);
|
||||
productUtils.deleteProductsStartsWith(startsWith);
|
||||
deleteChannelsStartsWith(startsWith);
|
||||
deleteWarehouseStartsWith(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.usAddress;
|
||||
shippingUtils.createShipping({
|
||||
channelId: defaultChannel.id,
|
||||
name,
|
||||
address,
|
||||
});
|
||||
})
|
||||
.then(
|
||||
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
|
||||
warehouse = warehouseResp;
|
||||
shippingMethod = shippingMethodResp;
|
||||
},
|
||||
);
|
||||
|
||||
cy.fixture("addresses").then(fixtureAddresses => {
|
||||
address = fixtureAddresses.plAddress;
|
||||
});
|
||||
|
||||
shippingUtils
|
||||
.createShippingWithDefaultChannelAndAddress(name)
|
||||
.then(resp => {
|
||||
category = resp.category;
|
||||
defaultChannel = resp.defaultChannel;
|
||||
warehouse = resp.warehouse;
|
||||
shippingMethod = resp.shippingMethod;
|
||||
});
|
||||
|
||||
productUtils
|
||||
.createTypeAttributeAndCategoryForProduct({ name, attributeValues })
|
||||
.then(
|
||||
|
@ -91,8 +96,8 @@ describe("Creating variants", () => {
|
|||
);
|
||||
});
|
||||
|
||||
xit(
|
||||
"should create variant without sku",
|
||||
it(
|
||||
"should create variant without sku TC: SALEOR_2807",
|
||||
{ tags: ["@products", "@allEnv"] },
|
||||
() => {
|
||||
const name = `${startsWith}${faker.datatype.number()}`;
|
||||
|
@ -112,12 +117,17 @@ describe("Creating variants", () => {
|
|||
.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,
|
||||
});
|
||||
enterVariantEditPage();
|
||||
cy.get(PRODUCT_DETAILS.addVariantButton)
|
||||
.click()
|
||||
.then(() => {
|
||||
createVariant({
|
||||
attributeName: variants[1].name,
|
||||
price: variants[1].price,
|
||||
channelName: defaultChannel.name,
|
||||
warehouseId: warehouse.id,
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
getProductVariants(createdProduct.id, defaultChannel.slug);
|
||||
|
@ -141,28 +151,25 @@ describe("Creating variants", () => {
|
|||
);
|
||||
|
||||
it(
|
||||
"should create simple product without sku SALEOR_2806",
|
||||
"should create simple product without sku SALEOR_2808",
|
||||
{ tags: ["@products", "@allEnv"] },
|
||||
() => {
|
||||
const name = `${startsWith}${faker.datatype.number()}`;
|
||||
const prices = { sellingPrice: 10, costPrice: 6 };
|
||||
|
||||
cy.visit(urlList.products)
|
||||
.get(PRODUCTS_LIST.createProductBtn)
|
||||
.click();
|
||||
fillUpProductTypeDialog({ productType: simpleProductType.name });
|
||||
cy.get(BUTTON_SELECTORS.submit)
|
||||
.click()
|
||||
.fillAutocompleteSelect(
|
||||
PRODUCTS_LIST.dialogProductTypeInput,
|
||||
simpleProductType.name,
|
||||
);
|
||||
cy.get(BUTTON_SELECTORS.submit).click();
|
||||
cy.get(PRODUCT_DETAILS.productNameInput)
|
||||
.get(PRODUCT_DETAILS.productNameInput)
|
||||
.type(name)
|
||||
.fillAutocompleteSelect(PRODUCT_DETAILS.categoryInput);
|
||||
selectChannelInDetailsPages(defaultChannel.name);
|
||||
cy.get(PRODUCT_DETAILS.costPriceInput)
|
||||
.type(10)
|
||||
.get(PRODUCT_DETAILS.sellingPriceInput)
|
||||
.type(10)
|
||||
.addAliasToGraphRequest("VariantCreate")
|
||||
fillUpPriceList(prices.sellingPrice);
|
||||
fillUpPriceList(prices.costPrice, priceInputLists.costPrice);
|
||||
cy.addAliasToGraphRequest("VariantCreate")
|
||||
.get(BUTTON_SELECTORS.confirm)
|
||||
.click()
|
||||
.confirmationMessageShouldDisappear()
|
||||
|
@ -170,18 +177,16 @@ describe("Creating variants", () => {
|
|||
.then(({ response }) => {
|
||||
const variantId =
|
||||
response.body.data.productVariantCreate.productVariant.id;
|
||||
|
||||
updateVariantWarehouse({ variantId, warehouseId: warehouse.id });
|
||||
updateVariantWarehouse({
|
||||
variantId,
|
||||
warehouseId: warehouse.id,
|
||||
quantity: 10,
|
||||
});
|
||||
});
|
||||
enterVariantEditPage();
|
||||
cy.addAliasToGraphRequest("ProductVariantDetails");
|
||||
selectChannelsForVariant();
|
||||
cy.get(PRODUCT_DETAILS.stockInput)
|
||||
.parents()
|
||||
.contains(warehouse.name)
|
||||
.get(PRODUCT_DETAILS.stockInput)
|
||||
.clearAndType(10)
|
||||
.get(BUTTON_SELECTORS.confirm)
|
||||
cy.get(BUTTON_SELECTORS.confirm)
|
||||
.click()
|
||||
.confirmationMessageShouldDisappear()
|
||||
.wait("@ProductVariantDetails")
|
||||
|
|
|
@ -9,23 +9,15 @@ import { SHARED_ELEMENTS } from "../../../elements/shared/sharedElements";
|
|||
import { productVariantDetailUrl } from "../../../fixtures/urlList";
|
||||
import {
|
||||
createVariant,
|
||||
createVariantForSimpleProduct,
|
||||
getVariant,
|
||||
updateChannelPriceInVariant,
|
||||
} from "../../../support/api/requests/Product";
|
||||
import {
|
||||
createTypeProduct,
|
||||
productAttributeAssignmentUpdate,
|
||||
} from "../../../support/api/requests/ProductType";
|
||||
import { getDefaultChannel } from "../../../support/api/utils/channelsUtils";
|
||||
import { createTypeProduct } from "../../../support/api/requests/ProductType";
|
||||
import { createWaitingForCaptureOrder } from "../../../support/api/utils/ordersUtils";
|
||||
import {
|
||||
createProductInChannelWithoutVariants,
|
||||
createTypeAttributeAndCategoryForProduct,
|
||||
deleteProductsStartsWith,
|
||||
} from "../../../support/api/utils/products/productsUtils";
|
||||
import {
|
||||
createShipping,
|
||||
deleteShippingStartsWith,
|
||||
} from "../../../support/api/utils/shippingUtils";
|
||||
import * as productUtils from "../../../support/api/utils/products/productsUtils";
|
||||
import * as shippingUtils from "../../../support/api/utils/shippingUtils";
|
||||
import { deleteWarehouseStartsWith } from "../../../support/api/utils/warehouseUtils";
|
||||
|
||||
describe("Updating products without sku", () => {
|
||||
const startsWith = "UpdateProductsSku";
|
||||
|
@ -47,55 +39,33 @@ describe("Updating products without sku", () => {
|
|||
|
||||
before(() => {
|
||||
cy.clearSessionData().loginUserViaRequest();
|
||||
deleteProductsStartsWith(startsWith);
|
||||
deleteShippingStartsWith(startsWith);
|
||||
getDefaultChannel()
|
||||
.then(channel => {
|
||||
defaultChannel = channel;
|
||||
cy.fixture("addresses");
|
||||
})
|
||||
.then(fixtureAddresses => {
|
||||
address = fixtureAddresses.plAddress;
|
||||
createShipping({
|
||||
channelId: defaultChannel.id,
|
||||
name,
|
||||
address,
|
||||
productUtils.deleteProductsStartsWith(startsWith);
|
||||
shippingUtils.deleteShippingStartsWith(startsWith);
|
||||
deleteWarehouseStartsWith(startsWith);
|
||||
|
||||
cy.fixture("addresses").then(fixtureAddresses => {
|
||||
address = fixtureAddresses.plAddress;
|
||||
});
|
||||
productUtils
|
||||
.createShippingProductTypeAttributeAndCategory(name, attributeValues)
|
||||
.then(resp => {
|
||||
cy.log(resp);
|
||||
attribute = resp.attribute;
|
||||
productTypeWithVariants = resp.productType;
|
||||
category = resp.category;
|
||||
defaultChannel = resp.defaultChannel;
|
||||
warehouse = resp.warehouse;
|
||||
shippingMethod = resp.shippingMethod;
|
||||
|
||||
createTypeProduct({
|
||||
name: productTypeWithoutVariantsName,
|
||||
attributeId: attribute.id,
|
||||
hasVariants: false,
|
||||
});
|
||||
})
|
||||
.then(
|
||||
({ warehouse: warehouseResp, shippingMethod: shippingMethodResp }) => {
|
||||
warehouse = warehouseResp;
|
||||
shippingMethod = shippingMethodResp;
|
||||
createTypeAttributeAndCategoryForProduct({ name, attributeValues });
|
||||
},
|
||||
)
|
||||
.then(
|
||||
({
|
||||
attribute: attributeResp,
|
||||
productType: productTypeResp,
|
||||
category: categoryResp,
|
||||
}) => {
|
||||
attribute = attributeResp;
|
||||
productTypeWithVariants = productTypeResp;
|
||||
category = categoryResp;
|
||||
productAttributeAssignmentUpdate({
|
||||
productTypeId: productTypeWithVariants.id,
|
||||
attributeId: attribute.id,
|
||||
});
|
||||
createTypeProduct({
|
||||
name: productTypeWithoutVariantsName,
|
||||
attributeId: attribute.id,
|
||||
hasVariants: false,
|
||||
});
|
||||
},
|
||||
)
|
||||
.then(productTypeResp => {
|
||||
productTypeWithoutVariants = productTypeResp;
|
||||
productAttributeAssignmentUpdate({
|
||||
productTypeId: productTypeWithoutVariants.id,
|
||||
attributeId: attribute.id,
|
||||
});
|
||||
createProductInChannelWithoutVariants({
|
||||
productUtils.createProductInChannelWithoutVariants({
|
||||
name,
|
||||
channelId: defaultChannel.id,
|
||||
attributeId: attribute.id,
|
||||
|
@ -109,9 +79,51 @@ describe("Updating products without sku", () => {
|
|||
beforeEach(() => {
|
||||
cy.clearSessionData().loginUserViaRequest();
|
||||
});
|
||||
it(
|
||||
"should be able to add SKU to simple product TC: SALEOR_2802",
|
||||
{ tags: ["@products", "@allEnv"] },
|
||||
() => {
|
||||
const productName = `${startsWith}${faker.datatype.number()}`;
|
||||
const sku = `Sku${faker.datatype.number()}`;
|
||||
let product;
|
||||
let variant;
|
||||
|
||||
const productData = {
|
||||
name: productName,
|
||||
attributeId: attribute.id,
|
||||
categoryId: category.id,
|
||||
productTypeId: productTypeWithoutVariants.id,
|
||||
channelId: defaultChannel.id,
|
||||
warehouseId: warehouse.id,
|
||||
quantityInWarehouse: 10,
|
||||
trackInventory: false,
|
||||
};
|
||||
createSimpleProductWithVariant(productData).then(resp => {
|
||||
product = resp.product;
|
||||
variant = resp.variant;
|
||||
|
||||
cy.visitAndWaitForProgressBarToDisappear(
|
||||
productVariantDetailUrl(product.id, variant.id),
|
||||
)
|
||||
.get(SHARED_ELEMENTS.skeleton)
|
||||
.should("not.exist")
|
||||
.get(VARIANTS_SELECTORS.skuInput)
|
||||
.type(sku)
|
||||
.addAliasToGraphRequest("VariantUpdate")
|
||||
.get(BUTTON_SELECTORS.confirm)
|
||||
.click()
|
||||
.waitForRequestAndCheckIfNoErrors("@VariantUpdate")
|
||||
.then(({ response }) => {
|
||||
const responseSku =
|
||||
response.body.data.productVariantUpdate.productVariant.sku;
|
||||
expect(responseSku).to.equal(sku);
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it(
|
||||
"should add sku to variant",
|
||||
"should add sku to variant TC: SALEOR_2803",
|
||||
{ tags: ["@products", "@allEnv", "@stable"] },
|
||||
() => {
|
||||
const sku = "NewSku";
|
||||
|
@ -146,7 +158,7 @@ describe("Updating products without sku", () => {
|
|||
);
|
||||
|
||||
it(
|
||||
"should remove sku from variant",
|
||||
"should remove sku from variant TC: SALEOR_2805",
|
||||
{ tags: ["@products", "@allEnv", "@stable"] },
|
||||
() => {
|
||||
let variant;
|
||||
|
@ -192,4 +204,41 @@ describe("Updating products without sku", () => {
|
|||
expect(order.id).to.be.ok;
|
||||
});
|
||||
}
|
||||
|
||||
function createSimpleProductWithVariant({
|
||||
name,
|
||||
channelId,
|
||||
warehouseId = null,
|
||||
quantityInWarehouse = 10,
|
||||
productTypeId,
|
||||
attributeId,
|
||||
categoryId,
|
||||
trackInventory = true,
|
||||
}) {
|
||||
let product;
|
||||
let variant;
|
||||
|
||||
return productUtils
|
||||
.createProductInChannelWithoutVariants({
|
||||
name,
|
||||
channelId,
|
||||
productTypeId,
|
||||
attributeId,
|
||||
categoryId,
|
||||
})
|
||||
.then(productResp => {
|
||||
product = productResp;
|
||||
createVariantForSimpleProduct({
|
||||
productId: product.id,
|
||||
warehouseId,
|
||||
quantityInWarehouse,
|
||||
trackInventory,
|
||||
});
|
||||
})
|
||||
.then(variantResp => {
|
||||
variant = variantResp;
|
||||
updateChannelPriceInVariant(variant.id, defaultChannel.id);
|
||||
})
|
||||
.then(() => ({ product, variant }));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -211,6 +211,58 @@ export function createVariant({
|
|||
.its("body.data.productVariantBulkCreate.productVariants");
|
||||
}
|
||||
|
||||
export function createVariantForSimpleProduct({
|
||||
productId,
|
||||
sku,
|
||||
warehouseId,
|
||||
quantityInWarehouse = 1,
|
||||
trackInventory = true,
|
||||
weight = 1,
|
||||
attributeId,
|
||||
attributeName = "value",
|
||||
}) {
|
||||
const skuLines = getValueWithDefault(sku, `sku: "${sku}"`);
|
||||
|
||||
const attributeLines = getValueWithDefault(
|
||||
attributeId,
|
||||
`attributes: [{
|
||||
id:"${attributeId}"
|
||||
values: ["${attributeName}"]
|
||||
}]`,
|
||||
"attributes:[]",
|
||||
);
|
||||
|
||||
const stocks = getValueWithDefault(
|
||||
warehouseId,
|
||||
`stocks:{
|
||||
warehouse:"${warehouseId}"
|
||||
quantity:${quantityInWarehouse}
|
||||
}`,
|
||||
);
|
||||
const mutation = `mutation{
|
||||
productVariantCreate(input: {
|
||||
${attributeLines}
|
||||
${skuLines}
|
||||
trackInventory:${trackInventory}
|
||||
weight: ${weight}
|
||||
product: "${productId}"
|
||||
${stocks}
|
||||
}) {
|
||||
productVariant{
|
||||
id
|
||||
name
|
||||
}
|
||||
errors{
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}`;
|
||||
return cy
|
||||
.sendRequestWithQuery(mutation)
|
||||
.its("body.data.productVariantCreate.productVariant");
|
||||
}
|
||||
|
||||
export function deleteProduct(productId) {
|
||||
const mutation = `mutation{
|
||||
productDelete(id: "${productId}"){
|
||||
|
@ -304,12 +356,18 @@ export function updateVariantPrice({ variantId, channelId, price }) {
|
|||
.its("body.data.productVariantChannelListingUpdate");
|
||||
}
|
||||
|
||||
export function updateVariantWarehouse({ variantId, warehouseId }) {
|
||||
export function updateVariantWarehouse({ variantId, warehouseId, quantity }) {
|
||||
const quantityInWarehouse = getValueWithDefault(
|
||||
quantity,
|
||||
`quantity:${quantity}`,
|
||||
`quantity: 0`,
|
||||
);
|
||||
|
||||
const mutation = `mutation{
|
||||
productVariantStocksCreate(variantId: "${variantId}",
|
||||
stocks:
|
||||
{
|
||||
quantity: 0,
|
||||
${quantityInWarehouse}
|
||||
warehouse: "${warehouseId}"
|
||||
}
|
||||
){
|
||||
|
|
|
@ -444,20 +444,29 @@ export function createShippingProductTypeAttributeAndCategory(
|
|||
) {
|
||||
let warehouse;
|
||||
let defaultChannel;
|
||||
let shippingMethod;
|
||||
|
||||
return createShippingWithDefaultChannelAndAddress(name)
|
||||
.then(({ warehouse: warehouseResp, defaultChannel: channel }) => {
|
||||
warehouse = warehouseResp;
|
||||
defaultChannel = channel;
|
||||
.then(
|
||||
({
|
||||
warehouse: warehouseResp,
|
||||
defaultChannel: channel,
|
||||
shippingMethod: shippingMethodResp,
|
||||
}) => {
|
||||
warehouse = warehouseResp;
|
||||
defaultChannel = channel;
|
||||
shippingMethod = shippingMethodResp;
|
||||
|
||||
createTypeAttributeAndCategoryForProduct({ name, attributeValues });
|
||||
})
|
||||
createTypeAttributeAndCategoryForProduct({ name, attributeValues });
|
||||
},
|
||||
)
|
||||
.then(({ attribute, productType, category }) => ({
|
||||
attribute,
|
||||
productType,
|
||||
category,
|
||||
warehouse,
|
||||
defaultChannel,
|
||||
shippingMethod,
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ Cypress.Commands.add("fillAutocompleteSelect", (selectSelector, option) => {
|
|||
});
|
||||
cy.contains(BUTTON_SELECTORS.selectOption, option)
|
||||
.should("be.visible")
|
||||
.click();
|
||||
.click({ force: true });
|
||||
cy.wrap(option).as("option");
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -3,6 +3,7 @@ import { PRODUCT_DETAILS } from "../../../../elements/catalog/products/product-d
|
|||
import { VARIANTS_SELECTORS } from "../../../../elements/catalog/products/variants-selectors";
|
||||
import { AVAILABLE_CHANNELS_FORM } from "../../../../elements/channels/available-channels-form";
|
||||
import { BUTTON_SELECTORS } from "../../../../elements/shared/button-selectors";
|
||||
import { updateVariantWarehouse } from "../../../../support/api/requests/Product";
|
||||
import { formatDate } from "../../../formatData/formatDate";
|
||||
import { selectChannelVariantInDetailsPage } from "../../channelsPage";
|
||||
|
||||
|
@ -14,6 +15,7 @@ export function variantsShouldBeVisible({ price }) {
|
|||
export function createVariant({
|
||||
sku,
|
||||
warehouseName,
|
||||
warehouseId,
|
||||
attributeName,
|
||||
price,
|
||||
costPrice = price,
|
||||
|
@ -23,6 +25,7 @@ export function createVariant({
|
|||
attributeName,
|
||||
sku,
|
||||
warehouseName,
|
||||
warehouseId,
|
||||
quantity,
|
||||
costPrice,
|
||||
price,
|
||||
|
@ -62,11 +65,21 @@ export function fillUpVariantDetails({
|
|||
attributeType = "DROPDOWN",
|
||||
sku,
|
||||
warehouseName,
|
||||
warehouseId,
|
||||
quantity,
|
||||
costPrice,
|
||||
price,
|
||||
}) {
|
||||
selectAttributeWithType({ attributeType, attributeName });
|
||||
cy.get(PRICE_LIST.priceInput)
|
||||
.each(input => {
|
||||
cy.wrap(input).type(price);
|
||||
})
|
||||
.get(PRICE_LIST.costPriceInput)
|
||||
.each(input => {
|
||||
cy.wrap(input).type(costPrice);
|
||||
});
|
||||
|
||||
if (sku) {
|
||||
cy.get(VARIANTS_SELECTORS.skuInputInAddVariant).type(sku);
|
||||
}
|
||||
|
@ -79,17 +92,13 @@ export function fillUpVariantDetails({
|
|||
.get(VARIANTS_SELECTORS.stockInput)
|
||||
.type(quantity);
|
||||
}
|
||||
|
||||
cy.get(PRICE_LIST.priceInput)
|
||||
.each(input => {
|
||||
cy.wrap(input).type(price);
|
||||
})
|
||||
.get(PRICE_LIST.costPriceInput)
|
||||
.each(input => {
|
||||
cy.wrap(input).type(costPrice);
|
||||
if (warehouseId) {
|
||||
saveVariant().then(({ response }) => {
|
||||
const variantId =
|
||||
response.body.data.productVariantCreate.productVariant.id;
|
||||
updateVariantWarehouse({ variantId, warehouseId, quantity });
|
||||
});
|
||||
|
||||
cy.get(VARIANTS_SELECTORS.saveButton).click();
|
||||
}
|
||||
}
|
||||
|
||||
export function fillUpVariantAttributeAndSku({ attributeName, sku }) {
|
||||
|
|
Loading…
Reference in a new issue