import { test, expect, chromium } from '@playwright/test'; import * as fs from 'fs'; const API_URL = process.env.API_URL || 'http://localhost:3001'; const BASE_URL = process.env.FRONTEND_URL || 'http://localhost:5173'; async function api(method: string, endpoint: string, body?: unknown, token?: string) { const headers: Record = { 'Content-Type': 'application/json' }; if (token) headers.Authorization = `Bearer ${token}`; const res = await fetch(`${API_URL}${endpoint}`, { method, headers, body: body ? JSON.stringify(body) : undefined }); return { status: res.status, body: await res.json() }; } test('diagnose editor DOM', async () => { const browser = await chromium.launch({ headless: true }); const page = await browser.newPage({ viewport: { width: 1600, height: 1000 } }); // Register user const email = `diag-${Date.now()}@example.com`; const reg = await api('POST', '/api/auth/register', { email, password: 'Test1234!', name: 'Diag' }); const token = reg.body.session.token; // Create project const proj = await api('POST', '/api/projects', { name: 'Diag', description: 'x' }, token); // Open app with token await page.goto(`${BASE_URL}/`); await page.evaluate((t) => localStorage.setItem('auth_token', t), token); await page.reload(); const failedRequests: string[] = []; const badResponses: { url: string; status: number }[] = []; page.on('requestfailed', req => failedRequests.push(`${req.method()} ${req.url()}: ${req.failure()?.errorText}`)); page.on('response', res => { const status = res.status(); if (status >= 400) badResponses.push({ url: res.url(), status }); }); page.on('console', msg => { if (msg.type() === 'error') console.log('CONSOLE ERROR:', msg.text()); }); page.on('pageerror', err => console.log('PAGE ERROR:', err.message)); await page.waitForSelector('.dashboard-project-card', { timeout: 10000 }); await page.locator('.dashboard-project-card').first().click(); // Card click now opens the project directly await page.waitForSelector('canvas', { timeout: 10000 }); await page.waitForTimeout(1000); // Take screenshot const shot = '/tmp/web-cad-clone/frontend/playwright-tests/screenshots/diagnose-editor.png'; fs.mkdirSync('/tmp/web-cad-clone/frontend/playwright-tests/screenshots', { recursive: true }); await page.screenshot({ path: shot, fullPage: false }); // Dump DOM structure of key elements const info = await page.evaluate(() => { const dataTools = Array.from(document.querySelectorAll('[data-tool]')).map(el => ({ tool: el.getAttribute('data-tool'), tag: el.tagName, className: el.className, text: el.textContent?.slice(0, 40) || '', visible: !!(el as HTMLElement).offsetParent, })); const toolBtns = Array.from(document.querySelectorAll('.tool-btn')).map(el => ({ tag: el.tagName, className: el.className, dataTool: el.getAttribute('data-tool'), text: el.textContent?.slice(0, 40) || '', visible: !!(el as HTMLElement).offsetParent, })); const leftbar = !!document.querySelector('.leftbar'); const ribbon = !!document.querySelector('.ribbon-bar, .ribbon'); const canvas = !!document.querySelector('canvas'); const canvasCount = document.querySelectorAll('canvas').length; return { leftbar, ribbon, canvas, canvasCount, dataTools, toolBtns }; }); const output = { ...info, failedRequests, badResponses }; fs.writeFileSync('/tmp/web-cad-clone/frontend/playwright-tests/editor-dom.json', JSON.stringify(output, null, 2)); console.log('DOM INFO:', JSON.stringify(output, null, 2)); console.log('Screenshot:', shot); await browser.close(); });