import { discountTemplates, apiMocks } from "../support/discount-codes-helpers"; describe("Discount Codes - Complete E2E Tests", () => { beforeEach(() => { cy.login(); }); describe("Navigation and Basic UI", () => { it("should display discount codes list page correctly", () => { cy.visit("/discount-codes"); cy.waitForLoading(); cy.contains("مدیریت کدهای تخفیف").should("be.visible"); cy.get('[title="کد تخفیف جدید"]').should("be.visible"); }); it("should navigate to create page", () => { cy.navigateToCreateDiscount(); cy.contains("ایجاد کد تخفیف").should("be.visible"); }); }); describe("Form Validation", () => { beforeEach(() => { cy.navigateToCreateDiscount(); }); it("should validate required fields", () => { cy.getByTestId("submit-discount-button").should("be.disabled"); cy.fillBasicDiscountInfo({ code: "TEST123", name: "Test Discount", }); cy.getByTestId("submit-discount-button").should("be.disabled"); cy.fillDiscountSettings({ type: "percentage", value: "10", status: "active", applicationLevel: "invoice", }); cy.getByTestId("submit-discount-button").should("not.be.disabled"); }); it("should validate field lengths and formats", () => { // Test code length cy.getByTestId("discount-code-input").type("AB"); cy.getByTestId("discount-name-input").type("Test"); cy.get(".text-red-600").should("contain", "کد باید حداقل ۳ کاراکتر باشد"); // Test code too long cy.getByTestId("discount-code-input").clear().type("A".repeat(51)); cy.get(".text-red-600").should( "contain", "کد نباید بیشتر از ۵۰ کاراکتر باشد" ); // Test name too long cy.getByTestId("discount-name-input").clear().type("A".repeat(101)); cy.get(".text-red-600").should( "contain", "نام نباید بیشتر از ۱۰۰ کاراکتر باشد" ); // Test description too long cy.getByTestId("discount-description-textarea").type("A".repeat(501)); cy.get(".text-red-600").should( "contain", "توضیحات نباید بیشتر از ۵۰۰ کاراکتر باشد" ); }); it("should validate numeric fields", () => { cy.fillBasicDiscountInfo({ code: "NUMTEST", name: "Number Test", }); // Test negative value cy.getByTestId("discount-value-input").type("-10"); cy.get(".text-red-600").should("contain", "مقدار باید بیشتر از صفر باشد"); // Test zero value cy.getByTestId("discount-value-input").clear().type("0"); cy.get(".text-red-600").should("contain", "مقدار باید بیشتر از صفر باشد"); }); }); describe("Discount Creation", () => { beforeEach(() => { // Mock successful API responses cy.intercept("GET", "**/discount/**", apiMocks.discountsList).as( "getDiscounts" ); cy.intercept("POST", "**/discount/**", (req) => { return apiMocks.successfulCreation(req.body); }).as("createDiscount"); }); it("should create basic percentage discount", () => { cy.createDiscountCode(discountTemplates.basicPercentage); cy.wait("@createDiscount"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); it("should create fixed amount discount", () => { cy.createDiscountCode(discountTemplates.fixedAmount); cy.wait("@createDiscount"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); it("should create fee percentage discount", () => { cy.createDiscountCode(discountTemplates.feePercentage); cy.wait("@createDiscount"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); it("should create discount with user restrictions", () => { cy.createDiscountCode(discountTemplates.loyalUsers); cy.wait("@createDiscount"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); it("should create time-based discount with all features", () => { cy.createDiscountCode(discountTemplates.timeBasedDiscount); cy.wait("@createDiscount"); cy.contains("کد تخفیف با موفقیت ایجاد شد").should("be.visible"); }); }); describe("Error Handling", () => { it("should handle validation errors from API", () => { cy.intercept("POST", "**/discount/**", apiMocks.validationError).as( "validationError" ); cy.navigateToCreateDiscount(); cy.fillBasicDiscountInfo(discountTemplates.basicPercentage); cy.fillDiscountSettings(discountTemplates.basicPercentage); cy.submitDiscountForm(); cy.wait("@validationError"); cy.contains("کد تخفیف تکراری است").should("be.visible"); }); it("should handle server errors", () => { cy.intercept("POST", "**/discount/**", apiMocks.serverError).as( "serverError" ); cy.navigateToCreateDiscount(); cy.fillBasicDiscountInfo(discountTemplates.basicPercentage); cy.fillDiscountSettings(discountTemplates.basicPercentage); cy.submitDiscountForm(); cy.wait("@serverError"); cy.contains("خطا در ایجاد کد تخفیف").should("be.visible"); }); it("should handle loading states", () => { cy.intercept("POST", "**/discount/**", { delay: 2000, ...apiMocks.successfulCreation(discountTemplates.basicPercentage), }).as("slowCreate"); cy.navigateToCreateDiscount(); cy.fillBasicDiscountInfo(discountTemplates.basicPercentage); cy.fillDiscountSettings(discountTemplates.basicPercentage); cy.submitDiscountForm(); // Check loading state cy.getByTestId("submit-discount-button").should("be.disabled"); cy.get(".animate-spin").should("be.visible"); cy.wait("@slowCreate"); }); }); describe("List Page Features", () => { beforeEach(() => { cy.intercept("GET", "**/discount/**", apiMocks.discountsList).as( "getDiscounts" ); cy.visit("/discount-codes"); cy.wait("@getDiscounts"); }); it("should search discount codes", () => { cy.searchDiscountCode("SAVE20"); cy.contains("SAVE20").should("be.visible"); cy.searchDiscountCode("NONEXISTENT"); cy.contains("هیچ کد تخفیفی یافت نشد").should("be.visible"); }); it("should clear filters", () => { cy.searchDiscountCode("TEST"); cy.clearDiscountFilters(); cy.get('input[placeholder*="جستجو"]').should("have.value", ""); }); it("should display discount codes with correct formatting", () => { cy.contains("SAVE20").should("be.visible"); cy.contains("20%").should("be.visible"); cy.get(".bg-green-100").should("contain", "فعال"); }); }); describe("Edit Functionality", () => { beforeEach(() => { cy.intercept("GET", "**/discount/**", apiMocks.discountsList).as( "getDiscounts" ); cy.intercept("GET", "**/discount/1", { statusCode: 200, body: { id: 1, code: "SAVE20", name: "20% Off Discount", description: "Get 20% off on your purchase", type: "percentage", value: 20, status: "active", application_level: "invoice", }, }).as("getDiscount"); cy.intercept("PUT", "**/discount/1", { statusCode: 200, body: { message: "updated successfully" }, }).as("updateDiscount"); }); it("should edit existing discount code", () => { cy.visit("/discount-codes"); cy.wait("@getDiscounts"); cy.contains("SAVE20") .parent() .parent() .within(() => { cy.get('[title="ویرایش"]').click(); }); cy.wait("@getDiscount"); cy.url().should("include", "/edit"); cy.getByTestId("discount-name-input") .clear() .type("Updated Discount Name"); cy.submitDiscountForm(); cy.wait("@updateDiscount"); cy.contains("کد تخفیف با موفقیت به‌روزرسانی شد").should("be.visible"); }); }); describe("Delete Functionality", () => { beforeEach(() => { cy.intercept("GET", "**/discount/**", apiMocks.discountsList).as( "getDiscounts" ); cy.intercept("DELETE", "**/discount/**", { statusCode: 200, body: { message: "deleted successfully" }, }).as("deleteDiscount"); }); it("should delete discount code", () => { cy.visit("/discount-codes"); cy.wait("@getDiscounts"); cy.contains("SAVE20") .parent() .parent() .within(() => { cy.get('[title="حذف"]').click(); }); cy.contains("آیا از حذف این کد تخفیف اطمینان دارید؟").should( "be.visible" ); cy.contains("button", "حذف").click(); cy.wait("@deleteDiscount"); cy.contains("کد تخفیف با موفقیت حذف شد").should("be.visible"); }); }); describe("Responsive Design", () => { it("should work on mobile devices", () => { cy.viewport("iphone-6"); cy.navigateToCreateDiscount(); cy.fillBasicDiscountInfo({ code: "MOBILE123", name: "Mobile Test", }); cy.fillDiscountSettings({ type: "percentage", value: "10", status: "active", applicationLevel: "invoice", }); cy.getByTestId("submit-discount-button").should("be.visible"); }); it("should work on tablets", () => { cy.viewport("ipad-2"); cy.visit("/discount-codes"); cy.waitForLoading(); cy.get("table").should("be.visible"); cy.get('[title="کد تخفیف جدید"]').should("be.visible"); }); }); describe("Accessibility", () => { it("should be keyboard navigable", () => { cy.navigateToCreateDiscount(); cy.getByTestId("discount-code-input").focus(); cy.focused().should("have.attr", "data-testid", "discount-code-input"); cy.focused().tab(); cy.focused().should("have.attr", "data-testid", "discount-name-input"); }); it("should have proper ARIA labels", () => { cy.navigateToCreateDiscount(); cy.get("label").should("have.length.greaterThan", 5); cy.get("input[required]").should("have.length.greaterThan", 3); }); it("should announce errors to screen readers", () => { cy.navigateToCreateDiscount(); cy.getByTestId("discount-code-input").type("AB"); cy.get(".text-red-600").should("have.attr", "role", "alert"); }); }); describe("Performance", () => { it("should load create page quickly", () => { const startTime = Date.now(); cy.navigateToCreateDiscount(); cy.getByTestId("discount-code-input") .should("be.visible") .then(() => { const loadTime = Date.now() - startTime; expect(loadTime).to.be.lessThan(3000); // Should load within 3 seconds }); }); it("should handle large forms efficiently", () => { cy.navigateToCreateDiscount(); // Fill form quickly without delays cy.getByTestId("discount-code-input").type("PERF123"); cy.getByTestId("discount-name-input").type("Performance Test"); cy.getByTestId("discount-description-textarea").type("A".repeat(400)); cy.getByTestId("discount-type-select").select("percentage"); cy.getByTestId("discount-value-input").type("25"); // Form should remain responsive cy.getByTestId("submit-discount-button").should("not.be.disabled"); }); }); });