Data and Progress tests done
This commit is contained in:
397
tests/data-progress.spec.ts
Normal file
397
tests/data-progress.spec.ts
Normal file
@@ -0,0 +1,397 @@
|
||||
import { test, expect } from './fixtures';
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
// Helper for setup
|
||||
async function loginAndSetup(page: any, createUniqueUser: any) {
|
||||
const user = await createUniqueUser();
|
||||
await page.goto('/');
|
||||
await page.getByLabel('Email').fill(user.email);
|
||||
await page.getByLabel('Password').fill(user.password);
|
||||
await page.getByRole('button', { name: 'Login' }).click();
|
||||
|
||||
try {
|
||||
const heading = page.getByRole('heading', { name: /Change Password/i });
|
||||
const dashboard = page.getByText('Free Workout');
|
||||
await expect(heading.or(dashboard)).toBeVisible({ timeout: 5000 });
|
||||
if (await heading.isVisible()) {
|
||||
await page.getByLabel('New Password').fill('StrongNewPass123!');
|
||||
await page.getByRole('button', { name: /Save|Change/i }).click();
|
||||
await expect(dashboard).toBeVisible();
|
||||
}
|
||||
} catch (e) {
|
||||
// Login might already be done
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
test.describe('IV. Data & Progress', () => {
|
||||
|
||||
test('4.1. A. Session History - View Past Sessions', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
// Subtask 2.1: Complete a workout session
|
||||
const exNameSession = 'Hist View Session ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', {
|
||||
data: { name: exNameSession, type: 'STRENGTH' },
|
||||
headers: { 'Authorization': `Bearer ${user.token}` }
|
||||
});
|
||||
|
||||
await page.getByRole('button', { name: /Free Workout|Start Empty/i }).click();
|
||||
|
||||
await page.getByRole('textbox', { name: /Select Exercise/i }).click();
|
||||
await page.getByText(exNameSession).click();
|
||||
|
||||
await page.getByLabel('Weight (kg)').first().fill('50');
|
||||
await page.getByLabel('Reps').first().fill('10');
|
||||
await page.getByRole('button', { name: /Log Set/i }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// Subtask 2.2: Log a sporadic set
|
||||
const exNameSporadic = 'Hist View Sporadic ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', {
|
||||
data: { name: exNameSporadic, type: 'STRENGTH' },
|
||||
headers: { 'Authorization': `Bearer ${user.token}` }
|
||||
});
|
||||
|
||||
await page.getByRole('button', { name: 'Quick Log' }).click();
|
||||
await page.getByRole('textbox', { name: /Select Exercise/i }).click();
|
||||
await page.getByText(exNameSporadic).click();
|
||||
|
||||
await page.getByLabel(/Reps/i).first().fill('12');
|
||||
await page.getByRole('button', { name: /Log Set/i }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Quit' }).click();
|
||||
|
||||
// 3. Navigate to History
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
|
||||
// Verification
|
||||
await expect(page.getByRole('heading', { name: 'History' })).toBeVisible();
|
||||
|
||||
// Check for Quick Log entry details
|
||||
await expect(page.getByText(/50\s*kg\s*x\s*12\s*reps/).or(page.getByText(/x 12 reps/))).toBeVisible();
|
||||
|
||||
// Check for Workout Session entry (shows summary)
|
||||
await expect(page.getByText('No plan').first()).toBeVisible();
|
||||
await expect(page.getByText('Sets:').first()).toBeVisible();
|
||||
|
||||
// Check for Quick Log heading
|
||||
await expect(page.getByRole('heading', { name: 'Quick Log' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.2. A. Session History - View Detailed Session', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
const exName = 'Detail View ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', {
|
||||
data: { name: exName, type: 'STRENGTH' },
|
||||
headers: { 'Authorization': `Bearer ${user.token}` }
|
||||
});
|
||||
|
||||
// Complete session
|
||||
await page.getByRole('button', { name: /Free Workout|Start Empty/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select Exercise/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
|
||||
await page.getByLabel('Weight (kg)').first().fill('50');
|
||||
await page.getByLabel('Reps').first().fill('10');
|
||||
await page.getByRole('button', { name: /Log Set/i }).click();
|
||||
|
||||
await expect(page.getByText('50 kg x 10 reps')).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// Navigate to History
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
|
||||
// Click on a workout session entry
|
||||
await page.getByText('No plan').first().click();
|
||||
|
||||
// Verification
|
||||
await expect(page.getByRole('heading', { name: /Edit|Session Details/ })).toBeVisible();
|
||||
|
||||
// Check details
|
||||
await expect(page.getByText('Start')).toBeVisible();
|
||||
await expect(page.getByText('End')).toBeVisible();
|
||||
await expect(page.getByText('Weight (kg)').first()).toBeVisible();
|
||||
|
||||
// Verify set details
|
||||
await expect(page.getByRole('heading', { name: /Sets/ })).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.3. A. Session History - Edit Past Session Details', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
const exName = 'Edit Sess ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
|
||||
// Open details
|
||||
await page.getByText('No plan').first().click();
|
||||
|
||||
// Modify Body Weight (first spinbutton usually)
|
||||
await page.getByRole('spinbutton').first().fill('75.5');
|
||||
|
||||
// Save
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
// Verify
|
||||
await expect(page.getByText('75.5kg')).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.4. A. Session History - Edit Individual Set in Past Session', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
const exName = 'Edit Set ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
|
||||
await expect(page.getByText('50 kg x 10 reps')).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
|
||||
// Open details
|
||||
await page.getByText('No plan').first().click();
|
||||
|
||||
// Modify weight from 50 to 55
|
||||
// Be specific with locator if possible, or use first matching input
|
||||
await page.locator('input[value="50"]').fill('55');
|
||||
|
||||
// Save
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
// Verify
|
||||
await page.getByText('No plan').first().click();
|
||||
await expect(page.locator('input[value="55"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.5. A. Session History - Delete Past Session', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
const exName = 'Del Sess ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
|
||||
await expect(page.getByText('50 kg x 10 reps')).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
await expect(page.getByText('No plan').first()).toBeVisible();
|
||||
|
||||
// Delete (2nd button usually)
|
||||
await page.getByRole('main').getByRole('button').nth(1).click();
|
||||
|
||||
// Confirm
|
||||
await expect(page.getByRole('heading', { name: 'Delete workout?' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
|
||||
// Verify empty
|
||||
await expect(page.getByText('History is empty')).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.6. A. Session History - Edit Sporadic Set', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
const exName = 'Spor Edit ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
await page.getByRole('button', { name: 'Quick Log' }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('12');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Quit' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Quick Log' })).toBeVisible();
|
||||
|
||||
// Edit (1st button for sporadic row)
|
||||
await page.getByRole('main').getByRole('button').nth(0).click();
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Edit' })).toBeVisible();
|
||||
await page.locator('input[value="12"]').fill('15');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
await expect(page.getByText(/50\s*kg\s*x\s*15\s*reps/)).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.7. A. Session History - Delete Sporadic Set', async ({ page, createUniqueUser, request }) => {
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
|
||||
const exName = 'Spor Del ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
await page.getByRole('button', { name: 'Quick Log' }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('12');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Quit' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'History' }).click();
|
||||
|
||||
// Delete (2nd button for sporadic row, or last button in main if only one row)
|
||||
// With only one row, buttons are Edit, Delete. Delete is 2nd.
|
||||
await page.getByRole('main').getByRole('button').last().click();
|
||||
|
||||
await expect(page.getByRole('dialog')).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
|
||||
await expect(page.getByText('50 kg x 12 reps')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('4.8. B. Performance Statistics - View Volume Chart', async ({ page, createUniqueUser, request }) => {
|
||||
test.setTimeout(120000);
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
const exName = 'Vol Chart ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
// Session 1
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
|
||||
await expect(page.getByText('50 kg x 10 reps')).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// Session 2
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('60');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Stats' }).click();
|
||||
await expect(page.getByText('Work Volume')).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.9. B. Performance Statistics - View Set Count Chart', async ({ page, createUniqueUser, request }) => {
|
||||
test.setTimeout(120000);
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
const exName = 'Set Chart ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
// Session 1
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// Session 2
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('60');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Stats' }).click();
|
||||
await expect(page.getByText('Number of Sets')).toBeVisible();
|
||||
});
|
||||
|
||||
test('4.10. B. Performance Statistics - View Body Weight Chart', async ({ page, createUniqueUser, request }) => {
|
||||
test.setTimeout(120000);
|
||||
const user = await loginAndSetup(page, createUniqueUser);
|
||||
const exName = 'BW Chart ' + randomUUID().slice(0, 4);
|
||||
await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });
|
||||
|
||||
// Complete 2 sessions (to unlock stats page - assuming constraint)
|
||||
// Session 1
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('50');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// Session 2
|
||||
await page.getByRole('button', { name: /Free Workout/i }).click();
|
||||
await page.getByRole('textbox', { name: /Select/i }).click();
|
||||
await page.getByText(exName).click();
|
||||
await page.getByLabel(/Weight/i).first().fill('60');
|
||||
await page.getByLabel(/Reps/i).first().fill('10');
|
||||
await page.getByRole('button', { name: /Log/i }).click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
||||
// Log body weight history via API
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
const dateStr = yesterday.toISOString().split('T')[0];
|
||||
|
||||
await page.evaluate(async ({ token, dateStr }) => {
|
||||
await fetch('/api/weight', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ weight: 70, dateStr })
|
||||
});
|
||||
}, { token: user.token, dateStr });
|
||||
|
||||
// Log today's weight via UI
|
||||
await page.getByRole('button', { name: 'Profile' }).click();
|
||||
await page.getByRole('button', { name: 'Weight Tracker' }).click();
|
||||
await page.getByPlaceholder('Enter weight...').fill('72');
|
||||
await page.getByRole('button', { name: 'Log', exact: true }).click();
|
||||
await expect(page.getByText('Weight logged successfully')).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Stats' }).click();
|
||||
await expect(page.getByText('Body Weight History')).toBeVisible();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('test', async ({ page }) => {
|
||||
// Recording...
|
||||
});
|
||||
@@ -1,36 +0,0 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('test', async ({ page }) => {
|
||||
await page.goto('http://localhost:3000/login');
|
||||
await page.getByRole('textbox', { name: 'Email' }).click();
|
||||
await page.getByRole('textbox', { name: 'Email' }).fill('admin@gymflow.ai');
|
||||
await page.getByRole('textbox', { name: 'Email' }).press('Tab');
|
||||
await page.getByRole('textbox', { name: 'Password' }).fill('admin123');
|
||||
await page.getByRole('button', { name: 'Login' }).click();
|
||||
await page.getByRole('button', { name: 'Plans' }).click();
|
||||
await page.getByRole('button', { name: 'Create Plan' }).click();
|
||||
await page.getByRole('textbox', { name: 'Name' }).click();
|
||||
await page.getByRole('textbox', { name: 'Name' }).fill('Smart Plan');
|
||||
await page.getByRole('button', { name: 'Add Exercise' }).click();
|
||||
await page.getByRole('button').filter({ hasText: /^$/ }).nth(2).click();
|
||||
await page.locator('[id="_r_3_"]').fill('Exercise A');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('button', { name: 'Add Exercise' }).click();
|
||||
await page.getByRole('button').filter({ hasText: /^$/ }).nth(3).click();
|
||||
await page.locator('[id="_r_4_"]').fill('Exercise B');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('button', { name: 'Start' }).nth(1).click();
|
||||
await page.getByRole('spinbutton', { name: 'Weight (kg)' }).click();
|
||||
await page.getByRole('spinbutton', { name: 'Weight (kg)' }).fill('12');
|
||||
await page.getByRole('spinbutton', { name: 'Reps' }).click();
|
||||
await page.getByRole('spinbutton', { name: 'Reps' }).fill('13');
|
||||
await page.getByRole('button', { name: 'Log Set' }).click();
|
||||
await page.getByRole('spinbutton', { name: 'Weight (kg)' }).click();
|
||||
await page.getByRole('spinbutton', { name: 'Weight (kg)' }).fill('13');
|
||||
await page.getByRole('spinbutton', { name: 'Reps' }).click();
|
||||
await page.getByRole('spinbutton', { name: 'Reps' }).fill('14');
|
||||
await page.getByRole('button', { name: 'Log Set' }).click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
});
|
||||
Reference in New Issue
Block a user