← back to Lawyer Directory Builder

_shoot_mobile.mjs

61 lines

import { chromium } from 'playwright';
import fs from 'node:fs/promises';

const BASE = 'http://localhost:9701';
const OUT  = '/tmp/lawyer-mobile';
await fs.mkdir(OUT, { recursive: true });

const surfaces = [
  { name: '01-landing',  path: '/' },
  { name: '02-find',     path: '/find-a-lawyer' },
  { name: '03-thanks',   path: '/find-a-lawyer/thanks?zip=90210&area=Personal+Injury' },
  { name: '03b-results', path: '/find-a-lawyer/results?zip=90210&area=Personal+Injury' },
  { name: '04-signup',   path: '/signup' },
  { name: '05-login',    path: '/login' },
  { name: '06-audit',    path: '/audit.html' },
  { name: '07-privacy',  path: '/privacy.html' },
  { name: '08-terms',    path: '/terms.html' },
  { name: '09-data',     path: '/data' },
  { name: '10-404',      path: '/this-page-does-not-exist' },
];

const browser = await chromium.launch();
const ctx = await browser.newContext({
  viewport: { width: 375, height: 812 },
  deviceScaleFactor: 3,
  userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Mobile',
});
const page = await ctx.newPage();
const findings = [];

for (const s of surfaces) {
  try {
    const resp = await page.goto(BASE + s.path, { waitUntil: 'networkidle', timeout: 12000 });
    await page.waitForTimeout(500);
    await page.screenshot({ path: `${OUT}/${s.name}-fold.png` });
    await page.screenshot({ path: `${OUT}/${s.name}-full.png`, fullPage: true });
    // Probe for obvious overflow / clipping
    const probe = await page.evaluate(() => {
      const docW = document.documentElement.scrollWidth;
      const winW = window.innerWidth;
      const overflowsRight = docW > winW + 4;
      // Find any element wider than viewport
      const wide = [];
      document.querySelectorAll('header, main, section, .config-section, .firm-card, .stats, .firms').forEach(el => {
        const r = el.getBoundingClientRect();
        if (r.right > winW + 4) wide.push(`${el.tagName.toLowerCase()}.${el.className.slice(0, 30)} right=${Math.round(r.right)}`);
      });
      return { docW, winW, overflowsRight, wide: wide.slice(0, 3) };
    });
    findings.push({ name: s.name, status: resp ? resp.status() : '?', ...probe });
  } catch (e) {
    findings.push({ name: s.name, err: String(e).slice(0, 120) });
  }
}
await browser.close();
console.log('=== MOBILE 375×812 ===');
findings.forEach(f => {
  const flag = f.overflowsRight ? '⚠️' : '✓';
  console.log(`${flag} [${f.status || 'err'}] ${f.name.padEnd(14)} docW=${f.docW || '?'}  wide=${(f.wide || []).join(' / ') || '—'}`);
});