Add ApiRequestContext to Selenium#17228
Add ApiRequestContext to Selenium#17228mayank-at-sauce wants to merge 4 commits intoSeleniumHQ:trunkfrom
Conversation
Add a `driver.request` API that lets Selenium users make HTTP requests with automatic browser cookie synchronization — bridging the biggest feature gap with Playwright's APIRequestContext. Key features: - Bidirectional cookie sync: browser cookies sent with API requests, API response cookies synced back to the browser - Isolated contexts via `new_context()` with separate cookie jars - Auth state persistence via `storage_state()` save/load to JSON - All HTTP methods: GET, POST, PUT, PATCH, DELETE, HEAD, plus `fetch()` - Common kwargs: data, form, json_data, headers, params, timeout, max_redirects, fail_on_status_code - Pure Python HTTP client using urllib3 (already a Selenium dep), no BiDi/WebSocket dependency - Resource cleanup on `driver.quit()` Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix host-only cookie overmatch (security): - _cookie_matches now takes default_domain param; cookies with empty/missing domain only match when hostname == default_domain - APIRequestContext derives default_domain from driver.current_url - IsolatedAPIRequestContext uses the request URL hostname Fix expired cookies still sent (correctness): - _cookie_matches rejects cookies with expiry <= now - _IsolatedAPIRequestContext._handle_response_cookies skips expired cookies (Max-Age=0/negative) instead of storing them Add storage_state path validation (reliability): - FileNotFoundError with clear message for missing files - ValueError wrapping JSONDecodeError for invalid JSON - OSError with clear message for unwritable paths Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review Summary by QodoAdd APIRequestContext for HTTP requests with browser cookie sync
WalkthroughsDescription• Add APIRequestContext for HTTP requests with automatic browser cookie synchronization • Implement bidirectional cookie sync between browser and API requests • Support isolated contexts via new_context() with separate cookie jars • Add storage_state() for auth state persistence to/from JSON files • Support all HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD) plus fetch() • Implement RFC 6265 compliant cookie matching with domain, path, secure, and expiry validation • Add comprehensive unit and integration tests with local HTTP server File Changes1. py/selenium/webdriver/common/api_request_context.py
|
Code Review by Qodo
1.
|
The problem this would solve:
Selenium currently has no way to make HTTP API calls that share authentication/cookie state with the browser session. This is a significant gap compared to Playwright's APIRequestContext,
which is one of the most-used features in modern test automation.
Common real-world scenarios that require this:
Fast test setup — Log in via API (POST /auth/login) to get auth cookies, then use those cookies in the browser to skip slow UI login flows
API + UI hybrid testing — Verify a UI action triggers the correct backend state (e.g., click "Delete" button, then call GET /api/items to confirm deletion)
Test data seeding — Create test fixtures via API before browser tests, sharing the same authenticated session
Backend assertion — After a browser interaction, assert API responses without opening new pages
Today, users must manually extract cookies from driver.get_cookies(), construct a separate requests.Session, and handle cookie format conversion. The reverse (API cookies → browser)
requires iterating and calling driver.add_cookie() per cookie, with domain/path matching issues. There is no built-in support for this.
Third-party libraries (https://github.com/tryolabs/requestium, https://github.com/cryzed/Selenium-Requests) exist but have limitations — they still require a running browser for every
request, lack isolated cookie contexts, and have no auth state persistence to disk.
How I expect the feature would work:
A new APIRequestContext class accessible from the WebDriver instance:
Make API calls that share cookies with the browser
response = driver.request.get("https://api.example.com/users")
assert response.status == 200
data = response.json()
Log in via API, cookies automatically available in browser
driver.request.post("https://example.com/api/login", data={
"username": "testuser",
"password": "testpass"
})
Browser now has the auth cookies — no UI login needed
driver.get("https://example.com/dashboard")
Create an isolated request context (separate cookie jar)
api = driver.request.new_context(base_url="https://api.example.com/")
api.post("/seed-data", data={"item": "test"})
api.dispose()
Save/load auth state to disk for reuse across tests
driver.request.storage_state(path="auth.json")
In another test:
api = driver.request.new_context(storage_state="auth.json")
Common kwargs for HTTP methods: data, form, headers, params, timeout, max_redirects, fail_on_status_code
Key behaviors:
Bidirectional cookie sync — Cookies set by API responses are automatically available in the browser (via driver.add_cookie()), and browser cookies are automatically sent with API
requests (via driver.get_cookies())
Isolated contexts — new_context() creates a separate cookie jar that does not affect the browser session
Auth state persistence — storage_state() serializes cookies to a JSON file; new_context(storage_state="file.json") restores them
No browser required for API calls — HTTP requests use Python's standard urllib or http.client (no external dependencies), the browser only needs to be running if you want cookie sync
Have you considered any alternatives or workarounds?
Current workarounds and their limitations:
Manual cookie transfer with requests library:
import requests
session = requests.Session()
for cookie in driver.get_cookies():
session.cookies.set(cookie['name'], cookie['value'], domain=cookie.get('domain'))
response = session.get("https://api.example.com/data")
Problems: Verbose, error-prone (domain/path/secure flag handling), no auto-sync back to browser, requires external dependency.
requestium library (github.com/tryolabs/requestium):
Provides transfer_session_cookies_to_driver() and transfer_driver_cookies_to_session(). But: requires explicit manual transfer calls (no auto-sync), no isolated contexts, no auth state
persistence, no storage_state to disk.
selenium-requests library (github.com/cryzed/Selenium-Requests):
Auto-syncs cookies but requires a running WebDriver for every HTTP request (opens hidden tabs), last updated Feb 2024 (stale), and has open bugs with modern browsers.
JavaScript execution (driver.execute_script with fetch()):
Can make API calls within the browser, but: responses are hard to extract to Python, no isolated contexts, can't run before page navigation, subject to CORS restrictions.
None of these provide a clean, built-in, first-class API that matches the simplicity and reliability of Playwright's APIRequestContext.