Best Python code snippet using playwright-python
test_click.py
Source:test_click.py
1# Copyright (c) Microsoft Corporation.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14import asyncio15import pytest16from playwright.async_api import Error, TimeoutError17async def give_it_a_chance_to_click(page):18 for _ in range(5):19 await page.evaluate(20 "() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"21 )22async def test_click_the_button(page, server):23 await page.goto(server.PREFIX + "/input/button.html")24 await page.click("button")25 assert await page.evaluate("result") == "Clicked"26async def test_click_svg(page, server):27 await page.set_content(28 """29 <svg height="100" width="100">30 <circle onclick="javascript:window.__CLICKED=42" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />31 </svg>32 """33 )34 await page.click("circle")35 assert await page.evaluate("window.__CLICKED") == 4236async def test_click_the_button_if_window_node_is_removed(page, server):37 await page.goto(server.PREFIX + "/input/button.html")38 await page.evaluate("() => delete window.Node")39 await page.click("button")40 assert await page.evaluate("() => result") == "Clicked"41async def test_click_on_a_span_with_an_inline_element_inside(page, server):42 await page.set_content(43 """44 <style>45 span::before {46 content: 'q'47 }48 </style>49 <span onclick='javascript:window.CLICKED=42'></span>50 """51 )52 await page.click("span")53 assert await page.evaluate("window.CLICKED") == 4254async def test_click_not_throw_when_page_closes(browser, server):55 context = await browser.new_context()56 page = await context.new_page()57 try:58 await asyncio.gather(59 page.close(),60 page.mouse.click(1, 2),61 )62 except Error:63 pass64 await context.close()65async def test_click_the_button_after_navigation(page, server):66 await page.goto(server.PREFIX + "/input/button.html")67 await page.click("button")68 await page.goto(server.PREFIX + "/input/button.html")69 await page.click("button")70 assert await page.evaluate("() => result") == "Clicked"71async def test_click_the_button_after_a_cross_origin_navigation_(page, server):72 await page.goto(server.PREFIX + "/input/button.html")73 await page.click("button")74 await page.goto(server.CROSS_PROCESS_PREFIX + "/input/button.html")75 await page.click("button")76 assert await page.evaluate("() => result") == "Clicked"77async def test_click_with_disabled_javascript(browser, server):78 context = await browser.new_context(java_script_enabled=False)79 page = await context.new_page()80 await page.goto(server.PREFIX + "/wrappedlink.html")81 async with page.expect_navigation():82 await page.click("a")83 assert page.url == server.PREFIX + "/wrappedlink.html#clicked"84 await context.close()85async def test_click_when_one_of_inline_box_children_is_outside_of_viewport(86 page, server87):88 await page.set_content(89 """90 <style>91 i {92 position: absolute93 top: -1000px94 }95 </style>96 <span onclick='javascript:window.CLICKED = 42;'><i>woof</i><b>doggo</b></span>97 """98 )99 await page.click("span")100 assert await page.evaluate("() => window.CLICKED") == 42101async def test_select_the_text_by_triple_clicking(page, server):102 await page.goto(server.PREFIX + "/input/textarea.html")103 text = "This is the text that we are going to try to select. Let's see how it goes."104 await page.fill("textarea", text)105 await page.click("textarea", click_count=3)106 assert (107 await page.evaluate(108 """() => {109 textarea = document.querySelector('textarea')110 return textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)111 }"""112 )113 == text114 )115async def test_click_offscreen_buttons(page, server):116 await page.goto(server.PREFIX + "/offscreenbuttons.html")117 messages = []118 page.on("console", lambda msg: messages.append(msg.text))119 for i in range(11):120 # We might've scrolled to click a button - reset to (0, 0).121 await page.evaluate("window.scrollTo(0, 0)")122 await page.click(f"#btn{i}")123 assert messages == [124 "button #0 clicked",125 "button #1 clicked",126 "button #2 clicked",127 "button #3 clicked",128 "button #4 clicked",129 "button #5 clicked",130 "button #6 clicked",131 "button #7 clicked",132 "button #8 clicked",133 "button #9 clicked",134 "button #10 clicked",135 ]136async def test_waitFor_visible_when_already_visible(page, server):137 await page.goto(server.PREFIX + "/input/button.html")138 await page.click("button")139 assert await page.evaluate("result") == "Clicked"140async def test_wait_with_force(page, server):141 error = None142 await page.goto(server.PREFIX + "/input/button.html")143 await page.eval_on_selector("button", "b => b.style.display = 'none'")144 try:145 await page.click("button", force=True)146 except Error as e:147 error = e148 assert "Element is not visible" in error.message149 assert await page.evaluate("result") == "Was not clicked"150async def test_wait_for_display_none_to_be_gone(page, server):151 done = list()152 await page.goto(server.PREFIX + "/input/button.html")153 await page.eval_on_selector("button", "b => b.style.display = 'none'")154 async def click():155 await page.click("button", timeout=0)156 done.append(True)157 clicked = asyncio.create_task(click())158 await give_it_a_chance_to_click(page)159 assert await page.evaluate("result") == "Was not clicked"160 assert done == []161 await page.eval_on_selector("button", "b => b.style.display = 'block'")162 await clicked163 assert done == [True]164 assert await page.evaluate("result") == "Clicked"165async def test_wait_for_visibility_hidden_to_be_gone(page, server):166 done = list()167 await page.goto(server.PREFIX + "/input/button.html")168 await page.eval_on_selector("button", "b => b.style.visibility = 'hidden'")169 async def click():170 await page.click("button", timeout=0)171 done.append(True)172 clicked = asyncio.create_task(click())173 await give_it_a_chance_to_click(page)174 assert await page.evaluate("result") == "Was not clicked"175 assert done == []176 await page.eval_on_selector("button", "b => b.style.visibility = 'visible'")177 await clicked178 assert done == [True]179 assert await page.evaluate("result") == "Clicked"180async def test_timeout_waiting_for_display_none_to_be_gone(page, server):181 await page.goto(server.PREFIX + "/input/button.html")182 await page.eval_on_selector("button", "b => b.style.display = 'none'")183 try:184 await page.click("button", timeout=5000)185 except Error as e:186 error = e187 assert "Timeout 5000ms exceeded" in error.message188 assert "waiting for element to be visible, enabled and not moving" in error.message189 assert "element is not visible - waiting" in error.message190async def test_timeout_waiting_for_visbility_hidden_to_be_gone(page, server):191 await page.goto(server.PREFIX + "/input/button.html")192 await page.eval_on_selector("button", "b => b.style.visibility = 'hidden'")193 try:194 await page.click("button", timeout=5000)195 except Error as e:196 error = e197 assert "Timeout 5000ms exceeded" in error.message198 assert "waiting for element to be visible, enabled and not moving" in error.message199 assert "element is not visible - waiting" in error.message200async def test_waitFor_visible_when_parent_is_hidden(page, server):201 done = list()202 await page.goto(server.PREFIX + "/input/button.html")203 await page.eval_on_selector("button", "b => b.parentElement.style.display = 'none'")204 async def click():205 await page.click("button", timeout=0)206 done.append(True)207 clicked = asyncio.create_task(click())208 await give_it_a_chance_to_click(page)209 assert done == []210 await page.eval_on_selector(211 "button", "b => b.parentElement.style.display = 'block'"212 )213 await clicked214 assert done == [True]215 assert await page.evaluate("result") == "Clicked"216async def test_click_wrapped_links(page, server):217 await page.goto(server.PREFIX + "/wrappedlink.html")218 await page.click("a")219 assert await page.evaluate("window.__clicked")220async def test_click_on_checkbox_input_and_toggle(page, server):221 await page.goto(server.PREFIX + "/input/checkbox.html")222 assert await page.evaluate("() => result.check") is None223 await page.click("input#agree")224 assert await page.evaluate("result.check")225 assert await page.evaluate("result.events") == [226 "mouseover",227 "mouseenter",228 "mousemove",229 "mousedown",230 "mouseup",231 "click",232 "input",233 "change",234 ]235 await page.click("input#agree")236 assert await page.evaluate("result.check") is False237async def test_click_on_checkbox_label_and_toggle(page, server):238 await page.goto(server.PREFIX + "/input/checkbox.html")239 assert await page.evaluate("result.check") is None240 await page.click('label[for="agree"]')241 assert await page.evaluate("result.check")242 assert await page.evaluate("result.events") == [243 "click",244 "input",245 "change",246 ]247 await page.click('label[for="agree"]')248 assert await page.evaluate("result.check") is False249async def test_not_hang_with_touch_enabled_viewports(playwright, server, browser):250 iphone_6 = playwright.devices["iPhone 6"]251 context = await browser.new_context(252 viewport=iphone_6["viewport"], has_touch=iphone_6["has_touch"]253 )254 page = await context.new_page()255 await page.mouse.down()256 await page.mouse.move(100, 10)257 await page.mouse.up()258 await context.close()259async def test_scroll_and_click_the_button(page, server):260 await page.goto(server.PREFIX + "/input/scrollable.html")261 await page.click("#button-5")262 assert (263 await page.evaluate("document.querySelector('#button-5').textContent")264 == "clicked"265 )266 await page.click("#button-80")267 assert (268 await page.evaluate("document.querySelector('#button-80').textContent")269 == "clicked"270 )271async def test_double_click_the_button(page, server):272 await page.goto(server.PREFIX + "/input/button.html")273 await page.evaluate(274 """() => {275 window.double = false;276 button = document.querySelector('button');277 button.addEventListener('dblclick', event => window.double = true);278 }"""279 )280 await page.dblclick("button")281 assert await page.evaluate("double")282 assert await page.evaluate("result") == "Clicked"283async def test_click_a_partially_obscured_button(page, server):284 await page.goto(server.PREFIX + "/input/button.html")285 await page.evaluate(286 """() => {287 button = document.querySelector('button');288 button.textContent = 'Some really long text that will go offscreen';289 button.style.position = 'absolute';290 button.style.left = '368px';291 }"""292 )293 await page.click("button")294 assert await page.evaluate("() => window.result") == "Clicked"295async def test_click_a_rotated_button(page, server):296 await page.goto(server.PREFIX + "/input/rotatedButton.html")297 await page.click("button")298 assert await page.evaluate("result") == "Clicked"299async def test_fire_contextmenu_event_on_right_click(page, server):300 await page.goto(server.PREFIX + "/input/scrollable.html")301 await page.click("#button-8", button="right")302 assert (303 await page.evaluate("document.querySelector('#button-8').textContent")304 == "context menu"305 )306async def test_click_links_which_cause_navigation(page, server):307 await page.set_content(f'<a href="{server.EMPTY_PAGE}">empty.html</a>')308 # This await should not hang.309 await page.click("a")310async def test_click_the_button_inside_an_iframe(page, server, utils):311 await page.goto(server.EMPTY_PAGE)312 await page.set_content('<div style="width:100px;height:100px">spacer</div>')313 await utils.attach_frame(page, "button-test", server.PREFIX + "/input/button.html")314 frame = page.frames[1]315 button = await frame.query_selector("button")316 await button.click()317 assert await frame.evaluate("window.result") == "Clicked"318async def test_click_the_button_with_device_scale_factor_set(browser, server, utils):319 context = await browser.new_context(320 viewport={"width": 400, "height": 400}, device_scale_factor=5321 )322 page = await context.new_page()323 assert await page.evaluate("window.devicePixelRatio") == 5324 await page.set_content('<div style="width:100px;height:100px">spacer</div>')325 await utils.attach_frame(page, "button-test", server.PREFIX + "/input/button.html")326 frame = page.frames[1]327 button = await frame.query_selector("button")328 await button.click()329 assert await frame.evaluate("window.result") == "Clicked"330 await context.close()331async def test_click_the_button_with_px_border_with_offset(page, server, is_webkit):332 await page.goto(server.PREFIX + "/input/button.html")333 await page.eval_on_selector("button", "button => button.style.borderWidth = '8px'")334 await page.click("button", position={"x": 20, "y": 10})335 assert await page.evaluate("result") == "Clicked"336 # Safari reports border-relative offsetX/offsetY.337 assert await page.evaluate("offsetX") == 20 + 8 if is_webkit else 20338 assert await page.evaluate("offsetY") == 10 + 8 if is_webkit else 10339async def test_click_the_button_with_em_border_with_offset(page, server, is_webkit):340 await page.goto(server.PREFIX + "/input/button.html")341 await page.eval_on_selector("button", "button => button.style.borderWidth = '2em'")342 await page.eval_on_selector("button", "button => button.style.fontSize = '12px'")343 await page.click("button", position={"x": 20, "y": 10})344 assert await page.evaluate("result") == "Clicked"345 # Safari reports border-relative offsetX/offsetY.346 assert await page.evaluate("offsetX") == 12 * 2 + 20 if is_webkit else 20347 assert await page.evaluate("offsetY") == 12 * 2 + 10 if is_webkit else 10348async def test_click_a_very_large_button_with_offset(page, server, is_webkit):349 await page.goto(server.PREFIX + "/input/button.html")350 await page.eval_on_selector("button", "button => button.style.borderWidth = '8px'")351 await page.eval_on_selector(352 "button", "button => button.style.height = button.style.width = '2000px'"353 )354 await page.click("button", position={"x": 1900, "y": 1910})355 assert await page.evaluate("() => window.result") == "Clicked"356 # Safari reports border-relative offsetX/offsetY.357 assert await page.evaluate("() => offsetX") == 1900 + 8 if is_webkit else 1900358 assert await page.evaluate("() => offsetY") == 1910 + 8 if is_webkit else 1910359async def test_click_a_button_in_scrolling_container_with_offset(360 page, server, is_webkit361):362 await page.goto(server.PREFIX + "/input/button.html")363 await page.eval_on_selector(364 "button",365 """button => {366 container = document.createElement('div');367 container.style.overflow = 'auto';368 container.style.width = '200px';369 container.style.height = '200px';370 button.parentElement.insertBefore(container, button);371 container.appendChild(button);372 button.style.height = '2000px';373 button.style.width = '2000px';374 button.style.borderWidth = '8px';375 }""",376 )377 await page.click("button", position={"x": 1900, "y": 1910})378 assert await page.evaluate("window.result") == "Clicked"379 # Safari reports border-relative offsetX/offsetY.380 assert await page.evaluate("offsetX") == 1900 + 8 if is_webkit else 1900381 assert await page.evaluate("offsetY") == 1910 + 8 if is_webkit else 1910382@pytest.mark.skip_browser("firefox")383async def test_click_the_button_with_offset_with_page_scale(384 browser, server, is_chromium, is_webkit385):386 context = await browser.new_context(387 viewport={"width": 400, "height": 400}, is_mobile=True388 )389 page = await context.new_page()390 await page.goto(server.PREFIX + "/input/button.html")391 await page.eval_on_selector(392 "button",393 """button => {394 button.style.borderWidth = '8px'395 document.body.style.margin = '0'396 }""",397 )398 await page.click("button", position={"x": 20, "y": 10})399 assert await page.evaluate("result") == "Clicked"400 expected = {"x": 28, "y": 18}401 if is_webkit:402 # WebKit rounds up during css -> dip -> css conversion.403 expected = {"x": 29, "y": 19}404 elif is_chromium:405 # Chromium rounds down during css -> dip -> css conversion.406 expected = {"x": 27, "y": 18}407 assert await page.evaluate("pageX") == expected["x"]408 assert await page.evaluate("pageY") == expected["y"]409 await context.close()410async def test_wait_for_stable_position(page, server):411 await page.goto(server.PREFIX + "/input/button.html")412 await page.eval_on_selector(413 "button",414 """button => {415 button.style.transition = 'margin 500ms linear 0s';416 button.style.marginLeft = '200px';417 button.style.borderWidth = '0';418 button.style.width = '200px';419 button.style.height = '20px';420 // Set display to "block" - otherwise Firefox layouts with non-even421 // values on Linux.422 button.style.display = 'block';423 document.body.style.margin = '0';424 }""",425 )426 await page.click("button")427 assert await page.evaluate("window.result") == "Clicked"428 assert await page.evaluate("pageX") == 300429 assert await page.evaluate("pageY") == 10430async def test_timeout_waiting_for_stable_position(page, server):431 await page.goto(server.PREFIX + "/input/button.html")432 button = await page.query_selector("button")433 await button.evaluate(434 """button => {435 button.style.transition = 'margin 5s linear 0s'436 button.style.marginLeft = '200px'437 }"""438 )439 error = None440 try:441 await button.click(timeout=5000)442 except Error as e:443 error = e444 assert "Timeout 5000ms exceeded." in error.message445 assert "waiting for element to be visible, enabled and not moving" in error.message446 assert "element is moving - waiting" in error.message447async def test_wait_for_becoming_hit_target(page, server):448 await page.goto(server.PREFIX + "/input/button.html")449 await page.eval_on_selector(450 "button",451 """button => {452 button.style.borderWidth = '0';453 button.style.width = '200px';454 button.style.height = '20px';455 document.body.style.margin = '0';456 document.body.style.position = 'relative';457 flyOver = document.createElement('div');458 flyOver.className = 'flyover';459 flyOver.style.position = 'absolute';460 flyOver.style.width = '400px';461 flyOver.style.height = '20px';462 flyOver.style.left = '-200px';463 flyOver.style.top = '0';464 flyOver.style.background = 'red';465 document.body.appendChild(flyOver);466 }""",467 )468 clicked = [False]469 async def click():470 await page.click("button")471 clicked.append(True)472 click_promise = asyncio.create_task(click())473 assert clicked == [False]474 await page.eval_on_selector(".flyover", "flyOver => flyOver.style.left = '0'")475 await give_it_a_chance_to_click(page)476 assert clicked == [False]477 await page.eval_on_selector(".flyover", "flyOver => flyOver.style.left = '200px'")478 await click_promise479 assert clicked == [False, True]480 assert await page.evaluate("() => window.result") == "Clicked"481async def test_timeout_waiting_for_hit_target(page, server):482 await page.goto(server.PREFIX + "/input/button.html")483 button = await page.query_selector("button")484 await page.evaluate(485 """() => {486 document.body.style.position = 'relative'487 blocker = document.createElement('div')488 blocker.id = 'blocker';489 blocker.style.position = 'absolute'490 blocker.style.width = '400px'491 blocker.style.height = '20px'492 blocker.style.left = '0'493 blocker.style.top = '0'494 document.body.appendChild(blocker)495 }"""496 )497 error = None498 try:499 await button.click(timeout=5000)500 except TimeoutError as e:501 error = e502 assert "Timeout 5000ms exceeded." in error.message503 assert '<div id="blocker"></div> intercepts pointer events' in error.message504 assert "retrying click action" in error.message505async def test_fail_when_obscured_and_not_waiting_for_hit_target(page, server):506 await page.goto(server.PREFIX + "/input/button.html")507 button = await page.query_selector("button")508 await page.evaluate(509 """() => {510 document.body.style.position = 'relative'511 blocker = document.createElement('div')512 blocker.style.position = 'absolute'513 blocker.style.width = '400px'514 blocker.style.height = '20px'515 blocker.style.left = '0'516 blocker.style.top = '0'517 document.body.appendChild(blocker)518 }"""519 )520 await button.click(force=True)521 assert await page.evaluate("window.result") == "Was not clicked"522async def test_wait_for_button_to_be_enabled(page, server):523 await page.set_content(524 '<button onclick="javascript:window.__CLICKED=true;" disabled><span>Click target</span></button>'525 )526 done = list()527 async def click():528 await page.click("text=Click target")529 done.append(True)530 click_promise = asyncio.create_task(click())531 await give_it_a_chance_to_click(page)532 assert await page.evaluate("() => window.__CLICKED") is None533 assert done == []534 await page.evaluate("document.querySelector('button').removeAttribute('disabled')")535 await click_promise536 assert await page.evaluate("window.__CLICKED")537async def test_timeout_waiting_for_button_to_be_enabled(page, server):538 await page.set_content(539 '<button onclick="javascript:window.__CLICKED=true;" disabled><span>Click target</span></button>'540 )541 error = None542 try:543 await page.click("text=Click target", timeout=3000)544 except TimeoutError as e:545 error = e546 assert await page.evaluate("window.__CLICKED") is None547 assert "Timeout 3000ms exceeded" in error.message548 assert "element is disabled - waiting" in error.message549async def test_wait_for_input_to_be_enabled(page, server):550 await page.set_content(551 '<input onclick="javascript:window.__CLICKED=true;" disabled>'552 )553 done = []554 async def click():555 await page.click("input")556 done.append(True)557 click_promise = asyncio.create_task(click())558 await give_it_a_chance_to_click(page)559 assert await page.evaluate("window.__CLICKED") is None560 assert done == []561 await page.evaluate("document.querySelector('input').removeAttribute('disabled')")562 await click_promise563 assert await page.evaluate("window.__CLICKED")564async def test_wait_for_select_to_be_enabled(page, server):565 await page.set_content(566 '<select onclick="javascript:window.__CLICKED=true;" disabled><option selected>Hello</option></select>'567 )568 done = []569 async def click():570 await page.click("select")571 done.append(True)572 click_promise = asyncio.create_task(click())573 await give_it_a_chance_to_click(page)574 assert await page.evaluate("window.__CLICKED") is None575 assert done == []576 await page.evaluate("document.querySelector('select').removeAttribute('disabled')")577 await click_promise578 assert await page.evaluate("window.__CLICKED")579async def test_click_disabled_div(page, server):580 await page.set_content(581 '<div onclick="javascript:window.__CLICKED=true;" disabled>Click target</div>'582 )583 await page.click("text=Click target")584 assert await page.evaluate("window.__CLICKED")585async def test_climb_dom_for_inner_label_with_pointer_events_none(page, server):586 await page.set_content(587 '<button onclick="javascript:window.__CLICKED=true;"><label style="pointer-events:none">Click target</label></button>'588 )589 await page.click("text=Click target")590 assert await page.evaluate("window.__CLICKED")591async def test_climb_up_to_role_button(page, server):592 await page.set_content(593 '<div role=button onclick="javascript:window.__CLICKED=true;"><div style="pointer-events:none"><span><div>Click target</div></span></div>'594 )595 await page.click("text=Click target")596 assert await page.evaluate("window.__CLICKED")597async def test_wait_for_BUTTON_to_be_clickable_when_it_has_pointer_events_none(598 page, server599):600 await page.set_content(601 '<button onclick="javascript:window.__CLICKED=true;" style="pointer-events:none"><span>Click target</span></button>'602 )603 done = []604 async def click():605 await page.click("text=Click target")606 done.append(True)607 click_promise = asyncio.create_task(click())608 await give_it_a_chance_to_click(page)609 assert await page.evaluate("window.__CLICKED") is None610 assert done == []611 await page.evaluate(612 "document.querySelector('button').style.removeProperty('pointer-events')"613 )614 await click_promise615 assert await page.evaluate("window.__CLICKED")616async def test_wait_for_LABEL_to_be_clickable_when_it_has_pointer_events_none(617 page, server618):619 await page.set_content(620 '<label onclick="javascript:window.__CLICKED=true;" style="pointer-events:none"><span>Click target</span></label>'621 )622 click_promise = asyncio.create_task(page.click("text=Click target"))623 # Do a few roundtrips to the page.624 for _ in range(5):625 assert await page.evaluate("window.__CLICKED") is None626 # remove 'pointer-events: none' css from button.627 await page.evaluate(628 "document.querySelector('label').style.removeProperty('pointer-events')"629 )630 await click_promise631 assert await page.evaluate("window.__CLICKED")632async def test_update_modifiers_correctly(page, server):633 await page.goto(server.PREFIX + "/input/button.html")634 await page.click("button", modifiers=["Shift"])635 assert await page.evaluate("shiftKey")636 await page.click("button", modifiers=[])637 assert await page.evaluate("shiftKey") is False638 await page.keyboard.down("Shift")639 await page.click("button", modifiers=[])640 assert await page.evaluate("shiftKey") is False641 await page.click("button")642 assert await page.evaluate("shiftKey")643 await page.keyboard.up("Shift")644 await page.click("button")645 assert await page.evaluate("shiftKey") is False646async def test_click_an_offscreen_element_when_scroll_behavior_is_smooth(page):647 await page.set_content(648 """649 <div style="border: 1px solid black; height: 500px; overflow: auto; width: 500px; scroll-behavior: smooth">650 <button style="margin-top: 2000px" onClick="window.clicked = true">hi</button>651 </div>652 """653 )654 await page.click("button")655 assert await page.evaluate("window.clicked")656async def test_report_nice_error_when_element_is_detached_and_force_clicked(657 page, server658):659 await page.goto(server.PREFIX + "/input/animating-button.html")660 await page.evaluate("addButton()")661 handle = await page.query_selector("button")662 await page.evaluate("stopButton(true)")663 error = None664 try:665 await handle.click(force=True)666 except Error as e:667 error = e668 assert await page.evaluate("window.clicked") is None669 assert "Element is not attached to the DOM" in error.message670async def test_fail_when_element_detaches_after_animation(page, server):671 await page.goto(server.PREFIX + "/input/animating-button.html")672 await page.evaluate("addButton()")673 handle = await page.query_selector("button")674 promise = asyncio.create_task(handle.click())675 await asyncio.sleep(0) # execute scheduled tasks, but don't await them676 await page.evaluate("stopButton(true)")677 with pytest.raises(Error) as exc_info:678 await promise679 assert await page.evaluate("window.clicked") is None680 assert "Element is not attached to the DOM" in exc_info.value.message681async def test_retry_when_element_detaches_after_animation(page, server):682 await page.goto(server.PREFIX + "/input/animating-button.html")683 await page.evaluate("addButton()")684 clicked = []685 async def click():686 await page.click("button")687 clicked.append(True)688 promise = asyncio.create_task(click())689 await asyncio.sleep(0) # execute scheduled tasks, but don't await them690 assert clicked == []691 assert await page.evaluate("window.clicked") is None692 await page.evaluate("stopButton(true)")693 await page.evaluate("addButton()")694 assert clicked == []695 assert await page.evaluate("window.clicked") is None696 await page.evaluate("stopButton(true)")697 await page.evaluate("addButton()")698 assert clicked == []699 assert await page.evaluate("window.clicked") is None700 await page.evaluate("stopButton(false)")701 await promise702 assert clicked == [True]703 assert await page.evaluate("window.clicked")704async def test_retry_when_element_is_animating_from_outside_the_viewport(page, server):705 await page.set_content(706 """<style>707 @keyframes move {708 from { left: -300px; }709 to { left: 0; }710 }711 button {712 position: absolute713 left: -300px714 top: 0715 bottom: 0716 width: 200px717 }718 button.animated {719 animation: 1s linear 1s move forwards720 }721 </style>722 <div style="position: relative; width: 300px; height: 300px;">723 <button onclick="window.clicked=true"></button>724 </div>725 """726 )727 handle = await page.query_selector("button")728 promise = asyncio.create_task(handle.click())729 await asyncio.sleep(0) # execute scheduled tasks, but don't await them730 await handle.evaluate("button => button.className = 'animated'")731 await promise732 assert await page.evaluate("window.clicked")733async def test_fail_when_element_is_animating_from_outside_the_viewport_with_force(734 page, server735):736 await page.set_content(737 """<style>738 @keyframes move {739 from { left: -300px; }740 to { left: 0; }741 }742 button {743 position: absolute;744 left: -300px;745 top: 0;746 bottom: 0747 width: 200px;748 }749 button.animated {750 animation: 1s linear 1s move forwards;751 }752 </style>753 <div style="position: relative; width: 300px; height: 300px;">754 <button onclick="window.clicked=true"></button>755 </div>756 """757 )758 handle = await page.query_selector("button")759 promise = asyncio.create_task(handle.click(force=True))760 await asyncio.sleep(0) # execute scheduled tasks, but don't await them761 await handle.evaluate("button => button.className = 'animated'")762 error = None763 try:764 await promise765 except Error as e:766 error = e767 assert await page.evaluate("window.clicked") is None768 assert "Element is outside of the viewport" in error.message769async def test_not_retarget_when_element_changes_on_hover(page, server):770 await page.goto(server.PREFIX + "/react.html")771 await page.evaluate(772 """() => {773 renderComponent(e('div', {}, [e(MyButton, { name: 'button1', renameOnHover: true }), e(MyButton, { name: 'button2' })] ));774 }"""775 )776 await page.click("text=button1")777 assert await page.evaluate("window.button1")778 assert await page.evaluate("window.button2") is None779async def test_not_retarget_when_element_is_recycled_on_hover(page, server):780 await page.goto(server.PREFIX + "/react.html")781 await page.evaluate(782 """() => {783 function shuffle() {784 renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));785 }786 renderComponent(e('div', {}, [e(MyButton, { name: 'button1', onHover: shuffle }), e(MyButton, { name: 'button2' })] ));787 }"""788 )789 await page.click("text=button1")790 assert await page.evaluate("window.button1") is None791 assert await page.evaluate("window.button2")792async def test_click_the_button_when_window_inner_width_is_corrupted(page, server):793 await page.goto(server.PREFIX + "/input/button.html")794 await page.evaluate("window.innerWidth = 0")795 await page.click("button")796 assert await page.evaluate("result") == "Clicked"797async def test_timeout_when_click_opens_alert(page, server):798 await page.set_content('<div onclick="window.alert(123)">Click me</div>')799 async with page.expect_event("dialog") as dialog_info:800 with pytest.raises(Error) as exc_info:801 await page.click("div", timeout=3000)802 assert "Timeout 3000ms exceeded" in exc_info.value.message803 dialog = await dialog_info.value804 await dialog.dismiss()805async def test_check_the_box(page):806 await page.set_content('<input id="checkbox" type="checkbox"></input>')807 await page.check("input")808 assert await page.evaluate("checkbox.checked")809async def test_not_check_the_checked_box(page):810 await page.set_content('<input id="checkbox" type="checkbox" checked></input>')811 await page.check("input")812 assert await page.evaluate("checkbox.checked")813async def test_uncheck_the_box(page):814 await page.set_content('<input id="checkbox" type="checkbox" checked></input>')815 await page.uncheck("input")816 assert await page.evaluate("checkbox.checked") is False817async def test_not_uncheck_the_unchecked_box(page):818 await page.set_content('<input id="checkbox" type="checkbox"></input>')819 await page.uncheck("input")820 assert await page.evaluate("checkbox.checked") is False821async def test_check_the_box_by_label(page):822 await page.set_content(823 '<label for="checkbox"><input id="checkbox" type="checkbox"></input></label>'824 )825 await page.check("label")826 assert await page.evaluate("checkbox.checked")827async def test_check_the_box_outside_label(page):828 await page.set_content(829 '<label for="checkbox">Text</label><div><input id="checkbox" type="checkbox"></input></div>'830 )831 await page.check("label")832 assert await page.evaluate("checkbox.checked")833async def test_check_the_box_inside_label_without_id(page):834 await page.set_content(835 '<label>Text<span><input id="checkbox" type="checkbox"></input></span></label>'836 )837 await page.check("label")838 assert await page.evaluate("checkbox.checked")839async def test_check_radio(page):840 await page.set_content(841 """842 <input type='radio'>one</input>843 <input id='two' type='radio'>two</input>844 <input type='radio'>three</input>"""845 )846 await page.check("#two")847 assert await page.evaluate("two.checked")848async def test_check_the_box_by_aria_role(page):849 await page.set_content(850 """<div role='checkbox' id='checkbox'>CHECKBOX</div>851 <script>852 checkbox.addEventListener('click', () => checkbox.setAttribute('aria-checked', 'true'))853 </script>"""854 )855 await page.check("div")...
test_network.py
Source:test_network.py
1# Copyright (c) Microsoft Corporation.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14import asyncio15import json16from asyncio.futures import Future17from typing import Dict, List, cast18import pytest19from playwright.async_api import Error, Page, Request, Response20async def test_request_fulfill(page, server):21 async def handle_request(route, request):22 assert route.request == request23 assert "empty.html" in request.url24 assert request.headers["user-agent"]25 assert request.method == "GET"26 assert request.post_data is None27 assert request.is_navigation_request()28 assert request.resource_type == "document"29 assert request.frame == page.main_frame30 assert request.frame.url == "about:blank"31 await route.fulfill(body="Text")32 await page.route(33 "**/empty.html",34 lambda route, request: asyncio.create_task(handle_request(route, request)),35 )36 response = await page.goto(server.EMPTY_PAGE)37 assert response.ok38 assert await response.text() == "Text"39async def test_request_continue(page, server):40 async def handle_request(route, request, intercepted):41 intercepted.append(True)42 await route.continue_()43 intercepted = list()44 await page.route(45 "**/*",46 lambda route, request: asyncio.create_task(47 handle_request(route, request, intercepted)48 ),49 )50 response = await page.goto(server.EMPTY_PAGE)51 assert response.ok52 assert intercepted == [True]53 assert await page.title() == ""54async def test_page_events_request_should_fire_for_navigation_requests(55 page: Page, server56):57 requests = []58 page.on("request", lambda r: requests.append(r))59 await page.goto(server.EMPTY_PAGE)60 assert len(requests) == 161async def test_page_events_request_should_fire_for_iframes(page, server, utils):62 requests = []63 page.on("request", lambda r: requests.append(r))64 await page.goto(server.EMPTY_PAGE)65 await utils.attach_frame(page, "frame1", server.EMPTY_PAGE)66 assert len(requests) == 267async def test_page_events_request_should_fire_for_fetches(page, server):68 requests = []69 page.on("request", lambda r: requests.append(r))70 await page.goto(server.EMPTY_PAGE)71 await page.evaluate('() => fetch("/empty.html")')72 assert len(requests) == 273async def test_page_events_request_should_report_requests_and_responses_handled_by_service_worker(74 page: Page, server75):76 await page.goto(server.PREFIX + "/serviceworkers/fetchdummy/sw.html")77 await page.evaluate("() => window.activationPromise")78 sw_response = None79 async with page.expect_request("**/*") as request_info:80 sw_response = await page.evaluate('() => fetchDummy("foo")')81 request = await request_info.value82 assert sw_response == "responseFromServiceWorker:foo"83 assert request.url == server.PREFIX + "/serviceworkers/fetchdummy/foo"84 response = await request.response()85 assert response.url == server.PREFIX + "/serviceworkers/fetchdummy/foo"86 assert await response.text() == "responseFromServiceWorker:foo"87async def test_request_frame_should_work_for_main_frame_navigation_request(88 page, server89):90 requests = []91 page.on("request", lambda r: requests.append(r))92 await page.goto(server.EMPTY_PAGE)93 assert len(requests) == 194 assert requests[0].frame == page.main_frame95async def test_request_frame_should_work_for_subframe_navigation_request(96 page, server, utils97):98 await page.goto(server.EMPTY_PAGE)99 requests = []100 page.on("request", lambda r: requests.append(r))101 await utils.attach_frame(page, "frame1", server.EMPTY_PAGE)102 assert len(requests) == 1103 assert requests[0].frame == page.frames[1]104async def test_request_frame_should_work_for_fetch_requests(page, server):105 await page.goto(server.EMPTY_PAGE)106 requests: List[Request] = []107 page.on("request", lambda r: requests.append(r))108 await page.evaluate('() => fetch("/digits/1.png")')109 requests = [r for r in requests if "favicon" not in r.url]110 assert len(requests) == 1111 assert requests[0].frame == page.main_frame112async def test_request_headers_should_work(113 page, server, is_chromium, is_firefox, is_webkit114):115 response = await page.goto(server.EMPTY_PAGE)116 if is_chromium:117 assert "Chrome" in response.request.headers["user-agent"]118 elif is_firefox:119 assert "Firefox" in response.request.headers["user-agent"]120 elif is_webkit:121 assert "WebKit" in response.request.headers["user-agent"]122async def test_request_headers_should_get_the_same_headers_as_the_server(123 page: Page, server, is_webkit, is_win124):125 server_request_headers_future: Future[Dict[str, str]] = asyncio.Future()126 def handle(request):127 normalized_headers = {128 key.decode().lower(): value[0].decode()129 for key, value in request.requestHeaders.getAllRawHeaders()130 }131 server_request_headers_future.set_result(normalized_headers)132 request.write(b"done")133 request.finish()134 server.set_route("/empty.html", handle)135 response = await page.goto(server.EMPTY_PAGE)136 server_headers = await server_request_headers_future137 if is_webkit and is_win:138 # Curl does not show accept-encoding and accept-language139 server_headers.pop("accept-encoding")140 server_headers.pop("accept-language")141 assert cast(Response, response).request.headers == server_headers142async def test_request_headers_should_get_the_same_headers_as_the_server_cors(143 page: Page, server, is_webkit, is_win144):145 await page.goto(server.PREFIX + "/empty.html")146 server_request_headers_future: Future[Dict[str, str]] = asyncio.Future()147 def handle_something(request):148 normalized_headers = {149 key.decode().lower(): value[0].decode()150 for key, value in request.requestHeaders.getAllRawHeaders()151 }152 server_request_headers_future.set_result(normalized_headers)153 request.setHeader("Access-Control-Allow-Origin", "*")154 request.write(b"done")155 request.finish()156 server.set_route("/something", handle_something)157 text = None158 async with page.expect_request("**/*") as request_info:159 text = await page.evaluate(160 """async url => {161 const data = await fetch(url);162 return data.text();163 }""",164 server.CROSS_PROCESS_PREFIX + "/something",165 )166 request = await request_info.value167 assert text == "done"168 server_headers = await server_request_headers_future169 if is_webkit and is_win:170 # Curl does not show accept-encoding and accept-language171 server_headers.pop("accept-encoding")172 server_headers.pop("accept-language")173 assert request.headers == server_headers174async def test_response_headers_should_work(page, server):175 server.set_route("/empty.html", lambda r: (r.setHeader("foo", "bar"), r.finish()))176 response = await page.goto(server.EMPTY_PAGE)177 assert response.headers["foo"] == "bar"178async def test_request_post_data_should_work(page, server):179 await page.goto(server.EMPTY_PAGE)180 server.set_route("/post", lambda r: r.finish())181 requests = []182 page.on("request", lambda r: requests.append(r))183 await page.evaluate(184 '() => fetch("./post", { method: "POST", body: JSON.stringify({foo: "bar"})})'185 )186 assert len(requests) == 1187 assert requests[0].post_data == '{"foo":"bar"}'188async def test_request_post_data__should_be_undefined_when_there_is_no_post_data(189 page, server190):191 response = await page.goto(server.EMPTY_PAGE)192 assert response.request.post_data is None193async def test_should_parse_the_json_post_data(page, server):194 await page.goto(server.EMPTY_PAGE)195 server.set_route("/post", lambda req: req.finish())196 requests = []197 page.on("request", lambda r: requests.append(r))198 await page.evaluate(199 """() => fetch('./post', { method: 'POST', body: JSON.stringify({ foo: 'bar' }) })"""200 )201 assert len(requests) == 1202 assert requests[0].post_data_json == {"foo": "bar"}203async def test_should_parse_the_data_if_content_type_is_form_urlencoded(page, server):204 await page.goto(server.EMPTY_PAGE)205 server.set_route("/post", lambda req: req.finish())206 requests = []207 page.on("request", lambda r: requests.append(r))208 await page.set_content(209 """<form method='POST' action='/post'><input type='text' name='foo' value='bar'><input type='number' name='baz' value='123'><input type='submit'></form>"""210 )211 await page.click("input[type=submit]")212 assert len(requests) == 1213 assert requests[0].post_data_json == {"foo": "bar", "baz": "123"}214async def test_should_be_undefined_when_there_is_no_post_data(page, server):215 response = await page.goto(server.EMPTY_PAGE)216 assert response.request.post_data_json is None217async def test_should_work_with_binary_post_data(page, server):218 await page.goto(server.EMPTY_PAGE)219 server.set_route("/post", lambda req: req.finish())220 requests = []221 page.on("request", lambda r: requests.append(r))222 await page.evaluate(223 """async () => {224 await fetch('./post', { method: 'POST', body: new Uint8Array(Array.from(Array(256).keys())) })225 }"""226 )227 assert len(requests) == 1228 buffer = requests[0].post_data_buffer229 assert len(buffer) == 256230 for i in range(256):231 assert buffer[i] == i232async def test_should_work_with_binary_post_data_and_interception(page, server):233 await page.goto(server.EMPTY_PAGE)234 server.set_route("/post", lambda req: req.finish())235 requests = []236 await page.route("/post", lambda route: asyncio.ensure_future(route.continue_()))237 page.on("request", lambda r: requests.append(r))238 await page.evaluate(239 """async () => {240 await fetch('./post', { method: 'POST', body: new Uint8Array(Array.from(Array(256).keys())) })241 }"""242 )243 assert len(requests) == 1244 buffer = requests[0].post_data_buffer245 assert len(buffer) == 256246 for i in range(256):247 assert buffer[i] == i248async def test_response_text_should_work(page, server):249 response = await page.goto(server.PREFIX + "/simple.json")250 assert await response.text() == '{"foo": "bar"}\n'251async def test_response_text_should_return_uncompressed_text(page, server):252 server.enable_gzip("/simple.json")253 response = await page.goto(server.PREFIX + "/simple.json")254 assert response.headers["content-encoding"] == "gzip"255 assert await response.text() == '{"foo": "bar"}\n'256async def test_response_text_should_throw_when_requesting_body_of_redirected_response(257 page, server258):259 server.set_redirect("/foo.html", "/empty.html")260 response = await page.goto(server.PREFIX + "/foo.html")261 redirected_from = response.request.redirected_from262 assert redirected_from263 redirected = await redirected_from.response()264 assert redirected.status == 302265 error = None266 try:267 await redirected.text()268 except Error as exc:269 error = exc270 assert "Response body is unavailable for redirect responses" in error.message271async def test_response_json_should_work(page, server):272 response = await page.goto(server.PREFIX + "/simple.json")273 assert await response.json() == {"foo": "bar"}274async def test_response_body_should_work(page, server, assetdir):275 response = await page.goto(server.PREFIX + "/pptr.png")276 with open(277 assetdir / "pptr.png",278 "rb",279 ) as fd:280 assert fd.read() == await response.body()281async def test_response_body_should_work_with_compression(page, server, assetdir):282 server.enable_gzip("/pptr.png")283 response = await page.goto(server.PREFIX + "/pptr.png")284 with open(285 assetdir / "pptr.png",286 "rb",287 ) as fd:288 assert fd.read() == await response.body()289async def test_response_status_text_should_work(page, server):290 server.set_route("/cool", lambda r: (r.setResponseCode(200, b"cool!"), r.finish()))291 response = await page.goto(server.PREFIX + "/cool")292 assert response.status_text == "cool!"293async def test_request_resource_type_should_return_event_source(page, server):294 SSE_MESSAGE = {"foo": "bar"}295 # 1. Setup server-sent events on server that immediately sends a message to the client.296 server.set_route(297 "/sse",298 lambda r: (299 r.setHeader("Content-Type", "text/event-stream"),300 r.setHeader("Connection", "keep-alive"),301 r.setHeader("Cache-Control", "no-cache"),302 r.setResponseCode(200),303 r.write(f"data: {json.dumps(SSE_MESSAGE)}\n\n".encode()),304 r.finish(),305 ),306 )307 # 2. Subscribe to page request events.308 await page.goto(server.EMPTY_PAGE)309 requests = []310 page.on("request", lambda r: requests.append(r))311 # 3. Connect to EventSource in browser and return first message.312 assert (313 await page.evaluate(314 """() => {315 const eventSource = new EventSource('/sse');316 return new Promise(resolve => {317 eventSource.onmessage = e => resolve(JSON.parse(e.data));318 });319 }"""320 )321 == SSE_MESSAGE322 )323 assert requests[0].resource_type == "eventsource"324async def test_network_events_request(page, server):325 requests = []326 page.on("request", lambda r: requests.append(r))327 await page.goto(server.EMPTY_PAGE)328 assert len(requests) == 1329 assert requests[0].url == server.EMPTY_PAGE330 assert requests[0].resource_type == "document"331 assert requests[0].method == "GET"332 assert await requests[0].response()333 assert requests[0].frame == page.main_frame334 assert requests[0].frame.url == server.EMPTY_PAGE335async def test_network_events_response(page, server):336 responses = []337 page.on("response", lambda r: responses.append(r))338 await page.goto(server.EMPTY_PAGE)339 assert len(responses) == 1340 assert responses[0].url == server.EMPTY_PAGE341 assert responses[0].status == 200342 assert responses[0].ok343 assert responses[0].request344async def test_network_events_request_failed(345 page, server, is_chromium, is_webkit, is_mac, is_win346):347 def handle_request(request):348 request.setHeader("Content-Type", "text/css")349 request.transport.loseConnection()350 server.set_route("/one-style.css", handle_request)351 failed_requests = []352 page.on("requestfailed", lambda request: failed_requests.append(request))353 await page.goto(server.PREFIX + "/one-style.html")354 assert len(failed_requests) == 1355 assert "one-style.css" in failed_requests[0].url356 assert await failed_requests[0].response() is None357 assert failed_requests[0].resource_type == "stylesheet"358 if is_chromium:359 assert failed_requests[0].failure == "net::ERR_EMPTY_RESPONSE"360 elif is_webkit:361 if is_mac:362 assert failed_requests[0].failure == "The network connection was lost."363 elif is_win:364 assert (365 failed_requests[0].failure366 == "Server returned nothing (no headers, no data)"367 )368 else:369 assert failed_requests[0].failure == "Message Corrupt"370 else:371 assert failed_requests[0].failure == "NS_ERROR_NET_RESET"372 assert failed_requests[0].frame373async def test_network_events_request_finished(page, server):374 async with page.expect_event("requestfinished") as event_info:375 await page.goto(server.EMPTY_PAGE)376 request = await event_info.value377 assert request.url == server.EMPTY_PAGE378 assert await request.response()379 assert request.frame == page.main_frame380 assert request.frame.url == server.EMPTY_PAGE381async def test_network_events_should_fire_events_in_proper_order(page, server):382 events = []383 page.on("request", lambda request: events.append("request"))384 page.on("response", lambda response: events.append("response"))385 response = await page.goto(server.EMPTY_PAGE)386 await response.finished()387 events.append("requestfinished")388 assert events == ["request", "response", "requestfinished"]389async def test_network_events_should_support_redirects(page, server):390 events = []391 page.on("request", lambda request: events.append(f"{request.method} {request.url}"))392 page.on(393 "response", lambda response: events.append(f"{response.status} {response.url}")394 )395 page.on("requestfinished", lambda request: events.append(f"DONE {request.url}"))396 page.on("requestfailed", lambda request: events.append(f"FAIL {request.url}"))397 server.set_redirect("/foo.html", "/empty.html")398 FOO_URL = server.PREFIX + "/foo.html"399 response = await page.goto(FOO_URL)400 await response.finished()401 assert events == [402 f"GET {FOO_URL}",403 f"302 {FOO_URL}",404 f"DONE {FOO_URL}",405 f"GET {server.EMPTY_PAGE}",406 f"200 {server.EMPTY_PAGE}",407 f"DONE {server.EMPTY_PAGE}",408 ]409 redirected_from = response.request.redirected_from410 assert "/foo.html" in redirected_from.url411 assert redirected_from.redirected_from is None412 assert redirected_from.redirected_to == response.request413async def test_request_is_navigation_request_should_work(page, server):414 pytest.skip(msg="test")415 requests = {}416 def handle_request(request):417 requests[request.url().split("/").pop()] = request418 page.on("request", handle_request)419 server.set_redirect("/rrredirect", "/frames/one-frame.html")420 await page.goto(server.PREFIX + "/rrredirect")421 print("kek")422 assert requests.get("rrredirect").is_navigation_request()423 assert requests.get("one-frame.html").is_navigation_request()424 assert requests.get("frame.html").is_navigation_request()425 assert requests.get("script.js").is_navigation_request() is False426 assert requests.get("style.css").is_navigation_request() is False427async def test_request_is_navigation_request_should_work_when_navigating_to_image(428 page, server429):430 requests = []431 page.on("request", lambda r: requests.append(r))432 await page.goto(server.PREFIX + "/pptr.png")433 assert requests[0].is_navigation_request()434async def test_set_extra_http_headers_should_work(page, server):435 await page.set_extra_http_headers({"foo": "bar"})436 request = (437 await asyncio.gather(438 server.wait_for_request("/empty.html"),439 page.goto(server.EMPTY_PAGE),440 )441 )[0]442 assert request.getHeader("foo") == "bar"443async def test_set_extra_http_headers_should_work_with_redirects(page, server):444 server.set_redirect("/foo.html", "/empty.html")445 await page.set_extra_http_headers({"foo": "bar"})446 request = (447 await asyncio.gather(448 server.wait_for_request("/empty.html"),449 page.goto(server.PREFIX + "/foo.html"),450 )451 )[0]452 assert request.getHeader("foo") == "bar"453async def test_set_extra_http_headers_should_work_with_extra_headers_from_browser_context(454 browser, server455):456 context = await browser.new_context()457 await context.set_extra_http_headers({"foo": "bar"})458 page = await context.new_page()459 request = (460 await asyncio.gather(461 server.wait_for_request("/empty.html"),462 page.goto(server.EMPTY_PAGE),463 )464 )[0]465 await context.close()466 assert request.getHeader("foo") == "bar"467async def test_set_extra_http_headers_should_override_extra_headers_from_browser_context(468 browser, server469):470 context = await browser.new_context(extra_http_headers={"fOo": "bAr", "baR": "foO"})471 page = await context.new_page()472 await page.set_extra_http_headers({"Foo": "Bar"})473 request = (474 await asyncio.gather(475 server.wait_for_request("/empty.html"),476 page.goto(server.EMPTY_PAGE),477 )478 )[0]479 await context.close()480 assert request.getHeader("foo") == "Bar"481 assert request.getHeader("bar") == "foO"482async def test_set_extra_http_headers_should_throw_for_non_string_header_values(483 page, server484):485 error = None486 try:487 await page.set_extra_http_headers({"foo": 1})488 except Error as exc:489 error = exc...
tests.py
Source:tests.py
1import unittest2from __init__ import Middleware3class DummyRequest(object):4 def __init__(self, useragent):5 self.META = {6 'HTTP_USER_AGENT': useragent,7 'HTTP_ACCEPT': ''8 }9def get_requests(agent_list):10 requests = []11 for agent in agent_list:12 request = DummyRequest(agent)13 14 Middleware.process_request(request)15 16 requests.append(request)17 return requests18class TestBrowserInfo(unittest.TestCase):19 def testDesktopWebkit(self):20 user_agents = [21 # Chrome22 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10',23 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.307.11 Safari/532.9',24 # Safari25 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-us) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4',26 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8',27 'mozilla/5.0 (macintosh; u; intel mac os x 10_6_6; en-us) applewebkit/533.19.4 (khtml, like gecko) version/5.0.3 safari/533.19.4',28 ]29 30 requests = get_requests(user_agents)31 32 for request in requests:33 self.assertEqual(request.is_webkit, True)34 self.assertEqual(request.is_wide_device, True)35 self.assertEqual(request.is_touch_device, False)36 37 def testDesktopNonWebkit(self):38 user_agents = [39 # Firefox40 'Mozilla/5.0 (Windows; U; Windows NT 6.1; nl; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13',41 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3',42 'mozilla/5.0 (macintosh; intel mac os x 10.6; rv:2.0b6) gecko/20100101 firefox/4.0b6'43 # IE44 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',45 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB0.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; GACID=)',46 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6.4; .NET CLR 1.1.4322; FDM; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)',47 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Rogers Hi Speed Internet; (R1 1.3))'48 ]49 50 requests = get_requests(user_agents)51 52 for request in requests:53 self.assertEqual(request.is_webkit, False)54 self.assertEqual(request.is_wide_device, True)55 self.assertEqual(request.is_touch_device, False)56 57 def testiPhoneiPodTouch(self):58 user_agents = [59 # Safari 3.1.1 for iPod Touch 2.060 'Mozilla/5.0 (iPod; U; CPU iPhone OS 2_0 like Mac OS X; de-de) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5A347 Safari/525.20',61 # iPhone 3G version 2.162 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_1 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F136 Safari/525.20',63 # iPhone 464 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7',65 # iPhone 566 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3'67 ]68 69 requests = get_requests(user_agents)70 71 for request in requests:72 self.assertEqual(request.is_webkit, True)73 self.assertEqual(request.is_ios_device, True)74 self.assertEqual(request.is_wide_device, False)75 self.assertEqual(request.is_touch_device, True)76 77 def testiOS5(self):78 user_agents = [79 # iPhone 580 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3',81 ]82 83 requests = get_requests(user_agents)84 85 for request in requests:86 self.assertEqual(request.is_ios5_device, True)87 88 def testiPad(self):89 user_agents = [90 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; es-es) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B405 Safari/531.21.10',91 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10',92 ]93 94 requests = get_requests(user_agents)95 96 for request in requests:97 self.assertEqual(request.is_webkit, True)98 self.assertEqual(request.is_ios_device, True)99 self.assertEqual(request.is_wide_device, True)100 self.assertEqual(request.is_touch_device, True)101 def testAndroid(self):102 user_agents = [103 #Nexus One104 'Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',105 # HTC Incredible106 'Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; ADR6300 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17',107 # Droid 2108 'Mozilla/5.0 (Linux; U; Android 2.2; en-us; DROID2 GLOBAL Build/S273) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',109 # Droid X110 'Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; DROIDX Build/VZW) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 480X854 motorola DROIDX',111 # Droid112 'Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; Droid Build/ESE81) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17',113 ]114 115 requests = get_requests(user_agents)116 117 for request in requests:118 self.assertEqual(request.is_webkit, True)119 self.assertEqual(request.is_android_device, True)120 self.assertEqual(request.is_wide_device, False)121 self.assertEqual(request.is_touch_device, True)122 def testWebOSNarrow(self):123 user_agents = [124 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0',125 'Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1',126 ]127 128 requests = get_requests(user_agents)129 130 for request in requests:131 self.assertEqual(request.is_webkit, True)132 self.assertEqual(request.is_webos_device, True)133 self.assertEqual(request.is_wide_device, False)134 self.assertEqual(request.is_touch_device, True)135 def testWindowsPhone(self):136 user_agents = [137 'Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0) Asus;Galaxy6',138 ]139 140 requests = get_requests(user_agents)141 142 for request in requests:143 self.assertEqual(request.is_webkit, False)144 self.assertEqual(request.is_windows_phone_device, True)145 self.assertEqual(request.is_wide_device, False)146 self.assertEqual(request.is_touch_device, True)147 def testKindle2(self):148 user_agents = [149 'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 600x800)',150 ]151 152 requests = get_requests(user_agents)153 154 for request in requests:155 self.assertEqual(request.is_webkit, False)156 self.assertEqual(request.is_kindle_device, True)157 self.assertEqual(request.is_wide_device, False)158 self.assertEqual(request.is_touch_device, False)159 def testKindle3(self):160 user_agents = [161 'Mozilla/5.0 (Linux; U; en-US) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/538.5+) Version/4.0 Kindle/3.0 (screen 600x800; rotate)',162 ]163 164 requests = get_requests(user_agents)165 166 for request in requests:167 self.assertEqual(request.is_webkit, True)168 self.assertEqual(request.is_kindle_device, True)169 self.assertEqual(request.is_wide_device, False)170 self.assertEqual(request.is_touch_device, False)171 def testSimpleDevices(self):172 user_agents = [173 'Nokia7600/2.0 (03.01) Profile/MIDP-1.0 Configuration/CLDC-1.0 (Google WAP Proxy/1.0)',174 'Nokia8310/1.0 (05.11) UP.Link/6.5.0.0.06.5.0.0.06.5.0.0.06.5.0.0.0',175 'MOT-COOL0/00.62 UP.Browser/6.2.3.4.c.1.128 (GUI) MMP/2.0'176 ]177 178 requests = get_requests(user_agents)179 180 for request in requests:181 self.assertEqual(request.is_simple_device, True)182 self.assertEqual(request.is_webkit, False)183 self.assertEqual(request.is_kindle_device, False)184 self.assertEqual(request.is_wide_device, False)185 self.assertEqual(request.is_touch_device, False)186 187 def testNoUA(self):188 class NoUARequest(object):189 META = {}190 191 request = NoUARequest()192 Middleware.process_request(request)193 194 assert not request.is_android_device195 assert not request.is_kindle_device196 assert not request.is_ios_device197 assert not request.is_touch_device198 assert not request.is_simple_device199 assert not request.is_webkit 200 assert not request.is_webos201 assert request.is_wide_device202 assert not request.is_windows_phone_device203if __name__ == '__main__':...
test_browsercontext_cookies.py
Source:test_browsercontext_cookies.py
1# Copyright (c) Microsoft Corporation.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14import datetime15import pytest16async def test_should_return_no_cookies_in_pristine_browser_context(context):17 assert await context.cookies() == []18async def test_should_get_a_cookie(context, page, server, is_firefox):19 await page.goto(server.EMPTY_PAGE)20 document_cookie = await page.evaluate(21 """() => {22 document.cookie = 'username=John Doe';23 return document.cookie;24 }"""25 )26 assert document_cookie == "username=John Doe"27 assert await context.cookies() == [28 {29 "name": "username",30 "value": "John Doe",31 "domain": "localhost",32 "path": "/",33 "expires": -1,34 "httpOnly": False,35 "secure": False,36 "sameSite": "None",37 }38 ]39async def test_should_get_a_non_session_cookie(context, page, server, is_firefox):40 await page.goto(server.EMPTY_PAGE)41 # @see https://en.wikipedia.org/wiki/Year_2038_problem42 date = int(datetime.datetime(2038, 1, 1).timestamp() * 1000)43 document_cookie = await page.evaluate(44 """timestamp => {45 const date = new Date(timestamp);46 document.cookie = `username=John Doe;expires=${date.toUTCString()}`;47 return document.cookie;48 }""",49 date,50 )51 assert document_cookie == "username=John Doe"52 assert await context.cookies() == [53 {54 "name": "username",55 "value": "John Doe",56 "domain": "localhost",57 "path": "/",58 "expires": date / 1000,59 "httpOnly": False,60 "secure": False,61 "sameSite": "None",62 }63 ]64async def test_should_properly_report_httpOnly_cookie(context, page, server):65 server.set_route(66 "/empty.html",67 lambda r: (68 r.setHeader("Set-Cookie", "name=value;httpOnly; Path=/"),69 r.finish(),70 ),71 )72 await page.goto(server.EMPTY_PAGE)73 cookies = await context.cookies()74 assert len(cookies) == 175 assert cookies[0]["httpOnly"] is True76async def test_should_properly_report_strict_sameSite_cookie(77 context, page, server, is_webkit, is_win78):79 if is_webkit and is_win:80 pytest.skip()81 server.set_route(82 "/empty.html",83 lambda r: (84 r.setHeader("Set-Cookie", "name=value;sameSite=Strict"),85 r.finish(),86 ),87 )88 await page.goto(server.EMPTY_PAGE)89 cookies = await context.cookies()90 assert len(cookies) == 191 assert cookies[0]["sameSite"] == "Strict"92async def test_should_properly_report_lax_sameSite_cookie(93 context, page, server, is_webkit, is_win94):95 if is_webkit and is_win:96 pytest.skip()97 server.set_route(98 "/empty.html",99 lambda r: (100 r.setHeader("Set-Cookie", "name=value;sameSite=Lax"),101 r.finish(),102 ),103 )104 await page.goto(server.EMPTY_PAGE)105 cookies = await context.cookies()106 assert len(cookies) == 1107 assert cookies[0]["sameSite"] == "Lax"108async def test_should_get_multiple_cookies(context, page, server, is_firefox):109 await page.goto(server.EMPTY_PAGE)110 document_cookie = await page.evaluate(111 """() => {112 document.cookie = 'username=John Doe';113 document.cookie = 'password=1234';114 return document.cookie.split('; ').sort().join('; ');115 }"""116 )117 cookies = await context.cookies()118 cookies.sort(key=lambda r: r["name"])119 assert document_cookie == "password=1234; username=John Doe"120 assert cookies == [121 {122 "name": "password",123 "value": "1234",124 "domain": "localhost",125 "path": "/",126 "expires": -1,127 "httpOnly": False,128 "secure": False,129 "sameSite": "None",130 },131 {132 "name": "username",133 "value": "John Doe",134 "domain": "localhost",135 "path": "/",136 "expires": -1,137 "httpOnly": False,138 "secure": False,139 "sameSite": "None",140 },141 ]142async def test_should_get_cookies_from_multiple_urls(context):143 await context.add_cookies(144 [145 {"url": "https://foo.com", "name": "doggo", "value": "woofs"},146 {"url": "https://bar.com", "name": "catto", "value": "purrs"},147 {"url": "https://baz.com", "name": "birdo", "value": "tweets"},148 ]149 )150 cookies = await context.cookies(["https://foo.com", "https://baz.com"])151 cookies.sort(key=lambda r: r["name"])152 assert cookies == [153 {154 "name": "birdo",155 "value": "tweets",156 "domain": "baz.com",157 "path": "/",158 "expires": -1,159 "httpOnly": False,160 "secure": True,161 "sameSite": "None",162 },163 {164 "name": "doggo",165 "value": "woofs",166 "domain": "foo.com",167 "path": "/",168 "expires": -1,169 "httpOnly": False,170 "secure": True,171 "sameSite": "None",172 },...
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!