The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use one Selenium WebDriver session, define your breakpoint cases as named width-and-height pairs, and loop through them with driver.set_window_size(width, height). After every navigation or resize, wait for a page-specific condition before asserting responsive behavior or saving a screenshot. This produces repeatable evidence for mobile, tablet, desktop, and any project-specific widths.
The repeatable pattern
A breakpoint test has five inputs: the URL, browser and driver versions, a list of viewport dimensions, a readiness condition, and the evidence or assertions to collect. Breakpoint values are test inputs chosen for your design; Selenium does not define a universal list.
- Choose named
(width, height)cases that represent the layouts your product supports. - Start a WebDriver session and navigate to the URL.
- Resize the current window for each case with
set_window_size. - Wait for a condition that proves the page is ready at that state.
- Check responsive and functional behavior, then save evidence whose filename includes the label and dimensions.
Complete Python example
Install Selenium in the environment used by your test suite, ensure Chrome and a compatible driver are available, and create the output directory before saving files. The following is a reusable pattern; replace the body wait with a condition that represents readiness for your page.
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
URL = "https://example.com"
BREAKPOINTS = {
"mobile": (375, 812),
"tablet": (768, 1024),
"desktop": (1440, 900),
}
artifacts = Path("artifacts")
artifacts.mkdir(parents=True, exist_ok=True)
with webdriver.Chrome() as driver:
wait = WebDriverWait(driver, 10)
driver.get(URL)
for label, (width, height) in BREAKPOINTS.items():
driver.set_window_size(width, height)
wait.until(EC.visibility_of_element_located((By.TAG_NAME, "body")))
# Add page-specific assertions here.
driver.save_screenshot(
str(artifacts / f"{label}-{width}x{height}.png")
)
set_window_size(width, height) changes the current browser window dimensions. The numbers passed to it should be recorded as part of the test result, because a screenshot without its exact dimensions is difficult to compare later.
#1 Best Overall
Set position and size together
When a test also needs a deterministic window position, use set_window_rect with width and height (and, where supported, x and y coordinates). It is the W3C-compatible API for setting window position and size in one call. For a viewport-only comparison, set_window_size is simpler.
What to verify at every breakpoint
Dimensions and responsive mode
Record the requested width and height, then assert the CSS-driven state expected at that width. Typical checks include whether navigation collapses, a menu button appears, columns stack, or a desktop-only panel is hidden. Assert observable behavior rather than assuming that a width automatically means “mobile” or “tablet.”
Functional state
Responsive layout is not enough if controls are unusable. Check that key buttons, links, forms, and menus are visible and enabled. If opening a menu changes the DOM, wait for the menu’s visible state before asserting it. Use selectors that express the product contract, such as a stable data attribute, rather than brittle generated class names.
Free tools Windows power users keep installed
One-click scans. No signup required.
Asynchronous content
A body element can become visible before data, images, or client-side layout work has finished. Replace the generic body wait with a documented expected condition: for example, visibility of a results panel, presence of a known heading, or an element becoming clickable. A fixed sleep is slower and less reliable because it can be too short on a busy run and unnecessarily long on a fast one.
Rank #2
Evidence and repeatability
Save screenshots and structured assertion output with the breakpoint label and dimensions, such as tablet-768x1024.png. Keep the URL, browser, driver version, breakpoint list, and relevant test data fixed when comparing runs. Differences in any of those inputs can look like a responsive regression.
Choosing breakpoint cases
Start with widths where your design actually changes, not a copied “standard” list. Include the narrowest supported layout, each navigation or grid transition, and the widest layout you promise to support. Height matters for fold-dependent behavior: a fixed header, sticky action bar, or dialog may behave differently at the same width with a short versus tall window.
- Named cases: use labels such as
mobile,tablet, anddesktopso reports are readable. - Boundary cases: test just below and just above a CSS media-query threshold when a change is important.
- Project-specific cases: include widths used by your design system, analytics, or supported devices; there is no universal Selenium breakpoint set.
- Exact recording: preserve the integer width and height passed to WebDriver in filenames and test output.
Assertions between resizes
You can reuse one browser session, but each iteration should establish its own state. If the page changes after the first case, either reload it or reset the relevant interaction before the next resize. Otherwise an open menu, scrolled position, selected filter, or lazy-loaded section can contaminate later evidence.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesfor label, (width, height) in BREAKPOINTS.items():
driver.set_window_size(width, height)
driver.get(URL) # optional: use when each case must start clean
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "main")))
menu = driver.find_element(By.CSS_SELECTOR, "[data-test=menu-button]")
if width < 700:
assert menu.is_displayed()
else:
assert not menu.is_displayed()
If navigation is expensive, navigate once and reset only the state that matters. Make that trade-off explicit in the test: a single navigation tests resize behavior, while a fresh navigation per case reduces state leakage.
Common failures and fixes
The screenshot has the wrong apparent viewport
WebDriver sets the browser window dimensions, which can include browser chrome depending on the driver and operating system. If your assertion concerns CSS viewport pixels, read the browser’s window.innerWidth and window.innerHeight with JavaScript and record those values alongside the requested window size. Use the measured viewport when diagnosing an off-by-chrome discrepancy.
Assertions run before the layout is ready
Replace an arbitrary delay with WebDriverWait and an expected condition tied to the page. For data loaded by JavaScript, wait for the results container, a loading indicator to disappear, or a specific state attribute. Increase the timeout only after confirming that the condition is correct.
Elements are present but not usable
Presence in the DOM does not prove visibility or clickability. Use visibility or element-to-be-clickable conditions, then investigate overlays, sticky headers, animations, and disabled states. A consent dialog or chat widget can cover the control even when the control itself is present.
The driver cannot start
Check that the browser and driver are installed, compatible, and available to the test environment. Pin versions in CI where reproducibility matters, and include them in failure artifacts. A Python import error, a missing executable, and a browser/driver mismatch are different problems and should be fixed separately.
Different runs produce different screenshots
Control the URL, test data, authentication, browser version, window dimensions, timezone, network dependencies, and animations where possible. Wait for a meaningful ready condition, and avoid comparing a page while it is still loading. Dynamic ads, timestamps, and personalized content may require test fixtures or masking.
Only the top of the page is captured
save_screenshot captures the current browser view. For full-page evidence, use a browser or test utility that supports full-page capture, or scroll and capture deliberate sections. Do not confuse a taller window with a full-page screenshot.
Performance, reliability, and cost decisions
One session with repeated resizing avoids browser startup overhead. Fresh navigation per case gives cleaner isolation but adds network and rendering time. Choose based on whether you are testing resize behavior or independent first loads. Parallel workers can shorten a large matrix, but they also increase CPU, memory, and backend load; keep each worker’s artifact directory distinct.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →For reliable CI, fail with the breakpoint label, requested dimensions, measured viewport, URL, browser and driver versions, console or application logs where available, and the screenshot. This turns a visual failure into a reproducible defect rather than an unexplained image diff.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you need screenshots rather than an in-process Selenium assertion, ScreenshotNeo provides a website screenshot API and MCP server. It accepts the consent banner 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 or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.
Its API supports full-page captures with lazy images loaded, CSS-selector element shots, dark mode, 12 device presets or any viewport, retina scale, PDF output, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors, delays or network idle, request and resource blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, TTL-controlled caching, signed public-image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Existing parameter names used by other screenshot APIs also work, which can simplify a migration.
One-call examples
See the ScreenshotNeo documentation for the current options. A basic cURL request is:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
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)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients, so an AI agent can request captures without you wiring browser automation. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account.
FAQ
Can I resize a WebDriver window after navigation?
Yes. Call set_window_size during the session, then wait for the responsive state you intend to inspect.
Should every breakpoint use a new browser?
No. Reusing a session is efficient. Use fresh navigation or a new session only when state isolation is more important than startup cost.
Are the example dimensions mandatory?
No. They are illustrative inputs. Select dimensions from your site’s supported layouts and media-query boundaries.
Recommended Free Tools
Frequently Asked Questions
Does Selenium emulate a phone?
Changing the window size tests a responsive layout at that browser size; it does not by itself reproduce every mobile-browser behavior. Add device-specific testing when touch, user-agent, or mobile browser differences matter.
How should I store breakpoint results in CI?
Keep each image and assertion result under a stable label-and-dimensions filename, and attach the browser, driver, URL, and measured viewport values to the test report.
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.

