Free tools Windows power users keep installed
One-click scans. No signup required.
Use a timestamp string in the path option when you need it in the filename. For text that viewers can see in the image, add an overlay before capture or post-process the screenshot buffer. These are different outcomes: page.screenshot() does not automatically print a timestamp into your pixels or add one to a caller-supplied path.
Choose where the timestamp belongs
| Goal | Best method | Result |
|---|---|---|
| Unique files for every run | Generate a filename-safe string and pass it to path |
Time appears in the file name, not the image |
| Time visible to readers | Add a page overlay before capture, or capture a buffer and post-process it | Timestamp is rendered in the pixels |
| Playwright Test artifact | Use testInfo.outputPath() and optionally testInfo.attach() |
Timestamped file or report attachment |
| CLI or MCP capture | Use an explicit filename when predictable naming matters | Tool-specific defaults otherwise apply |
The Page API documents path as the destination and infers the image format from its extension. See the Playwright Page API.
Add a timestamp to the screenshot filename
ISO 8601 is useful because it sorts chronologically. Colons are legal on Unix-like systems but problematic on Windows, so replace them with hyphens.
import { chromium } from 'playwright';
import { mkdir } from 'node:fs/promises';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await mkdir('screenshots', { recursive: true });
const timestamp = new Date().toISOString().replaceAll(':', '-');
const path = `screenshots/page-${timestamp}.png`;
await page.screenshot({ path, fullPage: true });
console.log(`Saved ${path}`);
await browser.close();
A generated name such as page-2026-09-29T14-05-33.412Z.png identifies the capture time in UTC. The extension selects PNG here; use .jpeg or .webp when those formats suit your storage or delivery pipeline.
Recommended Free Tools
#1 Best Overall
Keep names safe and sortable
- Keep the UTC
Zsuffix if teams in several time zones consume artifacts. - Use a run ID or test name before the timestamp when many pages are captured.
- Create the destination directory first; Playwright will not replace a missing parent directory.
- Do not put secrets, cookies, or full query strings in a filename.
Put visible timestamp text inside the image
A filename timestamp is metadata. It will not be visible when someone opens the image. You have two practical approaches.
Approach A: render an overlay in the page
Insert a fixed element, wait for it to render, then capture. This keeps the entire operation in Playwright and makes the overlay part of the pixels.
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
const visibleTimestamp = new Date().toISOString();
await page.evaluate((text) => {
const badge = document.createElement('div');
badge.textContent = text;
Object.assign(badge.style, {
position: 'fixed',
right: '12px',
bottom: '12px',
zIndex: '2147483647',
padding: '6px 9px',
color: '#fff',
background: 'rgba(0,0,0,.72)',
borderRadius: '4px',
font: '12px/1.2 monospace',
pointerEvents: 'none'
});
document.body.appendChild(badge);
}, visibleTimestamp);
await page.screenshot({ path: 'screenshots/with-timestamp.png', fullPage: true });
await browser.close();
For a full-page screenshot, a position: fixed badge can appear in each captured viewport segment depending on browser behavior. If one badge at a document coordinate is required, use position: absolute and place it relative to a sized container, or capture a single viewport.
Approach B: capture a buffer for post-processing
The screenshot API can return bytes instead of writing a file. The screenshots guide documents this buffer workflow for post-processing. Pass the buffer to the image library approved by your project, draw text, and write the resulting PNG or WebP.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →const buffer = await page.screenshot({ type: 'png' });
// Send buffer to your image-processing pipeline here.
// Render new Date().toISOString() as text, then save the processed bytes.
This option is preferable when the webpage must remain untouched, when you need identical typography across pages, or when a compliance watermark is applied outside the browser. The Playwright documentation explains the buffer step but does not mandate a particular image-processing library, so choose one that your runtime already supports.
Rank #2
Timestamped screenshots in Playwright Test
Playwright Test manages per-test output directories. Use testInfo.outputPath() rather than hand-building paths in a shared folder.
import { test, expect } from '@playwright/test';
test('checkout screenshot', async ({ page }, testInfo) => {
await page.goto('https://example.com');
const timestamp = new Date().toISOString().replaceAll(':', '-');
const file = testInfo.outputPath(`checkout-${timestamp}.png`);
await page.screenshot({ path: file, fullPage: true });
await testInfo.attach('checkout-screenshot', {
path: file,
contentType: 'image/png'
});
});
You can attach a buffer instead when you do not need a separate file:
const buffer = await page.screenshot();
await testInfo.attach('checkout-screenshot', {
body: buffer,
contentType: 'image/png'
});
These APIs are documented in TestInfo. Timestamped names are useful for retaining several artifacts; for visual regression, a stable name is usually easier for comparison tools.
Locator screenshots and element-specific timestamps
Use locator.screenshot() when only a matching element belongs in the artifact:
const card = page.locator('[data-testid="invoice"]');
const timestamp = new Date().toISOString().replaceAll(':', '-');
await card.screenshot({ path: `screenshots/invoice-${timestamp}.png` });
Locator-based capture is the recommended modern surface for matching elements. The Locator API documents this method; the ElementHandle API discourages using an element handle when a locator is available.
Rank #3
CLI and MCP naming is different from the Page API
The Playwright CLI screenshot command and Playwright MCP screenshot tool document timestamped default filenames when you omit their filename parameter. Those defaults belong to those tools; they do not mean that page.screenshot() silently timestamps your path.
- For repeatable automation, provide an explicit filename.
- For quick interactive captures, the CLI or MCP default can prevent accidental overwrites.
- Check the current tool’s option name before scripting around a default.
See Playwright Screenshots & PDF and Playwright MCP screenshots.
Reliable capture sequence
- Navigate and wait for the state you actually want, such as a selector, a short delay, or network idle.
- Generate the timestamp immediately before capture so it describes the screenshot operation, not an earlier setup step.
- Add an overlay if the time must be visible; otherwise use the filename only.
- Capture with an explicit extension and path.
- Verify the file exists or attach the returned buffer, then close the browser context.
For dynamic pages, waiting for networkidle alone may not mean that animations, lazy images, or application data are finished. Wait for a meaningful locator and disable animations in your test CSS when deterministic pixels matter.
Troubleshooting
The timestamp is in the name but not visible
That is expected: path controls output metadata. Add the DOM overlay or post-process a buffer.
Windows rejects the filename
Remove colons and other reserved characters. The replaceAll(':', '-') format above is safe for the ISO time portion.
Files overwrite each other
Include milliseconds, a test name, or a unique run ID. Also ensure parallel workers do not share a manually chosen fixed path.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →The overlay is missing
Inject it after navigation and before the screenshot, then wait for the next render tick or for a locator that confirms it exists. Check that page CSS does not hide it and that its z-index is high enough.
Only part of an element is captured
Use a locator screenshot for the element, ensure it is visible, and remove clipping or transforms that change its bounding box. Prefer locators over discouraged element-handle screenshots.
The test report has no attachment
Attach either the exact file path returned by testInfo.outputPath() or the screenshot buffer, and set the correct contentType.
CLI or MCP output names change unexpectedly
Do not rely on a tool’s omitted-filename default. Supply the explicit filename documented by that tool.
Or skip the browser setup
ScreenshotNeo is a screenshot API and MCP server when you want a single request instead of managing Playwright browsers. It removes cookie/consent banners, newsletter popups and chat widgets before capture; bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP tools—take_screenshot, get_page_info and capture_pdf—work with Claude, Cursor and other MCP clients.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for timestamp-friendly naming in your own pipeline and its other capture options, including full-page shots, CSS selectors, custom JavaScript, device presets, PDFs, signed links, async webhooks and bulk capture.
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan. Create a free ScreenshotNeo account.
FAQ
Does Playwright add timestamps automatically?
Not in the Page API when you provide a path. CLI and MCP have separate documented defaults when a filename is omitted.
Can a timestamp be added after a screenshot is saved?
Yes. Capture a buffer, render text with an image-processing pipeline, and save the transformed bytes.
Should visual regression screenshots use timestamps?
Usually no. Stable names make baseline comparison and review simpler; reserve timestamps for archival run artifacts.
Frequently Asked Questions
Does Playwright add timestamps automatically?
Not in the Page API when you provide a path. CLI and MCP have separate documented defaults when a filename is omitted.
Can a timestamp be added after a screenshot is saved?
Yes. Capture a buffer, render text with an image-processing pipeline, and save the transformed bytes.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteShould visual regression screenshots use timestamps?
Usually no. Stable names make baseline comparison and review simpler; reserve timestamps for archival run artifacts.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




