Skip to content

Commit 32ef4be

Browse files
committed
fix(page): use runBeforeUnload channel method
1 parent c465fe1 commit 32ef4be

3 files changed

Lines changed: 114 additions & 91 deletions

File tree

playwright/_impl/_page.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -852,14 +852,19 @@ async def aria_snapshot(
852852

853853
async def close(self, runBeforeUnload: bool = None, reason: str = None) -> None:
854854
self._close_reason = reason
855-
self._close_was_called = True
855+
if not runBeforeUnload:
856+
self._close_was_called = True
856857
try:
857-
await self._channel.send("close", None, locals_to_params(locals()))
858858
if self._owned_context:
859859
await self._owned_context.close()
860+
elif runBeforeUnload:
861+
await self._channel.send("runBeforeUnload", None)
862+
else:
863+
await self._channel.send("close", None, {"reason": reason})
860864
except Exception as e:
861-
if not is_target_closed_error(e) and not runBeforeUnload:
862-
raise e
865+
if is_target_closed_error(e) and not runBeforeUnload:
866+
return
867+
raise e
863868

864869
def is_closed(self) -> bool:
865870
return self._is_closed

tests/async/test_screencast.py

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,71 +35,81 @@ def on_frame(frame: ScreencastFrame) -> None:
3535
event.set()
3636

3737
await page.screencast.start(on_frame=on_frame)
38-
await page.goto(server.EMPTY_PAGE)
39-
await page.evaluate("() => document.body.style.backgroundColor = 'red'")
40-
# Force a couple of paint cycles so engines that only emit on visual change
41-
# still produce a frame. Mirrors upstream `ensureSomeFrames`.
42-
for _ in range(3):
43-
await page.evaluate(
44-
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
45-
)
46-
await page.screenshot()
47-
await asyncio.wait_for(event.wait(), timeout=10)
48-
await page.screencast.stop()
38+
try:
39+
await page.goto(server.EMPTY_PAGE)
40+
await page.evaluate("() => document.body.style.backgroundColor = 'red'")
41+
# Force a couple of paint cycles so engines that only emit on visual change
42+
# still produce a frame. Mirrors upstream `ensureSomeFrames`.
43+
for _ in range(3):
44+
await page.evaluate(
45+
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
46+
)
47+
await page.screenshot()
48+
await asyncio.wait_for(event.wait(), timeout=10)
49+
finally:
50+
await page.screencast.stop()
4951
assert len(received) >= 1
5052
assert all(isinstance(d, bytes) and len(d) > 0 for d in received)
5153

5254

5355
async def test_starting_twice_should_throw(page: Page) -> None:
5456
await page.screencast.start(on_frame=lambda f: None)
55-
with pytest.raises(Exception, match="already started"):
56-
await page.screencast.start(on_frame=lambda f: None)
57-
await page.screencast.stop()
57+
try:
58+
with pytest.raises(Exception, match="already started"):
59+
await page.screencast.start(on_frame=lambda f: None)
60+
finally:
61+
await page.screencast.stop()
5862

5963

6064
async def test_show_overlays_and_overlay_apis_should_not_throw(page: Page) -> None:
6165
await page.screencast.start(on_frame=lambda f: None)
62-
await page.screencast.show_overlay("<div>hello</div>", duration=100)
63-
await page.screencast.show_chapter("ch", description="desc", duration=100)
64-
await page.screencast.hide_overlays()
65-
await page.screencast.show_overlays()
66-
await page.screencast.show_actions(duration=100, position="top-right")
67-
await page.screencast.hide_actions()
68-
await page.screencast.stop()
66+
try:
67+
await page.screencast.show_overlay("<div>hello</div>", duration=100)
68+
await page.screencast.show_chapter("ch", description="desc", duration=100)
69+
await page.screencast.hide_overlays()
70+
await page.screencast.show_overlays()
71+
await page.screencast.show_actions(duration=100, position="top-right")
72+
await page.screencast.hide_actions()
73+
finally:
74+
await page.screencast.stop()
6975

7076

7177
async def test_on_frame_receives_viewport_size(
7278
browser: Browser, server: Server
7379
) -> None:
7480
context = await browser.new_context(viewport={"width": 1000, "height": 400})
75-
page = await context.new_page()
76-
received: list = []
77-
78-
def on_frame(frame: ScreencastFrame) -> None:
79-
received.append(frame)
80-
81-
size: ScreencastSize = {"width": 500, "height": 400}
82-
await page.screencast.start(on_frame=on_frame, size=size)
83-
await page.goto(server.EMPTY_PAGE)
84-
await page.evaluate("() => document.body.style.backgroundColor = 'red'")
85-
for _ in range(100):
86-
await page.evaluate(
87-
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
88-
)
89-
await page.screenshot()
90-
await page.screencast.stop()
91-
assert len(received) >= 1
92-
assert any(frame["viewportWidth"] == 1000 for frame in received)
93-
for frame in received:
94-
assert frame["viewportHeight"] == 400
95-
assert isinstance(frame["timestamp"], (int, float))
96-
await context.close()
81+
async with context:
82+
page = await context.new_page()
83+
received: list = []
84+
85+
def on_frame(frame: ScreencastFrame) -> None:
86+
received.append(frame)
87+
88+
size: ScreencastSize = {"width": 500, "height": 400}
89+
await page.screencast.start(on_frame=on_frame, size=size)
90+
try:
91+
await page.goto(server.EMPTY_PAGE)
92+
await page.evaluate("() => document.body.style.backgroundColor = 'red'")
93+
for _ in range(100):
94+
await page.evaluate(
95+
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
96+
)
97+
await page.screenshot()
98+
finally:
99+
await page.screencast.stop()
100+
assert len(received) >= 1
101+
assert any(frame["viewportWidth"] == 1000 for frame in received)
102+
for frame in received:
103+
assert frame["viewportHeight"] == 400
104+
assert isinstance(frame["timestamp"], (int, float))
97105

98106

99107
async def test_show_actions_should_accept_cursor_param(page: Page) -> None:
100108
await page.screencast.start(on_frame=lambda f: None)
101-
async with await page.screencast.show_actions(duration=100, cursor="pointer"):
102-
pass
103-
async with await page.screencast.show_actions(duration=100, cursor="none"):
104-
pass
105-
await page.screencast.stop()
109+
try:
110+
async with await page.screencast.show_actions(duration=100, cursor="pointer"):
111+
pass
112+
async with await page.screencast.show_actions(duration=100, cursor="none"):
113+
pass
114+
finally:
115+
await page.screencast.stop()

tests/sync/test_screencast.py

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,56 +27,64 @@ def test_should_expose_screencast_property(page: Page) -> None:
2727
def test_start_should_deliver_frames_via_callback(page: Page, server: Server) -> None:
2828
received: list = []
2929
page.screencast.start(on_frame=lambda f: received.append(f["data"]))
30-
page.goto(server.EMPTY_PAGE)
31-
page.evaluate("() => document.body.style.backgroundColor = 'red'")
32-
# Force a couple of paint cycles so engines that only emit on visual change
33-
# still produce a frame. Mirrors upstream `ensureSomeFrames`.
34-
for _ in range(3):
35-
page.evaluate(
36-
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
37-
)
38-
page.screenshot()
39-
deadline = time.time() + 10
40-
while not received and time.time() < deadline:
41-
page.wait_for_timeout(100)
42-
page.screencast.stop()
30+
try:
31+
page.goto(server.EMPTY_PAGE)
32+
page.evaluate("() => document.body.style.backgroundColor = 'red'")
33+
# Force a couple of paint cycles so engines that only emit on visual change
34+
# still produce a frame. Mirrors upstream `ensureSomeFrames`.
35+
for _ in range(3):
36+
page.evaluate(
37+
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
38+
)
39+
page.screenshot()
40+
deadline = time.time() + 10
41+
while not received and time.time() < deadline:
42+
page.wait_for_timeout(100)
43+
finally:
44+
page.screencast.stop()
4345
assert len(received) >= 1
4446
assert all(isinstance(d, bytes) and len(d) > 0 for d in received)
4547

4648

4749
def test_starting_twice_should_throw(page: Page) -> None:
4850
page.screencast.start(on_frame=lambda f: None)
49-
with pytest.raises(Exception, match="already started"):
50-
page.screencast.start(on_frame=lambda f: None)
51-
page.screencast.stop()
51+
try:
52+
with pytest.raises(Exception, match="already started"):
53+
page.screencast.start(on_frame=lambda f: None)
54+
finally:
55+
page.screencast.stop()
5256

5357

5458
def test_on_frame_receives_viewport_size(browser: Browser, server: Server) -> None:
5559
context = browser.new_context(viewport={"width": 1000, "height": 400})
56-
page = context.new_page()
57-
received: list = []
58-
size: ScreencastSize = {"width": 500, "height": 400}
59-
page.screencast.start(on_frame=lambda f: received.append(f), size=size)
60-
page.goto(server.EMPTY_PAGE)
61-
page.evaluate("() => document.body.style.backgroundColor = 'red'")
62-
for _ in range(100):
63-
page.evaluate(
64-
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
65-
)
66-
page.screenshot()
67-
page.screencast.stop()
68-
assert len(received) >= 1
69-
assert any(frame["viewportWidth"] == 1000 for frame in received)
70-
for frame in received:
71-
assert frame["viewportHeight"] == 400
72-
assert isinstance(frame["timestamp"], (int, float))
73-
context.close()
60+
with context:
61+
page = context.new_page()
62+
received: list = []
63+
size: ScreencastSize = {"width": 500, "height": 400}
64+
page.screencast.start(on_frame=lambda f: received.append(f), size=size)
65+
try:
66+
page.goto(server.EMPTY_PAGE)
67+
page.evaluate("() => document.body.style.backgroundColor = 'red'")
68+
for _ in range(100):
69+
page.evaluate(
70+
"() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"
71+
)
72+
page.screenshot()
73+
finally:
74+
page.screencast.stop()
75+
assert len(received) >= 1
76+
assert any(frame["viewportWidth"] == 1000 for frame in received)
77+
for frame in received:
78+
assert frame["viewportHeight"] == 400
79+
assert isinstance(frame["timestamp"], (int, float))
7480

7581

7682
def test_show_actions_should_accept_cursor_param(page: Page) -> None:
7783
page.screencast.start(on_frame=lambda f: None)
78-
with page.screencast.show_actions(duration=100, cursor="pointer"):
79-
pass
80-
with page.screencast.show_actions(duration=100, cursor="none"):
81-
pass
82-
page.screencast.stop()
84+
try:
85+
with page.screencast.show_actions(duration=100, cursor="pointer"):
86+
pass
87+
with page.screencast.show_actions(duration=100, cursor="none"):
88+
pass
89+
finally:
90+
page.screencast.stop()

0 commit comments

Comments
 (0)