import { test, expect } from './fixtures'; import { randomUUID } from 'crypto'; test.describe('AI Plan Creation', () => { test('2.14 A. Workout Plans - Create Plan with AI (Parametrized)', async ({ page, createUniqueUser }) => { const user = await loginAndSetup(page, createUniqueUser); // Mock the AI endpoint await page.route('**/api/ai/chat', async route => { const plan = { name: 'AI Advanced Plan', description: 'Generated High Intensity Plan', exercises: [ { name: 'Mock Push-ups', isWeighted: false, restTimeSeconds: 60, type: 'BODYWEIGHT', unilateral: false }, { name: 'Mock Weighted Pull-ups', isWeighted: true, restTimeSeconds: 90, type: 'BODYWEIGHT', unilateral: false } ] }; // The service expects { response: "string_or_json" } await route.fulfill({ json: { response: JSON.stringify(plan) } }); }); // Navigate to Plans await page.getByRole('button', { name: 'Plans' }).first().click(); // Click FAB to open menu const fab = page.getByLabel('Create Plan').or(page.getByRole('button', { name: '+' })); await fab.click(); // Click "With AI" await page.getByRole('button', { name: 'With AI' }).click(); // Verify Defaults await expect(page.getByText('Create Plan with AI')).toBeVisible(); // Equipment default: No equipment // Checking visual state might be hard if it's custom styled, but we can check the selected button style or text const eqSection = page.locator('div').filter({ hasText: 'Equipment' }).last(); // Assuming "No equipment" is selected. We can check class or aria-pressed if available, or just proceed to change it. // Level default: Intermediate const levelSection = page.locator('div').filter({ hasText: 'Level' }).last(); // Just verify buttons exist await expect(levelSection.getByRole('button', { name: 'Intermediate' })).toBeVisible(); // Intensity default: Moderate const intensitySection = page.locator('div').filter({ hasText: 'Intensity' }).last(); await expect(intensitySection.getByRole('button', { name: 'Moderate' })).toBeVisible(); // Modify Inputs // Change Level to Advanced await levelSection.getByRole('button', { name: 'Advanced' }).click(); // Change Intensity to High await intensitySection.getByRole('button', { name: 'High' }).click(); // Change Equipment to Free Weights await eqSection.getByRole('button', { name: /Free weights/i }).click(); // Click Generate await page.getByRole('button', { name: 'Generate' }).click(); // Verify Preview // Wait for preview to appear (mock response) await expect(page.getByText('Generated Plan')).toBeVisible({ timeout: 10000 }); await expect(page.getByText('Mock Push-ups')).toBeVisible(); await expect(page.getByText('Mock Weighted Pull-ups')).toBeVisible(); // Icons check (weighted vs bodyweight) - optional visual check // Click Save Plan await page.getByRole('button', { name: 'Save Plan' }).click(); // Verify Saved // Should close sheet and show plan list await expect(page.getByText('AI Advanced Plan')).toBeVisible(); await expect(page.getByText('Generated High Intensity Plan')).toBeVisible(); }); }); async function loginAndSetup(page: any, createUniqueUser: any) { const user = await createUniqueUser(); await page.goto('/'); await page.getByLabel('Email').fill(user.email); await page.getByLabel('Password').fill(user.password); await page.getByRole('button', { name: 'Login' }).click(); try { const heading = page.getByRole('heading', { name: /Change Password/i }); const dashboard = page.getByText('Free Workout'); await expect(heading.or(dashboard)).toBeVisible({ timeout: 5000 }); if (await heading.isVisible()) { await page.getByLabel('New Password').fill('StrongNewPass123!'); await page.getByRole('button', { name: /Save|Change/i }).click(); await expect(dashboard).toBeVisible(); } } catch (e) { // Login might already be done or dashboard loaded fast } return user; }