Skip to content

Commit 45506fb

Browse files
authored
Fix: set device does not apply deviceScaleFactor - HiDPI screenshots not possible (#270)
Fixes #255
1 parent a22af0e commit 45506fb

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/actions.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,10 +1147,29 @@ async function handleDevice(command: DeviceCommand, browser: BrowserManager): Pr
11471147
// Apply device viewport
11481148
await browser.setViewport(device.viewport.width, device.viewport.height);
11491149

1150+
// Apply or clear device scale factor
1151+
if (device.deviceScaleFactor && device.deviceScaleFactor !== 1) {
1152+
// Apply device scale factor for HiDPI/retina displays
1153+
await browser.setDeviceScaleFactor(
1154+
device.deviceScaleFactor,
1155+
device.viewport.width,
1156+
device.viewport.height,
1157+
device.isMobile ?? false
1158+
);
1159+
} else {
1160+
// Clear device scale factor override to restore default (1x)
1161+
try {
1162+
await browser.clearDeviceMetricsOverride();
1163+
} catch {
1164+
// Ignore error if override was never set
1165+
}
1166+
}
1167+
11501168
return successResponse(command.id, {
11511169
device: command.device,
11521170
viewport: device.viewport,
11531171
userAgent: device.userAgent,
1172+
deviceScaleFactor: device.deviceScaleFactor,
11541173
});
11551174
}
11561175

src/browser.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,40 @@ export class BrowserManager {
393393
await page.setViewportSize({ width, height });
394394
}
395395

396+
/**
397+
* Set device scale factor (devicePixelRatio) via CDP
398+
* This sets window.devicePixelRatio which affects how the page renders and responds to media queries
399+
*
400+
* Note: When using CDP to set deviceScaleFactor, screenshots will be at logical pixel dimensions
401+
* (viewport size), not physical pixel dimensions (viewport × scale). This is a Playwright limitation
402+
* when using CDP emulation on existing contexts. For true HiDPI screenshots with physical pixels,
403+
* deviceScaleFactor must be set at context creation time.
404+
*
405+
* Must be called after setViewport to work correctly
406+
*/
407+
async setDeviceScaleFactor(
408+
deviceScaleFactor: number,
409+
width: number,
410+
height: number,
411+
mobile: boolean = false
412+
): Promise<void> {
413+
const cdp = await this.getCDPSession();
414+
await cdp.send('Emulation.setDeviceMetricsOverride', {
415+
width,
416+
height,
417+
deviceScaleFactor,
418+
mobile,
419+
});
420+
}
421+
422+
/**
423+
* Clear device metrics override to restore default devicePixelRatio
424+
*/
425+
async clearDeviceMetricsOverride(): Promise<void> {
426+
const cdp = await this.getCDPSession();
427+
await cdp.send('Emulation.clearDeviceMetricsOverride');
428+
}
429+
396430
/**
397431
* Get device descriptor
398432
*/

0 commit comments

Comments
 (0)