How to Export a Webpage Screenshot from Playwright as a JPEG for a Report
Save a Playwright screenshot as a JPEG or attach its Buffer to a test report. Choose the right quality, page coverage, and pixel scale.
Use Playwright’s page.screenshot() with a .jpeg filename or set type: 'jpeg'. To include the image in a Playwright Test report, use the returned Buffer and attach it with contentType: 'image/jpeg'.
1. Save a webpage screenshot as a JPEG
This complete Node.js example opens a page and writes a full-page JPEG to disk:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
try {
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({
path: 'report.jpeg',
type: 'jpeg',
quality: 80,
fullPage: true,
scale: 'css',
});
} finally {
await browser.close();
}
})();
Install Playwright and its browser before running the script: npm install playwright followed by npx playwright install chromium. Playwright infers JPEG from the .jpeg path, but specifying type makes the intended format explicit. See the Playwright Page screenshot API.
2. Attach the JPEG to a Playwright Test report
For a report attachment, skip writing a temporary file. page.screenshot() returns a Buffer when no path is supplied; pass it directly to the test step attachment API:
import { test, expect } from '@playwright/test';
test('attach page screenshot to report', async ({ page }) => {
await page.goto('https://example.com');
const screenshot = await page.screenshot({ type: 'jpeg', quality: 80 });
await test.info().attach('page screenshot', {
body: screenshot,
contentType: 'image/jpeg',
});
});
The attachment content type tells the report how to present the image. The Playwright TestStepInfo documentation describes attachments and their content type.
3. Choose coverage, quality, and resolution
| Option | What it changes | When to use it |
|---|---|---|
quality |
JPEG compression, integer from 0 to 100; default is 80. | Raise it if compression artifacts affect report readability. Lower it when smaller files matter more. Check your own report output; no universal best value exists. |
fullPage |
Captures the full scrollable page when true; otherwise captures the viewport. |
Use full-page for a page overview. Use the viewport when the report should document exactly what was visible in the browser. |
scale |
'css' produces one output pixel per CSS pixel. 'device' uses device pixels and is the default. |
Use CSS scale for more predictable dimensions and often smaller output. Device scale can preserve high-DPI detail, with larger images as a tradeoff. |
type and path |
type: 'jpeg' selects JPEG; with a path, Playwright can infer the type from the extension. |
Set both for clarity, especially in scripts that may change output filenames. |
JPEG does not support transparency, so omitBackground cannot make a JPEG transparent. Choose PNG if transparent pixels are required. A full-page capture can be much taller than the viewport; consider whether the report needs the entire page or just the relevant section.
4. Make report captures repeatable
For repeatable visual reports, keep the browser and host environment consistent. Rendering can vary with the operating system, browser version, settings, hardware, power source, and headless mode. If captures are compared over time, also keep the viewport and screenshot options fixed. Playwright documents these sources of variation in its visual comparisons guidance.
For reliable page loading, choose an appropriate navigation condition. The example uses networkidle, but pages with analytics or long-lived requests may never become idle. In that case, wait for a meaningful selector or use a bounded timeout rather than waiting indefinitely. Use a stable test page state before capturing, such as after the relevant content appears.
5. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The file is PNG, not JPEG | The requested type or filename extension does not select JPEG. | Set type: 'jpeg' and use a .jpeg filename. |
| The report does not render the attachment as an image | The attachment lacks the correct MIME type or Buffer body. | Pass the Buffer as body and set contentType: 'image/jpeg'. |
| The image is larger than expected | scale: 'device' captures device pixels, or fullPage: true captures a long page. |
Use scale: 'css', capture only the viewport, or reduce JPEG quality if the resulting artifacts remain acceptable. |
| The screenshot has a solid background | JPEG cannot preserve transparency. | Use PNG for transparent output. |
| Navigation hangs before capture | The page keeps network connections open, so networkidle may not occur. |
Wait for a specific selector or another page condition that indicates the report content is ready. |
| Similar captures differ across runs | Browser or host rendering environment changed. | Keep browser version, operating system, viewport, headless setting, and capture options consistent. |
6. Performance, reliability, and cost
JPEG quality and pixel dimensions affect output size; full-page and device-scale captures can produce substantially larger images. The right setting depends on the report’s readability needs and storage or transfer limits. This workflow runs a browser, so account for browser installation, startup, page loading, and cleanup in your job design. Reuse a controlled environment for batches of captures, and always close the browser in a finally block so failures do not leave it running.
Playwright itself is the capture library; the dossier provides no hosted-service pricing or benchmark for this workflow. Your costs depend on where and how you run the browser and store or deliver the report.
7. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. Its API returns an image or PDF from one GET request, and its parameters also work with names used by other screenshot APIs. The examples below save the response body as a JPEG. See the ScreenshotNeo API documentation for supported parameters and formats.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-d format=jpeg \
-o report.jpeg
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={
"access_key": "YOUR_API_KEY",
"url": "https://stripe.com",
"format": "jpeg",
},
timeout=90,
)
r.raise_for_status()
with open("report.jpeg", "wb") as f:
f.write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
format: 'jpeg',
});
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(({ writeFile }) =>
writeFile('report.jpeg', Buffer.from(await res.arrayBuffer()))
);
With ScreenshotNeo, cookie banners are accepted and removed before capture, along with known newsletter popups and chat widgets. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed; response headers identify the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Can I use the screenshot Buffer without saving a file?
Yes. Attach the Buffer to the Playwright Test report with the image/jpeg content type, or pass it to another API that accepts binary image data.
Should I choose JPEG or PNG for a report?
Choose JPEG when lossy compression is acceptable and you want a photographic image format. Choose PNG when you need lossless output or transparency.
Does full-page capture change the viewport?
It changes the captured coverage to the full scrollable page. Set the viewport explicitly when consistent page layout and dimensions matter.


