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>
138 lines
5.2 KiB
TypeScript
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")');
|
|
}
|
|
});
|
|
});
|