fix: isolate tests — each test only operates on its own resources
- 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.
This commit is contained in:
@@ -59,7 +59,7 @@ test.describe('Milestone Editor', () => {
|
|||||||
await page.waitForSelector('a:has-text("📁 Projects")', { timeout: 10000 });
|
await page.waitForSelector('a:has-text("📁 Projects")', { timeout: 10000 });
|
||||||
console.log('✅ Logged in');
|
console.log('✅ Logged in');
|
||||||
|
|
||||||
// Step 2: Create Project
|
// Step 2: Create Project (unique name for this test)
|
||||||
console.log('📁 Creating project...');
|
console.log('📁 Creating project...');
|
||||||
await page.click('a:has-text("📁 Projects")');
|
await page.click('a:has-text("📁 Projects")');
|
||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
@@ -68,7 +68,7 @@ test.describe('Milestone Editor', () => {
|
|||||||
await page.click('button:has-text("+ New")');
|
await page.click('button:has-text("+ New")');
|
||||||
await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 });
|
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);
|
console.log('Creating project with name:', projectName);
|
||||||
await page.fill('input[placeholder="Project name"]', projectName);
|
await page.fill('input[placeholder="Project name"]', projectName);
|
||||||
await page.fill('input[placeholder="Description (optional)"]', 'Project for milestone testing');
|
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.click('button:has-text("Create")');
|
||||||
await page.waitForTimeout(2000);
|
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');
|
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...');
|
console.log('👆 Opening project...');
|
||||||
await page.click('.project-card');
|
await page.click(`.project-card:has-text("${projectName}")`);
|
||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
await page.waitForTimeout(1500);
|
await page.waitForTimeout(1500);
|
||||||
console.log('✅ Project opened');
|
console.log('✅ Project opened');
|
||||||
@@ -134,6 +135,30 @@ test.describe('Milestone Editor', () => {
|
|||||||
expect(hasMilestone).toBe(true);
|
expect(hasMilestone).toBe(true);
|
||||||
console.log('✅ Milestone verified in UI');
|
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!');
|
console.log('🎉 All milestone tests passed!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ test.describe('Project Editor', () => {
|
|||||||
|
|
||||||
console.log('✅ Logged in');
|
console.log('✅ Logged in');
|
||||||
|
|
||||||
// Step 2: Create Project
|
// Step 2: Create Project (unique name for this test)
|
||||||
console.log('📁 Creating project...');
|
console.log('📁 Creating project...');
|
||||||
// Click Projects in sidebar
|
// Click Projects in sidebar
|
||||||
await page.click('a:has-text("📁 Projects")');
|
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)
|
// Wait for the form to appear (look for the project name input)
|
||||||
await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 });
|
await page.waitForSelector('input[placeholder="Project name"]', { timeout: 10000 });
|
||||||
|
|
||||||
// Fill project form
|
// Fill project form with a unique, identifiable name
|
||||||
const projectName = 'Test Project ' + Date.now();
|
const projectName = 'ProjEditor Test ' + Date.now();
|
||||||
console.log('Creating project with name:', projectName);
|
console.log('Creating project with name:', projectName);
|
||||||
await page.fill('input[placeholder="Project name"]', projectName);
|
await page.fill('input[placeholder="Project name"]', projectName);
|
||||||
await page.fill('input[placeholder="Description (optional)"]', 'Project for E2E testing');
|
await page.fill('input[placeholder="Description (optional)"]', 'Project for E2E testing');
|
||||||
@@ -72,23 +72,14 @@ test.describe('Project Editor', () => {
|
|||||||
// Wait a bit for submission
|
// Wait a bit for submission
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
// Check if there are any errors in console
|
// Wait for our specific project card to appear
|
||||||
const errors = await page.evaluate(() => {
|
await page.waitForSelector(`.project-card:has-text("${projectName}")`, { timeout: 10000 });
|
||||||
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 });
|
|
||||||
console.log('✅ Project created');
|
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...');
|
console.log('🗑️ Deleting project...');
|
||||||
|
|
||||||
// Click on the project card to open it
|
await page.click(`.project-card:has-text("${projectName}")`);
|
||||||
await page.click('.project-card');
|
|
||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
await page.waitForTimeout(1000);
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
@@ -98,7 +89,7 @@ test.describe('Project Editor', () => {
|
|||||||
console.log('Delete button visible:', deleteBtnVisible);
|
console.log('Delete button visible:', deleteBtnVisible);
|
||||||
|
|
||||||
if (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 => {
|
page.on('dialog', async dialog => {
|
||||||
console.log('Dialog message:', dialog.message());
|
console.log('Dialog message:', dialog.message());
|
||||||
// Extract project name from the message - format: "Type the project name "XXX" to confirm deletion:"
|
// Extract project name from the message - format: "Type the project name "XXX" to confirm deletion:"
|
||||||
|
|||||||
Reference in New Issue
Block a user