Reviewing a responsive design means seeing it at several widths. Doing that by hand - resize the window, screenshot, resize again - is tedious and inconsistent: the window chrome, the scrollbar, and the device pixel ratio all drift between shots.
OmniCapt instead drives the Chrome DevTools Protocol (CDP) Emulation domain to override the page's device metrics programmatically, then captures each preset in a single batch. Every shot is pixel-consistent because the browser, not the OS window, defines the viewport.
Key Technical Concepts Covered
- Attaching the debugger: CDP access via the extension
debuggerAPI. - Overriding device metrics: width, height, and device pixel ratio.
- Batching presets: loop through desktop / tablet / mobile in one run.
- The devicePixelRatio gotcha: emulated DPR changes the output resolution.
Part of the engineering behind OmniCapt.
Overriding Device Metrics
With the debugger attached to a tab, Emulation.setDeviceMetricsOverride tells the renderer to lay the page out at an arbitrary width, height, and device pixel ratio - exactly as a real device would:
async function emulate(tabId, { width, height, dpr, mobile }) {
await chrome.debugger.sendCommand({ tabId }, 'Emulation.setDeviceMetricsOverride', {
width,
height,
deviceScaleFactor: dpr,
mobile,
});
}
Batching the Presets
A capture run is just a loop: apply each preset, let the layout settle, take the shot. OmniCapt ships desktop, tablet, and mobile defaults and captures them back to back without the user touching the window:
const PRESETS = [
{ name: 'desktop', width: 1440, height: 900, dpr: 1, mobile: false },
{ name: 'tablet', width: 768, height: 1024, dpr: 2, mobile: true },
{ name: 'mobile', width: 390, height: 844, dpr: 3, mobile: true },
];
for (const p of PRESETS) {
await emulate(tabId, p);
await settle(); // let media queries and layout apply
const shot = await chrome.debugger.sendCommand({ tabId }, 'Page.captureScreenshot', {
captureBeyondViewport: true,
});
save(`${p.name}.png`, shot.data); // base64 PNG
}
Mind the Device Pixel Ratio
The subtle trap is deviceScaleFactor. A mobile preset at width 390 with a DPR of 3 produces an image 1170 pixels wide, not 390 - which is correct (it matches a real phone), but surprising if you expected CSS pixels. OmniCapt records the emulated DPR alongside each capture so downstream tools scale correctly, and always clears the override when the batch finishes:
await chrome.debugger.sendCommand({ tabId }, 'Emulation.clearDeviceMetricsOverride');
await chrome.debugger.detach({ tabId });
Conclusion: Consistent by Construction
Letting the DevTools Protocol define the viewport removes the human variability from responsive screenshots. Override the metrics, loop the presets, respect the device pixel ratio, and clean up the override - and OmniCapt produces a full responsive set from a single click, every shot pixel-consistent.