WellNuo/e2e/auth.spec.ts
Sergei 20aacb4044 Update PRD, e2e tests, ralphy progress
- PRD.md updates
- E2E test updates (auth, complete-auth, full-flow)
- Ralphy progress tracking files
- Admin tsconfig files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-01 14:24:57 -08:00

159 lines
6.1 KiB
TypeScript

import { test, expect } from '@playwright/test';
const BASE_URL = 'https://wellnuo.smartlaunchhub.com/';
test.describe('WellNuo Web App Tests', () => {
test('Login screen loads correctly', async ({ page }) => {
page.on('console', msg => console.log(`BROWSER: ${msg.text()}`));
page.on('pageerror', err => console.log(`ERROR: ${err.message}`));
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
// Check main elements are visible
await expect(page.getByText('Welcome to WellNuo')).toBeVisible();
await expect(page.getByPlaceholder('Enter your email')).toBeVisible();
await expect(page.getByText('Continue')).toBeVisible();
await expect(page.getByText('I have an invite code')).toBeVisible();
console.log('✅ Login screen loaded correctly');
});
test('Email validation works', async ({ page }) => {
page.on('console', msg => console.log(`BROWSER: ${msg.text()}`));
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
// Try invalid email
await page.getByPlaceholder('Enter your email').fill('invalid-email');
await page.getByText('Continue').click();
// Should show error or stay on same page
await page.waitForTimeout(1000);
const url = page.url();
expect(url).toContain('/app'); // Should not navigate away
console.log('✅ Invalid email handled correctly');
});
test('Valid email shows OTP screen', async ({ page }) => {
page.on('console', msg => console.log(`BROWSER: ${msg.text()}`));
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
// Enter valid email
await page.getByPlaceholder('Enter your email').fill('test@example.com');
await page.getByText('Continue').click();
// Should show OTP screen
await expect(page.getByText(/verification code|Enter.*code/i)).toBeVisible({ timeout: 10000 });
console.log('✅ OTP screen appears for valid email');
});
test.skip('Full registration flow with temp email', async ({ page }) => {
// Debug: Log console messages
page.on('console', msg => console.log(`BROWSER LOG: ${msg.text()}`));
page.on('pageerror', err => console.log(`BROWSER ERROR: ${err.message}`));
// 1. Generate unique email
const timestamp = Date.now();
const email = `test.auto.${timestamp}@test.com`;
console.log(`Testing registration with: ${email}`);
// 2. Navigate to landing
const targetUrl = 'http://localhost:3000/app/';
console.log(`Navigating to: ${targetUrl}`);
await page.goto(targetUrl);
console.log(`Current URL: ${page.url()}`);
// Check we are on a login/welcome screen
// Note: Adjust selectors based on actual UI. Assuming "Enter Email" input exists.
// Expo web often manages navigation via history API.
// Wait for initial load
await expect(page.getByPlaceholder('Enter your email')).toBeVisible({ timeout: 10000 });
// 3. Enter Email and Request OTP
await page.getByPlaceholder('Enter your email').fill(email);
// Find "Continue" or "Code" button.
// Assuming button text contains "Continue" or similar.
await page.getByRole('button').filter({ hasText: /Continue|Code/i }).click();
// 4. Wait for OTP screen
await expect(page.getByText('Enter Verification Code')).toBeVisible();
// 5. Fetch OTP from DB
// Retrying a few times as DB insert might have slight delay
let code = '';
for (let i = 0; i < 5; i++) {
await page.waitForTimeout(1000); // Wait 1s
try {
code = execSync(`node "${FETCH_OTP_SCRIPT}" "${email}"`).toString().trim();
if (code && code.length === 6) break;
} catch (e) {
console.log('Waiting for OTP...');
}
}
expect(code).toMatch(/^\d{6}$/);
console.log(`Fetched OTP: ${code}`);
// 6. Enter OTP
// Assuming 6 separate inputs or one text input
// If one input:
const otpInput = page.getByPlaceholder('000000');
if (await otpInput.isVisible()) {
await otpInput.fill(code);
} else {
// Expo OTP input might be tricky (hidden input or separate fields)
// Let's try typing it
await page.keyboard.type(code);
}
// Submit OTP
await page.getByRole('button').filter({ hasText: /Verify|Login/i }).click();
// 7. Handle "Enter Name" (Complete Profile)
// If new user, likely asked for name
try {
await expect(page.getByText('What should we call you?')).toBeVisible({ timeout: 5000 });
await page.getByPlaceholder('Your Name').fill('Automated Tester');
await page.getByRole('button').filter({ hasText: /Continue/i }).click();
} catch (e) {
console.log('Skipped name entry (maybe not required?)');
}
// 8. Verify Dashboard
await expect(page.getByText('Dashboard')).toBeVisible();
await expect(page.getByText('Julia')).toBeVisible(); // Verify Voice AI present
console.log('Registration successful!');
});
test('Existing User Login Flow', async ({ page }) => {
// Debug: Log console messages
page.on('console', msg => console.log(`BROWSER: ${msg.text()}`));
page.on('pageerror', err => console.log(`ERROR: ${err.message}`));
await page.goto('https://wellnuo.smartlaunchhub.com/');
// Wait for app to load
await page.waitForLoadState('networkidle');
// Fill email
await page.getByPlaceholder('Enter your email').fill('test@test.com');
// Click Continue button (Expo uses div, not button)
await page.getByText('Continue').click();
// Wait for OTP screen
await expect(page.getByText(/verification code|Enter.*code/i)).toBeVisible({ timeout: 10000 });
console.log('OTP screen visible - login flow working!');
});
});