Skip to content

Commit 567316c

Browse files
authored
feat: aded Request.postDataJSON (microsoft#148)
1 parent d913f1d commit 567316c

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

playwright/async_api.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ def postData(self) -> typing.Union[str, NoneType]:
119119
"""
120120
return mapping.from_maybe_impl(self._impl_obj.postData)
121121

122+
@property
123+
def postDataJSON(self) -> typing.Union[typing.Dict, NoneType]:
124+
"""Request.postDataJSON
125+
126+
When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned. Otherwise it will be parsed as JSON.
127+
128+
Returns
129+
-------
130+
Optional[Dict]
131+
Parsed request's body for `form-urlencoded` and JSON as a fallback if any.
132+
"""
133+
return mapping.from_maybe_impl(self._impl_obj.postDataJSON)
134+
122135
@property
123136
def headers(self) -> typing.Dict[str, str]:
124137
"""Request.headers

playwright/network.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import mimetypes
1818
from pathlib import Path
1919
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, cast
20+
from urllib import parse
2021

2122
from playwright.connection import ChannelOwner, from_channel, from_nullable_channel
2223
from playwright.helper import (
@@ -63,6 +64,18 @@ def postData(self) -> Optional[str]:
6364
return None
6465
return base64.b64decode(b64_content).decode()
6566

67+
@property
68+
def postDataJSON(self) -> Optional[Dict]:
69+
post_data = self.postData
70+
if not post_data:
71+
return None
72+
content_type = self.headers["content-type"]
73+
if not content_type:
74+
return None
75+
if content_type == "application/x-www-form-urlencoded":
76+
return dict(parse.parse_qsl(post_data))
77+
return json.loads(post_data)
78+
6679
@property
6780
def headers(self) -> Dict[str, str]:
6881
return parse_headers(self._initializer["headers"])

playwright/sync_api.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ def postData(self) -> typing.Union[str, NoneType]:
119119
"""
120120
return mapping.from_maybe_impl(self._impl_obj.postData)
121121

122+
@property
123+
def postDataJSON(self) -> typing.Union[typing.Dict, NoneType]:
124+
"""Request.postDataJSON
125+
126+
When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned. Otherwise it will be parsed as JSON.
127+
128+
Returns
129+
-------
130+
Optional[Dict]
131+
Parsed request's body for `form-urlencoded` and JSON as a fallback if any.
132+
"""
133+
return mapping.from_maybe_impl(self._impl_obj.postDataJSON)
134+
122135
@property
123136
def headers(self) -> typing.Dict[str, str]:
124137
"""Request.headers

tests/async/test_network.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,36 @@ async def test_request_postdata_should_be_undefined_when_there_is_no_post_data(
207207
assert response.request.postData is None
208208

209209

210+
async def test_should_parse_the_json_post_data(page, server):
211+
await page.goto(server.EMPTY_PAGE)
212+
server.set_route("/post", lambda req: req.finish())
213+
requests = []
214+
page.on("request", lambda r: requests.append(r))
215+
await page.evaluate(
216+
"""() => fetch('./post', { method: 'POST', body: JSON.stringify({ foo: 'bar' }) })"""
217+
)
218+
assert len(requests) == 1
219+
assert requests[0].postDataJSON == {"foo": "bar"}
220+
221+
222+
async def test_should_parse_the_data_if_content_type_is_form_urlencoded(page, server):
223+
await page.goto(server.EMPTY_PAGE)
224+
server.set_route("/post", lambda req: req.finish())
225+
requests = []
226+
page.on("request", lambda r: requests.append(r))
227+
await page.setContent(
228+
"""<form method='POST' action='/post'><input type='text' name='foo' value='bar'><input type='number' name='baz' value='123'><input type='submit'></form>"""
229+
)
230+
await page.click("input[type=submit]")
231+
assert len(requests) == 1
232+
assert requests[0].postDataJSON == {"foo": "bar", "baz": "123"}
233+
234+
235+
async def test_should_be_undefined_when_there_is_no_post_data(page, server):
236+
response = await page.goto(server.EMPTY_PAGE)
237+
assert response.request.postDataJSON is None
238+
239+
210240
async def test_response_text_should_work(page, server):
211241
response = await page.goto(server.PREFIX + "/simple.json")
212242
assert await response.text() == '{"foo": "bar"}\n'

0 commit comments

Comments
 (0)