Files
gymflow/tests/rest-timer.spec.ts

151 lines
6.3 KiB
TypeScript

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/);
});
});