async def test_should_not_allow_getting_the_path( browser_type: BrowserType, launch_server, server: Server ): def handle_download(request): request.setHeader("Content-Type", "application/octet-stream") request.setHeader("Content-Disposition", "attachment") request.write(b"Hello world") request.finish() server.set_route("/download", handle_download) remote_server = launch_server() browser = await browser_type.connect(remote_server.ws_endpoint) page = await browser.new_page(accept_downloads=True) await page.set_content(f'<a href="{server.PREFIX}/download">download</a>') async with page.expect_download() as download_info: await page.click("a") download = await download_info.value with pytest.raises(Error) as exc: await download.path() assert ( exc.value.message == "Path is not available when using browser_type.connect(). Use save_as() to save a local copy." ) remote_server.kill()
def test_sync_network_events(page: Page, server: Server) -> None: server.set_route( "/hello-world", lambda request: ( request.setHeader("Content-Type", "text/plain"), request.write(b"Hello world"), request.finish(), ), ) page.goto(server.EMPTY_PAGE) messages = [] page.on( "request", lambda request: messages.append(f">>{request.method}{request.url}")) page.on( "response", lambda response: messages.append(f"<<{response.status}{response.url}"), ) response = page.evaluate( """async ()=> (await fetch("/hello-world")).text()""") assert response == "Hello world" assert messages == [ f">>GET{server.PREFIX}/hello-world", f"<<200{server.PREFIX}/hello-world", ]
async def test_should_round_trip_har_with_post_data(browser: Browser, server: Server, assetdir: Path, tmpdir: Path) -> None: server.set_route("/echo", lambda req: (req.write(req.post_body), req.finish())) fetch_function = """ async (body) => { const response = await fetch('/echo', { method: 'POST', body }); return await response.text(); }; """ har_path = tmpdir / "har.zip" context_1 = await browser.new_context(record_har_mode="minimal", record_har_path=har_path) page_1 = await context_1.new_page() await page_1.goto(server.EMPTY_PAGE) assert await page_1.evaluate(fetch_function, "1") == "1" assert await page_1.evaluate(fetch_function, "2") == "2" assert await page_1.evaluate(fetch_function, "3") == "3" await context_1.close() context_2 = await browser.new_context() await context_2.route_from_har(har=har_path, not_found="abort") page_2 = await context_2.new_page() await page_2.goto(server.EMPTY_PAGE) assert await page_2.evaluate(fetch_function, "1") == "1" assert await page_2.evaluate(fetch_function, "2") == "2" assert await page_2.evaluate(fetch_function, "3") == "3" with pytest.raises(Exception): await page_2.evaluate(fetch_function, "4")
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_report_request_headers_array(page: Page, server: Server, is_win: bool, browser_name: str) -> None: if is_win and browser_name == "webkit": pytest.skip( "libcurl does not support non-set-cookie multivalue headers") expected_headers = [] def handle(request: http.Request): for name, values in request.requestHeaders.getAllRawHeaders(): for value in values: expected_headers.append({ "name": name.decode().lower(), "value": value.decode() }) request.finish() server.set_route("/headers", handle) await page.goto(server.EMPTY_PAGE) async with page.expect_request("*/**") as request_info: await page.evaluate("""() => fetch('/headers', { headers: [ ['header-a', 'value-a'], ['header-b', 'value-b'], ['header-a', 'value-a-1'], ['header-a', 'value-a-2'], ] }) """) request = await request_info.value sorted_pw_request_headers = sorted( list( map( lambda header: { "name": header["name"].lower(), "value": header["value"], }, await request.headers_array(), )), key=lambda header: header["name"], ) sorted_expected_headers = sorted(expected_headers, key=lambda header: header["name"]) assert sorted_pw_request_headers == sorted_expected_headers assert await request.header_value("Header-A" ) == "value-a, value-a-1, value-a-2" assert await request.header_value("not-there") is None
async def test_should_fulfill_with_any_response(page: Page, server: Server): def server_handler(request: http.Request): request.setHeader("foo", "bar") request.write("Woo-hoo".encode()) request.finish() server.set_route("/sample", server_handler) sample_response = await page.request.get(server.PREFIX + "/sample") await page.route( "**/*", lambda route: route.fulfill( response=sample_response, status=201, content_type="text/plain"), ) response = await page.goto(server.EMPTY_PAGE) assert response.status == 201 assert await response.text() == "Woo-hoo" assert response.headers["foo"] == "bar"
async def test_should_report_response_headers_array(page: Page, server: Server, is_win, browser_name) -> None: if is_win and browser_name == "webkit": pytest.skip( "libcurl does not support non-set-cookie multivalue headers") expected_headers = { "header-a": ["value-a", "value-a-1", "value-a-2"], "header-b": ["value-b"], "set-cookie": ["a=b", "c=d"], } def handle(request: http.Request): for key in expected_headers: for value in expected_headers[key]: request.responseHeaders.addRawHeader(key, value) request.finish() server.set_route("/headers", handle) await page.goto(server.EMPTY_PAGE) async with page.expect_response("*/**") as response_info: await page.evaluate("""() => fetch('/headers') """) response = await response_info.value actual_headers = {} for header in await response.headers_array(): name = header["name"].lower() value = header["value"] if not actual_headers.get(name): actual_headers[name] = [] actual_headers[name].append(value) for key in ["Keep-Alive", "Connection", "Date", "Transfer-Encoding"]: if key in actual_headers: actual_headers.pop(key) if key.lower() in actual_headers: actual_headers.pop(key.lower()) assert actual_headers == expected_headers assert await response.header_value("not-there") is None assert await response.header_value("set-cookie") == "a=b\nc=d" assert await response.header_value("header-a" ) == "value-a, value-a-1, value-a-2" assert await response.header_values("set-cookie") == ["a=b", "c=d"]
async def test_should_override_with_defaults_when_intercepted_response_not_provided( page: Page, server: Server, browser_name: str): def server_handler(request: http.Request): request.setHeader("foo", "bar") request.write("my content".encode()) request.finish() server.set_route("/empty.html", server_handler) async def handle(route: Route): await page.request.fetch(route.request) await route.fulfill(status=201) await page.route("**/*", handle) response = await page.goto(server.EMPTY_PAGE) assert response.status == 201 assert await response.text() == "" if browser_name == "webkit": assert response.headers == {"content-type": "text/plain"} else: assert response.headers == {}
async def test_frame_wait_for_nav_should_fail_when_frame_detaches(page, server: Server): await page.goto(server.PREFIX + "/frames/one-frame.html") frame = page.frames[1] server.set_route("/empty.html", lambda _: None) with pytest.raises(Error) as exc_info: async with frame.expect_navigation(): async def after_it(): await server.wait_for_request("/empty.html") await page.eval_on_selector( "iframe", "frame => setTimeout(() => frame.remove(), 0)" ) await asyncio.gather( page.eval_on_selector( "iframe", "frame => frame.contentWindow.location.href = '/empty.html'", ), after_it(), ) assert "frame was detached" in exc_info.value.message
def test_sync_download(browser: Browser, server: Server) -> None: server.set_route( "/downloadWithFilename", lambda request: ( request.setHeader("Content-Type", "application/octet-stream"), request.setHeader("Content-Disposition", "attachment; filename=file.txt"), request.write(b"Hello world"), request.finish(), ), ) page = browser.new_page(accept_downloads=True) page.set_content(f'<a href="{server.PREFIX}/downloadWithFilename">download</a>') with page.expect_event("download") as download: page.click("a") assert download.value assert download.value.suggested_filename == "file.txt" path = download.value.path() assert os.path.isfile(path) with open(path, "r") as fd: assert fd.read() == "Hello world" page.close()
async def test_should_disambiguate_by_header(browser: Browser, server: Server, assetdir: Path, tmpdir: Path) -> None: server.set_route( "/echo", lambda req: (req.write(req.getHeader("baz").encode()), req.finish())) fetch_function = """ async (bazValue) => { const response = await fetch('/echo', { method: 'POST', body: '', headers: { foo: 'foo-value', bar: 'bar-value', baz: bazValue, } }); return await response.text(); }; """ har_path = tmpdir / "har.zip" context_1 = await browser.new_context(record_har_mode="minimal", record_har_path=har_path) page_1 = await context_1.new_page() await page_1.goto(server.EMPTY_PAGE) assert await page_1.evaluate(fetch_function, "baz1") == "baz1" assert await page_1.evaluate(fetch_function, "baz2") == "baz2" assert await page_1.evaluate(fetch_function, "baz3") == "baz3" await context_1.close() context_2 = await browser.new_context() await context_2.route_from_har(har=har_path) page_2 = await context_2.new_page() await page_2.goto(server.EMPTY_PAGE) assert await page_2.evaluate(fetch_function, "baz1") == "baz1" assert await page_2.evaluate(fetch_function, "baz2") == "baz2" assert await page_2.evaluate(fetch_function, "baz3") == "baz3" assert await page_2.evaluate(fetch_function, "baz4") == "baz1"
async def test_should_support_global_timeout_option(playwright: Playwright, server: Server): request = await playwright.request.new_context(timeout=1) server.set_route("/empty.html", lambda req: None) with pytest.raises(Error, match="Request timed out after 1ms"): await request.get(server.EMPTY_PAGE)
def test_should_throw_on_network_error(context: BrowserContext, server: Server) -> None: server.set_route("/test", lambda request: request.transport.loseConnection()) with pytest.raises(Error, match="socket hang up"): context.request.fetch(server.PREFIX + "/test")