← back to Prestige Car Wash Video

capture/capture.mjs

67 lines

import puppeteer from 'puppeteer-core';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { BASE, FRONT, ADMIN } from './shots.mjs';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const SHOTS_DIR = path.join(__dirname, '..', 'shots');
const CHROME = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
const VW = 1440, VH = 900, SCALE = 2;

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function shoot(page, id) {
  const file = path.join(SHOTS_DIR, `${id}.png`);
  await page.screenshot({ path: file, fullPage: true });
  const meta = await page.evaluate(() => ({
    w: document.documentElement.scrollWidth,
    h: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
  }));
  console.log(`  ✓ ${id.padEnd(14)} ${meta.w}x${meta.h}`);
  return { id, ...meta };
}

async function main() {
  fs.mkdirSync(SHOTS_DIR, { recursive: true });
  const browser = await puppeteer.launch({
    executablePath: CHROME,
    headless: 'new',
    defaultViewport: { width: VW, height: VH, deviceScaleFactor: SCALE },
    args: ['--hide-scrollbars', '--disable-gpu', '--force-color-profile=srgb'],
  });
  const page = await browser.newPage();
  await page.authenticate({ username: 'admin', password: 'DW2024!' });
  const dims = {};

  console.log('Act 1 — front-facing:');
  for (const s of FRONT) {
    await page.goto(BASE + s.path, { waitUntil: 'networkidle2', timeout: 30000 }).catch(() => {});
    await sleep(1200); // let hero video/animations settle to a clean frame
    dims[s.id] = await shoot(page, s.id);
  }

  console.log('Act 2 — admin growth center:');
  await page.goto(BASE + '/admin/', { waitUntil: 'networkidle2', timeout: 30000 }).catch(() => {});
  await sleep(1000);
  for (const s of ADMIN) {
    await page.evaluate((id) => window.go && window.go(id), s.id);
    // wait for the async fetch to paint the #view panel
    await page.waitForFunction(
      () => {
        const v = document.querySelector('#view');
        return v && v.innerHTML && v.innerHTML.trim().length > 40;
      },
      { timeout: 8000 }
    ).catch(() => {});
    await sleep(700);
    await page.evaluate(() => window.scrollTo(0, 0));
    dims['admin-' + s.id] = await shoot(page, 'admin-' + s.id);
  }

  fs.writeFileSync(path.join(SHOTS_DIR, 'dims.json'), JSON.stringify(dims, null, 2));
  await browser.close();
  console.log('Done. dims.json written.');
}
main().catch((e) => { console.error(e); process.exit(1); });