How to use test_goto_should_work_with_anchor_navigation method in Playwright Python

Best Python code snippet using playwright-python

Run Playwright Python automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

test_navigation.py

Source: test_navigation.py Github

copy
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 at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# 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 and
13# limitations under the License.
14
15import asyncio
16import re
17import sys
18from typing import Any
19
20import pytest
21
22from playwright.async_api import Error, Page, Request, TimeoutError
23from tests.server import Server
24
25
26async def test_goto_should_work(page, server):
27    await page.goto(server.EMPTY_PAGE)
28    assert page.url == server.EMPTY_PAGE
29
30
31async def test_goto_should_work_with_file_URL(page, server, assetdir):
32    fileurl = (assetdir / "frames" / "two-frames.html").as_uri()
33    await page.goto(fileurl)
34    assert page.url.lower() == fileurl.lower()
35    assert len(page.frames) == 3
36
37
38async def test_goto_should_use_http_for_no_protocol(page, server):
39    await page.goto(server.EMPTY_PAGE[7:])
40    assert page.url == server.EMPTY_PAGE
41
42
43async def test_goto_should_work_cross_process(page, server):
44    await page.goto(server.EMPTY_PAGE)
45    assert page.url == server.EMPTY_PAGE
46
47    url = server.CROSS_PROCESS_PREFIX + "/empty.html"
48    request_frames = []
49
50    def on_request(r: Request) -> None:
51        if r.url == url:
52            request_frames.append(r.frame)
53
54    page.on("request", on_request)
55
56    response = await page.goto(url)
57    assert page.url == url
58    assert response.frame == page.main_frame
59    assert request_frames[0] == page.main_frame
60    assert response.url == url
61
62
63async def test_goto_should_capture_iframe_navigation_request(page, server):
64    await page.goto(server.EMPTY_PAGE)
65    assert page.url == server.EMPTY_PAGE
66
67    request_frames = []
68
69    def on_request(r: Request) -> None:
70        if r.url == server.PREFIX + "/frames/frame.html":
71            request_frames.append(r.frame)
72
73    page.on("request", on_request)
74
75    response = await page.goto(server.PREFIX + "/frames/one-frame.html")
76    assert page.url == server.PREFIX + "/frames/one-frame.html"
77    assert response.frame == page.main_frame
78    assert response.url == server.PREFIX + "/frames/one-frame.html"
79
80    assert len(page.frames) == 2
81    assert request_frames[0] == page.frames[1]
82
83
84async def test_goto_should_capture_cross_process_iframe_navigation_request(
85    page, server
86):
87    await page.goto(server.EMPTY_PAGE)
88    assert page.url == server.EMPTY_PAGE
89
90    request_frames = []
91
92    def on_request(r: Request) -> None:
93        if r.url == server.CROSS_PROCESS_PREFIX + "/frames/frame.html":
94            request_frames.append(r.frame)
95
96    page.on("request", on_request)
97
98    response = await page.goto(server.CROSS_PROCESS_PREFIX + "/frames/one-frame.html")
99    assert page.url == server.CROSS_PROCESS_PREFIX + "/frames/one-frame.html"
100    assert response.frame == page.main_frame
101    assert response.url == server.CROSS_PROCESS_PREFIX + "/frames/one-frame.html"
102
103    assert len(page.frames) == 2
104    assert request_frames[0] == page.frames[1]
105
106
107async def test_goto_should_work_with_anchor_navigation(page, server):
108    await page.goto(server.EMPTY_PAGE)
109    assert page.url == server.EMPTY_PAGE
110    await page.goto(server.EMPTY_PAGE + "#foo")
111    assert page.url == server.EMPTY_PAGE + "#foo"
112    await page.goto(server.EMPTY_PAGE + "#bar")
113    assert page.url == server.EMPTY_PAGE + "#bar"
114
115
116async def test_goto_should_work_with_redirects(page, server):
117    server.set_redirect("/redirect/1.html", "/redirect/2.html")
118    server.set_redirect("/redirect/2.html", "/empty.html")
119    response = await page.goto(server.PREFIX + "/redirect/1.html")
120    assert response.status == 200
121    assert page.url == server.EMPTY_PAGE
122
123
124async def test_goto_should_navigate_to_about_blank(page, server):
125    response = await page.goto("about:blank")
126    assert response is None
127
128
129async def test_goto_should_return_response_when_page_changes_its_url_after_load(
130    page, server
131):
132    response = await page.goto(server.PREFIX + "/historyapi.html")
133    assert response.status == 200
134
135
136@pytest.mark.skip_browser("firefox")
137async def test_goto_should_work_with_subframes_return_204(page, server):
138    def handle(request):
139        request.setResponseCode(204)
140        request.finish()
141
142    server.set_route("/frames/frame.html", handle)
143
144    await page.goto(server.PREFIX + "/frames/one-frame.html")
145
146
147async def test_goto_should_fail_when_server_returns_204(
148    page, server, is_chromium, is_webkit
149):
150    # WebKit just loads an empty page.
151    def handle(request):
152        request.setResponseCode(204)
153        request.finish()
154
155    server.set_route("/empty.html", handle)
156
157    with pytest.raises(Error) as exc_info:
158        await page.goto(server.EMPTY_PAGE)
159    assert exc_info.value
160    if is_chromium:
161        assert "net::ERR_ABORTED" in exc_info.value.message
162    elif is_webkit:
163        assert "Aborted: 204 No Content" in exc_info.value.message
164    else:
165        assert "NS_BINDING_ABORTED" in exc_info.value.message
166
167
168async def test_goto_should_navigate_to_empty_page_with_domcontentloaded(page, server):
169    response = await page.goto(server.EMPTY_PAGE, wait_until="domcontentloaded")
170    assert response.status == 200
171
172
173async def test_goto_should_work_when_page_calls_history_api_in_beforeunload(
174    page, server
175):
176    await page.goto(server.EMPTY_PAGE)
177    await page.evaluate(
178        """() => {
179        window.addEventListener('beforeunload', () => history.replaceState(null, 'initial', window.location.href), false)
180    }"""
181    )
182
183    response = await page.goto(server.PREFIX + "/grid.html")
184    assert response.status == 200
185
186
187async def test_goto_should_fail_when_navigating_to_bad_url(
188    page, server, is_chromium, is_webkit
189):
190    with pytest.raises(Error) as exc_info:
191        await page.goto("asdfasdf")
192    if is_chromium or is_webkit:
193        assert "Cannot navigate to invalid URL" in exc_info.value.message
194    else:
195        assert "Invalid url" in exc_info.value.message
196
197
198async def test_goto_should_fail_when_navigating_to_bad_ssl(
199    page, https_server, browser_name
200):
201    with pytest.raises(Error) as exc_info:
202        await page.goto(https_server.EMPTY_PAGE)
203    expect_ssl_error(exc_info.value.message, browser_name)
204
205
206async def test_goto_should_fail_when_navigating_to_bad_ssl_after_redirects(
207    page, server, https_server, browser_name
208):
209    server.set_redirect("/redirect/1.html", "/redirect/2.html")
210    server.set_redirect("/redirect/2.html", "/empty.html")
211    with pytest.raises(Error) as exc_info:
212        await page.goto(https_server.PREFIX + "/redirect/1.html")
213    expect_ssl_error(exc_info.value.message, browser_name)
214
215
216async def test_goto_should_not_crash_when_navigating_to_bad_ssl_after_a_cross_origin_navigation(
217    page, server, https_server, browser_name
218):
219    await page.goto(server.CROSS_PROCESS_PREFIX + "/empty.html")
220    with pytest.raises(Error):
221        await page.goto(https_server.EMPTY_PAGE)
222
223
224async def test_goto_should_throw_if_networkidle2_is_passed_as_an_option(page, server):
225    with pytest.raises(Error) as exc_info:
226        await page.goto(server.EMPTY_PAGE, wait_until="networkidle2")
227    assert (
228        "wait_until: expected one of (load|domcontentloaded|networkidle|commit)"
229        in exc_info.value.message
230    )
231
232
233async def test_goto_should_fail_when_main_resources_failed_to_load(
234    page, server, is_chromium, is_webkit, is_win
235):
236    with pytest.raises(Error) as exc_info:
237        await page.goto("http://localhost:44123/non-existing-url")
238    if is_chromium:
239        assert "net::ERR_CONNECTION_REFUSED" in exc_info.value.message
240    elif is_webkit and is_win:
241        assert "Couldn't connect to server" in exc_info.value.message
242    elif is_webkit:
243        assert "Could not connect" in exc_info.value.message
244    else:
245        assert "NS_ERROR_CONNECTION_REFUSED" in exc_info.value.message
246
247
248async def test_goto_should_fail_when_exceeding_maximum_navigation_timeout(page, server):
249    # Hang for request to the empty.html
250    server.set_route("/empty.html", lambda request: None)
251    with pytest.raises(Error) as exc_info:
252        await page.goto(server.PREFIX + "/empty.html", timeout=1)
253    assert "Timeout 1ms exceeded" in exc_info.value.message
254    assert server.PREFIX + "/empty.html" in exc_info.value.message
255    assert isinstance(exc_info.value, TimeoutError)
256
257
258async def test_goto_should_fail_when_exceeding_default_maximum_navigation_timeout(
259    page, server
260):
261    # Hang for request to the empty.html
262    server.set_route("/empty.html", lambda request: None)
263    page.context.set_default_navigation_timeout(2)
264    page.set_default_navigation_timeout(1)
265    with pytest.raises(Error) as exc_info:
266        await page.goto(server.PREFIX + "/empty.html")
267    assert "Timeout 1ms exceeded" in exc_info.value.message
268    assert server.PREFIX + "/empty.html" in exc_info.value.message
269    assert isinstance(exc_info.value, TimeoutError)
270
271
272async def test_goto_should_fail_when_exceeding_browser_context_navigation_timeout(
273    page, server
274):
275    # Hang for request to the empty.html
276    server.set_route("/empty.html", lambda request: None)
277    page.context.set_default_navigation_timeout(2)
278    with pytest.raises(Error) as exc_info:
279        await page.goto(server.PREFIX + "/empty.html")
280    assert "Timeout 2ms exceeded" in exc_info.value.message
281    assert server.PREFIX + "/empty.html" in exc_info.value.message
282    assert isinstance(exc_info.value, TimeoutError)
283
284
285async def test_goto_should_fail_when_exceeding_default_maximum_timeout(page, server):
286    # Hang for request to the empty.html
287    server.set_route("/empty.html", lambda request: None)
288    page.context.set_default_timeout(2)
289    page.set_default_timeout(1)
290    with pytest.raises(Error) as exc_info:
291        await page.goto(server.PREFIX + "/empty.html")
292    assert "Timeout 1ms exceeded" in exc_info.value.message
293    assert server.PREFIX + "/empty.html" in exc_info.value.message
294    assert isinstance(exc_info.value, TimeoutError)
295
296
297async def test_goto_should_fail_when_exceeding_browser_context_timeout(page, server):
298    # Hang for request to the empty.html
299    server.set_route("/empty.html", lambda request: None)
300    page.context.set_default_timeout(2)
301    with pytest.raises(Error) as exc_info:
302        await page.goto(server.PREFIX + "/empty.html")
303    assert "Timeout 2ms exceeded" in exc_info.value.message
304    assert server.PREFIX + "/empty.html" in exc_info.value.message
305    assert isinstance(exc_info.value, TimeoutError)
306
307
308async def test_goto_should_prioritize_default_navigation_timeout_over_default_timeout(
309    page, server
310):
311    # Hang for request to the empty.html
312    server.set_route("/empty.html", lambda request: None)
313    page.set_default_timeout(0)
314    page.set_default_navigation_timeout(1)
315    with pytest.raises(Error) as exc_info:
316        await page.goto(server.PREFIX + "/empty.html")
317    assert "Timeout 1ms exceeded" in exc_info.value.message
318    assert server.PREFIX + "/empty.html" in exc_info.value.message
319    assert isinstance(exc_info.value, TimeoutError)
320
321
322async def test_goto_should_disable_timeout_when_its_set_to_0(page, server):
323    loaded = []
324    page.once("load", lambda: loaded.append(True))
325    await page.goto(server.PREFIX + "/grid.html", timeout=0, wait_until="load")
326    assert loaded == [True]
327
328
329async def test_goto_should_work_when_navigating_to_valid_url(page, server):
330    response = await page.goto(server.EMPTY_PAGE)
331    assert response.ok
332
333
334async def test_goto_should_work_when_navigating_to_data_url(page, server):
335    response = await page.goto("data:text/html,hello")
336    assert response is None
337
338
339async def test_goto_should_work_when_navigating_to_404(page, server):
340    response = await page.goto(server.PREFIX + "/not-found")
341    assert response.ok is False
342    assert response.status == 404
343
344
345async def test_goto_should_return_last_response_in_redirect_chain(page, server):
346    server.set_redirect("/redirect/1.html", "/redirect/2.html")
347    server.set_redirect("/redirect/2.html", "/redirect/3.html")
348    server.set_redirect("/redirect/3.html", server.EMPTY_PAGE)
349    response = await page.goto(server.PREFIX + "/redirect/1.html")
350    assert response.ok
351    assert response.url == server.EMPTY_PAGE
352
353
354async def test_goto_should_navigate_to_data_url_and_not_fire_dataURL_requests(
355    page, server
356):
357    requests = []
358    page.on("request", lambda request: requests.append(request))
359    dataURL = "data:text/html,<div>yo</div>"
360    response = await page.goto(dataURL)
361    assert response is None
362    assert requests == []
363
364
365async def test_goto_should_navigate_to_url_with_hash_and_fire_requests_without_hash(
366    page, server
367):
368    requests = []
369    page.on("request", lambda request: requests.append(request))
370    response = await page.goto(server.EMPTY_PAGE + "#hash")
371    assert response.status == 200
372    assert response.url == server.EMPTY_PAGE
373    assert len(requests) == 1
374    assert requests[0].url == server.EMPTY_PAGE
375
376
377async def test_goto_should_work_with_self_requesting_page(page, server):
378    response = await page.goto(server.PREFIX + "/self-request.html")
379    assert response.status == 200
380    assert "self-request.html" in response.url
381
382
383async def test_goto_should_fail_when_navigating_and_show_the_url_at_the_error_message(
384    page, server, https_server
385):
386    url = https_server.PREFIX + "/redirect/1.html"
387    with pytest.raises(Error) as exc_info:
388        await page.goto(url)
389    assert url in exc_info.value.message
390
391
392async def test_goto_should_be_able_to_navigate_to_a_page_controlled_by_service_worker(
393    page, server
394):
395    await page.goto(server.PREFIX + "/serviceworkers/fetch/sw.html")
396    await page.evaluate("window.activationPromise")
397    await page.goto(server.PREFIX + "/serviceworkers/fetch/sw.html")
398
399
400async def test_goto_should_send_referer(page, server):
401    [request1, request2, _] = await asyncio.gather(
402        server.wait_for_request("/grid.html"),
403        server.wait_for_request("/digits/1.png"),
404        page.goto(server.PREFIX + "/grid.html", referer="http://google.com/"),
405    )
406    assert request1.getHeader("referer") == "http://google.com/"
407    # Make sure subresources do not inherit referer.
408    assert request2.getHeader("referer") == server.PREFIX + "/grid.html"
409    assert page.url == server.PREFIX + "/grid.html"
410
411
412async def test_goto_should_reject_referer_option_when_set_extra_http_headers_provides_referer(
413    page, server
414):
415    await page.set_extra_http_headers({"referer": "http://microsoft.com/"})
416    with pytest.raises(Error) as exc_info:
417        await page.goto(server.PREFIX + "/grid.html", referer="http://google.com/")
418    assert (
419        '"referer" is already specified as extra HTTP header' in exc_info.value.message
420    )
421    assert server.PREFIX + "/grid.html" in exc_info.value.message
422
423
424async def test_goto_should_work_with_commit(page: Page, server):
425    await page.goto(server.EMPTY_PAGE, wait_until="commit")
426    assert page.url == server.EMPTY_PAGE
427
428
429async def test_network_idle_should_navigate_to_empty_page_with_networkidle(
430    page, server
431):
432    response = await page.goto(server.EMPTY_PAGE, wait_until="networkidle")
433    assert response.status == 200
434
435
436async def test_wait_for_nav_should_work(page, server):
437    await page.goto(server.EMPTY_PAGE)
438    async with page.expect_navigation() as response_info:
439        await page.evaluate(
440            "url => window.location.href = url", server.PREFIX + "/grid.html"
441        )
442    response = await response_info.value
443    assert response.ok
444    assert "grid.html" in response.url
445
446
447async def test_wait_for_nav_should_respect_timeout(page, server):
448    with pytest.raises(Error) as exc_info:
449        async with page.expect_navigation(url="**/frame.html", timeout=2500):
450            await page.goto(server.EMPTY_PAGE)
451    assert "Timeout 2500ms exceeded" in exc_info.value.message
452
453
454async def test_wait_for_nav_should_work_with_both_domcontentloaded_and_load(
455    page, server
456):
457    async with page.expect_navigation(
458        wait_until="domcontentloaded"
459    ), page.expect_navigation(wait_until="load"):
460        await page.goto(server.PREFIX + "/one-style.html")
461
462
463async def test_wait_for_nav_should_work_with_clicking_on_anchor_links(page, server):
464    await page.goto(server.EMPTY_PAGE)
465    await page.set_content('<a href="#foobar">foobar</a>')
466    async with page.expect_navigation() as response_info:
467        await page.click("a"),
468    response = await response_info.value
469    assert response is None
470    assert page.url == server.EMPTY_PAGE + "#foobar"
471
472
473async def test_wait_for_nav_should_work_with_clicking_on_links_which_do_not_commit_navigation(
474    page, server, https_server, browser_name
475):
476    await page.goto(server.EMPTY_PAGE)
477    await page.set_content(f"<a href='{https_server.EMPTY_PAGE}'>foobar</a>")
478    with pytest.raises(Error) as exc_info:
479        async with page.expect_navigation():
480            await page.click("a"),
481    expect_ssl_error(exc_info.value.message, browser_name)
482
483
484async def test_wait_for_nav_should_work_with_history_push_state(page, server):
485    await page.goto(server.EMPTY_PAGE)
486    await page.set_content(
487        """
488        <a onclick='javascript:pushState()'>SPA</a>
489        <script>
490            function pushState() { history.pushState({}, '', 'wow.html') }
491        </script>
492    """
493    )
494    async with page.expect_navigation() as response_info:
495        await page.click("a"),
496    response = await response_info.value
497    assert response is None
498    assert page.url == server.PREFIX + "/wow.html"
499
500
501async def test_wait_for_nav_should_work_with_history_replace_state(page, server):
502    await page.goto(server.EMPTY_PAGE)
503    await page.set_content(
504        """
505        <a onclick='javascript:replaceState()'>SPA</a>
506        <script>
507            function replaceState() { history.replaceState({}, '', '/replaced.html') }
508        </script>
509    """
510    )
511    async with page.expect_navigation() as response_info:
512        await page.click("a"),
513    response = await response_info.value
514    assert response is None
515    assert page.url == server.PREFIX + "/replaced.html"
516
517
518async def test_wait_for_nav_should_work_with_dom_history_back_forward(page, server):
519    await page.goto(server.EMPTY_PAGE)
520    await page.set_content(
521        """
522      <a id=back onclick='javascript:go_back()'>back</a>
523      <a id=forward onclick='javascript:go_forward()'>forward</a>
524      <script>
525        function go_back() { history.back(); }
526        function go_forward() { history.forward(); }
527        history.pushState({}, '', '/first.html')
528        history.pushState({}, '', '/second.html')
529      </script>
530    """
531    )
532    assert page.url == server.PREFIX + "/second.html"
533    async with page.expect_navigation() as back_response_info:
534        await page.click("a#back"),
535    back_response = await back_response_info.value
536    assert back_response is None
537    assert page.url == server.PREFIX + "/first.html"
538    async with page.expect_navigation() as forward_response_info:
539        await page.click("a#forward"),
540    forward_response = await forward_response_info.value
541    assert forward_response is None
542    assert page.url == server.PREFIX + "/second.html"
543
544
545async def test_wait_for_nav_should_work_when_subframe_issues_window_stop(page, server):
546    server.set_route("/frames/style.css", lambda _: None)
547    navigation_promise = asyncio.create_task(
548        page.goto(server.PREFIX + "/frames/one-frame.html")
549    )
550    await asyncio.sleep(0)
551    async with page.expect_event("frameattached") as frame_info:
552        pass
553    frame = await frame_info.value
554
555    async with page.expect_event("framenavigated", lambda f: f == frame):
556        pass
557    await asyncio.gather(frame.evaluate("() => window.stop()"), navigation_promise)
558
559
560async def test_wait_for_nav_should_work_with_url_match(page, server):
561    responses = [None, None, None]
562
563    async def wait_for_nav(url: Any, index: int) -> None:
564        async with page.expect_navigation(url=url) as response_info:
565            pass
566        responses[index] = await response_info.value
567
568    response0_promise = asyncio.create_task(
569        wait_for_nav(re.compile(r"one-style\.html"), 0)
570    )
571    response1_promise = asyncio.create_task(
572        wait_for_nav(re.compile(r"\/frame.html"), 1)
573    )
574    response2_promise = asyncio.create_task(
575        wait_for_nav(lambda url: "foo=bar" in url, 2)
576    )
577    assert responses == [None, None, None]
578    await page.goto(server.EMPTY_PAGE)
579    assert responses == [None, None, None]
580    await page.goto(server.PREFIX + "/frame.html")
581    assert responses[0] is None
582    await response1_promise
583    assert responses[1] is not None
584    assert responses[2] is None
585    await page.goto(server.PREFIX + "/one-style.html")
586    await response0_promise
587    assert responses[0] is not None
588    assert responses[1] is not None
589    assert responses[2] is None
590    await page.goto(server.PREFIX + "/frame.html?foo=bar")
591    await response2_promise
592    assert responses[0] is not None
593    assert responses[1] is not None
594    assert responses[2] is not None
595    await page.goto(server.PREFIX + "/empty.html")
596    assert responses[0].url == server.PREFIX + "/one-style.html"
597    assert responses[1].url == server.PREFIX + "/frame.html"
598    assert responses[2].url == server.PREFIX + "/frame.html?foo=bar"
599
600
601async def test_wait_for_nav_should_work_with_url_match_for_same_document_navigations(
602    page, server
603):
604    await page.goto(server.EMPTY_PAGE)
605    async with page.expect_navigation(url=re.compile(r"third\.html")) as response_info:
606        assert not response_info.is_done()
607        await page.evaluate("history.pushState({}, '', '/first.html')")
608        assert not response_info.is_done()
609        await page.evaluate("history.pushState({}, '', '/second.html')")
610        assert not response_info.is_done()
611        await page.evaluate("history.pushState({}, '', '/third.html')")
612    assert response_info.is_done()
613
614
615async def test_wait_for_nav_should_work_for_cross_process_navigations(page, server):
616    await page.goto(server.EMPTY_PAGE)
617    url = server.CROSS_PROCESS_PREFIX + "/empty.html"
618    async with page.expect_navigation(wait_until="domcontentloaded") as response_info:
619        await page.goto(url)
620    response = await response_info.value
621    assert response.url == url
622    assert page.url == url
623    assert await page.evaluate("document.location.href") == url
624
625
626async def test_expect_navigation_should_work_for_cross_process_navigations(
627    page, server
628):
629    await page.goto(server.EMPTY_PAGE)
630    url = server.CROSS_PROCESS_PREFIX + "/empty.html"
631    async with page.expect_navigation(wait_until="domcontentloaded") as response_info:
632        goto_task = asyncio.create_task(page.goto(url))
633    response = await response_info.value
634    assert response.url == url
635    assert page.url == url
636    assert await page.evaluate("document.location.href") == url
637    await goto_task
638
639
640async def test_wait_for_nav_should_work_with_commit(page: Page, server):
641    await page.goto(server.EMPTY_PAGE)
642    async with page.expect_navigation(wait_until="commit") as response_info:
643        await page.evaluate(
644            "url => window.location.href = url", server.PREFIX + "/grid.html"
645        )
646    response = await response_info.value
647    assert response.ok
648    assert "grid.html" in response.url
649
650
651async def test_wait_for_load_state_should_respect_timeout(page, server):
652    requests = []
653
654    def handler(request: Any):
655        requests.append(request)
656
657    server.set_route("/one-style.css", handler)
658
659    await page.goto(server.PREFIX + "/one-style.html", wait_until="domcontentloaded")
660    with pytest.raises(Error) as exc_info:
661        await page.wait_for_load_state("load", timeout=1)
662    assert "Timeout 1ms exceeded." in exc_info.value.message
663
664
665async def test_wait_for_load_state_should_resolve_immediately_if_loaded(page, server):
666    await page.goto(server.PREFIX + "/one-style.html")
667    await page.wait_for_load_state()
668
669
670async def test_wait_for_load_state_should_throw_for_bad_state(page, server):
671    await page.goto(server.PREFIX + "/one-style.html")
672    with pytest.raises(Error) as exc_info:
673        await page.wait_for_load_state("bad")
674    assert (
675        "state: expected one of (load|domcontentloaded|networkidle|commit)"
676        in exc_info.value.message
677    )
678
679
680async def test_wait_for_load_state_should_resolve_immediately_if_load_state_matches(
681    page, server
682):
683    await page.goto(server.EMPTY_PAGE)
684
685    requests = []
686
687    def handler(request: Any):
688        requests.append(request)
689
690    server.set_route("/one-style.css", handler)
691
692    await page.goto(server.PREFIX + "/one-style.html", wait_until="domcontentloaded")
693    await page.wait_for_load_state("domcontentloaded")
694
695
696async def test_wait_for_load_state_networkidle(page: Page, server: Server):
697    wait_for_network_idle_future = asyncio.create_task(
698        page.wait_for_load_state("networkidle")
699    )
700    await page.goto(server.PREFIX + "/networkidle.html")
701    await wait_for_network_idle_future
702
703
704async def test_wait_for_load_state_should_work_with_pages_that_have_loaded_before_being_connected_to(
705    page, context, server
706):
707    await page.goto(server.EMPTY_PAGE)
708    async with page.expect_popup() as popup_info:
709        await page.evaluate("window._popup = window.open(document.location.href)")
710
711    # The url is about:blank in FF.
712    popup = await popup_info.value
713    assert popup.url == server.EMPTY_PAGE
714    await popup.wait_for_load_state()
715    assert popup.url == server.EMPTY_PAGE
716
717
718async def test_wait_for_load_state_should_wait_for_load_state_of_empty_url_popup(
719    browser, page, is_firefox
720):
721    ready_state = []
722    async with page.expect_popup() as popup_info:
723        ready_state.append(
724            await page.evaluate(
725                """() => {
726            popup = window.open('')
727            return popup.document.readyState
728        }"""
729            )
730        )
731
732    popup = await popup_info.value
733    await popup.wait_for_load_state()
734    assert ready_state == ["uninitialized"] if is_firefox else ["complete"]
735    assert await popup.evaluate("() => document.readyState") == ready_state[0]
736
737
738async def test_wait_for_load_state_should_wait_for_load_state_of_about_blank_popup_(
739    browser, page
740):
741    async with page.expect_popup() as popup_info:
742        await page.evaluate("window.open('about:blank') && 1")
743    popup = await popup_info.value
744    await popup.wait_for_load_state()
745    assert await popup.evaluate("document.readyState") == "complete"
746
747
748async def test_wait_for_load_state_should_wait_for_load_state_of_about_blank_popup_with_noopener(
749    browser, page
750):
751    async with page.expect_popup() as popup_info:
752        await page.evaluate("window.open('about:blank', null, 'noopener') && 1")
753
754    popup = await popup_info.value
755    await popup.wait_for_load_state()
756    assert await popup.evaluate("document.readyState") == "complete"
757
758
759async def test_wait_for_load_state_should_wait_for_load_state_of_popup_with_network_url_(
760    browser, page, server
761):
762    await page.goto(server.EMPTY_PAGE)
763    async with page.expect_popup() as popup_info:
764        await page.evaluate("url => window.open(url) && 1", server.EMPTY_PAGE)
765
766    popup = await popup_info.value
767    await popup.wait_for_load_state()
768    assert await popup.evaluate("document.readyState") == "complete"
769
770
771async def test_wait_for_load_state_should_wait_for_load_state_of_popup_with_network_url_and_noopener_(
772    browser, page, server
773):
774    await page.goto(server.EMPTY_PAGE)
775    async with page.expect_popup() as popup_info:
776        await page.evaluate(
777            "url => window.open(url, null, 'noopener') && 1", server.EMPTY_PAGE
778        )
779
780    popup = await popup_info.value
781    await popup.wait_for_load_state()
782    assert await popup.evaluate("document.readyState") == "complete"
783
784
785async def test_wait_for_load_state_should_work_with_clicking_target__blank(
786    browser, page, server
787):
788    await page.goto(server.EMPTY_PAGE)
789    await page.set_content(
790        '<a target=_blank rel="opener" href="/one-style.html">yo</a>'
791    )
792    async with page.expect_popup() as popup_info:
793        await page.click("a")
794    popup = await popup_info.value
795    await popup.wait_for_load_state()
796    assert await popup.evaluate("document.readyState") == "complete"
797
798
799async def test_wait_for_load_state_should_wait_for_load_state_of_new_page(
800    context, page, server
801):
802    async with context.expect_page() as page_info:
803        await context.new_page()
804    new_page = await page_info.value
805    await new_page.wait_for_load_state()
806    assert await new_page.evaluate("document.readyState") == "complete"
807
808
809async def test_wait_for_load_state_in_popup(context, server):
810    page = await context.new_page()
811    await page.goto(server.EMPTY_PAGE)
812    css_requests = []
813
814    def handle_request(request):
815        css_requests.append(request)
816        request.write(b"body {}")
817        request.finish()
818
819    server.set_route("/one-style.css", handle_request)
820
821    async with page.expect_popup() as popup_info:
822        await page.evaluate(
823            "url => window.popup = window.open(url)", server.PREFIX + "/one-style.html"
824        )
825
826    popup = await popup_info.value
827    await popup.wait_for_load_state()
828    assert len(css_requests)
829
830
831async def test_go_back_should_work(page, server):
832    assert await page.go_back() is None
833
834    await page.goto(server.EMPTY_PAGE)
835    await page.goto(server.PREFIX + "/grid.html")
836
837    response = await page.go_back()
838    assert response.ok
839    assert server.EMPTY_PAGE in response.url
840
841    response = await page.go_forward()
842    assert response.ok
843    assert "/grid.html" in response.url
844
845    response = await page.go_forward()
846    assert response is None
847
848
849async def test_go_back_should_work_with_history_api(page, server):
850    await page.goto(server.EMPTY_PAGE)
851    await page.evaluate(
852        """() => {
853        history.pushState({}, '', '/first.html')
854        history.pushState({}, '', '/second.html')
855    }"""
856    )
857    assert page.url == server.PREFIX + "/second.html"
858
859    await page.go_back()
860    assert page.url == server.PREFIX + "/first.html"
861    await page.go_back()
862    assert page.url == server.EMPTY_PAGE
863    await page.go_forward()
864    assert page.url == server.PREFIX + "/first.html"
865
866
867async def test_frame_goto_should_navigate_subframes(page, server):
868    await page.goto(server.PREFIX + "/frames/one-frame.html")
869    assert "/frames/one-frame.html" in page.frames[0].url
870    assert "/frames/frame.html" in page.frames[1].url
871
872    response = await page.frames[1].goto(server.EMPTY_PAGE)
873    assert response.ok
874    assert response.frame == page.frames[1]
875
876
877async def test_frame_goto_should_reject_when_frame_detaches(page, server):
878    await page.goto(server.PREFIX + "/frames/one-frame.html")
879
880    await page.route("**/empty.html", lambda route, request: None)
881    navigation_task = asyncio.create_task(page.frames[1].goto(server.EMPTY_PAGE))
882    asyncio.create_task(page.eval_on_selector("iframe", "frame => frame.remove()"))
883    with pytest.raises(Error) as exc_info:
884        await navigation_task
885    assert "frame was detached" in exc_info.value.message
886
887
888async def test_frame_goto_should_continue_after_client_redirect(page, server):
889    server.set_route("/frames/script.js", lambda _: None)
890    url = server.PREFIX + "/frames/child-redirect.html"
891
892    with pytest.raises(Error) as exc_info:
893        await page.goto(url, timeout=2500, wait_until="networkidle")
894
895    assert "Timeout 2500ms exceeded." in exc_info.value.message
896    assert (
897        f'navigating to "{url}", waiting until "networkidle"' in exc_info.value.message
898    )
899
900
901async def test_frame_wait_for_nav_should_work(page, server):
902    await page.goto(server.PREFIX + "/frames/one-frame.html")
903    frame = page.frames[1]
904    async with frame.expect_navigation() as response_info:
905        await frame.evaluate(
906            "url => window.location.href = url", server.PREFIX + "/grid.html"
907        )
908    response = await response_info.value
909    assert response.ok
910    assert "grid.html" in response.url
911    assert response.frame == frame
912    assert "/frames/one-frame.html" in page.url
913
914
915async def test_frame_wait_for_nav_should_fail_when_frame_detaches(page, server: Server):
916    await page.goto(server.PREFIX + "/frames/one-frame.html")
917    frame = page.frames[1]
918    server.set_route("/empty.html", lambda _: None)
919    with pytest.raises(Error) as exc_info:
920        async with frame.expect_navigation():
921
922            async def after_it():
923                await server.wait_for_request("/empty.html")
924                await page.eval_on_selector(
925                    "iframe", "frame => setTimeout(() => frame.remove(), 0)"
926                )
927
928            await asyncio.gather(
929                page.eval_on_selector(
930                    "iframe",
931                    "frame => frame.contentWindow.location.href = '/empty.html'",
932                ),
933                after_it(),
934            )
935    assert "frame was detached" in exc_info.value.message
936
937
938async def test_frame_wait_for_load_state_should_work(page, server):
939    await page.goto(server.PREFIX + "/frames/one-frame.html")
940    frame = page.frames[1]
941
942    request_future = asyncio.Future()
943    await page.route(
944        server.PREFIX + "/one-style.css",
945        lambda route, request: request_future.set_result(route),
946    )
947
948    await frame.goto(server.PREFIX + "/one-style.html", wait_until="domcontentloaded")
949    request = await request_future
950    load_task = asyncio.create_task(frame.wait_for_load_state())
951    # give the promise a chance to resolve, even though it shouldn't
952    await page.evaluate("1")
953    assert not load_task.done()
954    asyncio.create_task(request.continue_())
955    await load_task
956
957
958async def test_reload_should_work(page, server):
959    await page.goto(server.EMPTY_PAGE)
960    await page.evaluate("window._foo = 10")
961    await page.reload()
962    assert await page.evaluate("window._foo") is None
963
964
965async def test_reload_should_work_with_data_url(page, server):
966    await page.goto("data:text/html,hello")
967    assert "hello" in await page.content()
968    assert await page.reload() is None
969    assert "hello" in await page.content()
970
971
972async def test_should_work_with__blank_target(page, server):
973    def handler(request):
974        request.write(
975            f'<a href="{server.EMPTY_PAGE}" target="_blank">Click me</a>'.encode()
976        )
977        request.finish()
978
979    server.set_route("/empty.html", handler)
980
981    await page.goto(server.EMPTY_PAGE)
982    await page.click('"Click me"')
983
984
985async def test_should_work_with_cross_process__blank_target(page, server):
986    def handler(request):
987        request.write(
988            f'<a href="{server.CROSS_PROCESS_PREFIX}/empty.html" target="_blank">Click me</a>'.encode()
989        )
990        request.finish()
991
992    server.set_route("/empty.html", handler)
993
994    await page.goto(server.EMPTY_PAGE)
995    await page.click('"Click me"')
996
997
998def expect_ssl_error(error_message: str, browser_name: str) -> None:
999    if browser_name == "chromium":
1000        assert "net::ERR_CERT_AUTHORITY_INVALID" in error_message
1001    elif browser_name == "webkit":
1002        if sys.platform == "darwin":
1003            assert "The certificate for this server is invalid" in error_message
1004        elif sys.platform == "win32":
1005            assert "SSL peer certificate or SSH remote key was not OK" in error_message
1006        else:
1007            assert "Unacceptable TLS certificate" in error_message
1008    else:
1009        assert "SSL_ERROR_UNKNOWN" in error_message
1010
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run Python Tests on LambdaTest Cloud Grid

Execute automation tests with Playwright Python on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)