const { chromium } = require('playwright'); const fs = require('fs'); const path = require('path'); async function compareRendered() { const browser = await chromium.launch({ headless: true }); console.log('\n=== COMPARING RENDERED SITES ===\n'); // OLD SITE const pageOld = await browser.newPage({ viewport: { width: 1920, height: 1080 } }); console.log('Loading OLD site (React)...'); await pageOld.goto('http://localhost:3000', { waitUntil: 'networkidle', timeout: 30000 }); // Wait for React to render await pageOld.waitForTimeout(2000); // Take screenshot await pageOld.screenshot({ path: './tests/screenshots/old-full-rendered.png', fullPage: true }); // Get actual rendered content const oldContent = await pageOld.evaluate(() => { const app = document.getElementById('app') || document.body; return { innerHTML: app.innerHTML.substring(0, 2000), hasContent: app.innerHTML.length > 100, classes: Array.from(document.querySelectorAll('[class]')).map(el => el.className).filter(c => c).slice(0, 50) }; }); console.log('OLD site content loaded:', oldContent.hasContent); console.log('OLD site classes found:', oldContent.classes.length); if (oldContent.classes.length > 0) { console.log('Sample classes:', oldContent.classes.slice(0, 10)); } // NEW SITE const pageNew = await browser.newPage({ viewport: { width: 1920, height: 1080 } }); console.log('\nLoading NEW site (Go+HTMX)...'); await pageNew.goto('http://localhost:1999', { waitUntil: 'networkidle' }); await pageNew.screenshot({ path: './tests/screenshots/new-full-rendered.png', fullPage: true }); // SIDE-BY-SIDE COMPARISON console.log('\n=== HEADER BADGES COMPARISON ===\n'); // Try multiple selectors for old site const oldBadgeSelectors = [ '[class*="badge"]', '[class*="title"]', 'div[class*="cv"]', '.badge', '.title-badge' ]; let oldBadges = null; for (const selector of oldBadgeSelectors) { try { const count = await pageOld.locator(selector).count(); if (count > 0) { console.log(`Found ${count} elements with selector: ${selector}`); oldBadges = await pageOld.$$eval(selector, elements => elements.slice(0, 5).map(el => { const computed = window.getComputedStyle(el); return { tag: el.tagName, class: el.className, text: el.textContent?.substring(0, 50), styles: { fontSize: computed.fontSize, fontWeight: computed.fontWeight, color: computed.color, backgroundColor: computed.backgroundColor, padding: computed.padding, height: computed.height } }; }) ); break; } } catch (e) { // Try next selector } } const newBadges = await pageNew.$$eval('.title-badge', elements => elements.slice(0, 5).map(el => { const computed = window.getComputedStyle(el); return { tag: el.tagName, class: el.className, text: el.textContent?.trim(), styles: { fontSize: computed.fontSize, fontWeight: computed.fontWeight, color: computed.color, backgroundColor: computed.backgroundColor, padding: computed.padding, height: computed.height } }; }) ); console.log('\nOLD site badges:'); console.log(JSON.stringify(oldBadges, null, 2)); console.log('\nNEW site badges:'); console.log(JSON.stringify(newBadges, null, 2)); // VISUAL PIXEL COMPARISON console.log('\n=== VISUAL COMPARISON ===\n'); // Get dimensions const oldDimensions = await pageOld.evaluate(() => ({ width: document.documentElement.scrollWidth, height: document.documentElement.scrollHeight })); const newDimensions = await pageNew.evaluate(() => ({ width: document.documentElement.scrollWidth, height: document.documentElement.scrollHeight })); console.log('OLD site dimensions:', oldDimensions); console.log('NEW site dimensions:', newDimensions); // Screenshot specific sections try { // Header comparison const oldHeader = pageOld.locator('header, [class*="header"], div').first(); const newHeader = pageNew.locator('.cv-title-badges-header').first(); if (await oldHeader.count() > 0) { await oldHeader.screenshot({ path: './tests/screenshots/old-header-section.png' }); } await newHeader.screenshot({ path: './tests/screenshots/new-header-section.png' }); // Sidebar comparison const oldSidebar = pageOld.locator('[class*="sidebar"], aside').first(); const newSidebar = pageNew.locator('.cv-sidebar').first(); if (await oldSidebar.count() > 0) { await oldSidebar.screenshot({ path: './tests/screenshots/old-sidebar-section.png' }); } await newSidebar.screenshot({ path: './tests/screenshots/new-sidebar-section.png' }); } catch (e) { console.log('Error capturing sections:', e.message); } // CREATE COMPARISON REPORT const report = { timestamp: new Date().toISOString(), oldSite: { url: 'http://localhost:3000', hasContent: oldContent.hasContent, classesFound: oldContent.classes.length, dimensions: oldDimensions, badges: oldBadges }, newSite: { url: 'http://localhost:1999', dimensions: newDimensions, badges: newBadges }, comparison: { dimensionsMatch: Math.abs(oldDimensions.width - newDimensions.width) < 50 && Math.abs(oldDimensions.height - newDimensions.height) < 50, pixelPerfect: null // To be determined by visual inspection } }; fs.writeFileSync( './tests/screenshots/comparison-report.json', JSON.stringify(report, null, 2) ); console.log('\nāœ“ Comparison complete!'); console.log('āœ“ Screenshots saved to tests/screenshots/'); console.log('āœ“ Report saved to comparison-report.json'); await browser.close(); } compareRendered().catch(console.error);