async def test_locators_has_does_not_encode_unicode(page: Page, server: Server): await page.goto(server.EMPTY_PAGE) locators = [ page.locator("button", has_text="Драматург"), page.locator("button", has_text=re.compile("Драматург")), page.locator("button", has=page.locator("text=Драматург")), ] for locator in locators: with pytest.raises(Error) as exc_info: await locator.click(timeout=1_000) assert "Драматург" in exc_info.value.message
async def test_page_events_request_should_accept_method(page: Page, server): class Log: def __init__(self): self.requests = [] def handle(self, request): self.requests.append(request) log = Log() page.on("request", log.handle) await page.goto(server.EMPTY_PAGE) assert len(log.requests) == 1
async def test_locators_is_editable_should_work(page: Page): await page.set_content( """ <input id=input1 disabled><textarea></textarea><input id=input2> """ ) input1 = page.locator("#input1") assert await input1.is_editable() is False input2 = page.locator("#input2") assert await input2.is_editable() is True
async def test_page_events_request_should_report_requests_and_responses_handled_by_service_worker( page: Page, server): await page.goto(server.PREFIX + "/serviceworkers/fetchdummy/sw.html") await page.evaluate("() => window.activationPromise") [request, sw_response ] = await asyncio.gather(page.waitForEvent("request"), page.evaluate('() => fetchDummy("foo")')) assert sw_response == "responseFromServiceWorker:foo" assert request.url == server.PREFIX + "/serviceworkers/fetchdummy/foo" response = await request.response() assert response.url == server.PREFIX + "/serviceworkers/fetchdummy/foo" assert await response.text() == "responseFromServiceWorker:foo"
async def test_should_emit_event(page: Page): await page.set_content("<input type=file>") fc_done: asyncio.Future = asyncio.Future() page.once("filechooser", lambda file_chooser: fc_done.set_result(file_chooser)) await page.click("input") file_chooser = await fc_done assert file_chooser assert ( repr(file_chooser) == f"<FileChooser page={file_chooser.page} element={file_chooser.element}>" )
async def test_locator_frame_locator_should_not_throw_on_first_last_nth( page: Page, server: Server) -> None: await route_ambiguous(page) await page.goto(server.EMPTY_PAGE) button1 = page.locator("body").frame_locator("iframe").first.locator( "button") assert await button1.text_content() == "Hello from iframe-1.html" button2 = page.locator("body").frame_locator("iframe").nth(1).locator( "button") assert await button2.text_content() == "Hello from iframe-2.html" button3 = page.locator("body").frame_locator("iframe").last.locator( "button") assert await button3.text_content() == "Hello from iframe-3.html"
async def test_assertions_locator_to_have_text(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("<div id=foobar>kek</div>") await expect(page.locator("div#foobar")).to_have_text("kek") await expect(page.locator("div#foobar")).not_to_have_text("top", timeout=100) await page.set_content("<div>Text \n1</div><div>Text 2a</div>") # Should only normalize whitespace in the first item. await expect(page.locator("div") ).to_have_text(["Text 1", re.compile(r"Text \d+a")])
async def test_should_accept_single_file(page: Page, server): await page.setContent('<input type=file oninput="javascript:console.timeStamp()">') file_chooser = ( await asyncio.gather(page.waitForEvent("filechooser"), page.click("input"),) )[0] assert file_chooser.page == page assert file_chooser.element await file_chooser.setFiles(FILE_TO_UPLOAD) assert await page.evalOnSelector("input", "input => input.files.length") == 1 assert ( await page.evalOnSelector("input", "input => input.files[0].name") == "file-to-upload.txt" )
async def test_should_fire(page: Page, server): result = [] async def on_dialog(dialog: Dialog): result.append(True) assert dialog.type == "alert" assert dialog.default_value == "" assert dialog.message == "yo" await dialog.accept() page.on("dialog", on_dialog) await page.evaluate("alert('yo')") assert result
async def test_should_allow_accepting_prompts(page: Page, server): result = [] async def on_dialog(dialog: Dialog): result.append(True) assert dialog.type == "prompt" assert dialog.default_value == "yes." assert dialog.message == "question?" await dialog.accept("answer!") page.on("dialog", on_dialog) assert await page.evaluate("prompt('question?', 'yes.')") == "answer!" assert result
async def test_assertions_locator_to_have_css(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content( "<div class=foobar style='color: rgb(234, 74, 90);'>kek</div>" ) await expect(page.locator("div.foobar")).to_have_css("color", "rgb(234, 74, 90)") await expect(page.locator("div.foobar")).not_to_have_css( "color", "rgb(42, 42, 42)", timeout=100 ) with pytest.raises(AssertionError): await expect(page.locator("div.foobar")).to_have_css( "color", "rgb(42, 42, 42)", timeout=100 )
async def test_assertions_locator_to_have_attribute(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("<div id=foobar>kek</div>") await expect(page.locator("div#foobar")).to_have_attribute("id", "foobar") await expect(page.locator("div#foobar") ).to_have_attribute("id", re.compile("foobar")) await expect(page.locator("div#foobar")).not_to_have_attribute("id", "kek", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div#foobar")).to_have_attribute("id", "koko", timeout=100)
def _capture_logs_from_browser_tabs(page: Page) -> None: """Capture browser tab logs.""" def _app_info(message: str) -> None: """Log message at info level.""" if page.plugin and page.plugin.workspace: workspace_logger = page.plugin.workspace.get_logger() if workspace_logger: workspace_logger.info(message) return logger.info(message) def _app_error(message: str) -> None: """Log message at error level.""" if page.plugin and page.plugin.workspace: workspace_logger = page.plugin.workspace.get_logger() if workspace_logger: workspace_logger.error(message) return logger.error(message) page.on( "targetcreated", lambda target: _app_info(str(target)), ) page.on("console", lambda target: _app_info(target.text)) page.on("error", lambda target: _app_error(target.text)) page.on("pageerror", lambda target: _app_error(str(target)))
async def test_should_report_downloads_with_acceptDownloads_false(page: Page, server): await page.setContent( f'<a href="{server.PREFIX}/downloadWithFilename">download</a>' ) download = (await asyncio.gather(page.waitForEvent("download"), page.click("a")))[0] assert download.url == f"{server.PREFIX}/downloadWithFilename" assert download.suggestedFilename == "file.txt" error: Optional[Error] = None try: await download.path() except Error as exc: error = exc assert "acceptDownloads" in await download.failure() assert error assert "acceptDownloads: true" in error.message
async def test_console_should_work(page: Page, server): messages: List[ConsoleMessage] = [] page.once("console", lambda m: messages.append(m)) await asyncio.gather( page.evaluate('() => console.log("hello", 5, {foo: "bar"})'), page.wait_for_event("console"), ) assert len(messages) == 1 message = messages[0] assert message.text == "hello 5 JSHandle@object" assert str(message) == "hello 5 JSHandle@object" assert message.type == "log" assert await message.args[0].json_value() == "hello" assert await message.args[1].json_value() == 5 assert await message.args[2].json_value() == {"foo": "bar"}
async def test_assertions_locator_to_have_class(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("<div class=foobar>kek</div>") await expect(page.locator("div.foobar")).to_have_class("foobar") await expect(page.locator("div.foobar")).to_have_class(["foobar"]) await expect(page.locator("div.foobar")).to_have_class(re.compile("foobar") ) await expect(page.locator("div.foobar") ).to_have_class([re.compile("foobar")]) await expect(page.locator("div.foobar")).not_to_have_class("kekstar", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div.foobar")).to_have_class("oh-no", timeout=100)
async def test_should_be_able_to_read_selected_file(page: Page): page.once("filechooser", lambda file_chooser: file_chooser.set_files(FILE_TO_UPLOAD)) await page.set_content("<input type=file>") content = await page.eval_on_selector( "input", """async picker => { picker.click(); await new Promise(x => picker.oninput = x); const reader = new FileReader(); const promise = new Promise(fulfill => reader.onload = fulfill); reader.readAsText(picker.files[0]); return promise.then(() => reader.result); }""", ) assert content == "contents of the file\n"
async def test_locators_evaluate_all_should_work(page: Page): await page.set_content( """<html><body><div class="tweet"><div class="like">100</div><div class="like">10</div></div></body></html>""" ) tweet = page.locator(".tweet .like") content = await tweet.evaluate_all("nodes => nodes.map(n => n.innerText)") assert content == ["100", "10"]
async def test_locators_evaluate_all_should_work_with_missing_selector( page: Page): await page.set_content( """<div class="a">not-a-child-div</div><div id="myId"></div""") tweet = page.locator("#myId .a") nodes_length = await tweet.evaluate_all("nodes => nodes.length") assert nodes_length == 0
async def test_should_give_access_to_the_intercepted_response( page: Page, server: Server): await page.goto(server.EMPTY_PAGE) route_task = asyncio.Future() await page.route("**/title.html", lambda route: route_task.set_result(route)) eval_task = asyncio.create_task( page.evaluate("url => fetch(url)", server.PREFIX + "/title.html")) route = await route_task response = await page.request.fetch(route.request) assert response.status == 200 assert response.status_text == "OK" assert response.ok is True assert response.url.endswith("/title.html") is True assert response.headers["content-type"] == "text/html; charset=utf-8" assert list( filter( lambda header: header["name"].lower() == "content-type", response.headers_array, )) == [{ "name": "Content-Type", "value": "text/html; charset=utf-8" }] await asyncio.gather( route.fulfill(response=response), eval_task, )
async def test_should_work_when_file_input_is_attached_to_DOM( page: Page, server): await page.set_content("<input type=file>") async with page.expect_event("filechooser") as fc_info: await page.click("input") file_chooser = await fc_info.value assert file_chooser
async def test_locators_click_should_work_with_node_removed( page: Page, server: Server): await page.goto(server.PREFIX + "/input/button.html") await page.evaluate("delete window['Node']") button = page.locator("button") await button.click() assert await page.evaluate("window['result']") == "Clicked"
async def test_assertions_locator_to_contain_text(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("<div id=foobar>kek</div>") await expect(page.locator("div#foobar")).to_contain_text("kek") await expect(page.locator("div#foobar")).not_to_contain_text("bar", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div#foobar")).to_contain_text("bar", timeout=100) await page.set_content( "<div>Text \n1</div><div>Text2</div><div>Text3</div>") await expect(page.locator("div") ).to_contain_text(["ext 1", re.compile("ext3")])
async def test_locators_set_checked(page: Page): await page.set_content("`<input id='checkbox' type='checkbox'></input>`") locator = page.locator("input") await locator.set_checked(True) assert await page.evaluate("checkbox.checked") await locator.set_checked(False) assert await page.evaluate("checkbox.checked") is False
async def test_drag_to(page: Page, server: Server) -> None: await page.goto(server.PREFIX + "/drag-n-drop.html") await page.locator("#source").drag_to(page.locator("#target")) assert (await page.eval_on_selector( "#target", "target => target.contains(document.querySelector('#source'))") is True)
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_request_headers_should_get_the_same_headers_as_the_server_cors( page: Page, server, is_webkit, is_win ): await page.goto(server.PREFIX + "/empty.html") server_request_headers_future: Future[Dict[str, str]] = asyncio.Future() def handle_something(request): normalized_headers = { key.decode().lower(): value[0].decode() for key, value in request.requestHeaders.getAllRawHeaders() } server_request_headers_future.set_result(normalized_headers) request.setHeader("Access-Control-Allow-Origin", "*") request.write(b"done") request.finish() server.set_route("/something", handle_something) requestPromise = asyncio.create_task(page.wait_for_event("request")) text = await page.evaluate( """async url => { const data = await fetch(url); return data.text(); }""", server.CROSS_PROCESS_PREFIX + "/something", ) request: Request = await requestPromise assert text == "done" server_headers = await server_request_headers_future if is_webkit and is_win: # Curl does not show accept-encoding and accept-language server_headers.pop("accept-encoding") server_headers.pop("accept-language") assert request.headers == server_headers
def test_baidu_search_with_network(page: Page, env: dict, fixtures): """ 获取请求/ 响应 """ import re page.on( "request", lambda request: print(">>", request.method, request.url) if not re.findall('.*/.[js|css|png]', request.url) else None) page.on( "response", lambda response: print("<<", response.status, response.url) if not re.findall('.*/.[js|css|png]', response.url) else None) baiduSearchPage = BaiduSearchPage(page) baiduSearchPage.open()
async def test_request_headers_should_get_the_same_headers_as_the_server_cors( page: Page, server, is_webkit, is_win): if is_webkit and is_win: pytest.xfail("Curl does not show accept-encoding and accept-language") await page.goto(server.PREFIX + "/empty.html") server_request_headers_future: Future[Dict[str, str]] = asyncio.Future() def handle_something(request): normalized_headers = { key.decode().lower(): value[0].decode() for key, value in request.requestHeaders.getAllRawHeaders() } server_request_headers_future.set_result(normalized_headers) request.setHeader("Access-Control-Allow-Origin", "*") request.write(b"done") request.finish() server.set_route("/something", handle_something) text = None async with page.expect_request("**/*") as request_info: text = await page.evaluate( """async url => { const data = await fetch(url); return data.text(); }""", server.CROSS_PROCESS_PREFIX + "/something", ) request = await request_info.value assert text == "done" server_headers = await server_request_headers_future assert await request.all_headers() == server_headers
def test_admin_login(page: Page): """ 登录后台 """ # Click [placeholder="请输入用户名"] page.click("[placeholder=\"请输入用户名\"]") # Fill [placeholder="请输入用户名"] page.fill("[placeholder=\"请输入用户名\"]", "admin") # Fill [placeholder="请输入登录密码"] page.fill("[placeholder=\"请输入登录密码\"]", "shopxo") # Click button:has-text("登录") page.click("button:has-text(\"登录\")") # Go to http://localhost/shopxo/admin.php?s=/index/index.html page.goto("http://localhost/shopxo/admin.php?s=/index/index.html") assert page.url == 'http://localhost/shopxo/admin.php?s=/index/index.html'