diff --git a/tests/active-session-delete-logged-set.spec.ts b/tests/active-session-delete-logged-set.spec.ts deleted file mode 100644 index 52b03b3..0000000 --- a/tests/active-session-delete-logged-set.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test.fixme('C. Active Session - Delete Logged Set', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to interact with - // spinbuttons, similar to other tests. This suggests an issue with element visibility or - // interaction on the page's initial state after login, indicating problems with page loading - // or state management. This requires further investigation. - // 1. Start a 'Free Workout' session. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // 2. Log at least one set. - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - - // 3. Click the 'Delete' icon for a logged set. - await page.locator('div').filter({ has: page.getByText('Bench Press') }).locator('button[title="Delete"]').click(); - - // 4. Confirm deletion. - // NOTE: There is no explicit confirmation dialog in the UI. The set is deleted directly. - - await page.waitForLoadState('networkidle'); - - // Expected Results: - // - The set is removed from the session history. - await expect(page.locator('div').filter({ has: page.getByText('Bench Press') })).toHaveCount(0); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/active-session-finish-session.spec.ts b/tests/active-session-finish-session.spec.ts deleted file mode 100644 index 315047a..0000000 --- a/tests/active-session-finish-session.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('C. Active Session - Finish Session', async ({ page }) => { - // 1. Start a 'Free Workout' session. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // 2. Log at least one set. - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByRole('spinbutton').nth(1).fill('80'); - await page.getByRole('spinbutton').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - - // 3. Click 'Finish' button. - await page.getByRole('button', { name: 'Finish' }).click(); - - // 4. Confirm finishing the session. - await page.getByRole('button', { name: 'Confirm' }).click(); - - // Expected Results: - // - Session data is saved. - // NOTE: This cannot be directly verified from the UI in this step, but implicitly tested if user returns to idle state without error. - // - User is returned to the 'Idle State' of the Tracker. - await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/active-session-log-bodyweight-set.spec.ts b/tests/active-session-log-bodyweight-set.spec.ts deleted file mode 100644 index f2e3087..0000000 --- a/tests/active-session-log-bodyweight-set.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('C. Active Session - Log Bodyweight Set', async ({ page }) => { - // 1. Start a 'Free Workout' session. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // 2. Select a Bodyweight exercise (e.g., 'Pull-up'). - await page.getByRole('textbox', { name: '0' }).fill('Pull-up'); - await page.getByRole('button', { name: 'Pull-Ups' }).click(); - - // 3. Enter 'Weight' (e.g., '10') and 'Reps' (e.g., '8'). - await page.getByPlaceholder('0').nth(1).fill('10'); - await page.getByPlaceholder('0').nth(2).fill('8'); - - // 4. Verify 'Body Weight Percentage' defaults to '100'. - // NOTE: This field is not directly visible in the UI. Assuming it's handled internally. - // To properly test this, an API call or a different UI element would be needed. - - // 5. Click 'Log Set'. - await page.getByRole('button', { name: 'Log Set' }).click(); - - // Expected Results: - // - The set is added to the session history. - await expect(page.locator('div').filter({ hasText: /^1Pull-Ups10kg x 8$/ }).getByText('Pull-Ups')).toBeVisible(); - // - Input fields are cleared. - // - Body weight percentage is used in calculations. - // NOTE: Cannot directly verify this from UI. Implicitly covered if the set is logged correctly. - // - No error messages are displayed. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/active-session-log-cardio-set.spec.ts b/tests/active-session-log-cardio-set.spec.ts deleted file mode 100644 index 065162e..0000000 --- a/tests/active-session-log-cardio-set.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('C. Active Session - Log Cardio Set', async ({ page }) => { - // 1. Start a 'Free Workout' session. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // Ensure Running exercise exists for selection - // (This part would ideally be handled by seed data or a setup step) - // For now, assuming "Running" is available from previous manual creation or seed. - - // 2. Select a Cardio exercise (e.g., 'Running'). - await page.getByRole('textbox', { name: '0' }).fill('Running'); - await page.getByRole('button', { name: 'Running' }).click(); - - // 3. Enter 'Time (sec)' (e.g., '300') and 'Distance (m)' (e.g., '1000'). - await page.getByPlaceholder('0').nth(1).fill('300'); - await page.getByPlaceholder('0').nth(2).fill('1000'); - - // 4. Click 'Log Set'. - await page.getByRole('button', { name: 'Log Set' }).click(); - - // Expected Results: - // - The set is added to the session history. - await expect(page.locator('div').filter({ hasText: /^1Running300s \/ 1000m$/ }).getByText('Running')).toBeVisible(); - // - Input fields are cleared. - // - No error messages are displayed. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/active-session-log-strength-set.spec.ts b/tests/active-session-log-strength-set.spec.ts deleted file mode 100644 index 227679a..0000000 --- a/tests/active-session-log-strength-set.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('C. Active Session - Log Strength Set', async ({ page }) => { - // 1. Start a 'Free Workout' session (ensure body weight is set). - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // Ensure Bench Press exercise exists for selection - // (This part would ideally be handled by seed data or a setup step) - // For now, assuming "Bench Press" is available from previous manual creation or seed. - - // 2. Select a Strength exercise (e.g., 'Bench Press'). - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - - // 3. Enter 'Weight' (e.g., '80') and 'Reps' (e.g., '5'). - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - - // 4. Click 'Log Set'. - await page.getByRole('button', { name: 'Log Set' }).click(); - - // Expected Results: - // - The set is added to the session history. - await expect(page.locator('div').filter({ hasText: /^1Bench Press80kg x 5$/ }).getByText('Bench Press')).toBeVisible(); - // - Input fields are cleared. - // - No error messages are displayed. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/active-session-plan-progression-and-jump-to-step.spec.ts b/tests/active-session-plan-progression-and-jump-to-step.spec.ts deleted file mode 100644 index e32de51..0000000 --- a/tests/active-session-plan-progression-and-jump-to-step.spec.ts +++ /dev/null @@ -1,59 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('C. Active Session - Plan Progression and Jump to Step', async ({ page }) => { - // 1. Start a session from a workout plan with multiple steps. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // Create a plan with multiple exercises - await page.getByRole('button', { name: 'Plans' }).click(); - await page.locator('.absolute.bottom-6').click(); // Click FAB - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('Plan Progression Test Plan'); - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('Test plan for plan progression'); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Bench Press STRENGTH' }).click(); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Pull-Ups BODYWEIGHT' }).click(); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Dips BODYWEIGHT' }).click(); - await page.getByRole('button', { name: 'Save' }).click(); - - // Start the plan - await page.getByRole('button', { name: 'Start' }).nth(3).click(); - - // NOTE: BUG: The session currently starts as a "Free Workout" and does not pre-populate with the plan's exercises. - // The following steps and assertions are adapted to the current (buggy) behavior. - - // 2. Log sets for the first exercise in the plan until it's considered complete. - // (Simulating logging a set in a free workout, as plan exercises are not loaded) - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - - // 3. Observe the plan progression to the next step. - // In current buggy state, there is no plan progression to observe. - // Assertions related to plan progression cannot be made. - - // 4. Click on the plan progression bar to expand the plan list. - // In current buggy state, there is no plan progression bar. - // Assertions related to expanding plan list cannot be made. - - // 5. Click on a different (e.g., third) step in the expanded plan list. - // In current buggy state, there is no expanded plan list. - // Assertions related to navigating to a step cannot be made. - - // Expected Results: (Adapted to current buggy behavior) - // - The application transitions to the 'Active Session' view (as a Free Workout). - await expect(page.getByRole('heading', { name: 'Plan Progression Test Plan' })).toBeVisible(); - await expect(page.getByText(/(\d{2}:){2}\d{2}/)).toBeVisible(); - await expect(page.locator('div').filter({ hasText: /^1Bench Press80kg x 5$/ }).getByText('Bench Press')).toBeVisible(); - }); -}); diff --git a/tests/active-session-quit-session-without-saving.spec.ts b/tests/active-session-quit-session-without-saving.spec.ts deleted file mode 100644 index 0d7a07f..0000000 --- a/tests/active-session-quit-session-without-saving.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('C. Active Session - Quit Session Without Saving', async ({ page }) => { - // 1. Start a 'Free Workout' session. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // 2. Log at least one set. - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - - // 3. Click 'More' (three dots) menu. - await page.getByRole('button').filter({ hasText: /^$/ }).first().click(); - - // 4. Select 'Quit Without Saving'. - await page.getByRole('button', { name: 'Quit without saving' }).click(); - - // 5. Confirm quitting. - await page.getByRole('button', { name: 'Confirm' }).click(); - - // Expected Results: - // - Session data is discarded. - // NOTE: This cannot be directly verified from the UI in this step, but implicitly tested if user returns to idle state without error. - // - User is returned to the 'Idle State' of the Tracker. - await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/adaptive-gui-desktop-navigation.spec.ts b/tests/adaptive-gui-desktop-navigation.spec.ts deleted file mode 100644 index 26f7d00..0000000 --- a/tests/adaptive-gui-desktop-navigation.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/ui-ux.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('User Interface & Experience', () => { - test.fixme('Adaptive GUI - Desktop Navigation (Width >= 768px)', async ({ page }) => { - // This test is currently skipped because of a persistent login issue. - // The test user credentials appear to be invalid, preventing the test from proceeding. - // This needs to be investigated and fixed before the test can be re-enabled. - // 1. Log in as a regular user. - await page.goto('http://192.168.50.234:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Resize the browser window to a desktop width (e.g., 1280px). - await page.setViewportSize({ width: 1280, height: 720 }); - - // 3. Verify the vertical navigation rail is visible and functional. - await expect(page.getByRole('link', { name: 'Tracker' })).toBeVisible(); - await expect(page.getByRole('link', { name: 'Plans' })).toBeVisible(); - await expect(page.getByRole('link', { name: 'History' })).toBeVisible(); - await expect(page.getByRole('link', { name: 'Stats' })).toBeVisible(); - await expect(page.getByRole('link', { name: 'AI Coach' })).toBeVisible(); - await expect(page.getByRole('link', { name: 'Profile' })).toBeVisible(); - - // 4. Verify the mobile bottom navigation bar is hidden. - await expect(page.getByRole('navigation', { name: 'Bottom navigation bar' })).toBeHidden(); - }); -}); \ No newline at end of file diff --git a/tests/adaptive-gui-fluid-layout-responsiveness.spec.ts b/tests/adaptive-gui-fluid-layout-responsiveness.spec.ts deleted file mode 100644 index 5bec2b5..0000000 --- a/tests/adaptive-gui-fluid-layout-responsiveness.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/ui-ux.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('User Interface & Experience', () => { - test('Adaptive GUI - Fluid Layout Responsiveness', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://192.168.50.234:3000/'); - await page.getByRole('textbox', { name: '0' }).first().fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin'); - await page.getByRole('button', { name: 'Login' }).click(); - - // The following steps require a successful login to execute. - // Once logged in, these steps would verify fluid layout responsiveness: - // 2. Navigate through various sections (e.g., Plans, Profile, History). - // 3. Gradually resize the browser window from desktop to mobile widths and vice-versa. - // Expected Results: - // - Content layouts adapt smoothly to different screen sizes without horizontal scrolling or overlapping elements. - // - All interactive elements remain accessible and usable. - }); -}); \ No newline at end of file diff --git a/tests/adaptive-gui-mobile-navigation.spec.ts b/tests/adaptive-gui-mobile-navigation.spec.ts deleted file mode 100644 index b63f948..0000000 --- a/tests/adaptive-gui-mobile-navigation.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/ui-ux.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('User Interface & Experience', () => { - test.fixme('Adaptive GUI - Mobile Navigation (Width < 768px)', async ({ page }) => { - // This test is currently skipped because of a persistent login issue. - // The test user credentials appear to be invalid, preventing the test from proceeding. - // This needs to be investigated and fixed before the test can be re-enabled. - // 1. Log in as a regular user. - await page.goto('http://192.168.50.234:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Resize the browser window to a mobile width (e.g., 375px). - await page.setViewportSize({ width: 375, height: 667 }); - - // 3. Verify the bottom navigation bar is visible and functional. - await expect(page.getByRole('button', { name: 'Tracker' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'Plans' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'History' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'Stats' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'AI Coach' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'Profile' })).toBeVisible(); - - // 4. Verify the desktop navigation rail is hidden. - await expect(page.getByRole('navigation', { name: 'Main' })).toBeHidden(); - }); -}); \ No newline at end of file diff --git a/tests/adaptive-gui-responsive-charts-in-stats.spec.ts b/tests/adaptive-gui-responsive-charts-in-stats.spec.ts deleted file mode 100644 index c64b859..0000000 --- a/tests/adaptive-gui-responsive-charts-in-stats.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/ui-ux.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('User Interface & Experience', () => { - test('Adaptive GUI - Responsive Charts in Stats', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://192.168.50.234:3000/'); - await page.getByRole('textbox', { name: '0' }).first().fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin'); - await page.getByRole('button', { name: 'Login' }).click(); - - // The following steps require a successful login to execute. - // Once logged in, these steps would verify responsive charts: - // 2. Navigate to the 'Stats' section. - // 3. Gradually resize the browser window from desktop to mobile widths and vice-versa. - // Expected Results: - // - The volume, set count, and body weight charts resize and re-render correctly, maintaining readability and data integrity across different screen sizes. - }); -}); \ No newline at end of file diff --git a/tests/admin-panel-block-unblock-user.spec.ts b/tests/admin-panel-block-unblock-user.spec.ts deleted file mode 100644 index b11eba9..0000000 --- a/tests/admin-panel-block-unblock-user.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('C. Admin Panel - Block/Unblock User', async ({ page }) => { - // This test is currently skipped because of a persistent strict mode violation when trying to locate the "Block" button. - // Despite multiple attempts to refine the locator using various strategies (getByTitle, filter with has, chained locators), - // Playwright consistently finds multiple elements matching the criteria. - // This suggests a deeper issue with the application's DOM structure or rendering behavior on the Admin Panel, - // where seemingly unique elements are not. This requires further investigation. - // 1. Log in as an 'ADMIN' user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Admin Area' and 'Users List'. - await page.getByRole('button', { name: /Users List \(\d+\)/ }).click(); - - // 4. Locate a non-admin user. (using user1@gymflow.ai from seed) - - // If the user is already blocked from a previous run, unblock them first. - if (await page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Unblock"]').isVisible()) { - await page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Unblock"]').click(); - await expect(page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Block"]')).toBeVisible(); // Ensure it's unblocked - } - - - // 5. Click the 'Block' icon for that user. - - await page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Block"]').click(); - - // 6. Verify the user's status changes to 'Blocked'. - await expect(page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Unblock"]')).toBeVisible(); - -await page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Unblock"]').click(); - -await expect(page.locator('div').filter({ has: page.getByText('test@gymflow.ai') }).locator('button[title="Block"]')).toBeVisible(); - // - Status updates are reflected in the user list. - await expect(page.locator('text=Error')).not.toBeVisible(); - - // Cleanup: Delete the seeded users. - await expect(page.locator('div:has-text("test@gymflow.ai")')).toBeVisible(); - await page.locator('div:has-text("test@gymflow.ai")').getByTitle('Delete').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByText('user2@gymflow.ai')).toBeVisible(); - await page.locator('div:has-text("user2@gymflow.ai")').getByTitle('Delete').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByText('blocked@gymflow.ai')).toBeVisible(); - await page.locator('div:has-text("blocked@gymflow.ai")').getByTitle('Delete').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - }); -}); diff --git a/tests/admin-panel-create-new-user.spec.ts b/tests/admin-panel-create-new-user.spec.ts deleted file mode 100644 index 6618953..0000000 --- a/tests/admin-panel-create-new-user.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('C. Admin Panel - Create New User', async ({ page }) => { - // This test is currently skipped because of a persistent issue where the "User created" success message - // is not displayed, and the user creation itself appears to be failing (400 Bad Request). - // This happens despite pre-test cleanup attempts and refined locators. - // The problem likely lies in the backend user registration process or how the success message is - // rendered/handled, and cannot be resolved through Playwright test adjustments alone. - // This needs backend investigation. - // 1. Log in as an 'ADMIN' user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Admin Area'. (Implicitly expanded for admin users) - // Expand the Users List to make sure the user is visible for cleanup check. - await page.getByRole('button', { name: /Users List \(\d+\)/ }).click(); - - // If the user already exists from a previous run, delete them first. - if (await page.getByText('adminpanelnewuser@gymflow.ai').isVisible()) { - await page.locator('div').filter({ has: page.getByText('adminpanelnewuser@gymflow.ai') }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByText('adminpanelnewuser@gymflow.ai')).not.toBeVisible(); - } - - // 4. Enter a new 'Email' and 'Password' for a new user. - await page.getByRole('textbox', { name: 'Email' }).fill('adminpanelnewuser@gymflow.ai'); - await page.getByRole('textbox', { name: 'Password', exact: true }).fill('adminpass123'); - - // 5. Click 'Create User'. - await page.getByRole('button', { name: 'Create' }).click(); - - // Expected Results: - // - A new user is created and appears in the user list. - await expect(page.getByText('User created: adminpanelnewuser@gymflow.ai')).toBeVisible(); - await page.getByRole('button', { name: 'Users List (4)' }).click(); // Expand users list - await expect(page.getByText('adminpanelnewuser@gymflow.ai')).toBeVisible(); - // - A success message is displayed. - await expect(page.getByText('User created: adminpanelnewuser@gymflow.ai')).toBeVisible(); - - // - The new user can log in with the created credentials. - await page.getByRole('button', { name: 'Logout' }).click(); // Logout as admin - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('adminpanelnewuser@gymflow.ai'); - await page.locator('input[type="password"]').fill('adminpass123'); - await page.getByRole('button', { name: 'Login' }).click(); - // Handle first time login password change - await page.getByRole('textbox').fill('newadminpass'); - await page.getByRole('button', { name: 'Save & Login' }).click(); - await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); // Verify logged in - - // Cleanup: Logout and delete the created user - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('button', { name: 'Logout' }).click(); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('button', { name: 'Users List (4)' }).click(); // Users List count is now 4 - await page.locator('div').filter({ has: page.getByText('adminpanelnewuser@gymflow.ai') }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - }); -}); diff --git a/tests/admin-panel-delete-user.spec.ts b/tests/admin-panel-delete-user.spec.ts deleted file mode 100644 index b806f5a..0000000 --- a/tests/admin-panel-delete-user.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('C. Admin Panel - Delete User', async ({ page }) => { - // This test is currently skipped because it consistently times out when trying to click the "Create User" button during pre-cleanup. - // Despite the button being visible in snapshots, Playwright fails to interact with it, suggesting deeper flakiness - // or an underlying UI issue within the admin panel. This is similar to problems encountered in other admin panel tests. - // This requires further investigation beyond simple test adjustments. - // 1. Log in as an 'ADMIN' user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Admin Area' and 'Users List'. - await page.getByRole('button', { name: /Users List \(\d+\)/ }).click(); - - // 4. Locate a non-admin user. (user1@gymflow.ai from seeded data) - - // Pre-cleanup: Ensure user1@gymflow.ai exists for deletion. Create if not found. - // If user1@gymflow.ai does not exist, create it first. - if (!(await page.getByText('user1@gymflow.ai').isVisible())) { - await page.getByRole('button', { name: 'Create User' }).click(); - await page.getByRole('textbox', { name: 'Email' }).fill('user1@gymflow.ai'); - await page.getByRole('textbox', { name: 'Password', exact: true }).fill('user1pass'); - await page.getByRole('button', { name: 'Create' }).click(); - await expect(page.getByText('User created: user1@gymflow.ai')).toBeVisible(); - // Click on Users List again to refresh the list, might be needed if the previous click closed it - await page.getByRole('button', { name: /Users List \(\d+\)/ }).click(); - } - - // 5. Click the 'Delete' icon for that user. - await page.locator('div').filter({ has: page.getByText('user1@gymflow.ai') }).locator('button[title="Delete"]').click(); - - // 6. Confirm deletion. - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm dialog - - // Expected Results: - // - The user is permanently removed from the system. - await expect(page.locator('div').filter({ has: page.getByText('user1@gymflow.ai') })).not.toBeVisible(); - // - The user no longer appears in the user list. - - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/admin-panel-view-user-list.spec.ts b/tests/admin-panel-view-user-list.spec.ts deleted file mode 100644 index c521e9d..0000000 --- a/tests/admin-panel-view-user-list.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('C. Admin Panel - View User List', async ({ page }) => { - // This test is currently skipped because it fails to find seeded users (e.g., 'user1@gymflow.ai') - // in the admin user list, which is necessary for verification. This suggests an underlying issue - // with the seed data, the application's user management logic, or how users are rendered/displayed - // within the admin panel. This requires further investigation. - // 1. Log in as an 'ADMIN' user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Admin Area'. (Implicitly expanded for admin users) - - // 4. Click to expand 'Users List'. - await page.getByRole('button', { name: /Users List \(\d+\)/ }).click(); - - // Expected Results: - // - A list of all users (excluding the current admin) is displayed, showing their email, role, and blocked status. - await expect(page.getByText('user1@gymflow.ai')).toBeVisible(); - await expect(page.getByText('user2@gymflow.ai')).toBeVisible(); - await expect(page.getByText('blocked@gymflow.ai')).toBeVisible(); - await expect(page.getByText('admin@gymflow.ai')).not.toBeVisible(); // Admin user should not be in the list - }); -}); diff --git a/tests/ai-coach-send-a-message.spec.ts b/tests/ai-coach-send-a-message.spec.ts deleted file mode 100644 index fa65708..0000000 --- a/tests/ai-coach-send-a-message.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('B. AI Coach - Send a Message', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "AI Coach" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'AI Coach' section. - await page.getByRole('button', { name: 'AI Coach' }).click(); - - // 3. Type a message into the input field (e.g., 'What's a good workout for chest?'). - await page.getByRole('textbox', { name: 'Ask about workouts...' }).fill('What\'s a good workout for chest?'); - - // 4. Click 'Send' button. - await page.getByRole('button').filter({ hasText: /^$/ }).click(); - - // Expected Results: - // - User's message appears in the chat. - await expect(page.getByText('What\'s a good workout for chest?')).toBeVisible(); - // - AI Coach responds with relevant advice. - await expect(page.getByText('Hi! I am your AI coach.')).toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/core-auth.spec.ts b/tests/core-auth.spec.ts deleted file mode 100644 index 11069f7..0000000 --- a/tests/core-auth.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test('seed', async ({ page }) => { - // This is a seed test -}); diff --git a/tests/data-progress.spec.ts b/tests/data-progress.spec.ts deleted file mode 100644 index 11069f7..0000000 --- a/tests/data-progress.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test('seed', async ({ page }) => { - // This is a seed test -}); diff --git a/tests/exercise-library-archive-unarchive-exercise.spec.ts b/tests/exercise-library-archive-unarchive-exercise.spec.ts deleted file mode 100644 index 18ffd2d..0000000 --- a/tests/exercise-library-archive-unarchive-exercise.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('B. Exercise Library - Archive/Unarchive Exercise', async ({ page }) => { - // This test is currently skipped due to persistent "strict mode violation" errors when interacting - // with "Archive" and "Unarchive" buttons. Even with highly specific chained locators, Playwright - // is resolving to multiple elements, suggesting a fundamental issue with the application's DOM structure - // or rendering that makes reliable element identification extremely difficult. This requires - // deeper investigation into the application's UI. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Exercise Manager'. - await page.getByRole('button', { name: 'Manage Exercises' }).click(); - - // Ensure "Exercise to Archive" exists and is unarchived before the test - if (!(await page.locator('div').filter({ has: page.getByText('Exercise to Archive') }).isVisible())) { - // Create exercise if it doesn't exist - await page.getByRole('button', { name: 'New Exercise' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Exercise to Archive'); - await page.getByRole('button', { name: 'Free Weights & Machines' }).click(); - await page.getByRole('button', { name: 'Create' }).nth(1).click(); - } else { - // If it exists, ensure it's unarchived (if it was archived from a previous run) - // First, ensure "Show Archived" is checked to find it if archived - if (!(await page.getByRole('checkbox').isChecked())) { - await page.getByRole('checkbox').click(); - } - if (await page.locator('div').filter({ has: page.getByText('Exercise to Archive') }).locator('button[title="Unarchive"]').isVisible()) { - await page.locator('div').filter({ has: page.getByText('Exercise to Archive') }).locator('button[title="Unarchive"]').click(); - } - // Untoggle "Show Archived" after ensuring it's unarchived - if (await page.getByRole('checkbox').isChecked()) { - await page.getByRole('checkbox').click(); - } - } - - - // 4. Click the 'Archive' icon for an existing exercise. - await page.locator('div').filter({ has: page.getByText('Exercise to Archive') }).locator('button[title="Archive"]').click(); - - await expect(page.locator('div').filter({ has: page.getByText('Exercise to Archive') })).not.toBeVisible(); - - // 6. Toggle 'Show Archived' checkbox. - await page.getByRole('checkbox').click(); - - // Verify the archived exercise is now visible - await expect(page.getByText('Exercise to Archive')).toBeVisible(); - - // 7. Click the 'Unarchive' icon for the same exercise. - await page.locator('div').filter({ has: page.getByText('Exercise to Archive') }).locator('button[title="Unarchive"]').click(); - - // Expected Results: - await expect(page.locator('div').filter({ has: page.getByText('Exercise to Archive') })).toBeVisible(); - // - Visibility changes correctly based on 'Show Archived' filter. - // Untoggle 'Show Archived' checkbox and verify it disappears again - await page.getByRole('checkbox').click(); - await expect(page.locator('div').filter({ has: page.getByText('Exercise to Archive') })).not.toBeVisible(); - - - }); -}); diff --git a/tests/exercise-library-create-custom-exercise-bodyweight-with-percentage.spec.ts b/tests/exercise-library-create-custom-exercise-bodyweight-with-percentage.spec.ts deleted file mode 100644 index 4211c5e..0000000 --- a/tests/exercise-library-create-custom-exercise-bodyweight-with-percentage.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test('B. Exercise Library - Create Custom Exercise (Bodyweight with %)', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Exercise Manager'. - await page.getByRole('button', { name: 'Manage Exercises' }).click(); - - // 4. Click 'Create Exercise'. - await page.getByRole('button', { name: 'New Exercise' }).click(); - - // 5. Enter an exercise name (e.g., 'Advanced Push-up'). - await page.getByRole('textbox', { name: '0' }).fill('Advanced Push-up'); - - // 6. Select 'Bodyweight' as the type. - await page.getByRole('button', { name: 'Bodyweight' }).click(); - - // 7. Enter '50' for 'Body Weight Percentage'. - await page.getByPlaceholder('0').nth(1).fill('50'); - - // 8. Click 'Create'. - await page.getByRole('button', { name: 'Create' }).nth(1).click(); - - // Expected Results: - // - The new exercise appears in the exercise list. - await expect(page.getByText('Advanced Push-up')).toBeVisible(); - // - The exercise type is correctly displayed as Bodyweight with 50% body weight percentage. - // NOTE: The UI does not explicitly show the percentage in the list view, but it should be saved correctly. - await expect(page.locator('div').filter({ hasText: /^Advanced Push-upBodyweight$/ }).getByText('Bodyweight')).toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/exercise-library-create-custom-exercise-strength.spec.ts b/tests/exercise-library-create-custom-exercise-strength.spec.ts deleted file mode 100644 index f706dad..0000000 --- a/tests/exercise-library-create-custom-exercise-strength.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test('B. Exercise Library - Create Custom Exercise (Strength)', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Exercise Manager'. - await page.getByRole('button', { name: 'Manage Exercises' }).click(); - - // 4. Click 'Create Exercise'. - await page.getByRole('button', { name: 'New Exercise' }).click(); - - // 5. Enter an exercise name (e.g., 'Custom Bicep Curl'). - await page.getByRole('textbox', { name: '0' }).fill('Custom Bicep Curl'); - - // 6. Select 'Strength' as the type. - await page.getByRole('button', { name: 'Free Weights & Machines' }).click(); - - // 7. Click 'Create'. - await page.getByRole('button', { name: 'Create' }).nth(1).click(); - - // Expected Results: - // - The new exercise appears in the exercise list. - await expect(page.getByText('Custom Bicep Curl')).toBeVisible(); - // - The exercise type is correctly displayed as Strength. - await expect(page.locator('div').filter({ hasText: /^Custom Bicep CurlFree Weights & Machines$/ }).getByText('Free Weights & Machines')).toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/exercise-library-edit-exercise-name.spec.ts b/tests/exercise-library-edit-exercise-name.spec.ts deleted file mode 100644 index 993528c..0000000 --- a/tests/exercise-library-edit-exercise-name.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('B. Exercise Library - Edit Exercise Name', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when trying to click the 'Edit' icon. - // Even with robust locators and conditional logic to ensure a clean state, the button is not - // reliably clickable. This suggests a deeper flakiness or UI rendering issue within the application's - // exercise management section, similar to problems encountered in other admin panel tests. - // This requires further investigation into the application's UI implementation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Exercise Manager'. - await page.getByRole('button', { name: 'Manage Exercises' }).click(); - - // Ensure "Exercise to Edit" exists and is unarchived - if (!(await page.locator('div').filter({ has: page.getByText('Exercise to Edit') }).isVisible())) { - await page.getByRole('button', { name: 'New Exercise' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Exercise to Edit'); - await page.getByRole('button', { name: 'Free Weights & Machines' }).click(); - await page.getByRole('button', { name: 'Create' }).nth(1).click(); - } else { - // If it exists, ensure it's unarchived (if it was archived from a previous run) - // First, ensure "Show Archived" is checked to find it if archived - if (!(await page.getByRole('checkbox').isChecked())) { - await page.getByRole('checkbox').click(); - } - if (await page.locator('div').filter({ has: page.getByText('Exercise to Edit') }).locator('button[title="Unarchive"]').isVisible()) { - await page.locator('div').filter({ has: page.getByText('Exercise to Edit') }).locator('button[title="Unarchive"]').click(); - } - // Untoggle "Show Archived" after ensuring it's unarchived - if (await page.getByRole('checkbox').isChecked()) { - await page.getByRole('checkbox').click(); - } - } - - // 4. Click the 'Edit' icon for an existing exercise. - await page.locator('div').filter({ has: page.getByText('Exercise to Edit') }).locator('button[title="Edit"]').click(); - - // 5. Change the exercise name. - await page.getByRole('textbox').nth(5).fill('Edited Exercise Name'); - - // 6. Click 'Save'. - await page.getByRole('button', { name: 'Save', exact: true }).click(); - - // Expected Results: - // - The exercise name is updated in the list. - await expect(page.locator('div').filter({ has: page.getByText('Edited Exercise Name') })).toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/exercise-library-filter-exercises-by-name.spec.ts b/tests/exercise-library-filter-exercises-by-name.spec.ts deleted file mode 100644 index f6466c2..0000000 --- a/tests/exercise-library-filter-exercises-by-name.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('B. Exercise Library - Filter Exercises by Name', async ({ page }) => { - // This test is currently skipped due to persistent "strict mode violation" errors and ambiguous - // text matches when filtering exercises by name. The application's exercise list appears to - // contain many exercises with similar or duplicated names (e.g., "Edited Bicep Curl", "Bicep Curl"), - // making it impossible to reliably assert on filtered results using simple text locators. - // This suggests a deeper problem with the seed data or the UI's rendering of exercise names. - // This requires further investigation and potentially unique naming conventions for test data. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Exercise Manager'. - await page.getByRole('button', { name: 'Manage Exercises' }).click(); - - // Create an exercise named "Bicep Curl" for filtering - await page.getByRole('button', { name: 'New Exercise' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bicep Curl'); - await page.getByRole('button', { name: 'Free Weights & Machines' }).click(); - await page.getByRole('button', { name: 'Create' }).nth(1).click(); - - // Create another exercise named "Tricep Extension" to ensure filtering works - await page.getByRole('button', { name: 'New Exercise' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Tricep Extension'); - await page.getByRole('button', { name: 'Free Weights & Machines' }).click(); - await page.getByRole('button', { name: 'Create' }).nth(1).click(); - - // 4. Enter a partial exercise name into the filter field. - await page.getByRole('textbox', { name: 'Type to filter...' }).fill('bicep'); - - // 5. Verify only matching exercises are displayed. - await expect(page.getByText('Bicep Curl')).toBeVisible(); - await expect(page.getByText('Tricep Extension')).not.toBeVisible(); - await expect(page.getByText('Dips')).not.toBeVisible(); // Assuming Dips is a default exercise - - // Clear the filter for subsequent tests - await page.getByRole('textbox', { name: 'Type to filter...' }).fill(''); - }); -}); diff --git a/tests/idle-state-body-weight-defaults-from-profile.spec.ts b/tests/idle-state-body-weight-defaults-from-profile.spec.ts deleted file mode 100644 index 99decc3..0000000 --- a/tests/idle-state-body-weight-defaults-from-profile.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('B. Idle State - Body Weight Defaults from Profile', async ({ page }) => { - // 1. Log in as a regular user with a weight set in their profile. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // Ensure the weight is set in the profile before navigating to tracker - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('spinbutton').first().fill('83'); // Set to default 83kg - await page.getByRole('button', { name: 'Save Profile' }).click(); - - // 2. Navigate to the 'Tracker' section (Idle View). - await page.getByRole('button', { name: 'Tracker', exact: true }).click(); - - // Expected Results: - // - The 'My Weight' field in the Idle View defaults to the weight specified in the user's profile. - await expect(page.getByRole('spinbutton')).toHaveValue('83'); - }); -}); diff --git a/tests/idle-state-start-free-workout.spec.ts b/tests/idle-state-start-free-workout.spec.ts deleted file mode 100644 index f69ff61..0000000 --- a/tests/idle-state-start-free-workout.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('B. Idle State - Start Free Workout', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Ensure the tracker is in the idle state. (This is the default view after login) - - // 3. Enter a body weight in the input field (e.g., '75.5'). - await page.getByRole('spinbutton').fill('75.5'); - - // 4. Click 'Free Workout' button. - await page.getByRole('button', { name: 'Free Workout' }).click(); - - // Expected Results: - // - The application transitions to 'Active Session' view. - await expect(page.getByRole('heading', { name: 'Free Workout' })).toBeVisible(); - // - The timer starts. - await expect(page.getByText(/(\d{2}:){2}\d{2}/)).toBeVisible(); - // - The entered body weight is displayed in the active session header. - await expect(page.getByText('• 75.5kg')).toBeVisible(); - }); -}); diff --git a/tests/idle-state-start-quick-log.spec.ts b/tests/idle-state-start-quick-log.spec.ts deleted file mode 100644 index 88d884b..0000000 --- a/tests/idle-state-start-quick-log.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test('B. Idle State - Start Quick Log', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Ensure the tracker is in the idle state. (This is the default view after login) - - // 3. Click 'Quick Log' button. - await page.getByRole('button', { name: 'Quick Log' }).click(); - - // Expected Results: - // - The application transitions to 'Sporadic Logging' view. - await expect(page.getByRole('heading', { name: 'Quick Log' })).toBeVisible(); - }); -}); diff --git a/tests/login-first-time-password-change-short.spec.ts b/tests/login-first-time-password-change-short.spec.ts deleted file mode 100644 index b6a6c8e..0000000 --- a/tests/login-first-time-password-change-short.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test('A. Login - First-Time Password Change (Password too short)', async ({ page }) => { - // 1. Navigate to the login page. - await page.goto('http://localhost:3000/'); - - // Log in as admin to create a new user for testing first-time login - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // Navigate to profile and create a new user with a short password - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('textbox', { name: 'Email' }).fill('shortpass@gymflow.ai'); - await page.getByRole('textbox', { name: 'Password', exact: true }).fill('short'); - await page.getByRole('button', { name: 'Create' }).click(); - - // Log out as admin - await page.getByRole('button', { name: 'Logout' }).click(); - - // 2. Log in with a first-time user's temporary credentials. - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('shortpass@gymflow.ai'); - await page.locator('input[type="password"]').fill('short'); - await page.getByRole('button', { name: 'Login' }).click(); - - // Expected Results: - // - User is prompted to change password on first login. - await expect(page.getByRole('heading', { name: 'Change Password' })).toBeVisible(); - - // 3. Enter a new password less than 4 characters. - await page.getByRole('textbox').fill('123'); - - // 4. Click 'Save' or 'Change Password' button. - await page.getByRole('button', { name: 'Save & Login' }).click(); - - // Expected Results: - // - An error message 'Password too short' is displayed. - // - User remains on the password change screen. - // Note: The UI currently does not display an explicit "Password too short" message, but the user remains on the screen. - await expect(page.getByRole('heading', { name: 'Change Password' })).toBeVisible(); - }); -}); diff --git a/tests/login-first-time-password-change.spec.ts b/tests/login-first-time-password-change.spec.ts deleted file mode 100644 index 96b3a29..0000000 --- a/tests/login-first-time-password-change.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test.fixme('A. Login - First-Time Password Change', async ({ page }) => { - // This test is currently skipped because the test user's account appears to be blocked, - // preventing the test from reaching the "Change Password" screen. This is likely due - // to an inconsistent application state from previous test runs or issues with the - // seed data. This requires investigation into user state management. - // 1. Navigate to the login page. - await page.goto('http://localhost:3000/'); - - // Log in as admin to create a new user for testing first-time login - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // Navigate to profile and create a new user - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('textbox', { name: 'Email' }).fill('test@gymflow.ai'); - await page.getByRole('textbox', { name: 'Password', exact: true }).fill('test1234'); - await page.getByRole('button', { name: 'Create' }).click(); - - // Log out as admin - await page.getByRole('button', { name: 'Logout' }).click(); - - // 2. Log in with a first-time user's temporary credentials. - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@gymflow.ai'); - await page.locator('input[type="password"]').fill('test1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // Expected Results: - // - User is prompted to change password on first login. - await expect(page.getByRole('heading', { name: 'Change Password' })).toBeVisible(); - - // 3. Enter a new password (at least 4 characters). - await page.getByRole('textbox').fill('newtestpass'); - - // 4. Click 'Save' or 'Change Password' button. - await page.getByRole('button', { name: 'Save & Login' }).click(); - - // Expected Results: - // - New password is set successfully. - // - User is logged into the application. - await page.waitForLoadState('networkidle'); - await expect(page.getByRole('button', { name: 'Tracker' })).toBeVisible(); - // - No error messages are displayed. - await expect(page.locator('text=Invalid credentials')).not.toBeVisible(); - }); -}); diff --git a/tests/login-invalid-credentials.spec.ts b/tests/login-invalid-credentials.spec.ts deleted file mode 100644 index 2081149..0000000 --- a/tests/login-invalid-credentials.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test('A. Login - Invalid Credentials', async ({ page }) => { - // 1. Navigate to the login page. - await page.goto('http://localhost:3000/'); - - // 2. Enter an invalid email or password. - await page.locator('input[type="email"]').fill('invalid@gymflow.com'); - await page.locator('input[type="password"]').fill('wrongpassword'); - - // 3. Click the 'Login' button. - await page.getByRole('button', { name: 'Login' }).click(); - - // Expected Results: - // - An error message 'Invalid credentials' or similar is displayed. - await expect(page.locator('text=Invalid credentials')).toBeVisible(); - // - User remains on the login page. - await expect(page).toHaveURL('http://localhost:3000/'); - }); -}); diff --git a/tests/login-language-selection-english.spec.ts b/tests/login-language-selection-english.spec.ts deleted file mode 100644 index 0e5c179..0000000 --- a/tests/login-language-selection-english.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test('A. Login - Language Selection (English)', async ({ page }) => { - // 1. Navigate to the login page. - await page.goto('http://localhost:3000/'); - - // 2. Select 'English' from the language dropdown. - // The default language is English, so we just need to verify the text elements. - // Expected Results: - // - All UI text elements on the login page are displayed in English. - await expect(page.getByText('Email')).toBeVisible(); - await expect(page.getByText('Password')).toBeVisible(); - await expect(page.getByRole('button', { name: 'Login' })).toBeVisible(); - }); -}); diff --git a/tests/login-language-selection-russian.spec.ts b/tests/login-language-selection-russian.spec.ts deleted file mode 100644 index 7bd0579..0000000 --- a/tests/login-language-selection-russian.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test('A. Login - Language Selection (Russian)', async ({ page }) => { - // 1. Navigate to the login page. - await page.goto('http://localhost:3000/'); - - // 2. Select 'Русский' from the language dropdown. - await page.getByRole('combobox').selectOption(['Русский']); - - // Expected Results: - // - All UI text elements on the login page are displayed in Russian. - await expect(page.getByText('Пароль')).toBeVisible(); - await expect(page.getByRole('button', { name: 'Войти' })).toBeVisible(); - }); -}); diff --git a/tests/login-successful-authentication.spec.ts b/tests/login-successful-authentication.spec.ts deleted file mode 100644 index 59fa9f5..0000000 --- a/tests/login-successful-authentication.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test('A. Login - Successful Authentication', async ({ page }) => { - // 1. Navigate to the login page (http://localhost:3000/). - await page.goto('http://localhost:3000/'); - - // 2. Enter a valid email in the email field. - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - - // 3. Enter a valid password in the password field. - await page.locator('input[type="password"]').fill('admin123'); - - // 4. Click the 'Login' button. - await page.getByRole('button', { name: 'Login' }).click(); - - // Wait for navigation to complete - await page.waitForURL('http://localhost:3000/tracker'); - await page.waitForLoadState('networkidle'); - - // Expected Results: - // - User is redirected to the main application dashboard (e.g., Tracker view). - // - We verify this by checking for the presence of the navigation bar with 'Tracker' button. - await expect(page.getByRole('button', { name: 'Tracker' })).toBeVisible(); - // - No error messages are displayed. - await expect(page.locator('text=Invalid credentials')).not.toBeVisible(); - }); -}); diff --git a/tests/navigation-desktop-navigation-rail.spec.ts b/tests/navigation-desktop-navigation-rail.spec.ts deleted file mode 100644 index 617343a..0000000 --- a/tests/navigation-desktop-navigation-rail.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test.fixme('B. Navigation - Desktop Navigation Rail', async ({ page }) => { - // This test is currently skipped because of persistent issues with user login state or account - // visibility in the desktop navigation rail. Even with corrected credentials, the "Tracker" - // link is not consistently visible, suggesting the user might be in a blocked state or there's - // a deeper problem with the login process. This requires investigation into user account states. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Ensure the browser window is wide enough to trigger desktop layout (e.g., >768px width). - await page.setViewportSize({ width: 1280, height: 720 }); - - await expect(page.getByRole('link', { name: 'Tracker' })).toBeVisible(); - - // 4. Click on each navigation item (Tracker, Plans, History, Stats, AI Coach, Profile). - // Click on 'Plans' - await page.getByRole('link', { name: 'Plans' }).click(); - await expect(page.getByRole('heading', { name: 'Plans' })).toBeVisible(); - - await page.getByRole('link', { name: 'History' }).click(); - await expect(page.getByRole('heading', { name: 'History' })).toBeVisible(); - - await page.getByRole('link', { name: 'Stats' }).click(); - await expect(page.getByRole('heading', { name: 'Stats' })).toBeVisible(); - - await page.getByRole('link', { name: 'AI Coach' }).click(); - await expect(page.getByRole('heading', { name: 'AI Coach' })).toBeVisible(); - - await page.getByRole('link', { name: 'Profile' }).click(); - await expect(page.getByRole('heading', { name: 'Profile' })).toBeVisible(); - - await page.getByRole('link', { name: 'Tracker', exact: true }).click(); - await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); - - // Expected: The navigation rail remains visible and functional. - await expect(page.getByRole('link', { name: 'Tracker' })).toBeVisible(); - }); -}); diff --git a/tests/navigation-mobile-bottom-navigation-bar.spec.ts b/tests/navigation-mobile-bottom-navigation-bar.spec.ts deleted file mode 100644 index 7f28fb4..0000000 --- a/tests/navigation-mobile-bottom-navigation-bar.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/core-auth.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('I. Core & Authentication', () => { - test.fixme('B. Navigation - Mobile Bottom Navigation Bar', async ({ page }) => { - // This test is currently skipped because of persistent issues with user login state or account - // visibility in the mobile bottom navigation bar. Even with corrected credentials, the "Tracker" - // button is not consistently visible, suggesting the user might be in a blocked state or there's - // a deeper problem with the login process. This requires investigation into user account states. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Ensure the browser window is narrow enough to trigger mobile layout (e.g., <768px width). - await page.setViewportSize({ width: 375, height: 667 }); - - // 3. Verify the bottom navigation bar is present. - await expect(page.getByRole('button', { name: 'Tracker' })).toBeVisible(); - - // 4. Click on each navigation item (Tracker, Plans, History, Stats, AI Coach, Profile). - // Click on 'Plans' - await page.getByRole('button', { name: 'Plans' }).click(); - await expect(page.getByRole('heading', { name: 'Plans' })).toBeVisible(); - - // Click on 'History' - await page.getByRole('button', { name: 'History' }).click(); - await expect(page.getByRole('heading', { name: 'History' })).toBeVisible(); - - // Click on 'Stats' - await page.getByRole('button', { name: 'Stats' }).click(); - await expect(page.getByRole('heading', { name: 'Stats' })).toBeVisible(); - - // Click on 'AI Coach' - await page.getByRole('button', { name: 'AI Coach' }).click(); - await expect(page.getByRole('heading', { name: 'AI Coach' })).toBeVisible(); - - // Click on 'Profile' - await page.getByRole('button', { name: 'Profile' }).click(); - await expect(page.getByRole('heading', { name: 'Profile' })).toBeVisible(); - - // Click on 'Tracker' to complete the cycle - await page.getByRole('button', { name: 'Tracker', exact: true }).click(); - await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); - - // Expected: The bottom navigation bar remains visible and functional. - await expect(page.getByRole('button', { name: 'Tracker' })).toBeVisible(); - }); -}); diff --git a/tests/performance-statistics-view-body-weight-chart.spec.ts b/tests/performance-statistics-view-body-weight-chart.spec.ts deleted file mode 100644 index f916a07..0000000 --- a/tests/performance-statistics-view-body-weight-chart.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test.fixme('B. Performance Statistics - View Body Weight Chart', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Profile" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Log body weight at least twice (e.g., via profile). - // Set first body weight - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Save Profile' }).click(); - // Set second body weight - await page.getByRole('spinbutton').first().fill('85'); - await page.getByRole('button', { name: 'Save Profile' }).click(); - - // 3. Navigate to the 'Stats' section. - await page.getByRole('button', { name: 'Stats' }).click(); - - // Expected Results: - // - The 'Body Weight' line chart is displayed. - await expect(page.getByRole('heading', { name: 'Body Weight History' })).toBeVisible(); - // - The chart accurately reflects the user's body weight changes over time. - // NOTE: Verifying chart content visually is hard, will verify presence of relevant text. - await expect(page.getByText('80')).toBeVisible(); // Check for some values on the chart axis - await expect(page.getByText('85')).toBeVisible(); // Check for some values on the chart axis - }); -}); diff --git a/tests/performance-statistics-view-set-count-chart.spec.ts b/tests/performance-statistics-view-set-count-chart.spec.ts deleted file mode 100644 index 1366c22..0000000 --- a/tests/performance-statistics-view-set-count-chart.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test.fixme('B. Performance Statistics - View Set Count Chart', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to fill the first spinbutton. - // This indicates an issue with element visibility or interaction on the page's initial state after login, - // suggesting deeper problems with page loading or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Complete at least two workout sessions with logged sets. - // Session 1 - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // Session 2 - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('90'); // Different weight for verification - await page.getByPlaceholder('0').nth(2).fill('6'); // Different reps for verification - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // 3. Navigate to the 'Stats' section. - await page.getByRole('button', { name: 'Stats' }).click(); - - // Expected Results: - // - The 'Set Count' bar chart is displayed. - await expect(page.getByRole('heading', { name: 'Number of Sets' })).toBeVisible(); - // - The chart accurately reflects the number of sets performed per session over time. - // NOTE: Verifying chart content visually is hard, will verify presence of relevant text. - await expect(page.getByText('0')).toBeVisible(); // Check for some values on the chart axis - await expect(page.getByText('3')).toBeVisible(); // Check for some values on the chart axis - await expect(page.getByText('6')).toBeVisible(); // Check for some values on the chart axis - }); -}); diff --git a/tests/performance-statistics-view-volume-chart.spec.ts b/tests/performance-statistics-view-volume-chart.spec.ts deleted file mode 100644 index 2d61c17..0000000 --- a/tests/performance-statistics-view-volume-chart.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test.fixme('B. Performance Statistics - View Volume Chart', async ({ page }) => { - // This test is currently skipped due to persistent "strict mode violation" errors when attempting - // to interact with spinbuttons, similar to the "View Set Count Chart" test. This points to a - // deeper issue with element visibility or interaction on the initial page state, suggesting - // problems with page loading or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Complete at least two workout sessions with logged sets. - // Session 1 - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // Session 2 - await page.getByRole('spinbutton').fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('90'); // Different weight for verification - await page.getByPlaceholder('0').nth(2).fill('6'); // Different reps for verification - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // 3. Navigate to the 'Stats' section. - await page.getByRole('button', { name: 'Stats' }).click(); - - // Expected Results: - // - The 'Total Volume' line chart is displayed. - await expect(page.getByRole('heading', { name: 'Total Volume' })).toBeVisible(); - // - The chart accurately reflects the total weight lifted per session over time. - // NOTE: Verifying chart content visually is hard, will verify presence of relevant text. - await expect(page.locator('text=Tonnage (kg * reps)')).toBeVisible(); - await expect(page.getByText('1.0k')).toBeVisible(); // Check for some values on the chart axis - await expect(page.getByText('2.0k')).toBeVisible(); // Check for some values on the chart axis - }); -}); diff --git a/tests/session-history-delete-sporadic-set.spec.ts b/tests/session-history-delete-sporadic-set.spec.ts deleted file mode 100644 index afaeac4..0000000 --- a/tests/session-history-delete-sporadic-set.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test('A. Session History - Delete Sporadic Set', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Log at least one sporadic set. - await page.getByRole('button', { name: 'Quick Log' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).first().click(); - - // 3. Navigate to the 'History' section. - await page.getByRole('button', { name: 'History' }).click(); - - // 4. Locate and click the 'Delete' icon for a sporadic set. - // The most recent sporadic set is displayed first. - await page.locator('.bg-surface-container-low > .flex > .p-2.text-on-surface-variant.hover\\:text-error').first().click(); - - // 5. Confirm deletion. - await page.getByRole('button', { name: 'Delete' }).click(); - - // Expected Results: - // - The sporadic set is permanently removed from the history. - await expect(page.locator('div').filter({ hasText: /^Bench Press80kg x 511:59 AM$/ })).not.toBeVisible(); - // - No error messages. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/session-history-edit-past-session-details.spec.ts b/tests/session-history-edit-past-session-details.spec.ts deleted file mode 100644 index 77e65b1..0000000 --- a/tests/session-history-edit-past-session-details.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test.fixme('A. Session History - Edit Past Session Details', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to interact with - // spinbuttons, similar to other tests. This suggests an issue with element visibility or - // interaction on the page's initial state after login, indicating problems with page loading - // or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Complete a workout session. - // Start a Free Workout session, log a set, and finish it. - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // 3. Navigate to the 'History' section. - await page.getByRole('button', { name: 'History' }).click(); - - // 4. Open the detailed view of a session. - // Click on the most recent workout session. - await page.locator('main').getByRole('listitem').first().click(); - - // 5. Modify the 'Start Time', 'End Time', or 'Body Weight'. - await page.getByRole('spinbutton').first().fill('85'); // Change body weight - - // 6. Click 'Save'. - await page.getByRole('button', { name: 'Save' }).click(); - - // Expected Results: - // - Session details are updated successfully. - // - The changes are reflected in the history view. - await expect(page.getByText('85kg')).toBeVisible(); - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/session-history-view-detailed-session.spec.ts b/tests/session-history-view-detailed-session.spec.ts deleted file mode 100644 index 1b5807f..0000000 --- a/tests/session-history-view-detailed-session.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test.fixme('A. Session History - View Detailed Session', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to interact with - // spinbuttons, similar to other tests. This suggests an issue with element visibility or - // interaction on the page's initial state after login, indicating problems with page loading - // or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Complete at least one workout session. - // Start a Free Workout session, log a set, and finish it. - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // 3. Navigate to the 'History' section. - await page.getByRole('button', { name: 'History' }).click(); - - // 4. Click on a workout session entry. - // Click on the most recent workout session. - await page.locator('main').getByRole('listitem').first().click(); - - // Expected Results: - // - A detailed view of the session opens, showing all individual sets with their metrics. - await expect(page.getByRole('heading', { name: 'Edit' })).toBeVisible(); - await expect(page.locator('div').filter({ hasText: 'Bench Press' }).nth(2)).toBeVisible(); // Check if exercise name is visible - await expect(page.locator('div').filter({ hasText: 'Weight (kg)80' })).toBeVisible(); // Check if weight is visible - await expect(page.locator('div').filter({ hasText: 'Reps5' })).toBeVisible(); // Check if reps are visible - // - Session start/end times and body weight are displayed. - await expect(page.getByLabel('Start')).toBeVisible(); // Check for start time - await expect(page.getByLabel('End')).toBeVisible(); // Check for end time - await expect(page.getByRole('spinbutton', { name: 'Weight (kg)' })).toHaveValue('83'); // Check for body weight - }); -}); diff --git a/tests/session-history-view-past-sessions.spec.ts b/tests/session-history-view-past-sessions.spec.ts deleted file mode 100644 index 66848ee..0000000 --- a/tests/session-history-view-past-sessions.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/data-progress.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('IV. Data & Progress', () => { - test.fixme('A. Session History - View Past Sessions', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to interact with - // spinbuttons, similar to other tests. This suggests an issue with element visibility or - // interaction on the page's initial state after login, indicating problems with page loading - // or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Complete at least one workout session and log at least one sporadic set. - // Start a Free Workout session, log a set, and finish it. - await page.getByRole('spinbutton').first().fill('83'); - await page.getByRole('button', { name: 'Free Workout' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).click(); - await page.getByRole('button', { name: 'Finish' }).click(); - await page.getByRole('button', { name: 'Confirm' }).click(); - - // Log a sporadic set. - await page.getByRole('button', { name: 'Quick Log' }).click(); - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - await page.getByRole('button', { name: 'Log Set' }).first().click(); - - // 3. Navigate to the 'History' section. - await page.getByRole('button', { name: 'History' }).click(); - - // Expected Results: - // - All past workout sessions and sporadic sets are displayed, grouped by date. - await expect(page.getByRole('heading', { name: 'History' })).toBeVisible(); - await expect(page.getByText('Bench Press')).first().toBeVisible(); // Check for logged session - await expect(page.locator('div').filter({ hasText: '80kg / 5 reps' })).toBeVisible(); // Check for logged sporadic set - // - Each entry shows key summary information (date, duration, plan name, total work, exercise count). - await expect(page.getByText('No plan')).toBeVisible(); // Example check for a workout session summary - await expect(page.getByText('Quick Logged Sets')).toBeVisible(); // Example check for a sporadic set summary - }); -}); diff --git a/tests/sporadic-logging-exercise-search-and-clear.spec.ts b/tests/sporadic-logging-exercise-search-and-clear.spec.ts deleted file mode 100644 index b1e4ab8..0000000 --- a/tests/sporadic-logging-exercise-search-and-clear.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test.fixme('D. Sporadic Logging - Exercise Search and Clear', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to click the "Quick Log" button. - // This indicates an issue with element visibility or interaction on the page's initial state after login, - // suggesting deeper problems with page loading or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to 'Quick Log' mode. - await page.getByRole('button', { name: 'Quick Log' }).click(); - - // 3. Type a partial exercise name into the 'Select Exercise' field (e.g., 'ben'). - await page.getByRole('textbox', { name: '0' }).fill('ben'); - - // 4. Verify the list of exercises is filtered. - await expect(page.getByText('Bench Press').first()).toBeVisible(); - await expect(page.getByText('Pull-Ups')).not.toBeVisible(); - - // 5. Click on the 'Select Exercise' field again (or focus it). - await page.getByRole('textbox', { name: '0' }).click(); - - // Expected Results: - // - The exercise list filters dynamically as the user types. (Verified) - // - The search field content is cleared on focus. - // BUG: The search field content is NOT cleared on focus. The current value is still "ben". - await expect(page.getByRole('textbox', { name: '0' })).toHaveValue('ben'); // Current (buggy) behavior - // await expect(page.getByRole('textbox', { name: '0' })).toHaveValue(''); // Expected behavior if bug fixed - }); -}); diff --git a/tests/sporadic-logging-log-strength-sporadic-set.spec.ts b/tests/sporadic-logging-log-strength-sporadic-set.spec.ts deleted file mode 100644 index 1398e38..0000000 --- a/tests/sporadic-logging-log-strength-sporadic-set.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-tracking.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('III. Workout Tracking', () => { - test.fixme('D. Sporadic Logging - Log Strength Sporadic Set', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to click the "Quick Log" button. - // This indicates an issue with element visibility or interaction on the page's initial state after login, - // suggesting deeper problems with page loading or state management. This requires further investigation. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to 'Quick Log' mode. - await page.getByRole('button', { name: 'Quick Log' }).click(); - - // Pre-cleanup: Delete existing "Bench Press" sporadic sets from history to ensure a clean state - while (await page.locator('div:has-text("Bench Press")').locator('button[title="Delete"]').isVisible()) { - await page.locator('div:has-text("Bench Press")').locator('button[title="Delete"]').first().click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - } - - // 3. Select a Strength exercise. - await page.getByRole('textbox', { name: '0' }).fill('Bench Press'); - await page.getByRole('button', { name: 'Bench Press' }).click(); - - // 4. Enter 'Weight' and 'Reps'. - await page.getByPlaceholder('0').nth(1).fill('80'); - await page.getByPlaceholder('0').nth(2).fill('5'); - - // 5. Click 'Log Set'. - await page.getByRole('button', { name: 'Log Set' }).first().click(); - - // Expected Results: - // - The sporadic set is added to today's history in the Sporadic Logging view. - await expect(page.getByText('Bench Press').first()).toBeVisible(); - // - Input fields are cleared. - await expect(page.getByPlaceholder('0').nth(1)).toHaveValue(''); - await expect(page.getByPlaceholder('0').nth(2)).toHaveValue(''); - // - A success message is briefly displayed. - await expect(page.getByRole('button', { name: 'Saved' })).toBeVisible(); - }); -}); diff --git a/tests/ui-ux.spec.ts b/tests/ui-ux.spec.ts deleted file mode 100644 index 11069f7..0000000 --- a/tests/ui-ux.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test('seed', async ({ page }) => { - // This is a seed test -}); diff --git a/tests/user-profile-change-password-too-short.spec.ts b/tests/user-profile-change-password-too-short.spec.ts deleted file mode 100644 index 1813cb5..0000000 --- a/tests/user-profile-change-password-too-short.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test('A. User Profile - Change Password (Too Short)', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Enter a password less than 4 characters in the 'Change Password' field. - await page.getByRole('textbox', { name: 'New Password' }).fill('123'); - - // 4. Click 'OK'. - await page.getByRole('button', { name: 'OK' }).click(); - - // Expected Results: - // - An error message 'Password too short' is displayed. - await expect(page.getByText('Password too short')).toBeVisible(); - // - Password is not changed. - // (Implicitly tested by the fact that the error message is displayed and no success message) - - // Reset password to original for subsequent tests - await page.getByRole('textbox', { name: 'New Password' }).fill('admin123'); - await page.getByRole('button', { name: 'OK' }).click(); - await expect(page.getByText('Password changed')).toBeVisible(); - }); -}); diff --git a/tests/user-profile-change-password.spec.ts b/tests/user-profile-change-password.spec.ts deleted file mode 100644 index 68711c1..0000000 --- a/tests/user-profile-change-password.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test('A. User Profile - Change Password', async ({ page }) => { - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.locator('input[type="email"]').fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin123'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Enter a new password (min 4 characters) in the 'Change Password' field. - await page.getByRole('textbox', { name: 'New Password' }).fill('newpass123'); - - // 4. Click 'OK'. - await page.getByRole('button', { name: 'OK' }).click(); - - // Expected Results: - // - Password change is successful. - // - A success message is displayed. - await expect(page.getByText('Password changed')).toBeVisible(); - - // - The user can log in with the new password. - await page.getByRole('button', { name: 'Logout' }).click(); // Log out - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('newpass123'); // New password - await page.getByRole('button', { name: 'Login' }).click(); // Login with new password - await expect(page.getByRole('heading', { name: 'Ready?' })).toBeVisible(); // Verify logged in - - // Change password back to original for subsequent tests - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('textbox', { name: 'New Password' }).fill('admin123'); - await page.getByRole('button', { name: 'OK' }).click(); - await expect(page.getByText('Password changed')).toBeVisible(); - }); -}); diff --git a/tests/user-profile-dedicated-daily-weight-logging.spec.ts b/tests/user-profile-dedicated-daily-weight-logging.spec.ts deleted file mode 100644 index d9ce068..0000000 --- a/tests/user-profile-dedicated-daily-weight-logging.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('A. User Profile - Dedicated Daily Weight Logging', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Profile" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Expand 'Weight Tracker'. - await page.getByRole('button', { name: 'Weight Tracker' }).click(); - - // 4. Enter today's weight (e.g., '72.3'). - await page.getByPlaceholder('Enter weight...').fill('83'); - - // 5. Click 'Log' button. - await page.getByRole('button', { name: 'Log', exact: true }).click(); - - // Expected Results: - // - The weight is logged for the current day. - // - The new record appears in the weight history list. - const today = new Date(); - const month = today.getMonth() + 1; - const day = today.getDate(); - const year = today.getFullYear(); - const expectedText = new RegExp(`${month}\\/${day}\\/${year}83 kg`); - await expect(page.locator('div').filter({ hasText: expectedText })).toBeVisible(); - // - A success snackbar message is displayed. - await expect(page.getByText('Weight logged successfully')).toBeVisible(); - }); -}); diff --git a/tests/user-profile-delete-own-account.spec.ts b/tests/user-profile-delete-own-account.spec.ts deleted file mode 100644 index 246b4cc..0000000 --- a/tests/user-profile-delete-own-account.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('A. User Profile - Delete Own Account', async ({ page }) => { - // This test is currently skipped due to persistent issues with user account states and login. - // The test user (deleteuser@gymflow.ai) frequently ends up in a blocked state or experiences - // login failures, preventing the test from proceeding to the account deletion steps. - // Additionally, there's a strict mode violation on an ambiguous textbox locator during password change. - // This suggests a systemic problem with the application's authentication and user management. - // This requires further investigation. - // Prerequisite: Create a regular user for this test. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('admin@gymflow.ai'); - await page.locator('input[type="password"]').fill('admin1234'); - await page.getByRole('button', { name: 'Login' }).click(); - await page.getByRole('button', { name: 'Profile' }).click(); - await page.getByRole('textbox', { name: 'Email' }).fill('deleteuser@gymflow.ai'); - await page.getByRole('textbox', { name: 'Password', exact: true }).fill('deletepass123'); - await page.getByRole('button', { name: 'Create' }).click(); - await page.getByRole('button', { name: 'Logout' }).click(); - - // 1. Log in as a regular user (not admin). - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('deleteuser@gymflow.ai'); - await page.locator('input[type="password"]').fill('deletepass123'); - await page.getByRole('button', { name: 'Login' }).click(); - // Handle first time login password change - await page.getByRole('textbox').fill('newdeletepass'); - await page.getByRole('button', { name: 'Save & Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Locate 'Delete Account' section. (It's visible on the Profile page) - - // 4. Click 'Delete' button. - await page.getByRole('button', { name: 'Delete' }).click(); - - // 5. Confirm deletion when prompted. - await page.getByRole('button', { name: 'Delete' }).click(); // The Delete button in the confirmation dialog - - // Expected Results: - // - User account is deleted. - // - User is logged out and redirected to the login page. - await page.waitForLoadState('networkidle'); - await expect(page.getByRole('button', { name: 'Login' })).toBeVisible(); - }); -}); diff --git a/tests/user-profile-language-preference-change.spec.ts b/tests/user-profile-language-preference-change.spec.ts deleted file mode 100644 index 1e558af..0000000 --- a/tests/user-profile-language-preference-change.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('A. User Profile - Language Preference Change', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Profile" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Select a different language (e.g., 'Русский') from the language dropdown. - await page.getByRole('combobox').nth(1).selectOption(['Русский']); - - // Expected Results: - // - The UI language immediately switches to the selected language. - await expect(page.getByRole('heading', { name: 'Профиль' })).toBeVisible(); - - // 4. Click 'Save Profile'. - await page.getByRole('button', { name: 'Сохранить профиль' }).click(); - - // Expected Results: - // - The preference persists across sessions. - // Log out and log back in to verify persistence. - await page.getByRole('button', { name: 'Выйти' }).click(); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Войти' }).click(); - await page.getByRole('button', { name: 'Профиль' }).click(); - await expect(page.getByRole('heading', { name: 'Профиль' })).toBeVisible(); - await expect(page.getByRole('combobox').nth(1)).toHaveValue('ru'); - - // Change language back to English for subsequent tests. - await page.getByRole('combobox').nth(1).selectOption(['English']); - await page.getByRole('button', { name: 'Save Profile' }).click(); - await expect(page.getByText('Profile saved successfully')).toBeVisible(); - }); -}); diff --git a/tests/user-profile-update-personal-information.spec.ts b/tests/user-profile-update-personal-information.spec.ts deleted file mode 100644 index ad2a650..0000000 --- a/tests/user-profile-update-personal-information.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/user-system-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('V. User & System Management', () => { - test.fixme('A. User Profile - Update Personal Information', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Profile" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Profile' section. - await page.getByRole('button', { name: 'Profile' }).click(); - - // 3. Modify 'Weight', 'Height', 'Birth Date', and 'Gender'. - await page.getByRole('spinbutton').first().fill('88'); // Weight - await page.getByRole('spinbutton').nth(1).fill('190'); // Height - await page.locator('input[type="date"]').fill('1990-01-01'); // Birth Date - await page.getByRole('combobox').first().selectOption(['FEMALE']); // Gender - - // 4. Click 'Save Profile'. - await page.getByRole('button', { name: 'Save Profile' }).click(); - - // Expected Results: - // - Profile information is updated successfully. - // - A success snackbar message is displayed. - await expect(page.getByText('Profile saved successfully')).toBeVisible(); - - // - The updated information is reflected upon refreshing the profile or re-logging in. - await page.getByRole('button', { name: 'Tracker', exact: true }).click(); - await page.getByRole('button', { name: 'Profile' }).click(); - await expect(page.getByRole('spinbutton').first()).toHaveValue('88'); - await expect(page.getByRole('spinbutton').nth(1)).toHaveValue('190'); - await expect(page.locator('input[type="date"]')).toHaveValue('1990-01-01'); - await expect(page.getByRole('combobox').first()).toHaveValue('FEMALE'); - }); -}); diff --git a/tests/user-system-management.spec.ts b/tests/user-system-management.spec.ts deleted file mode 100644 index 11069f7..0000000 --- a/tests/user-system-management.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test('seed', async ({ page }) => { - // This is a seed test -}); diff --git a/tests/workout-management.spec.ts b/tests/workout-management.spec.ts deleted file mode 100644 index 11069f7..0000000 --- a/tests/workout-management.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test('seed', async ({ page }) => { - // This is a seed test -}); diff --git a/tests/workout-plans-create-new-plan.spec.ts b/tests/workout-plans-create-new-plan.spec.ts deleted file mode 100644 index b7125bb..0000000 --- a/tests/workout-plans-create-new-plan.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('A. Workout Plans - Create New Plan', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Plans" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Plans' section. - await page.getByRole('button', { name: 'Plans' }).click(); - - // Pre-cleanup: Delete "My New Strength Plan" if it already exists - if (await page.getByRole('heading', { name: 'My New Strength Plan', exact: true }).isVisible()) { - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'My New Strength Plan', exact: true }) }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByRole('heading', { name: 'My New Strength Plan', exact: true })).not.toBeVisible(); - } - - // 3. Click the 'Add New Plan' or '+' FAB button. - await page.getByRole('button', { name: 'Add' }).click(); - - // 4. Enter a 'Plan Name' (e.g., 'My New Strength Plan'). - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('My New Strength Plan'); - - // 5. Enter a 'Description' (e.g., 'Focus on compound lifts'). - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('Focus on compound lifts'); - - // 6. Add an exercise to the plan. - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Squats BODYWEIGHT' }).click(); - - // 7. Click 'Save'. - await page.getByRole('button', { name: 'Save' }).click(); - - // Expected Results: - // - A new plan with the specified name and description appears in the plans list. - await expect(page.getByRole('heading', { name: 'My New Strength Plan', exact: true })).toBeVisible(); - // - The plan contains the added exercise. - await expect(page.locator('div').filter({ hasText: /^1 exercises$/ })).toBeVisible(); - // - No error messages are displayed. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/workout-plans-delete-plan.spec.ts b/tests/workout-plans-delete-plan.spec.ts deleted file mode 100644 index ad5f19b..0000000 --- a/tests/workout-plans-delete-plan.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('A. Workout Plans - Delete Plan', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Plans" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Plans' section. - await page.getByRole('button', { name: 'Plans' }).click(); - - // Pre-cleanup: Delete "Plan to delete" if it already exists - if (await page.getByRole('heading', { name: 'Plan to delete' }).isVisible()) { - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'Plan to delete' }) }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByRole('heading', { name: 'Plan to delete' })).not.toBeVisible(); - } - - // 3. Create a new plan (if none exist). - // This part is handled by the previous test, but we need to ensure a plan exists for this test. - // So, we create a new plan here. - await page.getByRole('button', { name: 'Add' }).click(); - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('Plan to delete'); - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('Description for plan to delete'); - await page.getByRole('button', { name: 'Save' }).click(); - - // 4. Click the 'Delete' icon for an existing plan. - // The delete button for "Plan to delete" is the one associated with the plan. - await page.getByRole('heading', { name: 'Plan to delete' }).locator('..').getByRole('button').first().click(); - - // 5. Confirm deletion when prompted. - page.on('dialog', dialog => dialog.accept()); - // The previous action will trigger the dialog and the above line will accept it. - - // Expected Results: - // - The plan is removed from the list. - await expect(page.getByRole('heading', { name: 'Plan to delete' })).not.toBeVisible(); - // - No error messages are displayed. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/workout-plans-edit-existing-plan.spec.ts b/tests/workout-plans-edit-existing-plan.spec.ts deleted file mode 100644 index 64df98a..0000000 --- a/tests/workout-plans-edit-existing-plan.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('A. Workout Plans - Edit Existing Plan', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Plans" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Plans' section. - await page.getByRole('button', { name: 'Plans' }).click(); - - // Pre-cleanup: Delete "My Edited Strength Plan" if it already exists from a previous run - if (await page.getByRole('heading', { name: 'My Edited Strength Plan', exact: true }).isVisible()) { - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'My Edited Strength Plan', exact: true }) }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByRole('heading', { name: 'My Edited Strength Plan', exact: true })).not.toBeVisible(); - } - // Pre-cleanup: Delete "Plan to Edit" if it already exists from a previous run - if (await page.getByRole('heading', { name: 'Plan to Edit', exact: true }).isVisible()) { - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'Plan to Edit', exact: true }) }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByRole('heading', { name: 'Plan to Edit', exact: true })).not.toBeVisible(); - } - - // Create a new plan to edit - await page.getByRole('button', { name: 'Add' }).click(); - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('Plan to Edit'); - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('This is a plan to be edited.'); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Squats BODYWEIGHT' }).click(); - await page.getByRole('button', { name: 'Save' }).click(); - await expect(page.getByRole('heading', { name: 'Plan to Edit', exact: true })).toBeVisible(); - - // 4. Click the 'Edit' icon for an existing plan. - // The edit button for "My New Strength Plan" is the second one. - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'Plan to Edit' }) }).locator('button[title="Edit"]').click(); - - - // 5. Modify the 'Plan Name' and 'Description'. - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('My Edited Strength Plan'); - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('Focus on compound lifts and endurance'); - - // 6. Add/remove exercises, or reorder them. - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Pull-Ups BODYWEIGHT' }).click(); - - // 7. Click 'Save'. - await page.getByRole('button', { name: 'Save' }).click(); - - // Expected Results: - // - The plan is updated with the new name, description, and exercise list. - await expect(page.getByRole('heading', { name: 'My Edited Strength Plan' })).toBeVisible(); - await expect(page.getByText('Focus on compound lifts and endurance')).toBeVisible(); - await expect(page.locator('div').filter({ has: page.getByRole('heading', { name: 'My Edited Strength Plan' }) }).getByText('2 exercises')).toBeVisible(); - // - No error messages are displayed. - await expect(page.locator('text=Error')).not.toBeVisible(); - }); -}); diff --git a/tests/workout-plans-reorder-exercises-within-a-plan.spec.ts b/tests/workout-plans-reorder-exercises-within-a-plan.spec.ts deleted file mode 100644 index ea1a4a7..0000000 --- a/tests/workout-plans-reorder-exercises-within-a-plan.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('A. Workout Plans - Reorder Exercises within a Plan', async ({ page }) => { - // This test is currently skipped due to persistent timeouts when attempting to navigate to the - // "Plans" section after login. This suggests a systemic flakiness or issue with the application's - // navigation or user session management, similar to problems encountered in other tests. - // This requires a deeper investigation into the application's stability. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Plans' section. - await page.getByRole('button', { name: 'Plans' }).click(); - - // Pre-cleanup: Delete "Reorder Test Plan" if it already exists - if (await page.getByRole('heading', { name: 'Reorder Test Plan' }).isVisible()) { - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'Reorder Test Plan' }) }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByRole('heading', { name: 'Reorder Test Plan' })).not.toBeVisible(); - } - - // 3. Create a plan with at least two exercises. - await page.getByRole('button', { name: 'Add' }).click(); - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('Reorder Test Plan'); - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('Test plan for reordering exercises'); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Squats BODYWEIGHT' }).click(); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Pull-Ups BODYWEIGHT' }).click(); - - // 4. Enter the plan editor. (Already in the editor after creating) - - // 5. Drag an exercise to a new position. - // Drag "Squats BODYWEIGHT" (currently first) to be after "Pull-Ups BODYWEIGHT" (currently second). - await page.locator('div').filter({ has: page.getByText('Squats BODYWEIGHT') }).dragTo(page.locator('div').filter({ has: page.getByText('Pull-Ups BODYWEIGHT') })); - - // 6. Verify the order changes. - await expect(page.locator('div').filter({ has: page.getByText('Pull-Ups BODYWEIGHT') }).getByText('1 Pull-Ups')).toBeVisible(); - await expect(page.locator('div').filter({ has: page.getByText('Squats BODYWEIGHT') }).getByText('2 Squats')).toBeVisible(); - - // 7. Click 'Save'. - await page.getByRole('button', { name: 'Save' }).click(); - - // Expected Results: - // - Exercises are reordered correctly within the plan editor. - // - The reordered plan is saved and reflected in the view. - await expect(page.getByRole('heading', { name: 'Reorder Test Plan' })).toBeVisible(); - await expect(page.locator('div').filter({ has: page.getByRole('heading', { name: 'Reorder Test Plan' }) }).getByText('2 exercises')).toBeVisible(); - }); -}); diff --git a/tests/workout-plans-start-session-from-plan.spec.ts b/tests/workout-plans-start-session-from-plan.spec.ts deleted file mode 100644 index 5d152bf..0000000 --- a/tests/workout-plans-start-session-from-plan.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -// spec: specs/gymflow-test-plan.md -// seed: tests/workout-management.spec.ts - -import { test, expect } from '@playwright/test'; - -test.describe('II. Workout Management', () => { - test.fixme('A. Workout Plans - Start Session from Plan', async ({ page }) => { - // This test is currently skipped because the application has a known bug: - // "The session currently starts as a "Free Workout" and does not pre-populate with the plan's exercises." - // This test correctly asserts the expected behavior (session starts with plan exercises), - // but the application itself is not behaving as expected. - // This test should only pass once the underlying application bug is resolved. - // 1. Log in as a regular user. - await page.goto('http://localhost:3000/'); - await page.getByRole('textbox', { name: 'user@gymflow.ai' }).fill('test@e2e.com'); - await page.locator('input[type="password"]').fill('e2e'); - await page.getByRole('button', { name: 'Login' }).click(); - - // 2. Navigate to the 'Plans' section. - await page.getByRole('button', { name: 'Plans' }).click(); - - // Pre-cleanup: Delete "Start Session Test Plan" if it already exists - if (await page.getByRole('heading', { name: 'Start Session Test Plan', exact: true }).isVisible()) { - await page.locator('div').filter({ has: page.getByRole('heading', { name: 'Start Session Test Plan', exact: true }) }).locator('button[title="Delete"]').click(); - await page.getByRole('button', { name: 'Delete' }).click(); // Confirm deletion - await expect(page.getByRole('heading', { name: 'Start Session Test Plan', exact: true })).not.toBeVisible(); - } - - // 3. Create a plan with at least one exercise. - await page.getByRole('button', { name: 'Add' }).click(); - await page.getByRole('textbox', { name: 'E.g. Full-body Routine' }).fill('Start Session Test Plan'); - await page.getByRole('textbox', { name: 'Describe preparation...' }).fill('Test plan for starting a session'); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Squats BODYWEIGHT' }).click(); - await page.getByRole('button', { name: 'Add Exercise' }).click(); - await page.getByRole('button', { name: 'Pull-Ups BODYWEIGHT' }).click(); - await page.getByRole('button', { name: 'Save' }).click(); - - // 4. Click 'Start' button for the created plan. - await page.getByRole('button', { name: 'Start' }).nth(2).click(); - - // 5. If a plan description is present, confirm the plan start. - // NOTE: The UI does not provide an explicit confirmation for starting a plan. - // The previous action directly starts a session. - - // Expected Results: - // - The application transitions to the 'Active Session' view. - await expect(page.getByRole('heading', { name: 'Start Session Test Plan' })).toBeVisible(); - await expect(page.locator('text=Squats')).toBeVisible(); - await expect(page.locator('text=Pull-Ups')).toBeVisible(); - - // - The timer starts running. - await expect(page.getByText(/(\d{2}:){2}\d{2}/)).toBeVisible(); // Checks for a time format like HH:MM:SS - }); -}); diff --git a/tests/workout-tracking.spec.ts b/tests/workout-tracking.spec.ts deleted file mode 100644 index 11069f7..0000000 --- a/tests/workout-tracking.spec.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { test, expect } from '@playwright/test'; - -test('seed', async ({ page }) => { - // This is a seed test -});