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

212 lines
8.7 KiB
TypeScript

import { test, expect } from './fixtures';
test.describe('Rest Timer', () => {
test('should allow setting a rest time in a free session', async ({ page, createUniqueUser }) => {
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 {
await page.getByRole('heading', { name: 'Change Password' }).waitFor();
await page.getByLabel('New Password').fill('StrongNewPassword123!');
await page.getByRole('button', { name: 'Save & Login' }).click();
} catch (e) {
// Ignore if the change password screen is not visible
}
await expect(page.getByText('Free Workout')).toBeVisible();
// Click the "Free Workout" button.
await page.getByRole('button', { name: 'Free Workout' }).click();
// The FAB timer should be visible (IDLE state: icon only)
const fab = page.locator('.fixed.bottom-24.right-6');
await expect(fab).toBeVisible();
// Click on the rest timer FAB to expand it and reveal the time value.
await fab.click();
// Wait for expansion and Edit button visibility
const editBtn = fab.locator('button[aria-label="Edit"]');
await expect(editBtn).toBeVisible();
await editBtn.click();
// Change the rest timer value to 90 seconds.
await page.getByRole('textbox').nth(1).fill('90');
// Confirm the new rest timer value.
const saveBtn = fab.locator('button[aria-label="Save"]');
await expect(saveBtn).toBeVisible();
await saveBtn.click();
// The timer should now be 90 seconds.
await expect(page.locator('div').filter({ hasText: /1:30|90/ }).first()).toBeVisible();
});
test('should validate manual input in the rest timer', async ({ page, createUniqueUser }) => {
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 {
await page.getByRole('heading', { name: 'Change Password' }).waitFor();
await page.getByLabel('New Password').fill('StrongNewPassword123!');
await page.getByRole('button', { name: 'Save & Login' }).click();
} catch (e) {
// Ignore
}
await expect(page.getByText('Free Workout')).toBeVisible();
// Start a Free Workout
await page.getByRole('button', { name: 'Free Workout' }).click();
// Expand the Rest Timer FAB (Click first!)
const fab = page.locator('.fixed.bottom-24.right-6');
await fab.click();
// Click 'Edit'
const editBtn = fab.locator('button[aria-label="Edit"]');
await expect(editBtn).toBeVisible();
await editBtn.click();
// Type '90' -> Verify '1:30' (if auto-format implemented) or manual '1:30'.
const timerInput = page.getByRole('textbox').nth(1);
await timerInput.fill('90');
await expect(timerInput).toHaveValue('90');
// Attempt to type non-digits -> Verify they are ignored.
await timerInput.fill('90abc');
await expect(timerInput).toHaveValue('90');
// Attempt to type '10:99' (invalid seconds) -> Verify it corrects to '10:59'.
await timerInput.fill('10:99');
await expect(timerInput).toHaveValue('10:59');
// Save
const saveBtn = fab.locator('button[aria-label="Save"]');
await saveBtn.click();
// Verify updated value in FAB (might need to wait or check visibility)
// After save, it usually stays expanded per code "setIsExpanded(true)"
});
test('should persist the rest timer value across sessions', async ({ page, createUniqueUser }) => {
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 {
await page.getByRole('heading', { name: 'Change Password' }).waitFor();
await page.getByLabel('New Password').fill('StrongNewPassword123!');
await page.getByRole('button', { name: 'Save & Login' }).click();
} catch (e) {
// Ignore
}
await expect(page.getByText('Free Workout')).toBeVisible();
// Start a Free Workout
await page.getByRole('button', { name: 'Free Workout' }).click();
// Click FAB to expand
const fab = page.locator('.fixed.bottom-24.right-6');
await fab.click();
// Edit timer to '0:45'.
const editBtn = fab.locator('button[aria-label="Edit"]');
await editBtn.click();
const timerInput = page.getByRole('textbox').nth(1);
await timerInput.fill('45');
const saveBtn = fab.locator('button[aria-label="Save"]');
await saveBtn.click();
// Quit session
await page.getByRole('button', { name: 'Finish' }).click();
await page.getByRole('button', { name: 'Confirm' }).click();
// Start Quick Log
await page.getByRole('button', { name: 'Quick Log' }).click();
// Verify timer default is now '0:45'.
const quickFab = page.locator('.fixed.bottom-24.right-6');
await quickFab.click();
await expect(page.locator('div').filter({ hasText: /0:45/ }).first()).toBeVisible();
});
test('should integrate the rest timer with plans', async ({ page, createUniqueUser }) => {
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 {
await page.getByRole('heading', { name: 'Change Password' }).waitFor();
await page.getByLabel('New Password').fill('StrongNewPassword123!');
await page.getByRole('button', { name: 'Save & Login' }).click();
} catch (e) {
// Ignore
}
await expect(page.getByText('Free Workout')).toBeVisible();
// Navigate to the "Plans" page.
await page.getByRole('button', { name: 'Plans' }).click();
// Create a new plan.
await page.getByRole('button', { name: 'Create Plan' }).click();
// Name the plan "Timer Test Plan".
await page.getByRole('textbox', { name: 'Name' }).fill('Timer Test Plan');
// Add the first exercise.
await page.getByRole('button', { name: 'Add Exercise' }).click();
await page.getByRole('button', { name: 'New Exercise' }).click();
await page.locator('[id="_r_4_"]').fill('Bench Press');
await page.getByRole('button', { name: 'Free Weights & Machines' }).click();
await page.getByRole('button', { name: 'Create' }).click();
await page.getByPlaceholder('Rest (s)').fill('30');
// Add the second exercise.
await page.getByRole('button', { name: 'Add Exercise' }).click();
await page.getByRole('button', { name: 'New Exercise' }).click();
await page.locator('[id="_r_5_"]').fill('Squat');
await page.getByRole('button', { name: 'Free Weights & Machines' }).click();
await page.getByRole('button', { name: 'Create' }).click();
await page.getByPlaceholder('Rest (s)').nth(1).fill('60');
// Save the plan.
await page.getByRole('button', { name: 'Save' }).click();
// Start the plan.
await page.getByRole('button', { name: 'Start' }).click();
// Timer Update: Click FAB
const fab = page.locator('.fixed.bottom-24.right-6');
await fab.click();
// Verify Timer shows '0:30'. Start it.
await expect(page.locator('div').filter({ hasText: /0:30/ }).first()).toBeVisible();
const startBtn = fab.locator('button[aria-label="Start"]');
await startBtn.click();
// Log Set for Step A while timer is running.
await page.getByRole('button', { name: 'Log Set' }).click();
// Verify Timer continues running (does not reset).
await expect(page.locator('div').filter({ hasText: /0:2[0-9]/ }).first()).toBeVisible();
// Reset Timer manually (or wait for finish).
const resetBtn = fab.locator('button[aria-label="Reset"]');
await resetBtn.click();
// Verify Timer now shows '1:00' (for Step B).
await expect(page.locator('div').filter({ hasText: /1:00/ }).first()).toBeVisible();
});
});