How to Capture a Playwright Screenshot of an Indian Mobile Banking Web App at 360 Pixels
Capture a banking web app at a 360 CSS-pixel mobile viewport with Playwright, choose viewport or full-page output, and protect sensitive test data.
Set Playwright’s browser context viewport to width: 360 CSS pixels, then capture with scale: 'css'. Set deviceScaleFactor: 1 too when the saved image must be exactly 360 raster pixels wide. The example below uses an illustrative test URL: use an environment you are authorized to access, and synthetic banking data where possible.
1. Set up Playwright and capture at 360px
This JavaScript example runs with Node.js and Chromium. It captures the initially visible viewport, which is usually the right choice when you want to inspect one mobile screen.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
try {
const context = await browser.newContext({
viewport: { width: 360, height: 800 },
deviceScaleFactor: 1,
isMobile: true,
locale: 'en-IN',
});
const page = await context.newPage();
await page.goto('https://your-test-banking-app.example', {
waitUntil: 'domcontentloaded',
timeout: 30000,
});
await page.screenshot({ path: 'banking-360.png', scale: 'css' });
await context.close();
} finally {
await browser.close();
}
})();
Install Playwright and its browser in your project with npm install -D playwright and npx playwright install chromium. Save the script as a JavaScript file and run it with Node.js. Replace the example URL with a permitted test page; the reserved .example host will not serve a real banking app.
What the settings mean
viewport: { width: 360, height: 800 }sets the emulated browser viewport in CSS pixels. The chosen height affects what appears in a viewport screenshot; the width is the 360-pixel target.deviceScaleFactor: 1sets the emulated device scale factor. Along with CSS screenshot scale, this makes the raster width 360 pixels.isMobile: trueenables mobile emulation behavior. It does not turn a desktop browser into a physical phone.locale: 'en-IN'sets the browser locale for pages that use it. It does not guarantee a particular currency, language, or server response.scale: 'css'makes screenshot output use CSS-pixel dimensions. Playwright’s default screenshot scale is device pixels, which can produce a wider image when the device scale factor is above 1.waitUntil: 'domcontentloaded'waits for the document’s DOM to be parsed. If the app fills content later through API calls, wait for a meaningful page element before capturing.
Playwright describes viewport settings as browser emulation; a 360-pixel emulated viewport alone does not prove that a page works correctly on a real phone. See the Playwright emulation guide and screenshot API reference.
2. Choose viewport or full-page output
A normal screenshot captures the visible viewport. Use fullPage: true only when you need the entire scrollable document; it produces a tall image rather than a single mobile screen.
// One screen at 360 CSS pixels wide
await page.screenshot({ path: 'banking-viewport.png', scale: 'css' });
// The full scrollable page, still rendered at the emulated 360 CSS-pixel width
await page.screenshot({
path: 'banking-full-page.png',
fullPage: true,
scale: 'css',
});
| Capture | Use it for | Output shape |
|---|---|---|
| Viewport (default) | Reviewing the initially visible mobile screen or a specific screen state | 360 CSS pixels wide; height follows the configured viewport |
| Full page | Reviewing a complete long page, including content below the fold | 360 CSS pixels wide; height follows the document and can be very large |
Playwright documents full-page mode as capturing the page as though displayed on a very tall screen. It is not equivalent to a user’s initial phone screen. See the full-page screenshot guide.
3. Wait for the banking page to be ready
A page can finish parsing before its account cards, balances, or transaction list load. If the page has a stable landmark, wait for it explicitly; choose a selector from your own test application.
await page.goto('https://your-test-banking-app.example', {
waitUntil: 'domcontentloaded',
timeout: 30000,
});
await page.locator('[data-testid="account-summary"]').waitFor({
state: 'visible',
timeout: 15000,
});
await page.screenshot({ path: 'banking-360.png', scale: 'css' });
The selector above is illustrative. Use a stable test ID or another locator that your application actually exposes. If content arrives only after authentication or a network response, use a test account and wait for an application-specific ready state rather than adding an arbitrary long sleep.
4. Protect financial information in screenshots
Screenshots may include account identifiers, balances, names, or transaction details. Prefer synthetic test data and keep captures out of public artifacts when they contain sensitive information. If you need a screenshot for debugging or documentation, mask sensitive elements before saving or sharing it.
await page.screenshot({
path: 'banking-redacted.png',
scale: 'css',
mask: [
page.locator('[data-testid="account-number"]'),
page.locator('[data-testid="balance"]'),
],
maskColor: '#000000',
});
Replace those test IDs with locators from your page. Check that each locator matches the sensitive content you intend to conceal; a screenshot mask is only as complete as the elements selected. Playwright documents screenshot masking in its screenshot API. OWASP’s Mobile Application Security Testing Guide discusses the risk of exposing financial information in screenshots; avoid capturing real customer details for routine tests.
5. cURL, Python, and Node.js alternatives
Playwright’s browser automation API is available in several languages. The title’s JavaScript example is above; below are equivalent minimal flows using Playwright for Python and Playwright for .NET (C#). cURL does not drive a browser, so it cannot produce a Playwright screenshot. For a one-request screenshot API alternative, see the ScreenshotNeo section below.
Python with Playwright
import asyncio
from pathlib import Path
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
try:
context = await browser.new_context(
viewport={"width": 360, "height": 800},
device_scale_factor=1,
is_mobile=True,
locale="en-IN",
)
page = await context.new_page()
await page.goto(
"https://your-test-banking-app.example",
wait_until="domcontentloaded",
timeout=30000,
)
await page.screenshot(path="banking-360.png", scale="css")
await context.close()
finally:
await browser.close()
asyncio.run(main())
Install with pip install playwright and playwright install chromium. Python’s screenshot API uses the same CSS-pixel scale choice. For a masked capture, pass mask=[page.locator(...)] to page.screenshot.
C# with Microsoft.Playwright
using Microsoft.Playwright;
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var context = await browser.NewContextAsync(new BrowserNewContextOptions
{
ViewportSize = new ViewportSize { Width = 360, Height = 800 },
DeviceScaleFactor = 1,
IsMobile = true,
Locale = "en-IN"
});
var page = await context.NewPageAsync();
await page.GotoAsync("https://your-test-banking-app.example",
new PageGotoOptions { WaitUntil = WaitUntilState.DOMContentLoaded, Timeout = 30000 });
await page.ScreenshotAsync(new PageScreenshotOptions
{
Path = "banking-360.png",
Scale = ScreenshotScale.Css
});
await context.CloseAsync();
Use the Microsoft.Playwright package and install its browsers with pwsh bin/Debug/netX/playwright.ps1 install chromium after building the project. The generated install script path can vary with project setup; follow the official .NET installation instructions.
Node.js with Playwright
The first section is the complete Node.js example. This shorter version highlights the output dimensions: 360 CSS pixels wide with device scale factor 1 and CSS screenshot scale.
const { chromium } = require('playwright');
const browser = await chromium.launch();
const context = await browser.newContext({
viewport: { width: 360, height: 800 },
deviceScaleFactor: 1,
});
const page = await context.newPage();
await page.goto('https://your-test-banking-app.example');
await page.screenshot({ path: 'banking-360.png', scale: 'css' });
await browser.close();
cURL
There is no cURL command that invokes Playwright’s local browser API. cURL can call an HTTP screenshot service. The ScreenshotNeo call in the next section returns an image response; its documentation describes available parameters and output formats.
6. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. A single GET request can return an image or PDF. For a 360-pixel-wide capture, request the target URL with the API’s width setting:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://your-test-banking-app.example \
-d width=360 \
-o banking-360.webp
See the ScreenshotNeo API documentation for authentication and supported parameters. The API accepts the parameter names used by other screenshot APIs as well, which can make switching easier. Use a permitted URL and avoid sending real financial information to a screenshot service unless your handling requirements allow it.
ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
7. Troubleshooting and reliability
| Symptom | Likely cause | Fix |
|---|---|---|
| Image is wider than 360 pixels | Screenshot scale is using device pixels, or the device scale factor is above 1. | Set deviceScaleFactor: 1 in the browser context and scale: 'css' in the screenshot call. |
| Page layout does not look mobile | The browser viewport is narrow, but the page may not have responsive styles; mobile emulation is not a real phone. | Check the app’s responsive breakpoints and viewport metadata. Validate on a real device or device farm when physical-device behavior matters. |
| Screenshot shows a spinner or missing account cards | The page was captured before asynchronous app content became ready. | Wait for a stable, app-specific locator or ready condition before capture. Avoid relying on fixed delays when a page state can be observed. |
| Navigation times out | The app may keep connections open, respond slowly, require a permitted login, or be unreachable from the runner. | Confirm the test URL and network access, use a suitable waitUntil condition, and wait for the needed content separately. Do not disable security checks on a live banking service. |
| Image is unexpectedly very tall | fullPage: true was enabled. |
Remove it for a single viewport image; retain it only when the full scrollable document is intended. |
| Sensitive data remains visible | A locator did not match every sensitive field, or the page renders the value elsewhere. | Use synthetic data where possible, inspect all rendered states, and mask every relevant locator before saving or sharing. |
Performance, reliability, and cost
Playwright runs a browser process, so it requires browser binaries and more setup than an HTTP screenshot request. Reuse a browser process across captures when automating a batch, while creating isolated contexts for separate sessions. Keep the screenshot scope to the visible viewport unless the full document is needed; full-page images can be much taller and larger. Wait for a specific ready state to reduce captures of incomplete pages, and set navigation and locator timeouts that match your test environment. No performance benchmark is implied here.
Playwright is an open-source automation library; the code shown does not call a paid screenshot API. Your operational costs depend on the machines, browser workers, and infrastructure you run it on. A hosted screenshot API instead has plan limits and per-plan pricing; ScreenshotNeo’s listed plans are Free (1,000/month), Starter ($5 for 3,000), Growth ($15 for 15,000), Pro ($39 for 60,000), Scale ($99 for 250,000), and Business ($249 for 1,000,000). Yearly billing gives two months free, and every feature is on every plan.
8. Frequently asked questions
Does a 360-pixel Playwright viewport guarantee compatibility with an Indian bank’s real mobile app?
No. It captures a browser page under emulated conditions. It does not prove compatibility on a physical phone, validate a bank’s production service, or establish behavior for a particular bank.
Should I set the viewport height to 800?
Use a height that matches the screen state you need to review. The width controls the 360 CSS-pixel target; the height determines how much is visible in a viewport capture.
Can I use a real customer account to get realistic screenshots?
Use synthetic test data when possible. Real account details and transactions can expose financial information in saved or shared images.
Does full-page mode capture a real phone’s scrolling behavior?
No. It captures the document as a tall page image. Use a viewport screenshot for a single-screen artifact and device testing for actual scrolling behavior.


