From 5e3678ee6752c6539643c8a7bb2cf50cb54353d4 Mon Sep 17 00:00:00 2001 From: zhi Date: Mon, 16 Mar 2026 06:32:32 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20isolate=20tests=20=E2=80=94=20each=20tes?= =?UTF-8?q?t=20only=20operates=20on=20its=20own=20resources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - milestone.spec.ts: use unique prefix 'Milestone Test Project', target project card by name, clean up (delete) project after verification - project-editor.spec.ts: use unique prefix 'ProjEditor Test', target project card by name instead of first .project-card match This prevents cross-test interference where project-editor would accidentally delete the project created by the milestone test. --- tests/milestone.spec.ts | 35 ++++++++++++++++++++++++++++++----- tests/project-editor.spec.ts | 25 ++++++++----------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/tests/milestone.spec.ts b/tests/milestone.spec.ts index 20e089c..59f04ac 100644 --- a/tests/milestone.spec.ts +++ b/tests/milestone.spec.ts @@ -59,7 +59,7 @@ test.describe('Milestone Editor', () => { await page.waitForSelector('a:has-text("๐Ÿ“ Projects")', { timeout: 10000 }); console.log('โœ… Logged in'); - // Step 2: Create Project + // Step 2: Create Project (unique name for this test) console.log('๐Ÿ“ Creating project...'); await page.click('a:has-text("๐Ÿ“ Projects")'); await page.waitForLoadState('networkidle'); @@ -68,7 +68,7 @@ test.describe('Milestone Editor', () => { await page.click('button:has-text("+ New")'); await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 }); - const projectName = 'Test Project ' + Date.now(); + 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'); @@ -76,12 +76,13 @@ test.describe('Milestone Editor', () => { await page.click('button:has-text("Create")'); await page.waitForTimeout(2000); - await page.waitForSelector('.project-card', { timeout: 10000 }); + // Wait for our specific project card to appear + await page.waitForSelector(`.project-card:has-text("${projectName}")`, { timeout: 10000 }); console.log('โœ… Project created'); - // Step 3: Click on project to open it + // Step 3: Click on OUR project to open it console.log('๐Ÿ‘† Opening project...'); - await page.click('.project-card'); + await page.click(`.project-card:has-text("${projectName}")`); await page.waitForLoadState('networkidle'); await page.waitForTimeout(1500); console.log('โœ… Project opened'); @@ -134,6 +135,30 @@ test.describe('Milestone Editor', () => { expect(hasMilestone).toBe(true); console.log('โœ… Milestone verified in UI'); + // Step 6: Cleanup โ€” delete the project we created + console.log('๐Ÿงน Cleaning up โ€” deleting project...'); + await page.click('a:has-text("๐Ÿ“ Projects")'); + await page.waitForLoadState('networkidle'); + await page.waitForSelector(`.project-card:has-text("${projectName}")`, { timeout: 10000 }); + await page.click(`.project-card:has-text("${projectName}")`); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1000); + + const deleteBtn = page.locator('button:has-text("Delete")'); + if (await deleteBtn.isVisible().catch(() => false)) { + page.on('dialog', async dialog => { + const match = dialog.message().match(/Type the project name "(.*)" to confirm/); + if (match) { + await dialog.accept(match[1]); + } else { + await dialog.accept(); + } + }); + await deleteBtn.click(); + await page.waitForTimeout(2000); + console.log('โœ… Project cleaned up'); + } + console.log('๐ŸŽ‰ All milestone tests passed!'); }); }); diff --git a/tests/project-editor.spec.ts b/tests/project-editor.spec.ts index 3c0de11..539cb89 100644 --- a/tests/project-editor.spec.ts +++ b/tests/project-editor.spec.ts @@ -44,7 +44,7 @@ test.describe('Project Editor', () => { console.log('โœ… Logged in'); - // Step 2: Create Project + // Step 2: Create Project (unique name for this test) console.log('๐Ÿ“ Creating project...'); // Click Projects in sidebar await page.click('a:has-text("๐Ÿ“ Projects")'); @@ -60,8 +60,8 @@ test.describe('Project Editor', () => { // Wait for the form to appear (look for the project name input) await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 }); - // Fill project form - const projectName = 'Test Project ' + Date.now(); + // 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'); @@ -72,23 +72,14 @@ test.describe('Project Editor', () => { // Wait a bit for submission await page.waitForTimeout(2000); - // Check if there are any errors in console - const errors = await page.evaluate(() => { - return window.__errors || []; - }); - if (errors.length > 0) { - console.log('Console errors:', errors); - } - - // Wait for project to be created (and appear in the grid) - check for any project card - await page.waitForSelector('.project-card', { timeout: 10000 }); + // Wait for our specific project card to appear + await page.waitForSelector(`.project-card:has-text("${projectName}")`, { timeout: 10000 }); console.log('โœ… Project created'); - // Step 3: Delete the created project + // Step 3: Delete the created project โ€” click OUR project card by name console.log('๐Ÿ—‘๏ธ Deleting project...'); - // Click on the project card to open it - await page.click('.project-card'); + await page.click(`.project-card:has-text("${projectName}")`); await page.waitForLoadState('networkidle'); await page.waitForTimeout(1000); @@ -98,7 +89,7 @@ test.describe('Project Editor', () => { console.log('Delete button visible:', deleteBtnVisible); if (deleteBtnVisible) { - // Set up prompt handler for the confirmation dialog - use dialog.defaultValue() to get the project name pattern + // Set up prompt handler for the confirmation dialog page.on('dialog', async dialog => { console.log('Dialog message:', dialog.message()); // Extract project name from the message - format: "Type the project name "XXX" to confirm deletion:"