import { test, expect, request } from '@playwright/test'; const BASE = process.env.PLAYWRIGHT_BASE_URL || 'http://192.168.0.251:13000'; const TEST_EMAIL = process.env.VITE_TEST_TEACHER_EMAIL; const TEST_PASSWORD = process.env.VITE_TEST_TEACHER_PASSWORD; async function serverReachable() { try { const ctx = await request.newContext(); const res = await ctx.get(BASE, { timeout: 3000 }).catch(() => null); await ctx.dispose(); return Boolean(res); } catch { return false; } } async function login(page) { await page.goto(`${BASE}/login`); await page.getByLabel('Email').fill(TEST_EMAIL); await page.getByLabel('Password').fill(TEST_PASSWORD); await page.getByRole('button', { name: 'Login' }).click(); await page.waitForURL((url) => /\/dashboard|\/node\//.test(url.pathname), { timeout: 15000 }); } function skipIfUnconfigured() { if (!TEST_EMAIL || !TEST_PASSWORD) test.skip(true, 'VITE_TEST_TEACHER_EMAIL / VITE_TEST_TEACHER_PASSWORD not set'); } test.describe('Node navigation', () => { test.beforeAll(async () => { skipIfUnconfigured(); const reachable = await serverReachable(); test.skip(!reachable, `Dev server not reachable at ${BASE}`); }); test('canvas remounts cleanly on node navigation', async ({ page }) => { const errors = []; page.on('pageerror', err => errors.push(err.message)); await login(page); await page.locator('[data-testid="tldraw-canvas"], .tl-container').waitFor({ timeout: 10000 }); const navLinks = page.locator('nav a, [data-testid="nav-node"]'); const count = await navLinks.count(); if (count > 1) { await navLinks.nth(1).click(); await page.waitForTimeout(2000); const hasCanvas = await page.locator('[data-testid="tldraw-canvas"], .tl-container') .waitFor({ timeout: 8000 }).then(() => true).catch(() => false); expect(hasCanvas).toBe(true); } const criticalErrors = errors.filter(e => /uncaught|undefined is not/i.test(e)); expect(criticalErrors).toHaveLength(0); }); });