📁 File · Network · API Mock
File · Network · API Mock: Playwright's page.route() mechanism works like a specialized postal inspector at a network checkpoint: you can intercept any letter (HTTP request) you
Playwright's page.route() mechanism works like a specialized postal inspector at a network checkpoint: you can intercept any letter (HTTP request) you choose, alter its contents, redirect it to a different address, or generate a fake reply without ever delivering it. Why couldn't Selenium do this? Selenium only controls the browser UI and never touches the network layer; to intercept API calls you needed a separate proxy server outside of Selenium (BrowserMob Proxy, Charles, mitmproxy), had to manage SSL certificates, and wire the proxy into the driver — in Java this meant dozens of lines of configuration code. Playwright connects directly to the browser's network stack (via the Chrome DevTools Protocol), so a single line like page.route("**/api/products", route => route.fulfill({body: JSON.stringify(mockData)})) lets you run full UI tests without a real backend. The practical QA payoff: write frontend tests before the backend is ready without being blocked; silence rate-limited or paid third-party APIs during test runs; and easily simulate error responses (500, 401, 429) to test edge cases at the UI layer.
Micro Lab: Playwright — Network mocking
Replace the TODO line with the critical line from the expected solution. This is not a real runtime; the goal is to reinforce writing the correct structure in a controlled way.
How Does setInputFiles() Bypass the Native File Dialog?
Clicking input[type="file"] normally…
Clicking input[type="file"] normally opens the operating system's native file picker — this window is OUTSIDE the page's DOM, and neither Selenium nor Playwright can reach it with a normal locator.
setInputFiles() writes the file path directly…
setInputFiles() writes the given file path directly into the input element's files list, WITHOUT ever opening the native window — it's a fully programmatic shortcut.
The browser fires a real "change" event…
When the input changes, the browser fires a real "change" event — the page's JS reacts normally, as if a user had actually picked the file.
When multiple files are passed as an array…
When multiple files are passed as an array, they are all added together in a SINGLE change event — no repeated click simulation is needed.
waitForEvent('filechooser') instead waits for the real dialog…
waitForEvent('filechooser') instead waits for the real dialog to open and fills it programmatically via fileChooser.setFiles() — in headless mode there's no visible window anyway, so neither approach ever SHOWS anything on screen.