ScreenshotNeo

BlogHow-to

How to Screenshot a Website at Moto G54 Screen Size Using Playwright

Emulate a Moto G54 sized mobile viewport in Playwright, capture the visible or full page, and understand why panel resolution is not CSS viewport size.

By the ScreenshotNeo team4 October 20268 min read

Direct answer: configure a Playwright browser context with a mobile viewport, navigate to the page, then call page.screenshot(). Use fullPage: true for the entire scrollable page. Motorola lists the Moto G54 5G panel as 2400 × 1080 pixels in a 20:9 format, but that is the physical display resolution, not a verified browser CSS viewport. Playwright’s device registry does not establish a Moto G54 preset. Treat any dimensions you choose manually as an approximation unless you measure the browser viewport on the handset.

The example below uses 393 × 873 CSS pixels, approximately the same 20:9 shape. This is a practical starting point, not a claim about the exact Moto G54 viewport or device pixel ratio.

1. Set up a Moto G54 shaped viewport

Install Playwright in a new Node project and install its Chromium browser:

npm init -y
npm install --save-dev playwright
npx playwright install chromium

Save the following as screenshot.mjs. Replace the target URL with the page you want to capture.

import { chromium } from 'playwright';

const targetUrl = 'https://example.com';
const outputPath = 'moto-g54-approx.png';

const browser = await chromium.launch({ headless: true });
try {
  const context = await browser.newContext({
    // Approximate 20:9 mobile CSS viewport; measure a real phone for exact dimensions.
    viewport: { width: 393, height: 873 },
    screen: { width: 393, height: 873 },
    deviceScaleFactor: 1,
    isMobile: true,
    hasTouch: true,
  });
  const page = await context.newPage();

  await page.goto(targetUrl, { waitUntil: 'domcontentloaded', timeout: 45_000 });
  // Prefer a page-specific readiness condition when you know what must render.
  await page.locator('body').waitFor({ state: 'visible', timeout: 15_000 });
  await page.screenshot({ path: outputPath, fullPage: false, scale: 'css' });

  console.log(`Saved ${outputPath}`);
  await context.close();
} finally {
  await browser.close();
}

Run it with node screenshot.mjs. The viewport sets the layout area in CSS pixels. screen, isMobile and hasTouch help emulate mobile behavior; viewport dimensions alone do not reproduce every device characteristic. Playwright documents device emulation settings including user agent, screen, viewport and touch behavior in its emulation guide.

2. Understand resolution, CSS pixels and device scale

The Moto G54 specification provides the panel’s physical pixel dimensions. Websites lay out content in CSS pixels, and the browser maps CSS pixels to device pixels using a device scale factor. The supplied research does not verify the G54’s browser viewport or its mapping to a device scale factor, so dividing 2400 × 1080 by a guessed DPR would not prove the right viewport.

Setting What it controls When to change it
viewport CSS layout width and height. Responsive breakpoints use this. To approximate the usable browser area or reproduce a measured CSS viewport.
screen Emulated screen dimensions exposed to the page. Set alongside viewport when you want a consistent mobile screen model.
deviceScaleFactor Relationship between CSS pixels and device pixels for emulation. Set to a measured value when output pixel dimensions or high-DPI behavior matter.
scale in screenshot options How Playwright writes screenshot pixels: css or device. Choose CSS-sized output for convenient visual comparisons, or device scale for higher pixel density.

For the default example, deviceScaleFactor: 1 and scale: 'css' keep the image aligned to CSS-pixel dimensions. This is useful for responsive layout checks, but it does not represent the Moto G54’s confirmed physical pixel output.

3. Capture viewport, full page or one element

A regular screenshot captures the currently visible viewport. A full-page screenshot captures content below the fold. To capture a component, use a locator screenshot:

// Replace the screenshot call in the script with one of these:

// Visible viewport only
await page.screenshot({ path: 'viewport.png', fullPage: false, scale: 'css' });

// Entire page, including content below the fold
await page.screenshot({ path: 'full-page.png', fullPage: true, scale: 'css' });

// A single element
await page.locator('main').screenshot({ path: 'main-element.png' });

For a page with lazy-loaded images, a full-page screenshot can be taken before below-the-fold media has loaded. Scroll through the page first or wait for the specific images or content your result requires, then capture. Playwright’s screenshot documentation covers viewport, element and full-page screenshots, along with CSS and device output scale: Playwright screenshots.

4. Configure an existing Playwright Test project

If the project already uses @playwright/test, define a dedicated project so the same approximate device settings are reused across tests. The user agent below is deliberately omitted: use a real Moto G54 browser user agent only if you have measured or captured it.

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  projects: [
    {
      name: 'moto-g54-shaped-mobile-approximation',
      use: {
        browserName: 'chromium',
        viewport: { width: 393, height: 873 },
        screen: { width: 393, height: 873 },
        deviceScaleFactor: 1,
        isMobile: true,
        hasTouch: true,
      },
    },
  ],
});
// tests/mobile-screenshot.spec.ts
import { test } from '@playwright/test';

test('capture page at an approximate Moto G54 shaped viewport', async ({ page }) => {
  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
  await page.locator('body').waitFor({ state: 'visible' });
  await page.screenshot({ path: 'moto-g54-approx.png', scale: 'css' });
});

Run the project with npx playwright test --project=moto-g54-shaped-mobile-approximation. If you destructure a predefined device profile in a context or config, put explicit viewport values after the device spread so they override its viewport. The reviewed Playwright registry result showed a Moto G4 entry, which is a different model; do not treat it as a Moto G54 preset.

5. Make the approximation more accurate

  1. On the target handset, inspect window.innerWidth and window.innerHeight in the browser’s remote debugging tools while the page is open. Record the browser’s CSS viewport in the orientation and browser mode you need.
  2. Measure or determine the device pixel ratio separately if physical output resolution matters. Do not infer it from the display resolution alone.
  3. Copy the measured viewport to Playwright’s viewport. Configure screen and deviceScaleFactor to match the measured setup when relevant.
  4. Compare the emulated result with a screenshot or visual inspection from the real G54. Check CSS width and height, touch behavior, user agent, screenshot scope and output scale as separate variables.

Motorola’s support specifications list the Moto G54 5G display as 6.5 inches, Full HD+ at 2400 × 1080, 405 ppi and 20:9. Those manufacturer figures describe the panel, not the browser’s usable CSS area. See Motorola’s Moto G54 specifications. Playwright’s emulation guide explains the device-like browser settings and viewport override: Playwright emulation.

6. Capture options that affect the result

Need Setting or approach Trade-off
Mobile breakpoints and layout Set viewport in CSS pixels. A manually selected size is approximate until measured on the phone.
Touch-oriented behavior Set isMobile: true and hasTouch: true. Does not make the browser identical to the handset.
Only the first screen page.screenshot({ fullPage: false }). Below-the-fold content is absent.
Entire document fullPage: true. Very long pages produce tall images and may expose lazy-loading or sticky-header differences.
One component locator(selector).screenshot(). The selector must resolve to the intended element.
Consistent CSS-pixel artifact scale: 'css'. Does not create a high-DPI physical-pixel image.
Device-pixel-scaled output scale: 'device' with an appropriate device scale factor. Image dimensions and file size increase with scale.

Other settings such as locale, timezone, color scheme, geolocation, permissions and user agent can change what a site renders. Configure them only when they are part of the behavior being reproduced; mobile viewport alone does not select all of them.

7. Troubleshooting

Symptom Likely cause Fix
Page still looks like desktop The site may not have a responsive viewport meta tag, or isMobile was not enabled. Check the page’s viewport meta tag and set mobile emulation options. Remember that viewport width itself drives many responsive breakpoints.
Screenshot is 1280 × 720 The context inherited Playwright’s documented default viewport. Set viewport explicitly on the context or test project.
Layout is close but not identical to the phone The chosen CSS dimensions, browser user agent, DPR, browser chrome or OS behavior differs. Measure the real browser viewport and DPR, align emulation settings, then compare with a real-device capture.
Images or cards are missing Content is lazy loaded, requires scrolling, or depends on application state. Scroll relevant regions, wait for specific locators or image completion, and capture after the state is ready.
page.goto times out The site is slow, a network request remains open, or the timeout is too short. Use domcontentloaded when a full load event is not required, increase the timeout for navigation, and wait for a meaningful page-specific selector rather than waiting indefinitely for all network activity.
Screenshot call times out The page is still changing or an animation never settles. Wait for the target state, disable or reduce animation in a controlled test stylesheet, or capture the specific element after it is stable.
Full-page image is unexpectedly huge The document is very long or output uses device-pixel scale. Capture the viewport or a component, use CSS scale, or split the page into sections.
Selector screenshot says no element found The selector is wrong or the element has not rendered. Confirm the selector, wait for it to become visible and account for content inside frames.

8. Performance, reliability and cost

Local Playwright gives you control over browser version, viewport and readiness conditions, but your runtime must install and launch the browser. Reuse one browser process for multiple pages where practical, close contexts after capture, and avoid full-page or device-scale output when a smaller viewport image is enough. Set navigation and element waits to match the page’s actual requirements; broad network-idle waits can be unreliable on pages with long-lived requests.

Playwright itself is an open-source automation framework, but running captures still consumes compute, storage and bandwidth on your machine or CI runners. Large full-page screenshots and high scale factors increase memory and output size. For exact handset validation, emulation is a useful repeatable check, while a real-device comparison catches browser and OS behavior that emulation may not model.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request returns an image or PDF. Here is the one-call cURL version using the same target URL; consult the ScreenshotNeo API documentation for parameters, including viewport and device presets that can be applied to a request.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
  • Cookie banners, popups and chat widgets are removed before the shot.
  • Bot checks, blank pages and failed loads are never billed.
  • An MCP server lets AI agents take screenshots.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.

Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Is 2400 × 1080 the Playwright viewport for a Moto G54?

No. It is the manufacturer’s physical display resolution. The browser CSS viewport and device scale mapping are not established by that panel specification.

Does Playwright include a Moto G54 device preset?

The research reviewed did not verify one. Configure an explicit mobile viewport, or use measured values from a real handset.

Do I need to own a Moto G54?

No. Playwright emulation can produce a mobile-sized capture without the handset. A physical device is useful for a separate validation pass when handset-specific accuracy matters.

Should I use a full-page screenshot for responsive testing?

Use a viewport screenshot to inspect the initial visible layout. Use a full-page capture when below-the-fold content is part of the artifact you need.

Where does Playwright document Android device viewport units?

The AndroidDevice API documents viewport width and height in pixels and a default viewport of 1280 × 720. Set a mobile viewport explicitly for this task: AndroidDevice API.