import { test, expect } from './fixtures'; test.describe('Rest Timer Feature', () => { // Helper to handle first login if needed (copied from core-auth) async function handleFirstLogin(page: any) { try { const heading = page.getByRole('heading', { name: /Change Password/i }); await expect(heading).toBeVisible({ timeout: 5000 }); await page.getByLabel('New Password').fill('StrongNewPass123!'); await page.getByRole('button', { name: /Save|Change/i }).click(); await expect(page.getByText('Free Workout')).toBeVisible(); } catch (e) { if (await page.getByText('Free Workout').isVisible()) return; // If login failed or other error const error = page.locator('.text-error'); if (await error.isVisible()) throw new Error(`Login failed: ${await error.textContent()}`); } } // Helper for logging in const loginUser = async (page: any, email: string, pass: string) => { await page.goto('/login'); await page.getByLabel('Email').fill(email); await page.getByLabel('Password').fill(pass); await page.getByRole('button', { name: "Login" }).click(); await handleFirstLogin(page); await page.waitForURL('/tracker'); }; test('TC-RT-01: Default timer value and manual adjustment in Free Session', async ({ page, createUniqueUser }) => { // Register/Create user via API const user = await createUniqueUser(); await loginUser(page, user.email, user.password); // 1. Start a free session await page.getByRole('button', { name: "Start Empty Session" }).click(); // 2. Check default timer value (should be 120s / 2:00) const fab = page.locator('.fixed.bottom-24.right-6'); await expect(fab).toBeVisible(); await fab.click(); // Expand const timeDisplay = fab.getByText('2:00'); await expect(timeDisplay).toBeVisible(); // 3. Adjust time to 90s await fab.getByLabel('Edit').click(); // Using aria-label added in component // Decrease 3 times (120 -> 120-15 = 105s) const minusBtn = fab.locator('button').filter({ has: page.locator('svg.lucide-minus') }); await minusBtn.click(); await minusBtn.click(); await minusBtn.click(); // Save const saveBtn = fab.locator('button').filter({ has: page.locator('svg.lucide-check') }); await saveBtn.click(); // Verify display is 1:45 and visible immediately (menu stays expanded) await expect(fab.getByText('1:45')).toBeVisible(); // 4. Persistence check: Quit and reload await page.getByLabel('Options').click(); await page.getByText('Quit without saving').click(); await page.getByRole('button', { name: 'Confirm' }).click(); await page.reload(); // Reload page to ensure persistence from server await page.getByRole('button', { name: "Start Empty Session" }).click(); await fab.click(); // Expand await expect(fab.getByText('1:45')).toBeVisible(); }); test('TC-RT-02: Timer functionality (Start/Pause/Reset)', async ({ page, createUniqueUser }) => { const user = await createUniqueUser(); await loginUser(page, user.email, user.password); await page.getByRole('button', { name: "Start Empty Session" }).click(); const fab = page.locator('.fixed.bottom-24.right-6'); await fab.click(); // Expand // Start const startBtn = fab.getByLabel('Start'); await startBtn.click(); // Check if running await expect(fab).toHaveText(/1:59|2:00/); await expect(fab.getByText('1:5')).toBeVisible({ timeout: 4000 }); // Wait for it to tick down // Pause const pauseBtn = fab.getByLabel('Pause'); await pauseBtn.click(); const pausedText = await fab.innerText(); await page.waitForTimeout(2000); const pausedTextAfter = await fab.innerText(); expect(pausedText).toBe(pausedTextAfter); // Reset const resetBtn = fab.getByLabel('Reset'); await resetBtn.click(); await expect(fab.getByText('2:00')).toBeVisible(); }); test('TC-RT-03: Plan Integration - Rest Time per Step', async ({ page, createUniqueUser }) => { const user = await createUniqueUser(); await loginUser(page, user.email, user.password); // 1. Create Exercise (Inline helper) await page.goto('/exercises'); await page.getByRole('button', { name: 'Create New Exercise' }).click(); await page.getByPlaceholder('Exercise Name').fill('Rest Bench Press'); // Select Muscle Group (Mock selection or just save if defaults work? Validation requires muscle/type) // Assuming defaults or simple selection await page.getByText('Target Muscle').click(); await page.getByText('Chest').click(); await page.getByText('Exercise Type').click(); await page.getByText('Strength').click(); await page.getByRole('button', { name: 'Save Exercise' }).click(); // 2. Create Plan with Rest Time await page.goto('/plans'); await page.getByRole('button', { name: 'Create Plan' }).click(); await page.getByPlaceholder('Plan Name').fill('Rest Test Plan'); await page.getByRole('button', { name: 'Add Exercise' }).click(); await page.getByText('Rest Bench Press').click(); // Set Rest Time to 60s await page.getByPlaceholder('Rest (s)').fill('60'); await page.getByRole('button', { name: 'Save Plan' }).click(); // 3. Start Plan await page.goto('/tracker'); // Ensure plans list is refreshed await page.reload(); await page.getByText('Rest Test Plan').click(); await page.getByRole('button', { name: 'Start Workout' }).click(); // 4. Log Set // Needs input for Weight/Reps if Weighted? Default is unweighted. await page.getByPlaceholder('Weight (kg)').fill('50'); await page.getByPlaceholder('Reps').fill('10'); await page.getByRole('button', { name: 'Log Set' }).click(); // 5. Verify Timer Auto-Start with 60s const fab = page.locator('.fixed.bottom-24.right-6'); // It should be running and showing ~1:00 or 0:59 await expect(fab).toHaveText(/1:00|0:59/); }); });