From 562bc91acb42ced10631bbcb38571f8d14f7f5ea Mon Sep 17 00:00:00 2001 From: Santiago de la Fuente Date: Wed, 11 Jun 2025 13:53:49 -0300 Subject: [PATCH] feat: optimize Cypress tests with API mocking --- cypress/e2e/correct_display_counter.cy.ts | 95 +++++++++++-------- cypress/e2e/donation_and_reward.cy.ts | 19 ++-- cypress/e2e/paypal_payment_flow.cy.ts | 2 +- cypress/e2e/project_donation_button.cy.ts | 34 +++++++ cypress/e2e/stripe_payment_flow.cy.ts | 4 +- ...t_add_multiple_contributions_to_cart.cy.ts | 2 +- .../test_payment_confirmation_success.cy.ts | 38 +++++++- .../e2e/test_payment_method_unavailable.cy.ts | 2 +- cypress/e2e/total_raised.cy.ts | 73 ++++++++++++++ cypress/e2e/total_raised.ts | 23 ----- 10 files changed, 211 insertions(+), 81 deletions(-) create mode 100644 cypress/e2e/total_raised.cy.ts delete mode 100644 cypress/e2e/total_raised.ts diff --git a/cypress/e2e/correct_display_counter.cy.ts b/cypress/e2e/correct_display_counter.cy.ts index 721a37fc..9fdd67b7 100644 --- a/cypress/e2e/correct_display_counter.cy.ts +++ b/cypress/e2e/correct_display_counter.cy.ts @@ -2,54 +2,69 @@ describe("Correct Display of Total Fundraising Counter", () => { beforeEach(() => { + cy.intercept("GET", "**/v4/project_rewards?project=100", { + statusCode: 200, + body: [ + { + id: 3827, + project: "/v4/projects/100", + title: 'CD "Al Paso de los Caracoles" + 2 Camisetas', + description: "CD físico del álbum junto con 2 camisetas oficiales", + money: { amount: 4000, currency: "EUR" }, + hasUnits: true, + unitsTotal: 5, + unitsAvailable: 5, + locales: ["es"], + }, + ], + }).as("projectRewards"); + + cy.intercept("GET", "**/v4/projects/100", { + statusCode: 200, + body: { + id: 100, + title: "Proyecto de Prueba", + amount: 12500, + minimal: 5000, + optimal: 25000, + received: 12500, + num_investors: 45, + status: "active", + currency: "EUR", + }, + }).as("projectData"); + cy.login(); cy.url().should("not.include", "/login"); }); + const verifyCounterElement = (label: any, shouldContainEuro = false) => { + cy.contains("p", label).should("be.visible").and("have.class", "text-[#575757]"); + + cy.contains("p", label) + .siblings("p") + .should(shouldContainEuro ? "be.visible" : "exist") + .and("have.class", "text-secondary") + .and("have.class", "text-[32px]") + .and("have.class", "font-bold") + .then(($el) => { + if (shouldContainEuro) { + expect($el.text()).to.contain("€"); + } + }); + }; + it("should display fundraising counter with total raised and remaining amounts", () => { cy.visit("/es/projects/100"); + cy.wait("@projectRewards", { timeout: 3000 }); + cy.get(".flex.h-\\[100\\%\\].flex-col.gap-6.rounded-\\[32px\\]").should("be.visible"); - cy.contains("p", "Obtenido").should("be.visible").and("have.class", "text-[#575757]"); - - cy.contains("p", "Obtenido") - .siblings("p") - .should("exist") - .and("have.class", "text-secondary") - .and("have.class", "text-[32px]") - .and("have.class", "font-bold"); - - cy.contains("p", "Donaciones realizadas") - .should("be.visible") - .and("have.class", "text-[#575757]"); - - cy.contains("p", "Donaciones realizadas") - .siblings("p") - .should("exist") - .and("have.class", "text-secondary") - .and("have.class", "text-[32px]") - .and("have.class", "font-bold"); - - cy.contains("p", "Óptimo").should("be.visible").and("have.class", "text-[#575757]"); - - cy.contains("p", "Óptimo") - .siblings("p") - .should("be.visible") - .and("contain.text", "€") - .and("have.class", "text-secondary") - .and("have.class", "text-[32px]") - .and("have.class", "font-bold"); - - cy.contains("p", "Mínimo").should("be.visible").and("have.class", "text-[#575757]"); - - cy.contains("p", "Mínimo") - .siblings("p") - .should("be.visible") - .and("contain.text", "€") - .and("have.class", "text-secondary") - .and("have.class", "text-[32px]") - .and("have.class", "font-bold"); + verifyCounterElement("Obtenido"); + verifyCounterElement("Donaciones realizadas"); + verifyCounterElement("Óptimo", true); + verifyCounterElement("Mínimo", true); cy.contains("button", "Donar a esta campaña") .should("be.visible") @@ -61,6 +76,8 @@ describe("Correct Display of Total Fundraising Counter", () => { it("should calculate and display remaining amount to reach funding goal", () => { cy.visit("/es/projects/100"); + cy.wait("@projectRewards", { timeout: 3000 }); + cy.contains("p", "Obtenido") .siblings("p") .invoke("text") diff --git a/cypress/e2e/donation_and_reward.cy.ts b/cypress/e2e/donation_and_reward.cy.ts index c10f7fdf..1283fffb 100644 --- a/cypress/e2e/donation_and_reward.cy.ts +++ b/cypress/e2e/donation_and_reward.cy.ts @@ -9,12 +9,8 @@ describe("Project Page - Donation and Reward Verification", () => { id: 3827, project: "/v4/projects/100", title: 'CD "Al Paso de los Caracoles" + 2 Camisetas', - description: - "CD físico del álbum junto con 2 camisetas oficiales del proyecto musical", - money: { - amount: 4000, - currency: "EUR", - }, + description: "CD físico del álbum junto con 2 camisetas oficiales", + money: { amount: 4000, currency: "EUR" }, hasUnits: true, unitsTotal: 5, unitsAvailable: 5, @@ -31,16 +27,13 @@ describe("Project Page - Donation and Reward Verification", () => { cy.visit("/es/projects/100"); cy.wait("@project100Rewards"); - cy.get("li.flex.flex-col.gap-2.rounded-4xl.border", { timeout: 10000 }).within(() => { - cy.get("h3.text-tertiary.text-2xl.font-semibold").should("exist").and("be.visible"); + cy.get("li.flex.flex-col.gap-2.rounded-4xl.border").within(() => { + cy.get("h3.text-tertiary.text-2xl.font-semibold").should("be.visible"); - cy.get("p.mb-2.text-sm.whitespace-pre-line.text-gray-800") - .should("exist") - .and("be.visible"); + cy.get("p.mb-2.text-sm.whitespace-pre-line.text-gray-800").should("be.visible"); cy.get('button[type="button"]') - .should("exist") - .and("be.visible") + .should("be.visible") .and("contain.text", "Dona") .and("contain.text", "40€"); }); diff --git a/cypress/e2e/paypal_payment_flow.cy.ts b/cypress/e2e/paypal_payment_flow.cy.ts index 6b3c6bd2..855fa4f4 100644 --- a/cypress/e2e/paypal_payment_flow.cy.ts +++ b/cypress/e2e/paypal_payment_flow.cy.ts @@ -38,7 +38,7 @@ describe("PayPal Payment Flow", () => { cy.contains("button", "Continuar").should("be.visible").should("be.enabled").click(); - cy.url({ timeout: 10000 }).should("not.include", "/login"); + cy.url({ timeout: 3000 }).should("not.include", "/login"); cy.url().should("include", "payment"); cy.get("form#payment", { timeout: 5000 }).should("exist"); diff --git a/cypress/e2e/project_donation_button.cy.ts b/cypress/e2e/project_donation_button.cy.ts index e38e15a3..1105b9e4 100644 --- a/cypress/e2e/project_donation_button.cy.ts +++ b/cypress/e2e/project_donation_button.cy.ts @@ -2,6 +2,38 @@ describe("Project Donation Button", () => { beforeEach(() => { + cy.intercept("GET", "**/v4/project_rewards?project=2", { + statusCode: 200, + body: [ + { + id: 4001, + project: "/v4/projects/2", + title: "Recompensa del Proyecto 2", + description: "Una recompensa de ejemplo para el proyecto 2", + money: { amount: 2000, currency: "EUR" }, + hasUnits: true, + unitsTotal: 10, + unitsAvailable: 8, + locales: ["es"], + }, + ], + }).as("project2Rewards"); + + cy.intercept("GET", "**/v4/projects/2", { + statusCode: 200, + body: { + id: 2, + title: "Proyecto 2 de Prueba", + amount: 8500, + minimal: 3000, + optimal: 15000, + received: 8500, + num_investors: 25, + status: "active", + currency: "EUR", + }, + }).as("project2Data"); + cy.login(); cy.on("uncaught:exception", () => false); }); @@ -9,6 +41,8 @@ describe("Project Donation Button", () => { it("should show the 'Donate to this campaign' button visible and clickable", () => { cy.visit("/es/projects/2"); + cy.wait("@project2Rewards", { timeout: 3000 }); + cy.contains("button", "Donar a esta campaña").should("be.visible").and("be.enabled"); }); }); diff --git a/cypress/e2e/stripe_payment_flow.cy.ts b/cypress/e2e/stripe_payment_flow.cy.ts index 567c9252..b44a3f7b 100644 --- a/cypress/e2e/stripe_payment_flow.cy.ts +++ b/cypress/e2e/stripe_payment_flow.cy.ts @@ -38,10 +38,10 @@ describe("Stripe Payment Flow", () => { cy.contains("button", "Continuar").should("be.visible").should("be.enabled").click(); - cy.url({ timeout: 10000 }).should("not.include", "/login"); + cy.url({ timeout: 3000 }).should("not.include", "/login"); cy.url().should("include", "payment"); - cy.get("form#payment", { timeout: 5000 }).should("exist"); + cy.get("form#payment", { timeout: 3000 }).should("exist"); cy.get("label[data-gateway='stripe']").should("be.visible").click(); diff --git a/cypress/e2e/test_add_multiple_contributions_to_cart.cy.ts b/cypress/e2e/test_add_multiple_contributions_to_cart.cy.ts index 5642d0b9..9babe5f8 100644 --- a/cypress/e2e/test_add_multiple_contributions_to_cart.cy.ts +++ b/cypress/e2e/test_add_multiple_contributions_to_cart.cy.ts @@ -56,7 +56,7 @@ describe("Checkout Flow - Multiple Contributions", () => { cy.contains("button", "Continuar").should("be.visible").should("be.enabled").click(); - cy.url({ timeout: 10000 }).should("not.include", "/login"); + cy.url({ timeout: 3000 }).should("not.include", "/login"); cy.url().should("include", "payment"); cy.get("form#payment").should("exist"); }); diff --git a/cypress/e2e/test_payment_confirmation_success.cy.ts b/cypress/e2e/test_payment_confirmation_success.cy.ts index 68d5272b..9ece6256 100644 --- a/cypress/e2e/test_payment_confirmation_success.cy.ts +++ b/cypress/e2e/test_payment_confirmation_success.cy.ts @@ -2,6 +2,42 @@ describe("Stripe Verification Flow", () => { beforeEach(() => { + cy.intercept("GET", "**/v4/payments/verify*", { + statusCode: 200, + body: { + checkoutId: "100", + status: "completed", + payment_status: "paid", + message: "El pago se ha procesado correctamente", + transaction_id: "stripe_tx_12345", + amount: 4000, + currency: "EUR", + }, + }).as("paymentVerify"); + + cy.intercept("GET", "**/v4/checkout/*/status", { + statusCode: 200, + body: { + id: "100", + status: "completed", + payment_method: "stripe", + verified: true, + message: "pago se ha procesado", + }, + }).as("checkoutStatus"); + + cy.intercept("GET", "**/v4/checkout/100", { + statusCode: 200, + body: { + id: "100", + status: "completed", + amount: 4000, + currency: "EUR", + payment_method: "stripe", + verified_at: new Date().toISOString(), + }, + }).as("checkoutDetails"); + cy.login(); cy.url().should("not.include", "/login"); }); @@ -9,6 +45,6 @@ describe("Stripe Verification Flow", () => { it("should handle successful payment verification with checkoutId", () => { cy.visit("/payment/verify?checkoutId=100"); - cy.contains(/pago se ha procesado/, { timeout: 10000 }).should("be.visible"); + cy.contains(/pago se ha procesado/, { timeout: 3000 }).should("be.visible"); }); }); diff --git a/cypress/e2e/test_payment_method_unavailable.cy.ts b/cypress/e2e/test_payment_method_unavailable.cy.ts index f45024f7..e1f12c30 100644 --- a/cypress/e2e/test_payment_method_unavailable.cy.ts +++ b/cypress/e2e/test_payment_method_unavailable.cy.ts @@ -36,7 +36,7 @@ describe("Checkout Flow - Stripe Payment Integration", () => { cy.contains("button", "Continuar").should("be.visible").click(); - cy.url({ timeout: 10000 }).should("not.include", "/login"); + cy.url({ timeout: 3000 }).should("not.include", "/login"); cy.url().should("include", "payment"); }; diff --git a/cypress/e2e/total_raised.cy.ts b/cypress/e2e/total_raised.cy.ts new file mode 100644 index 00000000..42258e2e --- /dev/null +++ b/cypress/e2e/total_raised.cy.ts @@ -0,0 +1,73 @@ +/// + +describe("View Total Raised by One-time Payments", () => { + beforeEach(() => { + cy.intercept("GET", "**/v4/gateway_charges*", { + statusCode: 200, + headers: { + "content-type": "application/ld+json", + }, + body: { + "@context": "/v4/contexts/GatewayCharge", + "@id": "/v4/gateway_charges", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/v4/gateway_charges/1", + "@type": "GatewayCharge", + id: 1, + amount: 2500, + currency: "EUR", + status: "completed", + gateway: "stripe", + created_at: "2025-01-15T10:00:00Z", + }, + { + "@id": "/v4/gateway_charges/2", + "@type": "GatewayCharge", + id: 2, + amount: 1500, + currency: "EUR", + status: "completed", + gateway: "paypal", + created_at: "2025-01-14T15:30:00Z", + }, + ], + "hydra:totalItems": 247, + "hydra:view": { + "@id": "/v4/gateway_charges?page=1&itemsPerPage=10&pagination=true", + "@type": "hydra:PartialCollectionView", + "hydra:first": "/v4/gateway_charges?page=1&itemsPerPage=10&pagination=true", + "hydra:last": "/v4/gateway_charges?page=25&itemsPerPage=10&pagination=true", + "hydra:next": "/v4/gateway_charges?page=2&itemsPerPage=10&pagination=true", + }, + "hydra:search": { + "@type": "hydra:IriTemplate", + }, + total_amount: "148,750", + total_count: 247, + currency: "EUR", + }, + }).as("gatewayCharges"); + + cy.login(); + cy.url().should("not.include", "/login"); + }); + + it("should display total contributions amount", () => { + cy.visit("/es/admin/aportes"); + + cy.wait("@gatewayCharges", { timeout: 3000 }); + + cy.contains("Total aportes:") + .should("be.visible") + .and("have.class", "text-base") + .and("have.class", "font-semibold") + .and("have.class", "text-[#575757]"); + + cy.get(".text-secondary") + .should("be.visible") + .and("contain.text", "€") + .and("have.class", "text-[40px]"); + }); +}); diff --git a/cypress/e2e/total_raised.ts b/cypress/e2e/total_raised.ts deleted file mode 100644 index b5d06f2f..00000000 --- a/cypress/e2e/total_raised.ts +++ /dev/null @@ -1,23 +0,0 @@ -/// - -describe("View Total Raised by One-time Payments", () => { - beforeEach(() => { - cy.login(); - cy.url().should("not.include", "/login"); - }); - - it("should display total contributions amount", () => { - cy.visit("/es/admin/aportes"); - - cy.contains("Total aportes:") - .should("be.visible") - .and("have.class", "text-base") - .and("have.class", "font-semibold") - .and("have.class", "text-[#575757]"); - - cy.get(".text-secondary") - .should("be.visible") - .and("contain.text", "€") - .and("have.class", "text-[40px]"); - }); -});