template-saas-frontend-v2/tests/e2e/onboarding/wizard.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

157 lines
5.7 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { testUser, loginAs } from '../fixtures/auth.fixture';
import { generateTestSlug } from '../utils/helpers';
test.describe('Onboarding Wizard', () => {
test.beforeEach(async ({ page }) => {
// Login as a user that needs onboarding
await loginAs(page, testUser.email, testUser.password);
// Navigate to onboarding if not already there
if (!page.url().includes('/onboarding')) {
await page.goto('/onboarding');
}
});
test('should display onboarding wizard', async ({ page }) => {
// Should show wizard container
await expect(page.locator('[data-testid="onboarding-wizard"], .onboarding-wizard')).toBeVisible();
// Should show progress indicator
await expect(page.locator('[data-testid="wizard-progress"], .wizard-progress')).toBeVisible();
});
test('Step 1: should complete company information', async ({ page }) => {
// Should be on step 1 (Company Info)
await expect(page.locator('[data-testid="step-company"], .step-company')).toBeVisible();
// Fill company name
await page.fill('input[name="name"]', 'My Test Company');
// Fill slug if editable
const slugInput = page.locator('input[name="slug"]');
if (await slugInput.isEditable()) {
await slugInput.fill(generateTestSlug());
}
// Click next/continue
await page.click('[data-testid="next-button"], button:has-text("Continuar"), button:has-text("Next")');
// Should advance to next step
await expect(page).toHaveURL(/step=2|invite/i);
});
test('Step 2: should handle team invitations', async ({ page }) => {
// Navigate to step 2 (if not already there)
await page.goto('/onboarding?step=2');
// Should show invite form
await expect(page.locator('[data-testid="step-invite"], .step-invite')).toBeVisible();
// Add team member email
const emailInput = page.locator('input[name="email"], input[placeholder*="email"]');
if (await emailInput.isVisible()) {
await emailInput.fill('teammate@example.com');
// Click add button
const addButton = page.locator('[data-testid="add-invite"], button:has-text("Agregar"), button:has-text("Add")');
if (await addButton.isVisible()) {
await addButton.click();
}
}
// Click next or skip
const nextButton = page.locator('[data-testid="next-button"], button:has-text("Continuar"), button:has-text("Next"), button:has-text("Skip")');
await nextButton.click();
// Should advance to next step
await expect(page).toHaveURL(/step=3|plan/i);
});
test('Step 2: should allow skipping invitations', async ({ page }) => {
await page.goto('/onboarding?step=2');
// Click skip button
const skipButton = page.locator('[data-testid="skip-button"], button:has-text("Omitir"), button:has-text("Skip")');
if (await skipButton.isVisible()) {
await skipButton.click();
// Should advance to next step without error
await expect(page).toHaveURL(/step=3|plan/i);
}
});
test('Step 3: should display available plans', async ({ page }) => {
await page.goto('/onboarding?step=3');
// Should show plan selection
await expect(page.locator('[data-testid="step-plan"], .step-plan')).toBeVisible();
// Should display at least one plan option
const planCards = page.locator('[data-testid="plan-card"], .plan-card');
await expect(planCards.first()).toBeVisible();
// Should have multiple plans
const planCount = await planCards.count();
expect(planCount).toBeGreaterThan(0);
});
test('Step 3: should select a plan', async ({ page }) => {
await page.goto('/onboarding?step=3');
// Click on first available plan
const planCard = page.locator('[data-testid="plan-card"], .plan-card').first();
await planCard.click();
// The plan should be selected (show visual indicator)
await expect(planCard).toHaveClass(/selected|active/);
// Click continue
await page.click('[data-testid="next-button"], button:has-text("Continuar"), button:has-text("Next")');
// Should advance to final step
await expect(page).toHaveURL(/step=4|complete/i);
});
test('Step 4: should complete onboarding', async ({ page }) => {
await page.goto('/onboarding?step=4');
// Should show completion step
await expect(page.locator('[data-testid="step-complete"], .step-complete')).toBeVisible();
// Click complete/finish button
await page.click('[data-testid="complete-button"], button:has-text("Completar"), button:has-text("Finish"), button:has-text("Complete")');
// Should redirect to dashboard
await expect(page).toHaveURL(/\/dashboard/, { timeout: 10000 });
});
test('should navigate back between steps', async ({ page }) => {
// Start at step 2
await page.goto('/onboarding?step=2');
// Click back button
const backButton = page.locator('[data-testid="back-button"], button:has-text("Atrás"), button:has-text("Back")');
if (await backButton.isVisible()) {
await backButton.click();
// Should go back to step 1
await expect(page).toHaveURL(/step=1|company/i);
}
});
test('should show progress indicator correctly', async ({ page }) => {
// Check progress on each step
for (let step = 1; step <= 4; step++) {
await page.goto(`/onboarding?step=${step}`);
// Progress indicator should reflect current step
const progressIndicator = page.locator('[data-testid="wizard-progress"], .wizard-progress');
await expect(progressIndicator).toBeVisible();
// Current step should be highlighted
const currentStepIndicator = page.locator(`[data-testid="step-${step}-indicator"], .step-indicator.active`);
// This may vary by implementation
}
});
});