template-saas-frontend-v2/tests/e2e/billing/subscription.spec.ts
rckrdmrd eb95d0e276 Initial commit - Frontend de template-saas migrado desde monorepo
Migración desde workspace-v2/projects/template-saas/apps/frontend
Este repositorio es parte del estándar multi-repo v2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:07:16 -06:00

138 lines
5.2 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { test as authTest } from '../fixtures/auth.fixture';
import { waitForPageLoad, waitForApi } from '../utils/helpers';
test.describe('Billing & Subscription', () => {
authTest('should display current subscription info', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
await waitForPageLoad(page);
// Should show subscription info
await expect(page.locator('[data-testid="subscription-info"], .subscription-info')).toBeVisible();
});
authTest('should show current plan details', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Should display plan name
const planName = page.locator('[data-testid="current-plan"], .current-plan');
await expect(planName).toBeVisible();
// Should show plan features
const planFeatures = page.locator('[data-testid="plan-features"], .plan-features');
await expect(planFeatures).toBeVisible();
});
authTest('should display available plans for upgrade', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Click on change plan or upgrade button
const changePlanButton = page.locator('[data-testid="change-plan"], button:has-text("Cambiar"), button:has-text("Upgrade")');
if (await changePlanButton.isVisible()) {
await changePlanButton.click();
// Should show plan options
const planOptions = page.locator('[data-testid="plan-option"], .plan-option');
expect(await planOptions.count()).toBeGreaterThan(0);
}
});
authTest('should show billing history', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Should have billing history section
const billingHistory = page.locator('[data-testid="billing-history"], .billing-history');
if (await billingHistory.isVisible()) {
// Should show invoices table or list
const invoices = page.locator('[data-testid="invoice-row"], .invoice-row');
// Count may be 0 if no invoices yet
expect(await invoices.count()).toBeGreaterThanOrEqual(0);
}
});
authTest('should show payment method', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Should show payment method section
const paymentMethod = page.locator('[data-testid="payment-method"], .payment-method');
if (await paymentMethod.isVisible()) {
await expect(paymentMethod).toBeVisible();
}
});
authTest('should allow adding payment method', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Click add payment method
const addPaymentButton = page.locator('[data-testid="add-payment-method"], button:has-text("Agregar"), button:has-text("Add payment")');
if (await addPaymentButton.isVisible()) {
await addPaymentButton.click();
// Should open Stripe elements or modal
// Note: Actual Stripe integration is mocked in E2E
const paymentModal = page.locator('[data-testid="payment-modal"], .payment-modal');
await expect(paymentModal).toBeVisible();
}
});
authTest('should open Stripe billing portal', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Click manage billing button
const manageBillingButton = page.locator('[data-testid="manage-billing"], button:has-text("Gestionar"), button:has-text("Manage")');
if (await manageBillingButton.isVisible()) {
// This would typically open Stripe's billing portal
// For E2E, we just verify the button exists and is clickable
await expect(manageBillingButton).toBeEnabled();
}
});
authTest('should show usage metrics if metered billing', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Check for usage section (optional, depends on plan type)
const usageSection = page.locator('[data-testid="usage-metrics"], .usage-metrics');
if (await usageSection.isVisible()) {
// Should show usage data
const usageData = page.locator('[data-testid="usage-value"], .usage-value');
await expect(usageData.first()).toBeVisible();
}
});
authTest('should show trial status if on trial', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Check for trial banner/indicator
const trialBanner = page.locator('[data-testid="trial-banner"], .trial-banner');
// If on trial, should show days remaining
if (await trialBanner.isVisible()) {
await expect(trialBanner).toContainText(/trial|días|days/i);
}
});
authTest('should allow canceling subscription', async ({ authenticatedPage: page }) => {
await page.goto('/admin/billing');
// Click cancel subscription
const cancelButton = page.locator('[data-testid="cancel-subscription"], button:has-text("Cancelar"), button:has-text("Cancel")');
if (await cancelButton.isVisible()) {
await cancelButton.click();
// Should show confirmation modal
const confirmModal = page.locator('[data-testid="confirm-modal"], .confirm-modal');
await expect(confirmModal).toBeVisible();
// Cancel the modal (don't actually cancel in test)
await page.click('[data-testid="cancel-modal"], button:has-text("No"), button:has-text("Volver")');
}
});
});