diff --git a/tests/pw/feature-map/feature-map.yml b/tests/pw/feature-map/feature-map.yml index 4e3150575c..ec458ee1ef 100644 --- a/tests/pw/feature-map/feature-map.yml +++ b/tests/pw/feature-map/feature-map.yml @@ -177,6 +177,16 @@ vendor can add product linked products (cross-sells): true vendor can remove product linked products (up-sells): true vendor can remove product linked products (cross-sells): true + vendor can add product attribute: true + vendor can create product attribute term: true + vendor can remove product attribute: true + vendor can remove product attribute term: true + vendor can add product bulk discount options: true + vendor can update product bulk discount options: true + vendor can remove product bulk discount options: true + vendor can add product geolocation (individual): true + vendor can update product geolocation (individual): true + vendor can remove product geolocation (individual): true - page: 'MyOrders' features: diff --git a/tests/pw/pages/productsPage.ts b/tests/pw/pages/productsPage.ts index a95ec338d4..f10a7c22c2 100644 --- a/tests/pw/pages/productsPage.ts +++ b/tests/pw/pages/productsPage.ts @@ -1293,6 +1293,90 @@ export class ProductsPage extends AdminPage { } } + // add product attribute + async addProductAttribute(productName: string, attribute: product['productInfo']['attribute'], addTerm: boolean = false): Promise { + await this.goToProductEdit(productName); + await this.selectByLabel(productsVendor.attribute.customAttribute, attribute.attributeName); + await this.clickAndWaitForResponse(data.subUrls.ajax, productsVendor.attribute.addAttribute); + await this.check(productsVendor.attribute.visibleOnTheProductPage); + await this.click(productsVendor.attribute.selectAll); + await this.notToHaveCount(productsVendor.attribute.attributeTerms, 0); + if (addTerm) { + await this.click(productsVendor.attribute.addNew); + await this.clearAndType(productsVendor.attribute.attributeTermInput, attribute.attributeTerm); + await this.clickAndWaitForResponse(data.subUrls.ajax, productsVendor.attribute.confirmAddAttributeTerm); + await this.toBeVisible(productsVendor.attribute.selectedAttributeTerm(attribute.attributeTerm)); + } + await this.clickAndWaitForResponse(data.subUrls.ajax, productsVendor.attribute.saveAttribute); + await this.saveProduct(); + await this.toBeVisible(productsVendor.attribute.savedAttribute(attribute.attributeName)); + } + + // remove product attribute + async removeProductAttribute(productName: string, attribute: string): Promise { + await this.goToProductEdit(productName); + await this.click(productsVendor.attribute.removeAttribute(attribute)); + await this.click(productsVendor.attribute.confirmRemoveAttribute); + await this.notToBeVisible(productsVendor.attribute.savedAttribute(attribute)); + await this.saveProduct(); + await this.notToBeVisible(productsVendor.attribute.savedAttribute(attribute)); + } + + // remove product attribute term + async removeProductAttributeTerm(productName: string, attribute: string, attributeTerm: string): Promise { + await this.goToProductEdit(productName); + await this.click(productsVendor.attribute.savedAttribute(attribute)); + await this.click(productsVendor.attribute.removeSelectedAttributeTerm(attributeTerm)); + await this.press('Escape'); // shift focus from element + await this.notToBeVisible(productsVendor.attribute.selectedAttributeTerm(attributeTerm)); + await this.clickAndWaitForResponse(data.subUrls.ajax, productsVendor.attribute.saveAttribute); + await this.saveProduct(); + await this.click(productsVendor.attribute.savedAttribute(attribute)); + await this.notToBeVisible(productsVendor.attribute.selectedAttributeTerm(attributeTerm)); + } + + // add product discount options + async addProductBulkDiscountOptions(productName: string, quantityDiscount: product['productInfo']['quantityDiscount']): Promise { + await this.goToProductEdit(productName); + await this.check(productsVendor.bulkDiscount.enableBulkDiscount); + await this.clearAndType(productsVendor.bulkDiscount.lotMinimumQuantity, quantityDiscount.minimumQuantity); + await this.clearAndType(productsVendor.bulkDiscount.lotDiscountInPercentage, quantityDiscount.discountPercentage); + await this.saveProduct(); + await this.toBeChecked(productsVendor.bulkDiscount.enableBulkDiscount); + await this.toHaveValue(productsVendor.bulkDiscount.lotMinimumQuantity, quantityDiscount.minimumQuantity); + await this.toHaveValue(productsVendor.bulkDiscount.lotDiscountInPercentage, quantityDiscount.discountPercentage); + } + + // add product discount options + async removeProductBulkDiscountOptions(productName: string): Promise { + await this.goToProductEdit(productName); + await this.uncheck(productsVendor.bulkDiscount.enableBulkDiscount); + await this.saveProduct(); + await this.notToBeChecked(productsVendor.bulkDiscount.enableBulkDiscount); + } + + // dokan pro modules + + // add product geolocation + async addProductGeolocation(productName: string, location: string): Promise { + await this.goToProductEdit(productName); + await this.uncheck(productsVendor.geolocation.sameAsStore); + await this.typeAndWaitForResponse(data.subUrls.gmap, productsVendor.geolocation.productLocation, location); + await this.press(data.key.arrowDown); + await this.press(data.key.enter); + await this.saveProduct(); + await this.notToBeChecked(productsVendor.geolocation.sameAsStore); + await this.toHaveValue(productsVendor.geolocation.productLocation, location); + } + + // remove product geolocation + async removeProductGeolocation(productName: string): Promise { + await this.goToProductEdit(productName); + await this.check(productsVendor.geolocation.sameAsStore); + await this.saveProduct(); + await this.toBeChecked(productsVendor.geolocation.sameAsStore); + } + // add product EU compliance async addProductEuCompliance(productName: string, euCompliance: product['productInfo']['euCompliance']): Promise { await this.goToProductEdit(productName); diff --git a/tests/pw/tests/e2e/productsDetails.spec.ts b/tests/pw/tests/e2e/productsDetails.spec.ts index 838e343afb..dc819ea603 100644 --- a/tests/pw/tests/e2e/productsDetails.spec.ts +++ b/tests/pw/tests/e2e/productsDetails.spec.ts @@ -356,4 +356,62 @@ test.describe('Product details functionality test', () => { test('vendor can remove product linked products (cross-sells)', { tag: ['@pro', '@vendor'] }, async () => { await vendor.removeProductLinkedProducts(productName, data.product.productInfo.linkedProducts, 'cross-sells'); }); + + // attribute + + test('vendor can add product attribute', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.addProductAttribute(productName1, data.product.productInfo.attribute); + }); + + // todo: refactor below tests + test('vendor can create product attribute term', { tag: ['@pro', '@vendor'] }, async () => { + const [, , , attributeName] = await apiUtils.createAttributeTerm(payloads.createAttribute(), payloads.createAttributeTerm(), payloads.adminAuth); + const [, , productName] = await apiUtils.createProduct(payloads.createProduct(), payloads.vendorAuth); + await vendor.addProductAttribute(productName, { ...data.product.productInfo.attribute, attributeName: attributeName }, true); + }); + + test('vendor can remove product attribute', { tag: ['@pro', '@vendor'] }, async () => { + const [, attributeId, , attributeName, attributeTerm] = await apiUtils.createAttributeTerm(payloads.createAttribute(), payloads.createAttributeTerm(), payloads.adminAuth); + const attributes = { id: attributeId, name: attributeName, options: [attributeTerm] }; + const [, , productName] = await apiUtils.createProduct({ ...payloads.createProduct(), attributes: [attributes] }, payloads.vendorAuth); + await vendor.removeProductAttribute(productName, attributeName); + }); + + test('vendor can remove product attribute term', { tag: ['@pro', '@vendor'] }, async () => { + const [, attributeId, , attributeName, attributeTerm] = await apiUtils.createAttributeTerm(payloads.createAttribute(), payloads.createAttributeTerm(), payloads.adminAuth); + const [, , , , attributeTerm2] = await apiUtils.createAttributeTerm(payloads.createAttribute(), payloads.createAttributeTerm(), payloads.adminAuth); + const attributes = { id: attributeId, name: attributeName, options: [attributeTerm, attributeTerm2] }; + const [, , productName] = await apiUtils.createProduct({ ...payloads.createProduct(), attributes: [attributes] }, payloads.vendorAuth); + await vendor.removeProductAttributeTerm(productName, attributeName, attributeTerm2); + }); + + // todo: vendor cant add already added attribute + + // discount options + + test('vendor can add product bulk discount options', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.addProductBulkDiscountOptions(productName1, data.product.productInfo.quantityDiscount); + }); + + test('vendor can update product bulk discount options', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.addProductBulkDiscountOptions(productName, data.product.productInfo.quantityDiscount); + }); + + test('vendor can remove product bulk discount options', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.removeProductBulkDiscountOptions(productName); + }); + + // geolocation + + test('vendor can add product geolocation (individual)', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.addProductGeolocation(productName1, data.product.productInfo.geolocation); + }); + + test('vendor can update product geolocation (individual)', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.addProductGeolocation(productName, data.product.productInfo.geolocation); + }); + + test('vendor can remove product geolocation (individual)', { tag: ['@pro', '@vendor'] }, async () => { + await vendor.removeProductGeolocation(productName); + }); });