cdpfleet Docs GitHub Dashboard

Cases / #29 · 2026-10-09 · Easy

Visual capture: full-page screenshot, element crop and PDF in one session

Four captures from one page load — viewport, full page, a single element and a PDF — rendered in the remote browser and saved on your machine, with their sizes and timings.

Chromium

Run on production on 2026-10-09: ✓ Node.js ✓ Python ✓ Java ✓ C# ✓ Go

The problem

You need visual proof of what a page showed — for monitoring, archiving, tests or a report. A viewport screenshot only covers the window; pages scroll; sometimes you want one component; sometimes a document. All of it can come from the one page the remote browser already rendered — but how big and how slow is each, once the bytes have to travel back to you?

What we used, and why

WhatWhy
chromium, headless: "new"page.pdf() needs a Chromium-based browser (Chrome and Edge print headful too).
page.screenshot()The visible area of the viewport.
page.screenshot({ fullPage: true })The whole scrollable page in one tall image.
locator(".product_pod").first().screenshot()Crops to one element's box — for component-level checks.
page.pdf()The page as a print document.
waitUntil: "networkidle"Images and styles have loaded before anything is captured.

How it works

  1. Open books.toscrape.com and wait for the network to go quiet.
  2. Take a viewport screenshot, a full-page screenshot and an element screenshot of the first product card, saving each locally.
  3. Render the page as a PDF.
  4. Print the size and time of every capture.

The code

The same program in five languages (also on GitHub, with the raw output). Set these environment variables first:

// npm install [email protected]
// env: CDPFLEET_API_KEY, PROXY_URL
import { chromium } from 'playwright';
import { stat, unlink, mkdir } from 'fs/promises';
import { tmpdir } from 'os';
import { join } from 'path';

const KEY = process.env.CDPFLEET_API_KEY;
const PAGE = 'https://books.toscrape.com/';

const res = await fetch('https://starter.cdpfleet.com/chromium/session', {
  method: 'POST',
  headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
  body: JSON.stringify({ proxy: process.env.PROXY_URL, headless: 'new' }),
});
if (!res.ok) throw new Error(`launch ${res.status} ${await res.text()}`);
const { wsUrl } = await res.json();
const browser = await chromium.connect(wsUrl, { headers: { 'x-api-key': KEY } });

const dir = join(tmpdir(), `cdpfleet-captures-${Date.now()}`);
await mkdir(dir, { recursive: true });

async function capture(label, fn) {
  const t = Date.now();
  const path = join(dir, label.replace(/\s+/g, '-') + (label.includes('pdf') ? '.pdf' : '.png'));
  await fn(path);
  const { size } = await stat(path);
  await unlink(path);
  return { type: label, file_size_bytes: size, seconds: Math.round((Date.now() - t) / 10) / 100 };
}

try {
  const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
  await page.goto(PAGE, { timeout: 60000, waitUntil: 'networkidle' });

  const results = [];
  results.push(await capture('viewport screenshot', (p) => page.screenshot({ path: p })));
  results.push(await capture('full-page screenshot', (p) => page.screenshot({ path: p, fullPage: true })));
  results.push(await capture('element screenshot', (p) => page.locator('.product_pod').first().screenshot({ path: p })));
  results.push(await capture('pdf', (p) => page.pdf({ path: p })));

  console.log(JSON.stringify({ captures: results }, null, 2));
} finally {
  await browser.close();
}

What we got

CaptureKBSeconds
viewport screenshot1390.18
full-page screenshot6540.54
element screenshot230.16
pdf3290.18

From the Node.js run on 2026-10-09. IP addresses are replaced with placeholders (203.0.113.x); equal addresses stay equal. The other languages produced the same findings.

Raw output (Node.js)
{
  "captures": [
    {
      "type": "viewport screenshot",
      "file_size_bytes": 142800,
      "seconds": 0.18
    },
    {
      "type": "full-page screenshot",
      "file_size_bytes": 669597,
      "seconds": 0.54
    },
    {
      "type": "element screenshot",
      "file_size_bytes": 23401,
      "seconds": 0.16
    },
    {
      "type": "pdf",
      "file_size_bytes": 337327,
      "seconds": 0.18
    }
  ]
}

Takeaways