Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: Chrome DevTools Recorder does not provide a documented Python export for its Puppeteer format. Recorder’s Puppeteer export is JavaScript for Node.js. To run the same user flow in Python, keep the Recorder JSON (or use the generated JavaScript as a reference), then translate each action to Playwright Python or Selenium. If you need to replay the original JSON without translating it, use Puppeteer Replay in its JavaScript/Node ecosystem instead.
What Chrome Recorder actually exports
DevTools Recorder stores a flow as a sequence of actions: navigation, element selection, typing, clicks, waits and checks. Its export options include JSON and Puppeteer-based formats. The Puppeteer export produces JavaScript; it is not a Python script that can be imported and executed by a Python interpreter.
That leaves three practical routes:
- Translate the flow to Python: use Playwright’s Python API or Selenium’s Python WebDriver bindings.
- Replay the recording with minimal translation: keep the JSON and run it with Puppeteer Replay, which is a Puppeteer/JavaScript tool rather than a Python runtime.
- Use the generated Puppeteer file as a map: inspect its selectors, inputs and ordering while writing an equivalent Python test.
The exact conversion depends on the recorded website, browser version, operating system and test runner. An automatically translated flow is not guaranteed to keep working when the target page changes, so plan to validate and repair selectors and waits.
Free tools Windows power users keep installed
One-click scans. No signup required.
Recommended workflow: Recorder JSON to Python
- Record and verify the flow. In Chrome DevTools, open Recorder, create or select the user flow, and run it once while the page is in the state you expect.
- Export JSON. Use the Recorder export menu and save the JSON user flow. Keep this as the editable description of the actions. You can also export Puppeteer JavaScript to inspect the generated selectors and navigation behavior.
- Choose a Python library. Playwright is a good fit when you want synchronous or asynchronous APIs and support for Chromium, Firefox and WebKit. Selenium is appropriate when your project already uses WebDriver conventions.
- Install the package and browser components. Follow the current installation instructions for your chosen library. Playwright projects normally install the Python package and then the browser binaries; Selenium projects install the Python binding and use the Chrome/WebDriver setup supported by the installed versions.
- Map every action. Convert navigation, selectors, typed values, clicks, viewport settings, pop-ups, waits and assertions one by one. Preserve the order, but replace brittle timing with state-based waits where possible.
- Run against the real target. Treat the first run as validation. Repair selectors when labels, DOM structure or frames differ from the recording, and add an assertion for the outcome that matters to your test.
Playwright Python translation
The Playwright library can be used as a general purpose browser automation tool, providing APIs for web applications in both synchronous and asynchronous Python. The following is a complete synchronous starting point. Replace the URL, selectors and values with the actions in your Recorder flow.
#1 Best Overall
from playwright.sync_api import sync_playwright
TARGET = "https://example.com/login"
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={"width": 1440, "height": 900})
page.goto(TARGET, wait_until="domcontentloaded")
page.get_by_label("Email").fill("[email protected]")
page.get_by_label("Password").fill("replace-with-a-test-secret")
page.get_by_role("button", name="Sign in").click()
# Express the intended result, not merely a delay.
page.get_by_role("heading", name="Dashboard").wait_for()
print(page.url)
browser.close()
For an asynchronous test runner, use the async API and await each operation:
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(viewport={"width": 1440, "height": 900})
await page.goto("https://example.com", wait_until="domcontentloaded")
await page.get_by_role("link", name="Pricing").click()
await page.get_by_role("heading", name="Plans").wait_for()
await browser.close()
asyncio.run(main())
Recorder may emit CSS or XPath-like selectors rather than accessible roles. You can use a locator such as page.locator("form input[name='email']"), but prefer a stable role, label, test id or distinctive text when the application provides one. If the action occurs inside an iframe, locate the frame first and then use its locator. If a click opens a new tab, wait for the popup while performing the click:
with page.expect_popup() as popup_info:
page.get_by_role("link", name="Open report").click()
report = popup_info.value
report.get_by_role("heading", name="Report").wait_for()
Selenium Python translation
Selenium’s Python binding uses WebDriver commands. This example starts Chrome, navigates, interacts with elements and waits for a result. The selectors are illustrative; copy the intent of your Recorder actions rather than assuming these exact selectors exist on your site.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →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
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 20)
try:
driver.set_window_size(1440, 900)
driver.get("https://example.com/login")
wait.until(EC.visibility_of_element_located((By.NAME, "email"))).send_keys("[email protected]")
driver.find_element(By.NAME, "password").send_keys("replace-with-a-test-secret")
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "h1.dashboard")))
print(driver.current_url)
finally:
driver.quit()
WebDriver setup is version-sensitive: Chrome, the driver and Selenium must be compatible according to the current Selenium and browser documentation. Keep the browser session in a try/finally block so failed tests do not leave processes behind.
Rank #2
How to translate common Recorder actions
| Recorder intent | Playwright Python | Selenium Python |
|---|---|---|
| Navigate | page.goto(url) |
driver.get(url) |
| Type into a field | locator.fill(value) |
element.send_keys(value) |
| Click | locator.click() |
element.click() |
| Select an option | locator.select_option("value") |
Select(element).select_by_value("value") |
| Wait for a condition | locator.wait_for() or an assertion |
WebDriverWait(...).until(...) |
| Read text | locator.inner_text() |
element.text |
| Set viewport | browser.new_page(viewport={...}) |
driver.set_window_size(width, height) |
Recorder’s generated JavaScript can reveal whether an action expects navigation, a dialog, a new page or a particular selector. Recreate that behavior explicitly in Python. For authentication, use a dedicated test account and inject secrets through environment variables rather than committing them to the script.
Replay the original JSON instead of converting it
Puppeteer Replay is the closest documented route to running a Recorder JSON flow with minimal translation. It provides a command-line and API workflow for Recorder JSON and supports customization and transformation. It remains a JavaScript/Puppeteer solution, so it does not turn the flow into Python or let a Python test runner execute it directly.
Choose this route when preserving the original recording matters more than using Python. Choose Playwright or Selenium when the flow must live in a Python test suite, share Python fixtures, or run under a Python CI framework.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Selectors, waits and assertions that survive translation
Prefer stable selectors
Generated selectors often depend on DOM nesting, classes or transient text. Prefer an accessible label, role, name or application-provided test identifier. If no stable hook exists, ask the application team for one instead of adding increasingly complex XPath.
Wait for state, not time
A fixed sleep may pass on a fast machine and fail under CI load. Wait for the element to be visible, enabled or attached; wait for a URL change or a response when navigation is the outcome. Use a short delay only when the application has a documented animation or debounce that cannot be observed another way.
Assert the business result
A successful click is not proof that the flow worked. Assert a heading, URL, confirmation message, downloaded file or other state that represents completion. Keep assertions close to the action that should cause them so failures identify the broken step.
Troubleshooting translated flows
- “Element not found” or timeout: confirm the page URL, wait for the correct state, inspect whether the element is inside an iframe, and replace a generated selector with a stable role, label or test id.
- Click intercepted: a consent banner, modal or sticky overlay may cover the target. Handle the overlay as a recorded step, wait for it to disappear, or select the intended element more precisely.
- Typing has no effect: ensure the field is visible and enabled, and use the library’s fill/send-keys operation after focusing the correct frame.
- Navigation race: combine the click with an explicit navigation or URL wait. For a new tab, wait for the popup before addressing its page.
- Works headed but fails headless: set a deterministic viewport, check responsive breakpoints, remove assumptions about mouse position, and capture a screenshot or DOM dump at failure.
- Intermittent failures: eliminate fixed sleeps, wait on network or visible state where appropriate, isolate test data, and ensure each run starts with a clean context.
- Browser startup failure: verify that Playwright’s browser binaries are installed or that Selenium’s Chrome/driver versions are compatible; also check CI sandbox and display requirements.
- Recorder flow changed: re-record the affected action, compare the JSON or generated JavaScript with the current DOM, and update the Python mapping rather than blindly retrying.
Performance, reliability and cost decisions
Headless mode usually reduces display overhead, while reusing a browser process can reduce startup time. Do not reuse pages or authentication state across tests unless shared state is intentional; isolation makes failures easier to reproduce. Run a small smoke flow first, then parallelize independent contexts only after the target site and test data can tolerate concurrent sessions.
Browser automation consumes CPU, memory, network bandwidth and time. Failed translations cost developer time rather than a special API fee, but CI minutes and hosted browser resources still matter. Keep recordings short, avoid unnecessary full-page waits, and collect artifacts only on failure. The sources do not establish a success rate for any automatic converter, so treat every conversion as code that requires review.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your requirement is simply to capture the resulting page rather than replay every interaction, ScreenshotNeo provides a single website-screenshot request. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each of those cleanup steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
Use the API documentation at https://screenshotneo.com/docs/ for the full option set. A basic call is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in 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)
And in 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}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. Features include full-page lazy-image capture, CSS-element capture, device presets, custom viewport and retina scale, PDF controls, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification.
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 minuteThe Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan. Create a free ScreenshotNeo account to try it without a card.
FAQ
Can I import a Recorder JSON file directly into Python?
Not as a documented native Python runtime. Use the JSON as the source for a Playwright or Selenium translation, or replay it with Puppeteer Replay.
Best Value
Should I choose Playwright or Selenium?
Choose Playwright for its sync/async Python APIs and broad browser support; choose Selenium when your organization already standardizes on WebDriver and its surrounding tooling.
Is the generated Puppeteer JavaScript useless if I want Python?
No. It is a useful reference for action order, selectors, navigation and expected page state, even though it cannot be executed by Python unchanged.
Recommended Free Tools
Frequently Asked Questions
Can I import a Recorder JSON file directly into Python?
Not as a documented native Python runtime. Use the JSON as the source for a Playwright or Selenium translation, or replay it with Puppeteer Replay.
Should I choose Playwright or Selenium?
Choose Playwright for its sync/async Python APIs and broad browser support; choose Selenium when your organization already standardizes on WebDriver and its surrounding tooling.
Is the generated Puppeteer JavaScript useless if I want Python?
No. It is a useful reference for action order, selectors, navigation and expected page state, even though it cannot be executed by Python unchanged.
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.

