async def test_should_propagate_extra_http_headers_with_redirects( playwright: Playwright, server: Server): server.set_redirect("/a/redirect1", "/b/c/redirect2") server.set_redirect("/b/c/redirect2", "/simple.json") request = await playwright.request.new_context( extra_http_headers={"My-Secret": "Value"}) [req1, req2, req3, _] = await asyncio.gather( server.wait_for_request("/a/redirect1"), server.wait_for_request("/b/c/redirect2"), server.wait_for_request("/simple.json"), request.get(f"{server.PREFIX}/a/redirect1"), ) assert req1.getHeader("my-secret") == "Value" assert req2.getHeader("my-secret") == "Value" assert req3.getHeader("my-secret") == "Value"
async def test_should_override_request_url(page: Page, context: BrowserContext, server: Server) -> None: url = [] await context.route( "**/global-var.html", lambda route: ( url.append(route.request.url), asyncio.create_task(route.continue_()), ), ) await context.route( "**/foo", lambda route: asyncio.create_task( route.fallback(url=server.PREFIX + "/global-var.html")), ) [server_request, response, _] = await asyncio.gather( server.wait_for_request("/global-var.html"), page.wait_for_event("response"), page.goto(server.PREFIX + "/foo"), ) assert url == [server.PREFIX + "/global-var.html"] assert response.url == server.PREFIX + "/foo" assert await page.evaluate("() => window['globalVar']") == 123 assert server_request.uri == b"/global-var.html" assert server_request.method == b"GET"
async def test_should_support_multipart_form_data(context: BrowserContext, server: Server): file = { "name": "f.js", "mimeType": "text/javascript", "buffer": b"var x = 10;\r\n;console.log(x);", } [request, response] = await asyncio.gather( server.wait_for_request("/empty.html"), context.request.post( server.PREFIX + "/empty.html", multipart={ "firstName": "John", "lastName": "Doe", "file": file, }, ), ) assert request.method == b"POST" assert request.getHeader("Content-Type").startswith( "multipart/form-data; ") assert request.getHeader("Content-Length") == str(len(request.post_body)) assert request.args[b"firstName"] == [b"John"] assert request.args[b"lastName"] == [b"Doe"] assert request.args[b"file"][0] == file["buffer"]
async def test_should_amend_binary_post_data(page: Page, context: BrowserContext, server: Server): await page.goto(server.EMPTY_PAGE) post_data_buffer = [] await context.route( "**/*", lambda route: ( post_data_buffer.append(route.request.post_data), asyncio.create_task(route.continue_()), ), ) await context.route( "**/*", lambda route: asyncio.create_task( route.fallback(post_data=b"\x00\x01\x02\x03\x04")), ) [server_request, result] = await asyncio.gather( server.wait_for_request("/sleep.zzz"), page.evaluate( "fetch('/sleep.zzz', { method: 'POST', body: 'birdy' })"), ) # FIXME: should this be bytes? assert post_data_buffer == ["\x00\x01\x02\x03\x04"] assert server_request.method == b"POST" assert server_request.post_body == b"\x00\x01\x02\x03\x04"
async def test_should_use_playwright_as_a_user_agent(playwright: Playwright, server: Server): request = await playwright.request.new_context() [server_req, _] = await asyncio.gather( server.wait_for_request("/empty.html"), request.get(server.EMPTY_PAGE), ) assert str(server_req.getHeader("User-Agent")).startswith("Playwright/") await request.dispose()
async def test_should_add_default_headers(context: BrowserContext, page: Page, server: Server): [request, response] = await asyncio.gather( server.wait_for_request("/empty.html"), context.request.get(server.EMPTY_PAGE), ) assert request.getHeader("Accept") == "*/*" assert request.getHeader("Accept-Encoding") == "gzip,deflate,br" assert request.getHeader("User-Agent") == await page.evaluate( "() => navigator.userAgent")
async def test_should_contain_default_user_agent(playwright: Playwright, server: Server): request = await playwright.request.new_context() [request, _] = await asyncio.gather( server.wait_for_request("/empty.html"), request.get(server.EMPTY_PAGE), ) user_agent = request.getHeader("user-agent") assert "python" in user_agent assert f"{sys.version_info.major}.{sys.version_info.minor}" in user_agent
async def test_should_support_query_params(context: BrowserContext, server: Server, method: str): expected_params = {"p1": "v1", "парам2": "знач2"} [server_req, _] = await asyncio.gather( server.wait_for_request("/empty.html"), getattr(context.request, method)(server.EMPTY_PAGE + "?p1=foo", params=expected_params), ) assert server_req.args["p1".encode()][0].decode() == "v1" assert len(server_req.args["p1".encode()]) == 1 assert server_req.args["парам2".encode()][0].decode() == "знач2"
async def test_should_support_global_user_agent_option(playwright: Playwright, server: Server): request = await playwright.request.new_context(user_agent="My Agent") response = await request.get(server.PREFIX + "/empty.html") [request, _] = await asyncio.gather( server.wait_for_request("/empty.html"), request.get(server.EMPTY_PAGE), ) assert response.ok is True assert response.url == server.EMPTY_PAGE assert request.getHeader("user-agent") == "My Agent"
async def test_should_upload_large_file( browser_type: BrowserType, launch_server: Callable[[], RemoteServer], playwright: Playwright, server: Server, tmp_path, ): remote = launch_server() browser = await browser_type.connect(remote.ws_endpoint) context = await browser.new_context() page = await context.new_page() await page.goto(server.PREFIX + "/input/fileupload.html") large_file_path = tmp_path / "200MB.zip" data = b"A" * 1024 with large_file_path.open("wb") as f: for i in range(0, 200 * 1024 * 1024, len(data)): f.write(data) input = page.locator('input[type="file"]') events = await input.evaluate_handle( """ e => { const events = []; e.addEventListener('input', () => events.push('input')); e.addEventListener('change', () => events.push('change')); return events; } """ ) await input.set_input_files(large_file_path) assert await input.evaluate("e => e.files[0].name") == "200MB.zip" assert await events.evaluate("e => e") == ["input", "change"] [request, _] = await asyncio.gather( server.wait_for_request("/upload"), page.click("input[type=submit]"), ) contents = request.args[b"file1"][0] assert len(contents) == 200 * 1024 * 1024 assert contents[:1024] == data # flake8: noqa: E203 assert contents[len(contents) - 1024 :] == data match = re.search( rb'^.*Content-Disposition: form-data; name="(?P<name>.*)"; filename="(?P<filename>.*)".*$', request.post_body, re.MULTILINE, ) assert match.group("name") == b"file1" assert match.group("filename") == b"200MB.zip"
async def test_should_json_stringify_body_when_content_type_is_application_json( playwright: Playwright, server: Server, serialization: Any): request = await playwright.request.new_context() [req, _] = await asyncio.gather( server.wait_for_request("/empty.html"), request.post( server.EMPTY_PAGE, headers={"content-type": "application/json"}, data=serialization, ), ) body = req.post_body assert body.decode() == json.dumps(serialization, separators=(",", ":")) await request.dispose()
async def test_should_delete_header_with_undefined_value( page: Page, context: BrowserContext, server: Server) -> None: await page.goto(server.EMPTY_PAGE) server.set_route( "/something", lambda r: ( r.setHeader("Acces-Control-Allow-Origin", "*"), r.write(b"done"), r.finish(), ), ) intercepted_request = [] async def capture_and_continue(route: Route, request: Request): intercepted_request.append(request) await route.continue_() await context.route("**/*", capture_and_continue) async def delete_foo_header(route: Route, request: Request): headers = await request.all_headers() await route.fallback(headers={**headers, "foo": None}) await context.route(server.PREFIX + "/something", delete_foo_header) [server_req, text] = await asyncio.gather( server.wait_for_request("/something"), page.evaluate( """ async url => { const data = await fetch(url, { headers: { foo: 'a', bar: 'b', } }); return data.text(); } """, server.PREFIX + "/something", ), ) assert text == "done" assert not intercepted_request[0].headers.get("foo") assert intercepted_request[0].headers.get("bar") == "b" assert not server_req.getHeader("foo") assert server_req.getHeader("bar") == "b"
async def test_should_support_fulfill_after_intercept( page: Page, context: BrowserContext, server: Server, assetdir: Path ): request_future = asyncio.create_task(server.wait_for_request("/title.html")) async def handle_route(route: Route): response = await page.request.fetch(route.request) await route.fulfill(response=response) await context.route("**", handle_route) response = await page.goto(server.PREFIX + "/title.html") request = await request_future assert request.uri.decode() == "/title.html" original = (assetdir / "title.html").read_text() assert await response.text() == original
async def test_should_not_add_context_cookie_if_cookie_header_passed_as_parameter( context: BrowserContext, server: Server): await context.add_cookies([{ "name": "username", "value": "John Doe", "url": server.EMPTY_PAGE, "expires": -1, "httpOnly": False, "secure": False, "sameSite": "Lax", }]) [server_req, _] = await asyncio.gather( server.wait_for_request("/empty.html"), context.request.get(server.EMPTY_PAGE, headers={"Cookie": "foo=bar"}), ) assert server_req.getHeader("Cookie") == "foo=bar"
async def test_should_add_session_cookies_to_request(context: BrowserContext, server: Server): await context.add_cookies([{ "name": "username", "value": "John Doe", "url": server.EMPTY_PAGE, "expires": -1, "httpOnly": False, "secure": False, "sameSite": "Lax", }]) [server_req, response] = await asyncio.gather( server.wait_for_request("/empty.html"), context.request.get(server.EMPTY_PAGE), ) assert server_req.getHeader("Cookie") == "username=John Doe"
async def test_should_accept_already_serialized_data_as_bytes_when_content_type_is_application_json( playwright: Playwright, server: Server): request = await playwright.request.new_context() stringified_value = json.dumps({ "foo": "bar" }, separators=(",", ":")).encode() [req, _] = await asyncio.gather( server.wait_for_request("/empty.html"), request.post( server.EMPTY_PAGE, headers={"content-type": "application/json"}, data=stringified_value, ), ) body = req.post_body assert body == stringified_value await request.dispose()
async def test_should_amend_post_data(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) post_data = [] await page.route( "**/*", lambda route: ( post_data.append(route.request.post_data), asyncio.create_task(route.continue_()), ), ) await page.route( "**/*", lambda route: asyncio.create_task(route.fallback(post_data="doggo"))) [server_request, _] = await asyncio.gather( server.wait_for_request("/sleep.zzz"), page.evaluate( "() => fetch('/sleep.zzz', { method: 'POST', body: 'birdy' })"), ) assert post_data == ["doggo"] assert server_request.post_body == b"doggo"
async def test_should_amend_method(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) method = [] await page.route( "**/*", lambda route: ( method.append(route.request.method), asyncio.create_task(route.continue_()), ), ) await page.route( "**/*", lambda route: asyncio.create_task(route.fallback(method="POST"))) [request, _] = await asyncio.gather( server.wait_for_request("/sleep.zzz"), page.evaluate("() => fetch('/sleep.zzz')"), ) assert method == ["POST"] assert request.method == b"POST"
async def test_should_support_application_x_www_form_urlencoded( context: BrowserContext, server: Server): [request, response] = await asyncio.gather( server.wait_for_request("/empty.html"), context.request.post( server.PREFIX + "/empty.html", form={ "firstName": "John", "lastName": "Doe", "file": "f.js", }, ), ) assert request.method == b"POST" assert request.getHeader( "Content-Type") == "application/x-www-form-urlencoded" body = request.post_body.decode() assert request.getHeader("Content-Length") == str(len(body)) params = parse_qs(request.post_body) assert params[b"firstName"] == [b"John"] assert params[b"lastName"] == [b"Doe"] assert params[b"file"] == [b"f.js"]