diff --git a/tests/milestone.spec.ts b/tests/milestone.spec.ts index 5cd8ee0..f971f28 100644 --- a/tests/milestone.spec.ts +++ b/tests/milestone.spec.ts @@ -6,7 +6,7 @@ const ADMIN_USERNAME = 'admin'; const ADMIN_PASSWORD = 'admin123'; test.describe('Milestone Editor', () => { - test('login -> create project -> create milestone through frontend form', async ({ page }) => { + test('login -> create project -> create and edit milestone through modal', async ({ page }) => { // Step 1: Login (with retry — backend may still be warming up) console.log('🔐 Logging in...'); @@ -66,14 +66,14 @@ test.describe('Milestone Editor', () => { await page.waitForSelector('button:has-text("+ New")', { timeout: 10000 }); await page.click('button:has-text("+ New")'); - await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 }); + await page.waitForSelector('.modal', { timeout: 10000 }); const projectName = 'Milestone Test Project ' + Date.now(); console.log('Creating project with name:', projectName); - await page.fill('input[placeholder="Project name"]', projectName); - await page.fill('input[placeholder="Description (optional)"]', 'Project for milestone testing'); + await page.getByTestId('project-name-input').fill(projectName); + await page.getByTestId('project-description-input').fill('Project for milestone testing'); - await page.click('button:has-text("Create")'); + await page.click('.modal button.btn-primary:has-text("Create")'); await page.waitForTimeout(2000); // Wait for our specific project card to appear @@ -122,20 +122,27 @@ test.describe('Milestone Editor', () => { // Step 5: Verify milestone was created console.log('🔍 Verifying milestone...'); - - // Get the heading text const headingText = await page.locator('h3').filter({ hasText: /Milestones/i }).textContent(); console.log('Heading text:', headingText); - - // Check if milestone count > 0 const hasMilestone = headingText && /\(1?\d+\)/.test(headingText) && !headingText.includes('(0)'); console.log('Has milestone:', hasMilestone); - - // Verify milestone exists in UI expect(hasMilestone).toBe(true); console.log('✅ Milestone verified in UI'); - // Note: intentionally NOT deleting the project/milestone — leave for inspection + // Step 6: Open milestone and edit it via modal + console.log('✏️ Editing milestone...'); + await page.click(`.milestone-item:has-text("${milestoneName}")`); + await page.waitForLoadState('networkidle'); + await page.click('button:has-text("Edit Milestone")'); + await page.waitForSelector('.modal', { timeout: 10000 }); + + const updatedMilestoneName = `${milestoneName} Updated`; + await page.getByTestId('milestone-title-input').fill(updatedMilestoneName); + await page.click('.modal button.btn-primary:has-text("Save")'); + await page.waitForSelector('.modal', { state: 'detached', timeout: 10000 }); + await expect(page.locator(`h2:has-text("${updatedMilestoneName}")`)).toBeVisible({ timeout: 10000 }); + console.log('✅ Milestone edited'); + console.log('🎉 All milestone tests passed!'); }); }); diff --git a/tests/project-editor.spec.ts b/tests/project-editor.spec.ts index 539cb89..ab3c743 100644 --- a/tests/project-editor.spec.ts +++ b/tests/project-editor.spec.ts @@ -7,7 +7,7 @@ const ADMIN_USERNAME = 'admin'; const ADMIN_PASSWORD = 'admin123'; test.describe('Project Editor', () => { - test('login -> create project -> delete project -> logout', async ({ page }) => { + test('login -> create project -> edit project via modal -> delete project -> logout', async ({ page }) => { // Step 1: Login console.log('🔐 Logging in...'); await page.goto(`${BASE_URL}/login`); @@ -57,17 +57,14 @@ test.describe('Project Editor', () => { // Click create project button - it's "+ New" await page.waitForSelector('button:has-text("+ New")', { timeout: 10000 }); await page.click('button:has-text("+ New")'); - // Wait for the form to appear (look for the project name input) - await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 }); + await page.waitForSelector('.modal', { timeout: 10000 }); - // Fill project form with a unique, identifiable name const projectName = 'ProjEditor Test ' + Date.now(); console.log('Creating project with name:', projectName); - await page.fill('input[placeholder="Project name"]', projectName); - await page.fill('input[placeholder="Description (optional)"]', 'Project for E2E testing'); + await page.getByTestId('project-name-input').fill(projectName); + await page.getByTestId('project-description-input').fill('Project for E2E testing'); - // Submit project form - await page.click('button:has-text("Create")'); + await page.click('.modal button.btn-primary:has-text("Create")'); // Wait a bit for submission await page.waitForTimeout(2000); @@ -76,12 +73,23 @@ test.describe('Project Editor', () => { await page.waitForSelector(`.project-card:has-text("${projectName}")`, { timeout: 10000 }); console.log('✅ Project created'); - // Step 3: Delete the created project — click OUR project card by name - console.log('🗑️ Deleting project...'); - + // Step 3: Edit the created project via modal + console.log('✏️ Editing project via modal...'); await page.click(`.project-card:has-text("${projectName}")`); await page.waitForLoadState('networkidle'); await page.waitForTimeout(1000); + + await page.click('button:has-text("Edit")'); + await page.waitForSelector('.modal', { timeout: 10000 }); + const updatedDescription = `Updated project description ${Date.now()}`; + await page.getByTestId('project-description-input').fill(updatedDescription); + await page.click('.modal button.btn-primary:has-text("Save")'); + await page.waitForSelector('.modal', { state: 'detached', timeout: 10000 }); + await expect(page.locator(`text=${updatedDescription}`)).toBeVisible({ timeout: 10000 }); + console.log('✅ Project edited'); + + // Step 4: Delete the created project — click OUR project card by name + console.log('🗑️ Deleting project...'); // Look for delete button const deleteBtn = page.locator('button:has-text("Delete")'); diff --git a/tests/task.spec.ts b/tests/task.spec.ts index 684123e..236686b 100644 --- a/tests/task.spec.ts +++ b/tests/task.spec.ts @@ -52,10 +52,10 @@ test.describe('Task & Comment Flow', () => { await page.waitForSelector('button:has-text("+ New")', { timeout: 10000 }); await page.click('button:has-text("+ New")'); - await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 }); - await page.fill('input[placeholder="Project name"]', projectName); - await page.fill('input[placeholder="Description (optional)"]', 'Project for task & comment testing'); - await page.click('button:has-text("Create")'); + await page.waitForSelector('.modal', { timeout: 10000 }); + await page.getByTestId('project-name-input').fill(projectName); + await page.getByTestId('project-description-input').fill('Project for task & comment testing'); + await page.click('.modal button.btn-primary:has-text("Create")'); await page.waitForTimeout(2000); await page.waitForSelector(`.project-card:has-text("${projectName}")`, { timeout: 10000 }); @@ -117,6 +117,19 @@ test.describe('Task & Comment Flow', () => { await expect(taskRow).toBeVisible({ timeout: 10000 }); console.log('✅ Task created and verified'); + // Edit the created task via task detail modal + console.log('✏️ Editing created task...'); + await taskRow.click(); + await page.waitForURL(/\/tasks\/\d+$/, { timeout: 10000 }); + await page.click('button:has-text("Edit Task")'); + await page.waitForSelector('.modal.task-create-modal', { timeout: 10000 }); + const updatedTaskTitle = `${taskTitle} Updated`; + await page.getByTestId('task-title-input').fill(updatedTaskTitle); + await page.getByTestId('create-task-button').click(); + await page.waitForSelector('.modal.task-create-modal', { state: 'detached', timeout: 10000 }); + await expect(page.locator(`h2:has-text("${updatedTaskTitle}")`)).toBeVisible({ timeout: 10000 }); + console.log('✅ Task edited and verified'); + // ── Step 5: Create a Task item (for comment testing) ─────────────── // Milestone tasks don't have a detail page with comments, so we create // a Task item from the shared Tasks-page modal to test the comment flow.