From 9e1f2a4455fa4b8c0dfc03bba225a9eefee1a9fe Mon Sep 17 00:00:00 2001 From: Mohammed Alkindi Date: Mon, 12 Oct 2026 22:02:18 -0700 Subject: [PATCH] fix(network): keep blank values in Request.post_data_json for form bodies parse_qsl drops empty fields by default, so a body such as a=&b=1 lost the a key. The JS client uses URLSearchParams, which keeps them. --- playwright/_impl/_network.py | 2 +- tests/async/test_page_network_request.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/playwright/_impl/_network.py b/playwright/_impl/_network.py index 3e5b8fe89..0897355f4 100644 --- a/playwright/_impl/_network.py +++ b/playwright/_impl/_network.py @@ -263,7 +263,7 @@ def post_data_json(self) -> Optional[Any]: return None content_type = self.headers.get("content-type") if content_type and "application/x-www-form-urlencoded" in content_type: - return dict(parse.parse_qsl(post_data)) + return dict(parse.parse_qsl(post_data, keep_blank_values=True)) try: return json.loads(post_data) except Exception: diff --git a/tests/async/test_page_network_request.py b/tests/async/test_page_network_request.py index bab4d5fd0..71494c25a 100644 --- a/tests/async/test_page_network_request.py +++ b/tests/async/test_page_network_request.py @@ -55,12 +55,12 @@ async def test_should_parse_the_data_if_content_type_is_application_x_www_form_u headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', }, - body: 'foo=bar&baz=123' + body: 'foo=bar&baz=123&empty=' })""" ) request = await request_info.value assert request - assert request.post_data_json == {"foo": "bar", "baz": "123"} + assert request.post_data_json == {"foo": "bar", "baz": "123", "empty": ""} async def test_existing_response_should_return_response_after_it_is_received(