const { chromium } = require('playwright'); const URL = 'https://studiosfeedback.com'; const OUT = '/home/claude/agency-web/audit2'; const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'; async function slowScroll(page, perStep = 250, frac = 0.55) { await page.evaluate(async ({ perStep, frac }) => { const step = Math.max(200, Math.round(window.innerHeight * frac)); for (let y = 0; y < document.body.scrollHeight; y += step) { window.scrollTo(0, y); await new Promise((r) => setTimeout(r, perStep)); } window.scrollTo(0, document.body.scrollHeight); await new Promise((r) => setTimeout(r, 1500)); }, { perStep, frac }); } // crop targets by CSS selector -> filename const TARGETS = [ { sel: 'section.proof', name: 'trustedby' }, { sel: 'section.score', name: 'scoreboard' }, { sel: 'section.loop', name: 'howitworks' }, { sel: 'section.quotes', name: 'testimonials' }, ]; (async () => { const browser = await chromium.launch(); // DESKTOP crops let ctx = await browser.newContext({ viewport: { width: 1440, height: 900 }, userAgent: UA, deviceScaleFactor: 2 }); let page = await ctx.newPage(); await page.goto(URL, { waitUntil: 'networkidle', timeout: 60000 }).catch(async () => { await page.goto(URL, { waitUntil: 'load', timeout: 60000 }); }); await page.keyboard.press('Escape').catch(() => {}); await slowScroll(page, 250, 0.55); await slowScroll(page, 200, 0.45); await page.waitForTimeout(800); for (const t of TARGETS) { const el = page.locator(t.sel).first(); try { await el.scrollIntoViewIfNeeded(); await page.waitForTimeout(900); await el.screenshot({ path: `${OUT}/desktop-${t.name}.png` }); console.log('crop desktop', t.name); } catch (e) { console.log('FAIL desktop', t.name, e.message); } } // For the long "How it works" loop, also grab the 4 per-step panels individually if present const steps = await page.locator('section.loop [class*="step" i], section.loop article, section.loop .loop__panel').count().catch(() => 0); console.log('loop step-like elements:', steps); await ctx.close(); // MOBILE crops ctx = await browser.newContext({ viewport: { width: 390, height: 844 }, userAgent: UA, deviceScaleFactor: 2 }); page = await ctx.newPage(); await page.goto(URL, { waitUntil: 'networkidle', timeout: 60000 }).catch(async () => { await page.goto(URL, { waitUntil: 'load', timeout: 60000 }); }); await page.keyboard.press('Escape').catch(() => {}); await slowScroll(page, 250, 0.55); await slowScroll(page, 200, 0.45); await page.waitForTimeout(800); for (const t of TARGETS) { const el = page.locator(t.sel).first(); try { await el.scrollIntoViewIfNeeded(); await page.waitForTimeout(900); await el.screenshot({ path: `${OUT}/mobile-${t.name}.png` }); console.log('crop mobile', t.name); } catch (e) { console.log('FAIL mobile', t.name, e.message); } } await ctx.close(); await browser.close(); console.log('done'); })();