{"id":225,"library":"playwright","title":"Playwright","description":"Microsoft's browser automation library for Python. Automates Chromium, Firefox, and WebKit. Current version is 1.58.0 (Jan 2026). Requires Python >=3.9. Critical two-step install: pip install playwright followed by playwright install to download browser binaries — omitting the second step causes BrowserType.launch: Executable doesn't exist error.","status":"active","version":"1.58.0","language":"python","source_language":"en","source_url":"https://playwright.dev/python/docs/release-notes","tags":["browser-automation","testing","web-scraping","chromium","firefox","webkit","e2e"],"install":[{"cmd":"pip install playwright","lang":"bash","label":"Step 1: Install Python package"},{"cmd":"playwright install","lang":"bash","label":"Step 2: Download browser binaries (REQUIRED)"},{"cmd":"playwright install chromium","lang":"bash","label":"Step 2 (minimal): Chromium only"},{"cmd":"playwright install --with-deps","lang":"bash","label":"Step 2 (CI/Linux): Install browsers + OS dependencies"}],"dependencies":[{"reason":"Required for sync API. Installed automatically.","package":"greenlet","optional":false},{"reason":"Required. Installed automatically.","package":"pyee","optional":false}],"imports":[{"note":"Import from playwright.sync_api or playwright.async_api — not from playwright directly. The correct sync import is from playwright.sync_api import sync_playwright.","wrong":"import playwright  # ImportError — must import from submodule\nfrom playwright import sync_playwright  # ImportError — wrong path","symbol":"sync_playwright","correct":"from playwright.sync_api import sync_playwright\n\nwith sync_playwright() as p:\n    browser = p.chromium.launch(headless=True)\n    page = browser.new_page()\n    page.goto('https://example.com')\n    print(page.title())\n    browser.close()"},{"note":"Sync API: from playwright.sync_api import sync_playwright. Async API: from playwright.async_api import async_playwright. Never mix sync and async — calling await on sync methods raises TypeError.","wrong":"from playwright.sync_api import async_playwright  # ImportError — async is in async_api","symbol":"async_playwright","correct":"import asyncio\nfrom playwright.async_api import async_playwright\n\nasync def main():\n    async with async_playwright() as p:\n        browser = await p.chromium.launch()\n        page = await browser.new_page()\n        await page.goto('https://example.com')\n        await browser.close()\n\nasyncio.run(main())"}],"quickstart":{"code":"from playwright.sync_api import sync_playwright\n\nwith sync_playwright() as p:\n    # Launch browser\n    browser = p.chromium.launch(headless=True)\n    context = browser.new_context()\n    page = context.new_page()\n    \n    # Navigate and interact\n    page.goto('https://example.com')\n    print('Title:', page.title())\n    \n    # Use locators (preferred over selectors)\n    page.get_by_role('button', name='Submit').click()\n    page.get_by_label('Email').fill('user@example.com')\n    \n    # Wait for navigation\n    page.wait_for_load_state('networkidle')\n    \n    # Screenshot\n    page.screenshot(path='screenshot.png')\n    browser.close()","lang":"python","description":"Basic sync pattern. Use locators (get_by_role, get_by_label) not raw CSS selectors."},"warnings":[{"fix":"Two-step install: pip install playwright then playwright install. In CI/Docker: playwright install --with-deps to also install OS-level dependencies.","message":"Browser binaries are NOT included in the pip package. After pip install playwright, you must run playwright install (or playwright install chromium) to download browsers. Omitting this raises: BrowserType.launch: Executable doesn't exist at [path].","severity":"breaking","affected_versions":"all"},{"fix":"Pin playwright<1.51 for Python 3.8 environments.","message":"Python 3.8 support dropped in 1.51. Minimum is now Python 3.9.","severity":"breaking","affected_versions":">= 1.51"},{"fix":"Use a dedicated accessibility testing library like Axe. The Playwright docs link to Axe integration guides.","message":"page.accessibility was removed in 1.57 after 3 years of deprecation. Code using page.accessibility raises AttributeError.","severity":"breaking","affected_versions":">= 1.57"},{"fix":"Update Dockerfiles to use: FROM mcr.microsoft.com/playwright/python:v1.58.0-jammy","message":"Docker image mcr.microsoft.com/playwright no longer contains Python. Use mcr.microsoft.com/playwright/python for Python-based automation in Docker.","severity":"breaking","affected_versions":">= 1.21"},{"fix":"Pick one: from playwright.sync_api import sync_playwright for sync code, or from playwright.async_api import async_playwright for async code. Never import from the wrong module.","message":"Mixing sync and async APIs causes cryptic errors. Using await on sync_playwright methods raises TypeError. Using sync methods inside async functions can deadlock.","severity":"gotcha","affected_versions":"all"},{"fix":"Replace page.click('#submit') with page.get_by_role('button', name='Submit').click(). Use page.get_by_label() for form inputs, page.get_by_test_id() for data-testid attributes.","message":"Locators are strongly preferred over raw CSS/XPath selectors. page.query_selector() and page.click('#some-id') work but are fragile. Locators (get_by_role, get_by_label, get_by_text) are auto-retrying and test-ID based.","severity":"gotcha","affected_versions":"all"},{"fix":"After every pip install --upgrade playwright, run playwright install again.","message":"playwright install downloads browsers to a version-specific cache path. Upgrading playwright without re-running playwright install uses stale binaries and may cause browser launch failures.","severity":"gotcha","affected_versions":"all"},{"fix":"To resolve this, consider using a slightly older, officially supported Python version (e.g., Python 3.12 or 3.11, depending on current Playwright release cycles). Alternatively, wait for Playwright to release compatible distributions for your Python version and platform. Always check Playwright's official documentation or PyPI page for supported Python versions and their compatible environments.","message":"Playwright might not immediately release official wheels or provide full support for the very latest Python versions upon their release. If you are using a bleeding-edge Python version (e.g., Python 3.13+), 'pip install playwright' may fail with 'No matching distribution found' if compatible distributions are not yet available on PyPI for your specific environment (Python version, OS, architecture).","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:01:46.780Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"After installing the Python package (`pip install playwright`), you must also install the browser binaries by running `playwright install` in your terminal. For specific browsers, use `playwright install chromium`, `playwright install firefox`, or `playwright install webkit`.","cause":"This error occurs when the Playwright browser binaries have not been downloaded or are not found at the expected path, usually because the `playwright install` command was not run after `pip install playwright`, or there's a version mismatch.","error":"BrowserType.launch: Executable doesn't exist at C:\\Users\\<user>\\AppData\\Local\\ms-playwright\\chromium-xxxx\\chrome-win\\chrome.exe"},{"fix":"Install the Playwright Python package using `pip install playwright`. If it's already installed, ensure your Python environment is correctly activated and there isn't a file named `playwright.py` in your project directory that might be shadowing the actual library.","cause":"This error means the Playwright Python package is not installed in your current Python environment, or there's an issue with your Python path or a naming conflict (e.g., a local file named `playwright.py`).","error":"ModuleNotFoundError: No module named 'playwright'"},{"fix":"Increase the timeout for the specific action or globally. For an action, pass a `timeout` argument (e.g., `page.goto('url', timeout=60000)`). For waiting for a selector, use `page.locator('#element').wait_for(timeout=10000)`. Avoid arbitrary `time.sleep()` calls and rely on Playwright's auto-waiting capabilities or explicit waits for conditions.","cause":"This generic timeout error indicates that a Playwright operation (like navigating, clicking, or waiting for a selector) took longer than the default 30-second timeout to complete.","error":"playwright._impl._api_types.Error: TimeoutError: Timeout 30000ms exceeded."},{"fix":"Ensure that the web server or application you are trying to access is running and accessible at the specified URL and port from within the environment where Playwright is executing. In CI environments, this often means properly setting up and waiting for a `webServer` in your Playwright configuration or ensuring service dependencies are met.","cause":"This error occurs when Playwright tries to navigate to a URL, but the browser cannot establish a connection to the specified address, often seen in CI/CD pipelines or when the target server (e.g., a local web server) is not running or accessible from the Playwright context.","error":"page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:3000/"},{"fix":"Ensure all asynchronous operations involving Playwright objects are `await`ed. Use `with sync_playwright() as p:` for synchronous API to ensure proper resource management. Avoid closing pages, contexts, or browsers until all intended interactions with them are complete. If iterating, use `for...of` loops with `await` for asynchronous operations inside the loop.","cause":"This error typically occurs when you attempt to interact with a Playwright object (like a `Page`, `Context`, or `ElementHandle`) after it has already been closed, disposed, or the underlying browser process has terminated prematurely. It's common in asynchronous code where `await` might be missing, or a loop doesn't complete its operations before the browser is closed.","error":"locator.click: Target closed"}],"ecosystem":"pypi","meta_description":null,"install_score":50,"install_tag":"draft","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"draft","tag_description":"notable install failures or slow imports","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":7.8,"disk_size":"154M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.29,"mem_mb":9.2,"disk_size":"156M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.5,"mem_mb":10.2,"disk_size":"148M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":10.8,"disk_size":"147M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":8,"disk_size":"153M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}