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>
157 lines
5.7 KiB
TypeScript
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
|
|
}
|
|
});
|
|
});
|