diff --git a/playwright/_impl/_network.py b/playwright/_impl/_network.py index 132c67a49..bd8aa4221 100644 --- a/playwright/_impl/_network.py +++ b/playwright/_impl/_network.py @@ -16,6 +16,7 @@ import base64 import inspect import json +import json as json_utils import mimetypes import sys from collections import defaultdict @@ -288,6 +289,12 @@ async def fulfill( ) -> None: self._check_not_handled() params = locals_to_params(locals()) + + if json is not None: + if body is not None: + raise Error("Can specify either body or json parameters") + body = json_utils.dumps(json) + if response: del params["response"] params["status"] = ( @@ -298,8 +305,6 @@ async def fulfill( ) from playwright._impl._fetch import APIResponse - if json is not None: - body = json.dumps(json) if body is None and path is None and isinstance(response, APIResponse): if response._request._connection is self._connection: params["fetchResponseUid"] = response._fetch_uid diff --git a/tests/async/test_request_fulfill.py b/tests/async/test_request_fulfill.py index e619a37f9..b48ae8047 100644 --- a/tests/async/test_request_fulfill.py +++ b/tests/async/test_request_fulfill.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json + from playwright.async_api import Page, Route from tests.server import Server @@ -25,3 +27,52 @@ async def handle(route: Route): response = await page.goto(server.PREFIX + "/title.html") assert response.status == 200 assert await page.title() == "Woof-Woof" + + +async def test_should_fulfill_json(page: Page, server: Server) -> None: + async def handle(route: Route) -> None: + await route.fulfill(status=201, headers={"foo": "bar"}, json={"bar": "baz"}) + + await page.route("**/*", handle) + + response = await page.goto(server.EMPTY_PAGE) + assert response + assert response.status == 201 + assert response.headers["content-type"] == "application/json" + assert json.loads(await page.evaluate("document.body.textContent")) == { + "bar": "baz" + } + + +async def test_should_fulfill_json_overriding_existing_response( + page: Page, server: Server +) -> None: + server.set_route( + "/tags", + lambda request: ( + request.setHeader("foo", "bar"), + request.write('{"tags": ["a", "b"]}'.encode()), + request.finish(), + ), + ) + + original = {} + + async def handle(route: Route) -> None: + response = await route.fetch() + json = await response.json() + original["tags"] = json["tags"] + json["tags"] = ["c"] + await route.fulfill(response=response, json=json) + + await page.route("**/*", handle) + + response = await page.goto(server.PREFIX + "/tags") + assert response + assert response.status == 200 + assert response.headers["content-type"] == "application/json" + assert response.headers["foo"] == "bar" + assert original["tags"] == ["a", "b"] + assert json.loads(await page.evaluate("document.body.textContent")) == { + "tags": ["c"] + } diff --git a/tests/sync/test_request_fulfill.py b/tests/sync/test_request_fulfill.py index f7b44316d..d51737389 100644 --- a/tests/sync/test_request_fulfill.py +++ b/tests/sync/test_request_fulfill.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import json + from playwright.sync_api import Page, Route from tests.server import Server @@ -26,3 +28,48 @@ def handle(route: Route) -> None: assert response assert response.status == 200 assert page.title() == "Woof-Woof" + + +def test_should_fulfill_json(page: Page, server: Server) -> None: + def handle(route: Route) -> None: + route.fulfill(status=201, headers={"foo": "bar"}, json={"bar": "baz"}) + + page.route("**/*", handle) + + response = page.goto(server.EMPTY_PAGE) + assert response + assert response.status == 201 + assert response.headers["content-type"] == "application/json" + assert json.loads(page.evaluate("document.body.textContent")) == {"bar": "baz"} + + +def test_should_fulfill_json_overriding_existing_response( + page: Page, server: Server +) -> None: + server.set_route( + "/tags", + lambda request: ( + request.setHeader("foo", "bar"), + request.write('{"tags": ["a", "b"]}'.encode()), + request.finish(), + ), + ) + + original = {} + + def handle(route: Route) -> None: + response = route.fetch() + json = response.json() + original["tags"] = json["tags"] + json["tags"] = ["c"] + route.fulfill(response=response, json=json) + + page.route("**/*", handle) + + response = page.goto(server.PREFIX + "/tags") + assert response + assert response.status == 200 + assert response.headers["content-type"] == "application/json" + assert response.headers["foo"] == "bar" + assert original["tags"] == ["a", "b"] + assert json.loads(page.evaluate("document.body.textContent")) == {"tags": ["c"]}