import { test, expect } from '@playwright/test'; const BASE_URL = process.env.BASE_URL || process.env.FRONTEND_URL || 'http://frontend:3000'; // Test credentials from globalSetup const ADMIN_USERNAME = 'admin'; const ADMIN_PASSWORD = 'admin123'; test.describe('Project Editor', () => { test('login -> create project -> delete project -> logout', async ({ page }) => { // Step 1: Login console.log('🔐 Logging in...'); await page.goto(`${BASE_URL}/login`); await page.waitForLoadState('networkidle'); await page.fill('input[type="text"], input[name="username"]', ADMIN_USERNAME); await page.fill('input[type="password"], input[name="password"]', ADMIN_PASSWORD); // Capture login response const loginPromise = page.waitForResponse(response => response.url().includes('/auth/token') && response.request().method() === 'POST' , { timeout: 10000 }).catch(() => null); await page.click('button[type="submit"], button:has-text("Sign in")'); const loginResponse = await loginPromise; if (loginResponse) { console.log('Login response status:', loginResponse.status()); console.log('Login response:', (await loginResponse.text()).substring(0, 200)); } else { console.log('No /auth/token response'); } // Wait for navigation await page.waitForURL(`${BASE_URL}/**`, { timeout: 10000 }); await page.waitForLoadState('networkidle'); // Debug: check localStorage const token = await page.evaluate(() => localStorage.getItem('token')); console.log('Token after login:', token ? 'present' : 'missing'); // Debug: check current URL console.log('Current URL:', page.url()); console.log('✅ Logged in'); // Step 2: Create Project (unique name for this test) console.log('📁 Creating project...'); // Click Projects in sidebar await page.click('a:has-text("📁 Projects")'); await page.waitForLoadState('networkidle'); // Debug: log all buttons on page const buttons = await page.locator('button').allTextContents(); console.log('Buttons on page:', buttons); // 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 }); // 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'); // Submit project form await page.click('button:has-text("Create")'); // Wait a bit for submission await page.waitForTimeout(2000); // 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 — click OUR project card by name console.log('🗑️ Deleting project...'); await page.click(`.project-card:has-text("${projectName}")`); await page.waitForLoadState('networkidle'); await page.waitForTimeout(1000); // Look for delete button const deleteBtn = page.locator('button:has-text("Delete")'); const deleteBtnVisible = await deleteBtn.isVisible().catch(() => false); console.log('Delete button visible:', deleteBtnVisible); if (deleteBtnVisible) { // 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:" 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 deleted'); } else { console.log('Delete button not found'); } // Step 4: Logout console.log('🚪 Logging out...'); // Click logout button in sidebar await page.click('button:has-text("Log out")'); // Wait for token to be cleared await page.waitForFunction(() => !localStorage.getItem('token'), { timeout: 10000 }); console.log('✅ Logged out'); // Verify we're logged out by checking for login button await page.waitForSelector('button:has-text("Log in")', { timeout: 10000 }); }); });