diff --git a/apps/web/src/routes/dashboard/subscription/__tests__/index.test.tsx b/apps/web/src/routes/dashboard/subscription/__tests__/index.test.tsx
index fca277e..3be2e75 100644
--- a/apps/web/src/routes/dashboard/subscription/__tests__/index.test.tsx
+++ b/apps/web/src/routes/dashboard/subscription/__tests__/index.test.tsx
@@ -427,8 +427,10 @@ describe("interaction", () => {
const gridScope = within(planGrid as HTMLElement);
const brand1Card = gridScope
.getByText("subscription.plans.brand1.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand1Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand1Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
const ctaElements = screen.getAllByText(/subscription\.proceed/);
expect(ctaElements.length).toBeGreaterThanOrEqual(1);
});
@@ -439,8 +441,10 @@ describe("interaction", () => {
const gridScope = within(planGrid as HTMLElement);
const brand2Card = gridScope
.getByText("subscription.plans.brand2.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand2Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand2Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
const ctaButtons = screen.getAllByRole("button", { name: /subscription\.proceed/ });
const bigCta = ctaButtons.find((b) => b.textContent?.includes("₺350,00"));
expect(bigCta).toBeTruthy();
@@ -460,8 +464,10 @@ describe("interaction", () => {
const gridScope = within(planGrid as HTMLElement);
const brand3Card = gridScope
.getByText("subscription.plans.brand3.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand3Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand3Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
expect(screen.getByText("subscription.orderSummary")).toBeInTheDocument();
expect(screen.getByText("subscription.orderSummaryPlan")).toBeInTheDocument();
expect(screen.getByText("subscription.orderSummaryPeriod")).toBeInTheDocument();
@@ -480,8 +486,10 @@ describe("interaction", () => {
const gridScope1 = within(planGrid1 as HTMLElement);
const brand1Card = gridScope1
.getByText("subscription.plans.brand1.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand1Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand1Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
fireEvent.click(screen.getByRole("button", { name: "common.yearly" }));
// Yearly price appears in both card and summary
const summaryPrices = screen.getAllByText("₺2.000,00");
@@ -519,8 +527,10 @@ describe("interaction", () => {
const gridScopeNav = within(planGridNav as HTMLElement);
const brand2Card = gridScopeNav
.getByText("subscription.plans.brand2.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand2Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand2Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
fireEvent.click(screen.getByTestId("brand-selector-select"));
// Click the big CTA (not the small card button)
const ctaButtons = screen.getAllByRole("button", { name: /subscription\.proceed/ });
@@ -542,8 +552,10 @@ describe("interaction", () => {
const gridScopeErr = within(planGridErr as HTMLElement);
const brand1Card = gridScopeErr
.getByText("subscription.plans.brand1.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand1Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand1Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
const ctaButtons = screen.getAllByRole("button", { name: /subscription\.proceed/ });
const bigCta = ctaButtons.find((b) => b.textContent?.includes("₺"))!;
fireEvent.click(bigCta);
@@ -567,22 +579,26 @@ describe("interaction", () => {
});
const planGridCur = document.querySelector(".grid.gap-4");
const gridScopeCur = within(planGridCur as HTMLElement);
+ // brand1 card should have a selectable button (not current plan)
const brand1Card = gridScopeCur
.getByText("subscription.plans.brand1.name")
- .closest('[class*="relative"]')!;
- expect(brand1Card.className).toContain("cursor-pointer");
- // Current plan card should NOT be clickable
- const cards = document.querySelectorAll('[class*="relative"]');
- let foundNonClickable = false;
- cards.forEach((card) => {
+ .closest('[class*="rounded-xl"]')!;
+ const brand1Button = within(brand1Card as HTMLElement).queryByRole("button");
+ expect(brand1Button).toBeTruthy();
+ // Current plan (brand2) should NOT have a button — it shows a non-interactive div instead
+ const currentPlanCards = document.querySelectorAll('[class*="rounded-xl"]');
+ let currentPlanHasNoButton = false;
+ currentPlanCards.forEach((card) => {
if (
card.textContent?.includes("subscription.plans.brand2.name") &&
card.className.includes("border-green")
) {
- if (!card.className.includes("cursor-pointer")) foundNonClickable = true;
+ // Current plan card should have a div with "Mevcut Plan" text, not a button
+ const btn = card.querySelector("button");
+ if (!btn) currentPlanHasNoButton = true;
}
});
- expect(foundNonClickable).toBe(true);
+ expect(currentPlanHasNoButton).toBe(true);
});
});
@@ -593,8 +609,10 @@ describe("interaction", () => {
const gridScopePersist = within(planGridPersist as HTMLElement);
const brand3Card = gridScopePersist
.getByText("subscription.plans.brand3.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand3Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand3Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
expect(screen.getByText("subscription.orderSummary")).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "common.yearly" }));
expect(screen.getByText("subscription.orderSummary")).toBeInTheDocument();
@@ -614,8 +632,10 @@ describe("trust and i18n", () => {
const gridScopePH1 = within(planGridPH1 as HTMLElement);
const brand2Card = gridScopePH1
.getByText("subscription.plans.brand2.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand2Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand2Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
fireEvent.click(screen.getByTestId("brand-selector-select"));
const ctaButtons = screen.getAllByRole("button", { name: /subscription\.proceed/ });
fireEvent.click(ctaButtons.find((b) => b.textContent?.includes("₺"))!);
@@ -625,14 +645,16 @@ describe("trust and i18n", () => {
);
});
- it("fires plan_selected event when clicking a plan card", () => {
+ it("fires plan_selected event when clicking a plan card button", () => {
renderPage();
const planGridPH2 = document.querySelector(".grid.gap-4");
const gridScopePH2 = within(planGridPH2 as HTMLElement);
const brand3Card = gridScopePH2
.getByText("subscription.plans.brand3.name")
- .closest('[class*="relative"]')!;
- fireEvent.click(brand3Card);
+ .closest('[class*="rounded-xl"]')!;
+ fireEvent.click(
+ within(brand3Card as HTMLElement).getByRole("button", { name: "subscription.choosePlan" }),
+ );
expect(mockCapture).toHaveBeenCalledWith("plan_selected", { plan: "brand3" });
});
@@ -832,15 +854,16 @@ describe("accessibility", () => {
},
eligibleForTrial: false,
});
- const cards = document.querySelectorAll('[class*="relative"]');
+ const cards = document.querySelectorAll('[class*="rounded-xl"]');
let found = false;
cards.forEach((card) => {
if (
card.textContent?.includes("subscription.plans.brand2.name") &&
- card.className.includes("border-green") &&
- !card.className.includes("cursor-pointer")
- )
- found = true;
+ card.className.includes("border-green")
+ ) {
+ // Current plan card should not have a button element
+ if (!card.querySelector("button")) found = true;
+ }
});
expect(found).toBe(true);
});
diff --git a/apps/web/src/routes/dashboard/subscription/index.tsx b/apps/web/src/routes/dashboard/subscription/index.tsx
index 39754c8..a313105 100644
--- a/apps/web/src/routes/dashboard/subscription/index.tsx
+++ b/apps/web/src/routes/dashboard/subscription/index.tsx
@@ -803,6 +803,20 @@ export function SubscriptionPage() {