Yes, you can use Java Playwright to take screenshots at multiple viewport widths by creating a new browser context for each width and calling the page screenshot method within that context. You define the viewport size when you create the context, then capture the page as a PNG or JPEG file, and repeat the process for each width in your test list.
Why Viewport-Width Screenshots Matter
Responsive design means a page can look completely different on a 360px phone, a 768px tablet, and a 1920px desktop. A single screenshot at one width only shows one slice of that experience. Taking screenshots at multiple viewport widths lets you visually verify that navigation menus collapse correctly, images scale without distortion, and text does not overflow or get cut off. This is especially useful for regression testing after CSS changes, for documenting responsive behavior in design reviews, and for generating gallery images for documentation or client presentations.
How Playwright Handles Viewports
Playwright separates the browser window from the viewport. The viewport is the visible area of the page, and you control it via the BrowserContext. Each context can have its own viewport size, device scale factor, user agent, and other emulation settings. When you create a new context with newContext(new Browser.NewContextOptions().setViewportSize(width, height)), all pages opened in that context use that viewport. The key point is that the viewport is a context-level setting, not a page-level one. Changing it after the page has loaded requires calling page.setViewportSize(width, height), which triggers a re-layout and is useful for dynamic resizing tests, but for a clean set of screenshots, creating a fresh context per width is simpler and avoids any state leakage.
Step-by-Step Implementation
Here is a complete Java example using Playwright’s synchronous API. It assumes you have the Playwright dependency in your pom.xml or build.gradle.
- Create a Playwright instance and launch a browser (Chromium, Firefox, or WebKit).
- Define your list of widths, for example: 375, 768, 1024, 1440.
- Loop through each width. Inside the loop:
- Create a new context with the desired viewport size. Use a height like 800 or 900; the height only affects the initial viewport, not the full-page screenshot.
- Open a new page in that context and navigate to your target URL.
- Wait for the page to load (using
page.waitForLoadState()) and optionally wait for fonts or images. - Take a full-page screenshot using
page.screenshot(new Page.ScreenshotOptions().setFullPage(true).setPath("screenshot-" + width + ".png")). - Close the context to free memory and resources.
Here is the code snippet:
import com.microsoft.playwright.*;
import java.util.Arrays;
import java.util.List;
public class MultiViewportScreenshot {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch();
List<Integer> widths = Arrays.asList(375, 768, 1024, 1440);
for (int width : widths) {
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setViewportSize(width, 800));
Page page = context.newPage();
page.navigate("https://example.com");
page.waitForLoadState(LoadState.NETWORKIDLE);
page.screenshot(new Page.ScreenshotOptions()
.setFullPage(true)
.setPath("screenshot-" + width + ".png"));
context.close();
}
browser.close();
}
}
}
This produces four PNG files, one per width. The setFullPage(true) option captures the entire scrollable page, which is usually what you want for responsive review. If you only need the visible area, omit that option.
Choosing Which Viewport Widths to Test
There is no universal standard, but a common set covers the main breakpoints used by CSS frameworks like Bootstrap and Tailwind:
- 360–414 px – typical phone widths (iPhone, Android).
- 768 px – portrait tablet.
- 1024 px – landscape tablet / small laptop.
- 1280–1440 px – standard desktop.
- 1920 px – large desktop monitors.
If your site uses custom breakpoints, match those instead. You can also read your CSS media queries and extract the exact pixel values they use. For most projects, 4–6 widths give good coverage without excessive runtime.
Common Pitfalls and Solutions
One frequent mistake is taking a screenshot immediately after navigate() without waiting for resources like web fonts or lazy-loaded images. Use waitForLoadState(LoadState.NETWORKIDLE) or wait for a specific selector to appear. Another issue is that full-page screenshots on very long pages can be memory-intensive; consider capping the page height or using a headless browser to reduce overhead. Also, if you are testing a page that uses JavaScript to change layout based on device width (like serving different components), make sure you also set the isMobile and hasTouch options on the context if you want to emulate a phone exactly. Finally, remember that screenshots are pixel-based; if you need to compare them automatically, you will need an image comparison library, as Playwright does not include one.
Alternatives to Playwright for This Task
Other tools can also capture multi-viewport screenshots. Selenium with WebDriver can resize the browser window, but it is slower and more brittle. Puppeteer (Node.js) offers similar functionality to Playwright but is JavaScript-only. Cypress can take screenshots but has limited multi-tab and multi-context support. For static sites, you could use headless Chrome directly with the --window-size flag, but that does not give you full-page capture easily. Playwright stands out because it is cross-language (Java, Python, C#, JavaScript), has automatic waiting, and handles modern web features well.
Performance and Resource Considerations
Creating a new browser context per width is the cleanest approach but does use more memory than resizing a single page. Each context is a separate incognito-like session, so it does not share cookies or local storage. If you are testing many widths (e.g., 10 or more), you might want to reuse a single context and call page.setViewportSize() before each screenshot. That approach is faster because it avoids re-creating the context, but it can cause layout shifts if the page has stateful JavaScript. For most use cases, the per-context method is recommended. Also, consider running your screenshots in parallel using Playwright’s test runner or a Java executor service to speed up the process, especially if you have many URLs and widths.
Frequently Asked Questions
Can I take a screenshot at a specific device like an iPhone?
Yes, Playwright has a built-in device descriptor registry. You can use playwright.devices().get("iPhone 13") to get a set of predefined options including viewport size, user agent, and touch support. Then pass those options to newContext(). This gives a more accurate emulation than just setting the viewport width.
How do I save screenshots with a timestamp in the filename?
Use Java’s LocalDateTime.now() and format it with DateTimeFormatter. For example: String fileName = "screenshot-" + width + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss")) + ".png". This helps avoid overwriting previous runs.
Does the viewport height matter for full-page screenshots?
No, when setFullPage(true) is used, Playwright captures the entire scrollable height of the page, regardless of the viewport height. The viewport height only affects what is visible when the page first loads, which can influence lazy-loading behavior. For full-page captures, a height of 800 is fine.
Can I take screenshots of a page that requires login?
Yes. Before navigating to the protected page, you can either add cookies to the context using context.addCookies(), or you can perform the login steps in the page (fill in the form, click submit) and then navigate to the target URL. Because each context is isolated, you need to log in for each width or use a persistent context with a storage state file.
What is the difference between full-page and element screenshots?
A full-page screenshot captures the entire scrollable area of the page. An element screenshot captures only a specific element, such as a header or a product card, using locator.screenshot(). Element screenshots are useful when you want to focus on a particular component across different viewports, but they do not show the overall layout.
Is it better to use headless or headed mode for screenshots?
Headless mode is faster and uses fewer resources, and it produces identical screenshots for most pages. Headed mode is useful when you want to visually debug what is happening, but it is slower. For automated screenshot generation, headless is the standard choice.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Valheim Server Not Showing in Community List Fixes
- DisplayPort vs HDMI: Which Cable Should You Use?
- Soundbar vs 2.1 Speaker System: Which Is Better?
- Survive Lava for Brainrot Tier List170 points
- MySQL Dump Import: Fix Common Errors
- Mouse Moving on Its Own? Causes & Fixes