diff --git a/.changeset/fifty-gifts-join.md b/.changeset/fifty-gifts-join.md new file mode 100644 index 00000000000..fd4c1b3b25b --- /dev/null +++ b/.changeset/fifty-gifts-join.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": minor +--- + +Adding tests for promotion rules CRUD diff --git a/playwright/data/e2eTestData.ts b/playwright/data/e2eTestData.ts index c8d484086e8..7489efa4ec6 100644 --- a/playwright/data/e2eTestData.ts +++ b/playwright/data/e2eTestData.ts @@ -27,24 +27,102 @@ export const DISCOUNTS = { name: "e2e promotion to be edited", type: "Catalog", id: "UHJvbW90aW9uOjI0MGVkZGVkLWYzMTAtNGUzZi1iNTlmLTFlMGFkYWE2ZWFkYg==" +}, +promotionWithoutRulesToBeDeleted: { + id: "UHJvbW90aW9uOjRmNTQwMDc1LTZlZGMtNDI1NC1hY2U2LTQ2MzdlMGYxZWJhOA==", + name: "e2e Order predicate promotion without rules", + type: "Order", +}, +catalogPromotionWithRulesToBeDeleted: { + id: "UHJvbW90aW9uOmYyY2VjMDhkLTVkYmUtNGVjNC05NTNjLWMzMmQ5ZGQ2MTExYw==", + name: "e2e Catalog promo with rules to be deleted", + type: "Catalog", + rules: [ + { + id: "UHJvbW90aW9uUnVsZTo3NDk4MGVhNS0zNDA2LTQxZGYtOTc3Mi1jMzg3MjNhMWEwOWM=", + name: "rule 1" + }, + + { + id: "UHJvbW90aW9uUnVsZTozMTEyMTE0Yy1hYjFkLTQ3OTktODY0My1jZDhlODMwYzllZmE=", + name: "rule 2" + }, + + { + id: "UHJvbW90aW9uUnVsZTozOWE3Zjc1Zi1jYTdmLTQ4ODgtOGE4NC02NzdjMTVhOGQ4Yjc=", + name: "rule 3" + } + + ], +}, +orderPromotionWithRulesToBeDeleted: { + id: "UHJvbW90aW9uOjA1MDllZjhjLTc0ZTEtNGMyMC1iZDk5LWRhYWU1YWJlZDM1Nw==", + name: "e2e Order promo with rules to be deleted", + type: "Order", + rules: [ + {id: "UHJvbW90aW9uUnVsZTo2ZTdlODNkOS1kNjJlLTQ2YmQtOGE2ZS03OTdlYTZiODk2NmQ=", +name: "rule #1"}, + +{id: "UHJvbW90aW9uUnVsZTo1MzQwNjEyYy0wOWJhLTQxYzUtYmY2Yy1lYmUzZTQ3MjY0MjY=", +name: "rule #2"}, + +{id: "UHJvbW90aW9uUnVsZTpjMzk5ZTM1Ni04OWFhLTQ0MTUtYWE0Zi01NThlZDQ2M2IwNTM=", +name: "rule #3"} + + ], }, - promotionWithoutRulesToBeDeleted: { - id: "UHJvbW90aW9uOjRmNTQwMDc1LTZlZGMtNDI1NC1hY2U2LTQ2MzdlMGYxZWJhOA==", - name: "e2e Order predicate promotion without rules", + orderPromotionWithRulesToBeUpdated: { + id: "UHJvbW90aW9uOjI0Njg3NmM5LWM1ZWMtNDBiYi1iMzExLWE3YWQ2YzBiZDc4NQ==", + name: "e2e Order promo with rules to be updated", type: "Order", + rules: [ + { + id: "UHJvbW90aW9uUnVsZTo3NmEwOGYzZi0xMzZhLTRmNTUtYTc0NS1kZmIxNDZkOWI4ZGQ=", + name: "rule 1", + channel: "Channel-PLN", + channelCurrency: "PLN", + }, + { + id: "UHJvbW90aW9uUnVsZTpjODIxMWJhNS05ZGRmLTRhYzQtOTdlMS04YmM0MzNhZjRlOTM=", + name: "rule 2", + channel: "Channel-PLN", + channelCurrency: "PLN", + giftRewardToBeDeleted:"UHJvZHVjdFZhcmlhbnQ6MjE0" + }, + ], }, - promotionWithRulesToBeDeleted: { - name: "e2e Catalog predicate promotion with rules", - id: "UHJvbW90aW9uOjY0N2M2MzdhLTZjNTEtNDYxZC05MjQ2LTc0YTY0OGM0ZjAxNA==", - }, - cataloguePromotion: { - name: "e2e Catalog promotion for adding rules", - id: "UHJvbW90aW9uOjNmODZjZDAwLTUwNWEtNGVkNC04ZTliLTJmOGI4NGM3NGNlOQ==", + catalogPromotionWithRulesToBeUpdated: { + id: "UHJvbW90aW9uOmJkZTgyNGQ4LTk4ZTktNDM1NC04ODE4LTE1YzVjNmI2MWU2NQ==", + name: "e2e Catalog promo with rules to be updated", + type: "Catalog", + rules: [ + { + id: "UHJvbW90aW9uUnVsZTplOWZjNjc2NS1kNzM2LTRhMzMtYjBiMy1hZWMxY2FmNGVkMDE=", + name: "rule #1", + channel: "Channel-USD", + channelCurrency: "USD", + }, + + { + id: "UHJvbW90aW9uUnVsZToyZjM3ZjRhOS01NjY0LTQzMDEtOWU4Zi0zZTliZGFjNmUyYjE=", + name: "rule 2", + channel: "Channel-USD", + channelCurrency: "USD", + }, + ], }, - orderPromotion: { - name: "e2e Order promotion for adding rules", - id: "UHJvbW90aW9uOjJlM2VhNDkyLTRhMTAtNDYzOS05MWVmLTc1YzQ1OTUxNGQyMQ==", +promotionWithRulesToBeDeleted: { + name: "e2e Catalog predicate promotion with rules", + id: "UHJvbW90aW9uOjY0N2M2MzdhLTZjNTEtNDYxZC05MjQ2LTc0YTY0OGM0ZjAxNA==", +}, +cataloguePromotion:{ + name: "e2e Catalog promotion for adding rules", + id: "UHJvbW90aW9uOjNmODZjZDAwLTUwNWEtNGVkNC04ZTliLTJmOGI4NGM3NGNlOQ==", +}, +orderPromotion: { + name: "e2e Order promotion for adding rules", + id: "UHJvbW90aW9uOjJlM2VhNDkyLTRhMTAtNDYzOS05MWVmLTc1YzQ1OTUxNGQyMQ==", }, } @@ -397,4 +475,4 @@ export const TRANSLATIONS = { name: "Summer collection", info: "Translation used in clear translation test", } -} \ No newline at end of file +} diff --git a/playwright/pages/dialogs/deleteDiscountDialog.ts b/playwright/pages/dialogs/deleteDiscountDialog.ts index 762e29ab506..a24766106cb 100644 --- a/playwright/pages/dialogs/deleteDiscountDialog.ts +++ b/playwright/pages/dialogs/deleteDiscountDialog.ts @@ -5,10 +5,9 @@ export class DeleteDiscountDialog { constructor( page: Page, - readonly deleteButton = page.getByTestId( - "delete-confirmation-button", - ), - ) { + readonly deleteButton = page.getByTestId("delete-confirmation-button") + + ) { this.page = page; } diff --git a/playwright/pages/dialogs/deleteRuleDialog.ts b/playwright/pages/dialogs/deleteRuleDialog.ts new file mode 100644 index 00000000000..c4a8f25813d --- /dev/null +++ b/playwright/pages/dialogs/deleteRuleDialog.ts @@ -0,0 +1,20 @@ +import type { Page } from "@playwright/test"; + +export class DeleteRuleDialog { + readonly page: Page; + + constructor( + page: Page, + readonly deleteRuleButton = page.getByTestId("delete-rule-button"), + readonly cancelButton = page.getByTestId("cancel-delete-rule-button"), + ) { + this.page = page; + } + + async clickConfirmDeleteButton() { + await this.deleteRuleButton.click() + } + async cancelDeletion() { + await this.cancelButton.click(); + } +} diff --git a/playwright/pages/dialogs/promotionRuleDialog.ts b/playwright/pages/dialogs/promotionRuleDialog.ts index bfca843def0..b76a3bb383c 100644 --- a/playwright/pages/dialogs/promotionRuleDialog.ts +++ b/playwright/pages/dialogs/promotionRuleDialog.ts @@ -11,8 +11,7 @@ export class PromotionRuleDialog { "select-option", ), readonly ruleDescriptionInput = page.getByTestId("rich-text-editor-rule-description"), - readonly addFirstRuleConditionButton = page.getByTestId("add-first-condition-button"), - readonly addAnotherRuleConditionButton = page.getByTestId("add-another-condition-button"), + readonly addRuleConditionButton = page.getByTestId("add-condition-button"), readonly addRuleConditionSection = page.getByTestId("conditions-section"), readonly addRuleConditionPredicateDropdown = page.getByTestId("rule-condition-predicate-dropdown"), readonly addRuleConditionTypeDropdown = page.getByTestId("rule-condition-type-dropdown"), @@ -23,8 +22,11 @@ export class PromotionRuleDialog { readonly percentageRewardValueTypeOption = page.getByTestId("percentage-reward-value-type"), readonly fixedRewardValueTypeOption = page.getByTestId("fixed-reward-value-type"), readonly saveRuleButton = page.getByTestId("saveRuleButton"), + readonly ruleConfirmationButton = page.getByTestId("saveRuleButton"), readonly gteConditionValueInput = page.getByTestId("condition-value-0").first(), readonly lteConditionValueInput = page.getByTestId("condition-value-0").last(), + readonly ruleConditionRow = page.getByTestId("rule-condition-row"), + ) { this.page = page; @@ -47,20 +49,16 @@ export class PromotionRuleDialog { await this.ruleNameInput.fill(name); } - async clickFirstAddRuleConditionButton() { - await this.addFirstRuleConditionButton.click(); - await this.addRuleConditionSection.waitFor({ + async clickAddRuleConditionButton() { + await this.addRuleConditionButton.click({force: true}); + await this.ruleConditionRow.last().waitFor({ state: "visible", timeout: 10000, }); } - async clickAnotherAddRuleConditionButton() { - await this.addAnotherRuleConditionButton.click(); - await this.addRuleConditionSection.waitFor({ - state: "visible", - timeout: 10000, - }); + async removeExistingGiftReward(giftRewardId: string, index: number = 0) { + await this.page.getByTestId(`selected-option-${giftRewardId}-${index}`).getByText('✕').click(); } async selectPercentageRewardValueType() { @@ -73,7 +71,7 @@ export class PromotionRuleDialog { async selectOrderRewardType(type: string) { await this.rewardTypeSelect.click(); - await this.selectOption.filter({hasText:type}).click() + await this.selectOption.filter({ hasText: type }).click() } async selectSubtotalDiscountType() { @@ -90,25 +88,15 @@ export class PromotionRuleDialog { async selectPredicate(predicate: string, index: number = 0) { await this.page.getByTestId(`condition-name-${index}`).click(); - await this.page.getByRole("listbox").waitFor({ - state: "visible", - timeout: 10000, - }); - await this.page.getByTestId('select-option').getByText(predicate, { exact: true }).click(); + await this.page.getByRole('option', { name: predicate, exact: true }).click(); } async selectRuleConditionType(type: string) { await this.addRuleConditionTypeDropdown.last().click(); - await this.page.getByRole("listbox").waitFor({ - state: "visible", - timeout: 10000, - }); - await this.page.getByTestId('select-option').getByText(type).click(); + await this.page.getByTestId("select-option").filter({hasText:type}).click(); } async typeRuleConditionValue(value: string, index: number = 0) { - await this.addRuleConditionValueDropdown.locator('[contenteditable="true"]') - await this.page.getByTestId(`condition-value-${index}`).click(); await this.page.getByTestId(`condition-value-${index}`).fill(value); } @@ -118,7 +106,7 @@ export class PromotionRuleDialog { } - async clickRuleConditionPredicateDropdown(){ + async clickRuleConditionPredicateDropdown() { await this.addRuleConditionPredicateDropdown.last().click(); await this.page.getByRole("listbox").waitFor({ state: "visible", @@ -128,21 +116,19 @@ export class PromotionRuleDialog { async selectGiftReward(giftName: string) { await this.rewardGiftSelect.fill(giftName); - await this.page.getByRole("listbox").waitFor({ - state: "visible", - timeout: 10000, - }); - await this.page.getByTestId('select-option').getByText(giftName).first().click(); + await this.page.getByText(giftName).first().click(); } async selectRuleConditionValue(name: string) { - await this.addRuleConditionValueDropdown.locator('[contenteditable="true"]') - await this.page.getByTestId('condition-value-0').click(); - await this.page.getByTestId('condition-value-0').fill(name); - await this.page.getByTestId('select-option').getByText(name, { exact: false }).first().click(); + await this.page.getByTestId("condition-value-0").click() + await this.page.getByRole('option', { name, }).first().click(); } async clickSaveRuleButton() { await this.saveRuleButton.click(); } + + async clickSaveEditedRuleButton() { + await this.ruleConfirmationButton.click(); + } } diff --git a/playwright/pages/discountsPage.ts b/playwright/pages/discountsPage.ts index f329ba812b9..c0c8b5daa9f 100644 --- a/playwright/pages/discountsPage.ts +++ b/playwright/pages/discountsPage.ts @@ -1,15 +1,16 @@ import type { Page } from "@playwright/test"; import { URL_LIST } from "@data/url"; import { DeleteDiscountDialog } from "@dialogs/deleteDiscountDialog"; +import { DeleteRuleDialog } from "@dialogs/deleteRuleDialog"; import { PromotionRuleDialog } from "@pages/dialogs/promotionRuleDialog"; import { BasePage } from "@pages/basePage"; import { date } from "faker"; export class DiscountsPage extends BasePage { - deleteDialog: DeleteDiscountDialog; + deleteDiscountDialog: DeleteDiscountDialog; promotionRuleDialog: PromotionRuleDialog; - + deleteRuleDialog: DeleteRuleDialog; constructor( page: Page, @@ -27,15 +28,20 @@ export class DiscountsPage extends BasePage { readonly addRuleButton = page.getByTestId("add-rule"), readonly editRuleButton = page.getByTestId("rule-edit-button"), readonly deleteRuleButton = page.getByTestId("rule-delete-button"), + readonly ruleName = page.getByTestId("rule-name"), readonly addRuleDialog = page.getByTestId("add-rule-dialog"), readonly ruleSection = page.getByTestId("rule-list"), readonly existingRule = ruleSection.getByTestId("added-rule"), - + readonly ruleLabelWithActions = page.getByTestId("rule-label-with-actions"), + readonly ruleSummaryChip = page.getByTestId("rule-summary-chip"), + readonly ruleValueChip = page.getByTestId("rule-value-chip"), + readonly deleteRuleModal = page.getByTestId("delete-rule-dialog"), ) { super(page) - this.deleteDialog = new DeleteDiscountDialog(page); + this.deleteDiscountDialog = new DeleteDiscountDialog(page); this.promotionRuleDialog = new PromotionRuleDialog(page); -} + this.deleteRuleDialog = new DeleteRuleDialog(page); + } async clickCreateDiscountButton() { await this.createDiscountButton.click(); } @@ -89,18 +95,21 @@ export class DiscountsPage extends BasePage { await this.discountForm.waitFor({ state: "visible", - timeout: 10000, + timeout: 30000, }); } async clickAddRuleButton() { - await this.page.getByTestId('add-rule').click();} + await this.page.getByTestId('add-rule').click(); + } - async clickEditRuleButton(){ - await this.page.getByTestId('rule-edit-button').click();} + async clickEditRuleButton(rule: string) { + await this.existingRule.locator(this.ruleLabelWithActions).filter({ hasText: rule }).locator(this.editRuleButton).click(); + } - async clickDeleteRuleButton() { - await this.deleteRuleButton.click() } + async clickDeleteRuleButton(rule: string) { + await this.existingRule.locator(this.ruleLabelWithActions).filter({ hasText: rule }).locator(this.deleteRuleButton).click(); + } async openPromotionRuleModal() { await this.addRuleButton.click(); diff --git a/playwright/tests/discounts.spec.ts b/playwright/tests/discounts.spec.ts index bbb00af0940..a7d1e95dec8 100644 --- a/playwright/tests/discounts.spec.ts +++ b/playwright/tests/discounts.spec.ts @@ -65,23 +65,25 @@ for (const promotion of promotions) { }); await expect(discounts.discountNameInput).toHaveValue(promotion.name, {timeout: 30000}); await discounts.clickDeleteButton(); - await discounts.deleteDialog.clickConfirmDeleteButton(); + await discounts.deleteDiscountDialog.clickConfirmDeleteButton(); await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); })}; const promotion = DISCOUNTS.cataloguePromotion -const products = { promotionRule: "Products", predicateValue: PRODUCTS.e2eProductWithVariant1.name, predicate: PRODUCTS.e2eProductWithVariant1.name }; -const categories = { promotionRule: "Categories", predicateValue: CATEGORIES.e2eCategory.name, predicate: CATEGORIES.e2eCategory.name }; -const collections = { promotionRule: "Collections", predicateValue: COLLECTIONS.e2eCollection.name, predicate: COLLECTIONS.e2eCollection.name }; const variant = PRODUCTS.e2eProductWithVariant1.variantName const productWithVariant = PRODUCTS.e2eProductWithVariant1.name const productWithVariantName = `${ productWithVariant }` + ` - ` + `${ variant }` -const variants = {promotionRule: "Variants", predicateValue: `${productWithVariant}`, predicate: `${productWithVariantName}`} +const variants = {promotionRule: "Variants", predicateValue: productWithVariantName} +const products = { promotionRule: "Products", predicateValue: PRODUCTS.e2eProductWithVariant1.name }; +const categories = { promotionRule: "Categories", predicateValue: CATEGORIES.e2eCategory.name }; +const collections = { promotionRule: "Collections", predicateValue: COLLECTIONS.e2eCollection.name}; + + const predicateValues = [categories, collections, products, variants]; const rewardValue = "10"; const channelName = CHANNELS.channelPLN.name -for (const { promotionRule, predicateValue, predicate } of predicateValues) { - test(`TC: SALEOR_100 Create ${promotionRule} rule for ${predicate} in a catalogue promotion @discounts @e2e`, async () => { +for (const { promotionRule, predicateValue } of predicateValues) { + test(`TC: SALEOR_100 Create ${promotionRule} rule for ${predicateValue} in a catalogue promotion @discounts @e2e`, async () => { await discounts.gotoExistingDiscount(promotion.id); await discounts.ruleSection.waitFor({ state: "visible", @@ -94,7 +96,7 @@ for (const { promotionRule, predicateValue, predicate } of predicateValues) { await discounts.promotionRuleDialog.selectSingleChannel(channelName); await discounts.promotionRuleDialog.selectPercentageRewardValueType() await discounts.promotionRuleDialog.typeRewardValue(rewardValue); - await discounts.promotionRuleDialog.clickFirstAddRuleConditionButton(); + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown(); await discounts.promotionRuleDialog.selectPredicate(promotionRule); await discounts.promotionRuleDialog.selectRuleConditionValue(predicateValue); @@ -102,7 +104,7 @@ for (const { promotionRule, predicateValue, predicate } of predicateValues) { await discounts.promotionRuleDialog.typeRewardValue(rewardValue); await discounts.promotionRuleDialog.clickSaveRuleButton(); await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); - await expect(discounts.existingRule.filter({ hasText: `Catalog rule: ${name}` })).toContainText(`Catalog rule: ${name}Discount of ${rewardValue}% on the purchase of ${promotionRule}: ${predicate} through the ${channelName}`) + await expect(discounts.existingRule.filter({ hasText: `Catalog rule: ${name}` }).first()).toContainText(`Catalog rule: ${name}Discount of ${rewardValue}% on the purchase of ${promotionRule}: ${predicateValue} through the ${channelName}`) } )}; @@ -127,21 +129,21 @@ for (const { conditionType, value, conditionDesc } of notEqConditions) { await discounts.promotionRuleDialog.selectSubtotalDiscountType() await discounts.promotionRuleDialog.selectFixedRewardValueType() await discounts.promotionRuleDialog.typeRewardValue(rewardValueFixed); - await discounts.promotionRuleDialog.clickFirstAddRuleConditionButton(); + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown(); await discounts.promotionRuleDialog.selectPredicate("Subtotal price"); await discounts.promotionRuleDialog.selectRuleConditionType("is") await discounts.promotionRuleDialog.typeRuleConditionValue("100.00"); - await discounts.promotionRuleDialog.clickAnotherAddRuleConditionButton(); + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown(); await discounts.promotionRuleDialog.selectPredicate("Total price", 1); await discounts.promotionRuleDialog.selectRuleConditionType(conditionType) await discounts.promotionRuleDialog.typeRuleConditionValue(value, 1); await discounts.promotionRuleDialog.clickSaveRuleButton(); await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); - await expect(discounts.existingRule.filter({ hasText: `Order rule: ${name}` })).toContainText(`Order rule: ${name}Discount of ${currency} ${rewardValueFixed} on the purchase of Subtotal price: ${currency} 100.00Total price: ${conditionDesc} ${currency} ${value} through the ${channelName}`) + await expect(discounts.existingRule.filter({ hasText: `Order rule: ${name}` }).first()).toContainText(`Order rule: ${name}Discount of ${currency} ${rewardValueFixed} on the purchase of Subtotal price: ${currency} 100.00Total price: ${conditionDesc} ${currency} ${value} through the ${channelName}`) ;} -)} +)}; const condition1 = { condition: "Subtotal", gte:"150.00", lte: "170.00"} @@ -161,15 +163,97 @@ for (const { condition, lte, gte } of conditionsBetween) { await discounts.promotionRuleDialog.selectSingleChannel(channelName); await discounts.promotionRuleDialog.selectGiftRewardDiscountType() await discounts.promotionRuleDialog.selectGiftReward("Polo Shirt") - await discounts.promotionRuleDialog.clickFirstAddRuleConditionButton(); + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown(); await discounts.promotionRuleDialog.selectPredicate(`${condition} price`); await discounts.promotionRuleDialog.selectRuleConditionType("between") await discounts.promotionRuleDialog.typeRuleConditionBoundaryValues(gte, lte); await discounts.promotionRuleDialog.clickSaveRuleButton(); await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); - await expect(discounts.existingRule.filter({ hasText: `Order rule: ${name}` })).toContainText( + await expect(discounts.existingRule.filter({ hasText: `Order rule: ${name}` }).first()).toContainText( `Order rule: ${name}Discount of Gift on the purchase of ${condition} price: PLN ${ gte }–${ lte } through the ${ channelName }`); } ) } + +const orderRules = [DISCOUNTS.orderPromotionWithRulesToBeUpdated.rules[0], DISCOUNTS.orderPromotionWithRulesToBeUpdated.rules[1]] +for (const rule of orderRules) { + test(`TC: SALEOR_103 Update promotion ${rule.name} from Order promotion @discounts @e2e`, async () => { + await discounts.gotoExistingDiscount(DISCOUNTS.orderPromotionWithRulesToBeUpdated.id); + await discounts.ruleSection.waitFor({ + state: "visible", + timeout: 10000, + }) + await expect(discounts.existingRule.filter({ hasText: `Order rule: ${rule.name}` })).toBeVisible(); + await discounts.clickEditRuleButton(`Order rule: ${rule.name}`); + if ((await (discounts.promotionRuleDialog.ruleConditionRow).isVisible())) { + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); + await discounts.promotionRuleDialog.selectPredicate("Total price",1); + await discounts.promotionRuleDialog.typeRuleConditionValue("13.33", 1); + await discounts.promotionRuleDialog.typeRewardValue("1.00"); + await discounts.promotionRuleDialog.clickSaveEditedRuleButton(); + await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); + await expect(discounts.existingRule.filter({ hasText: `Order rule: ${orderRules[0].name}` }).first()).toContainText(`Order rule: ${orderRules[0].name}Discount of ${orderRules[0].channelCurrency} 1.00 on the purchase of Subtotal price: ${orderRules[0].channelCurrency} 25.00Total price: ${orderRules[0].channelCurrency} 13.33 through the ${orderRules[0].channel}`) +} + else { + const giftRewardToBeDeleted = orderRules[1].giftRewardToBeDeleted ?? ''; + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); + await expect(discounts.promotionRuleDialog.ruleConditionRow.last()).toBeAttached(); + await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown(); + await discounts.promotionRuleDialog.selectPredicate("Subtotal price"); + await discounts.promotionRuleDialog.selectRuleConditionType("is") + await discounts.promotionRuleDialog.typeRuleConditionValue("100.00"); + await discounts.promotionRuleDialog.removeExistingGiftReward(giftRewardToBeDeleted); + await discounts.promotionRuleDialog.selectGiftReward("Blue Hoodie") + await discounts.promotionRuleDialog.clickSaveEditedRuleButton(); + await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); + await expect(discounts.existingRule.filter({ hasText: `Order rule: ${orderRules[1].name}` }).first()).toContainText(`Order rule: ${orderRules[1].name}Discount of Gift on the purchase of Subtotal price: ${orderRules[1].channelCurrency} 100.00 through the ${orderRules[1].channel}`); + } + })} + +const catalogRules = [DISCOUNTS.catalogPromotionWithRulesToBeUpdated.rules[0], DISCOUNTS.catalogPromotionWithRulesToBeUpdated.rules[1]] +for (const rule of catalogRules) { + test(`TC: SALEOR_104 Update promotion ${rule.name} from Catalog promotion @discounts @e2e`, async () => { + await discounts.gotoExistingDiscount(DISCOUNTS.catalogPromotionWithRulesToBeUpdated.id); + await discounts.ruleSection.waitFor({ + state: "visible", + timeout: 10000, + }) + await expect(discounts.existingRule.filter({ hasText: `Catalog rule: ${rule.name}` })).toBeVisible(); + const ruleChips = await discounts.existingRule.filter({ hasText: `Catalog rule: ${rule.name}` }).locator(discounts.ruleSummaryChip).count(); + await discounts.clickEditRuleButton(`Catalog rule: ${rule.name}`); + if (await (discounts.promotionRuleDialog.ruleConditionRow).isVisible()) { + await discounts.promotionRuleDialog.selectRuleConditionValue(PRODUCTS.e2eProductWithVariant1.name); + await discounts.promotionRuleDialog.rewardValueInput.clear(); + await expect (discounts.promotionRuleDialog.rewardValueInput).not.toHaveValue("10.00"); + await discounts.promotionRuleDialog.typeRewardValue("15.00"); + } else { + await discounts.promotionRuleDialog.clickAddRuleConditionButton(); + await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown(); + await discounts.promotionRuleDialog.selectPredicate("Collections"); + await discounts.promotionRuleDialog.selectRuleConditionValue(COLLECTIONS.e2eCollection.name); + } + await discounts.promotionRuleDialog.clickSaveEditedRuleButton(); + await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); + await expect(discounts.existingRule.filter({ hasText: `Catalog rule: ${rule.name}` }).locator(discounts.ruleSummaryChip)).toHaveCount(ruleChips + 1); + }) + +} + + const promotionsWithRules = [DISCOUNTS.orderPromotionWithRulesToBeDeleted, DISCOUNTS.catalogPromotionWithRulesToBeDeleted] + for (const promotion of promotionsWithRules) { + for (const rule of promotion.rules) { + test(`TC: SALEOR_105 Delete promotion ${rule.name} from ${promotion.type} promotion @discounts @e2e`, async () => { + await discounts.gotoExistingDiscount(promotion.id); + await discounts.ruleSection.waitFor({ + state: "visible", + timeout: 10000, + }) + await discounts.clickDeleteRuleButton(`${promotion.type} rule: ${rule.name}`); + await expect(discounts.deleteRuleModal).toBeVisible({ timeout: 10000 }); + await discounts.deleteRuleDialog.clickConfirmDeleteButton(); + await expect(discounts.successBanner).toBeVisible({ timeout: 10000 }); + await expect(discounts.ruleSection).not.toHaveText(`${promotion.type}: ${rule.name}`); + }) + } + } diff --git a/src/discounts/components/DiscountRules/componenets/RuleDeleteModal/RuleDeleteModal.tsx b/src/discounts/components/DiscountRules/componenets/RuleDeleteModal/RuleDeleteModal.tsx index 87fb76a01df..f84fa8ddc65 100644 --- a/src/discounts/components/DiscountRules/componenets/RuleDeleteModal/RuleDeleteModal.tsx +++ b/src/discounts/components/DiscountRules/componenets/RuleDeleteModal/RuleDeleteModal.tsx @@ -27,7 +27,7 @@ export const RuleDeleteModal = ({ return ( - + - - + diff --git a/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditionRow/RuleConditionRow.tsx b/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditionRow/RuleConditionRow.tsx index 4f8439533dc..6fd78c94b7a 100644 --- a/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditionRow/RuleConditionRow.tsx +++ b/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditionRow/RuleConditionRow.tsx @@ -27,6 +27,7 @@ export const RuleConditionRow = ({ __gridTemplateColumns="200px 106px 1fr 35px" placeItems="center" alignItems="start" + data-test-id="rule-condition-row" > append(createEmptyCodition())} - data-test-id="add-another-condition-button" + data-test-id="add-condition-button" > diff --git a/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditions/components/AddConditionsSection/AddConditionsSection.tsx b/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditions/components/AddConditionsSection/AddConditionsSection.tsx index d07f595f132..1fad40d2b6b 100644 --- a/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditions/components/AddConditionsSection/AddConditionsSection.tsx +++ b/src/discounts/components/DiscountRules/componenets/RuleForm/components/RuleConditions/components/AddConditionsSection/AddConditionsSection.tsx @@ -27,7 +27,7 @@ export const AddConditionsSection = ({ alignSelf="start" disabled={disabled} onClick={addCondition} - data-test-id="add-first-condition-button" + data-test-id="add-condition-button" > diff --git a/src/discounts/components/DiscountRules/componenets/RulesList/RulesList.tsx b/src/discounts/components/DiscountRules/componenets/RulesList/RulesList.tsx index 845a0b35ad6..218ea03f4f4 100644 --- a/src/discounts/components/DiscountRules/componenets/RulesList/RulesList.tsx +++ b/src/discounts/components/DiscountRules/componenets/RulesList/RulesList.tsx @@ -51,11 +51,12 @@ export const RulesList = ({ - + onRuleDelete(index)} diff --git a/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleSummaryChips/RuleSummaryChips.tsx b/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleSummaryChips/RuleSummaryChips.tsx index 6e1b4a307a6..01f2375e58c 100644 --- a/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleSummaryChips/RuleSummaryChips.tsx +++ b/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleSummaryChips/RuleSummaryChips.tsx @@ -19,6 +19,7 @@ export const RuleSummaryChips = ({ __color={color.text} __borderColor={color.border} marginRight={1.5} + data-test-id="rule-summary-chip" > {label}: {value} diff --git a/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleValueChips/RuleValueChips.tsx b/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleValueChips/RuleValueChips.tsx index 2169f681e41..b98fc00268d 100644 --- a/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleValueChips/RuleValueChips.tsx +++ b/src/discounts/components/DiscountRules/componenets/RulesList/components/RuleSummary/components/RuleValueChips/RuleValueChips.tsx @@ -25,6 +25,7 @@ export const RuleValueChips = ({ backgroundColor="accent1Pressed" borderColor="accent1" color="default1" + data-test-id="rule-value-chip" > {rule.rewardType === RewardTypeEnum.GIFT ? intl.formatMessage({ defaultMessage: "Gift", id: "ZBs2Pb" })