diff --git a/tests/browsing_context/__snapshots__/test_navigate_events.ambr b/tests/browsing_context/__snapshots__/test_navigate_events.ambr index a82927e5e..2b8aff392 100644 --- a/tests/browsing_context/__snapshots__/test_navigate_events.ambr +++ b/tests/browsing_context/__snapshots__/test_navigate_events.ambr @@ -185,6 +185,67 @@ }), ]) # --- +# name: test_navigate_beforeunload_cancel[capabilities0] + list([ + dict({ + 'method': 'script.message', + 'params': dict({ + 'channel': 'beforeunload_channel', + 'data': dict({ + 'type': 'string', + 'value': 'beforeunload', + }), + 'source': dict({ + 'context': 'stable_0', + }), + }), + 'type': 'event', + }), + dict({ + 'method': 'browsingContext.navigationStarted', + 'params': dict({ + 'context': 'stable_0', + 'navigation': 'stable_1', + 'url': 'stable_2', + }), + 'type': 'event', + }), + dict({ + 'method': 'browsingContext.userPromptOpened', + 'params': dict({ + 'context': 'stable_0', + 'handler': 'dismiss', + 'message': '', + 'type': 'beforeunload', + }), + 'type': 'event', + }), + dict({ + 'method': 'browsingContext.navigationFailed', + 'params': dict({ + 'context': 'stable_0', + 'navigation': 'stable_1', + 'url': 'stable_2', + }), + 'type': 'event', + }), + dict({ + 'error': 'unknown error', + 'id': 'stable_3', + 'message': 'net::ERR_ABORTED', + 'type': 'error', + }), + dict({ + 'method': 'browsingContext.userPromptClosed', + 'params': dict({ + 'accepted': False, + 'context': 'stable_0', + 'type': 'beforeunload', + }), + 'type': 'event', + }), + ]) +# --- # name: test_navigate_checkEvents[complete] list([ dict({ @@ -688,6 +749,29 @@ # --- # name: test_navigate_hang_navigate_again_checkEvents list([ + dict({ + 'method': 'script.message', + 'params': dict({ + 'channel': 'beforeunload_channel', + 'data': dict({ + 'type': 'string', + 'value': 'beforeunload', + }), + 'source': dict({ + 'context': 'stable_0', + }), + }), + 'type': 'event', + }), + dict({ + 'method': 'browsingContext.navigationStarted', + 'params': dict({ + 'context': 'stable_0', + 'navigation': 'stable_1', + 'url': 'stable_2', + }), + 'type': 'event', + }), dict({ 'method': 'network.beforeRequestSent', 'params': dict({ @@ -704,7 +788,7 @@ 'params': dict({ 'context': 'stable_0', 'navigation': 'stable_1', - 'url': 'stable_3', + 'url': 'stable_2', }), 'type': 'event', }), diff --git a/tests/browsing_context/test_navigate_events.py b/tests/browsing_context/test_navigate_events.py index b64906dba..a2027b86e 100644 --- a/tests/browsing_context/test_navigate_events.py +++ b/tests/browsing_context/test_navigate_events.py @@ -16,7 +16,7 @@ import pytest from syrupy.filters import props from test_helpers import (execute_command, goto_url, send_JSON_command, - subscribe, wait_for_event) + subscribe) SNAPSHOT_EXCLUDE = props("timestamp", "timings", "headers", "stacktrace", "response", "initiator", "realm") @@ -25,16 +25,21 @@ ] -async def set_beforeunload_handler(websocket, context_id): +async def set_beforeunload_handler(websocket, context_id, show_popup=False): await execute_command( websocket, { "method": "script.callFunction", "params": { "functionDeclaration": """ - (channel) => { + (channel, show_popup) => { window.addEventListener('beforeunload', () => { channel("beforeunload"); - },false) + if(show_popup) { + event.returnValue = "Are you sure you want to leave?"; + event.preventDefault(); + } + },false); + document.body.click(); } """, "arguments": [{ @@ -42,12 +47,16 @@ async def set_beforeunload_handler(websocket, context_id): "value": { "channel": "beforeunload_channel", "ownership": "none", - }, + } + }, { + "type": "boolean", + "value": show_popup }], "target": { "context": context_id, }, - "awaitPromise": False + "awaitPromise": False, + "userActivation": True } }) @@ -220,8 +229,7 @@ async def test_navigate_dataUrl_checkEvents(websocket, context_id, url_base, @pytest.mark.asyncio async def test_navigate_hang_navigate_again_checkEvents( websocket, context_id, url_base, url_hang_forever, - url_example_another_origin, read_messages, snapshot, - assert_no_more_messages): + url_example_another_origin, read_messages, snapshot): # Use `url_example_another_origin`, as `url_example` will hang because of # `url_hang_forever`. await goto_url(websocket, context_id, url_base) @@ -230,6 +238,9 @@ async def test_navigate_hang_navigate_again_checkEvents( websocket, ["browsingContext", "script.message", "network.beforeRequestSent"]) + messages_log = [] + known_values = {} + await send_JSON_command( websocket, { "method": "browsingContext.navigate", @@ -240,7 +251,10 @@ async def test_navigate_hang_navigate_again_checkEvents( } }) - await wait_for_event(websocket, "browsingContext.navigationStarted") + messages_log += await read_messages(3, + keys_to_stabilize=KEYS_TO_STABILIZE, + known_values=known_values, + sort=False) await send_JSON_command( websocket, { @@ -252,10 +266,52 @@ async def test_navigate_hang_navigate_again_checkEvents( } }) - messages = await read_messages(10, + messages_log += await read_messages(9, + keys_to_stabilize=KEYS_TO_STABILIZE, + known_values=known_values, + check_no_other_messages=True, + sort=False) + + assert messages_log == snapshot(exclude=SNAPSHOT_EXCLUDE) + + +@pytest.mark.asyncio +@pytest.mark.parametrize('capabilities', [{ + 'unhandledPromptBehavior': { + 'beforeUnload': 'dismiss' + } +}], + indirect=True) +async def test_navigate_beforeunload_cancel(websocket, context_id, url_base, + url_hang_forever, + url_example_another_origin, + read_messages, snapshot): + # Use `url_example_another_origin`, as `url_example` will hang because of + # `url_hang_forever`. + await goto_url(websocket, context_id, url_base) + await set_beforeunload_handler(websocket, context_id, True) + await subscribe( + websocket, + ["browsingContext", "script.message", "network.beforeRequestSent"]) + + known_values = {} + + await send_JSON_command( + websocket, { + "method": "browsingContext.navigate", + "params": { + "url": url_hang_forever, + "wait": "complete", + "context": context_id + } + }) + + messages = await read_messages(6, keys_to_stabilize=KEYS_TO_STABILIZE, + known_values=known_values, check_no_other_messages=True, sort=False) + assert messages == snapshot(exclude=SNAPSHOT_EXCLUDE) diff --git a/tests/conftest.py b/tests/conftest.py index 85570d34c..e1738087b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -334,6 +334,7 @@ async def read_messages(message_count, bool] = lambda _: True, keys_to_stabilize: list[str] = [], check_no_other_messages: bool = False, + known_values: dict[str, str] | None = None, sort=True): messages = [] for _ in range(message_count): @@ -352,7 +353,7 @@ async def read_messages(message_count, messages.sort(key=lambda x: x["method"] if "method" in x else str( x["id"]) if "id" in x else "") # Stabilize some values through the messages. - stabilize_key_values(messages, keys_to_stabilize) + stabilize_key_values(messages, keys_to_stabilize, known_values) if len(messages) > message_count: # "Assert equals" to produce a readable overview of all received