Skip to content

Commit 75c6e50

Browse files
committed
test: add tests for window ID retrieval and valid tab ID filtering
1 parent 8d92f98 commit 75c6e50

File tree

4 files changed

+1188
-7
lines changed

4 files changed

+1188
-7
lines changed

tests/test_browser/test_browser_base.py

Lines changed: 186 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
from pydoll.commands import (
1313
BrowserCommands,
1414
FetchCommands,
15+
RuntimeCommands,
1516
StorageCommands,
1617
TargetCommands,
1718
)
1819
from pydoll.protocol.fetch.events import FetchEvent
1920
from pydoll.connection.connection_handler import ConnectionHandler
20-
from pydoll.constants import DownloadBehavior, PermissionType
21+
from pydoll.constants import DownloadBehavior, PermissionType, NetworkErrorReason
2122

2223

2324
class ConcreteBrowser(Browser):
@@ -95,7 +96,7 @@ async def test_start_browser_success(mock_browser):
9596
)
9697

9798
assert '--user-data-dir=' in str(mock_browser.options.arguments), (
98-
'Diretório temporário não configurado'
99+
'Temporary directory not configured'
99100
)
100101

101102

@@ -134,7 +135,6 @@ async def test_new_tab(mock_browser):
134135
'result': {'targetId': 'new_page'}
135136
}
136137
tab = await mock_browser.new_tab()
137-
print('TAB: ', tab)
138138
assert tab._target_id == 'new_page'
139139
assert isinstance(tab, Tab)
140140

@@ -195,6 +195,33 @@ async def test_window_management(mock_browser):
195195
BrowserCommands.set_window_minimized('window1'), timeout=10
196196
)
197197

198+
@pytest.mark.asyncio
199+
async def test_get_window_id_for_target(mock_browser):
200+
mock_browser._connection_handler.ping.return_value = True
201+
mock_browser._get_valid_tab_id = AsyncMock(return_value='page1')
202+
203+
tab = await mock_browser.start()
204+
mock_browser._connection_handler.execute_command.return_value = {
205+
'result': {'windowId': 'page1'}
206+
}
207+
window_id = await mock_browser.get_window_id_for_tab(tab)
208+
assert window_id == 'page1'
209+
mock_browser._connection_handler.execute_command.assert_called_with(
210+
BrowserCommands.get_window_for_target('page1'), timeout=10
211+
)
212+
213+
214+
@pytest.mark.asyncio
215+
async def test_get_window_id(mock_browser):
216+
mock_browser.get_targets = AsyncMock(return_value=[{'targetId': 'target1', 'type': 'page'}])
217+
mock_browser._connection_handler.execute_command.return_value = {
218+
'result': {'windowId': 'window1'}
219+
}
220+
window_id = await mock_browser.get_window_id()
221+
assert window_id == 'window1'
222+
mock_browser._connection_handler.execute_command.assert_called_with(
223+
BrowserCommands.get_window_for_target('target1'), timeout=10
224+
)
198225

199226
@pytest.mark.asyncio
200227
async def test_stop_browser(mock_browser):
@@ -350,7 +377,7 @@ async def test_create_browser_context(mock_browser):
350377
TargetCommands.create_browser_context()
351378
)
352379

353-
# Testar com proxy
380+
# Test with proxy
354381
mock_browser._execute_command.return_value = {
355382
'result': {'browserContextId': 'context2'}
356383
}
@@ -487,7 +514,7 @@ async def test_headless_mode(mock_browser):
487514

488515
@pytest.mark.asyncio
489516
async def test_multiple_tab_handling(mock_browser):
490-
# Simular a obtenção de múltiplas abas
517+
# Simulate getting multiple tabs
491518
mock_browser._connection_handler.execute_command.side_effect = [
492519
{'result': {'targetId': 'tab1'}},
493520
{'result': {'targetId': 'tab2'}}
@@ -499,9 +526,162 @@ async def test_multiple_tab_handling(mock_browser):
499526
assert tab1._target_id == 'tab1'
500527
assert tab2._target_id == 'tab2'
501528

502-
# Verificar que as chamadas corretas foram feitas
529+
# Verify that correct calls were made
503530
calls = mock_browser._connection_handler.execute_command.call_args_list
504531
assert calls[0][0][0] == TargetCommands.create_target('https://example1.com', None)
505532
assert calls[1][0][0] == TargetCommands.create_target('https://example2.com', None)
506533

507534

535+
# New tests for _get_valid_tab_id
536+
@pytest.mark.asyncio
537+
async def test_get_valid_tab_id_success():
538+
"""Test _get_valid_tab_id with a valid tab."""
539+
targets = [
540+
{'type': 'page', 'url': 'https://example.com', 'targetId': 'valid_tab_1'},
541+
{'type': 'extension', 'url': 'chrome-extension://abc123', 'targetId': 'ext_1'},
542+
{'type': 'page', 'url': 'chrome://newtab/', 'targetId': 'valid_tab_2'}
543+
]
544+
545+
result = await Browser._get_valid_tab_id(targets)
546+
assert result == 'valid_tab_1'
547+
548+
549+
@pytest.mark.asyncio
550+
async def test_get_valid_tab_id_no_valid_tabs():
551+
"""Test _get_valid_tab_id when there are no valid tabs."""
552+
targets = [
553+
{'type': 'extension', 'url': 'chrome-extension://abc123', 'targetId': 'ext_1'},
554+
{'type': 'background_page', 'url': 'chrome://background', 'targetId': 'bg_1'}
555+
]
556+
557+
with pytest.raises(exceptions.NoValidTabFound):
558+
await Browser._get_valid_tab_id(targets)
559+
560+
561+
@pytest.mark.asyncio
562+
async def test_get_valid_tab_id_empty_targets():
563+
"""Test _get_valid_tab_id with empty targets list."""
564+
targets = []
565+
566+
with pytest.raises(exceptions.NoValidTabFound):
567+
await Browser._get_valid_tab_id(targets)
568+
569+
570+
@pytest.mark.asyncio
571+
async def test_get_valid_tab_id_missing_target_id():
572+
"""Test _get_valid_tab_id when valid tab has no targetId."""
573+
targets = [
574+
{'type': 'page', 'url': 'https://example.com'}, # No targetId
575+
{'type': 'extension', 'url': 'chrome-extension://abc123', 'targetId': 'ext_1'}
576+
]
577+
578+
with pytest.raises(exceptions.NoValidTabFound, match='Tab missing targetId'):
579+
await Browser._get_valid_tab_id(targets)
580+
581+
582+
@pytest.mark.asyncio
583+
async def test_get_valid_tab_id_filters_extensions():
584+
"""Test if _get_valid_tab_id correctly filters extensions."""
585+
targets = [
586+
{'type': 'page', 'url': 'chrome-extension://abc123/popup.html', 'targetId': 'ext_page'},
587+
{'type': 'page', 'url': 'https://example.com', 'targetId': 'valid_tab'}
588+
]
589+
590+
result = await Browser._get_valid_tab_id(targets)
591+
assert result == 'valid_tab'
592+
593+
594+
# Tests for enable_runtime_events and disable_runtime_events
595+
@pytest.mark.asyncio
596+
async def test_enable_runtime_events(mock_browser):
597+
"""Test enable_runtime_events."""
598+
await mock_browser.enable_runtime_events()
599+
600+
mock_browser._connection_handler.execute_command.assert_called_with(
601+
RuntimeCommands.enable()
602+
)
603+
604+
605+
@pytest.mark.asyncio
606+
async def test_disable_runtime_events(mock_browser):
607+
"""Test disable_runtime_events."""
608+
await mock_browser.disable_runtime_events()
609+
610+
mock_browser._connection_handler.execute_command.assert_called_with(
611+
RuntimeCommands.disable()
612+
)
613+
614+
615+
# Tests for fail_request and fulfill_request
616+
@pytest.mark.asyncio
617+
async def test_fail_request(mock_browser):
618+
"""Test fail_request."""
619+
request_id = 'test_request_123'
620+
error_reason = NetworkErrorReason.FAILED
621+
622+
await mock_browser.fail_request(request_id, error_reason)
623+
624+
mock_browser._connection_handler.execute_command.assert_called_with(
625+
FetchCommands.fail_request(request_id, error_reason), timeout=10
626+
)
627+
628+
629+
@pytest.mark.asyncio
630+
async def test_fulfill_request(mock_browser):
631+
"""Test fulfill_request."""
632+
request_id = 'test_request_123'
633+
response_code = 200
634+
response_headers = [{'name': 'Content-Type', 'value': 'application/json'}]
635+
response_body = {'status': 'success', 'data': 'test'}
636+
637+
await mock_browser.fulfill_request(
638+
request_id, response_code, response_headers, response_body
639+
)
640+
641+
mock_browser._connection_handler.execute_command.assert_called_with(
642+
FetchCommands.fulfill_request(
643+
request_id, response_code, response_headers, response_body
644+
), timeout=10
645+
)
646+
647+
648+
# Additional test for 'on' with async callback
649+
@pytest.mark.asyncio
650+
async def test_event_registration_with_async_callback(mock_browser):
651+
"""Test async callback registration."""
652+
mock_browser._connection_handler.register_callback.return_value = 456
653+
654+
async def async_test_callback(event):
655+
"""Test async callback."""
656+
return f"Processed event: {event}"
657+
658+
callback_id = await mock_browser.on('test_async_event', async_test_callback, temporary=False)
659+
assert callback_id == 456
660+
661+
mock_browser._connection_handler.register_callback.assert_called_with(
662+
'test_async_event', ANY, False
663+
)
664+
665+
# Verify that callback was registered correctly
666+
call_args = mock_browser._connection_handler.register_callback.call_args
667+
registered_callback = call_args[0][1] # Second argument (callback)
668+
669+
# The registered callback should be a function
670+
assert callable(registered_callback)
671+
672+
673+
@pytest.mark.asyncio
674+
async def test_event_registration_sync_callback(mock_browser):
675+
"""Test sync callback registration."""
676+
mock_browser._connection_handler.register_callback.return_value = 789
677+
678+
def sync_test_callback(event):
679+
"""Test sync callback."""
680+
return f"Processed sync event: {event}"
681+
682+
callback_id = await mock_browser.on('test_sync_event', sync_test_callback, temporary=True)
683+
assert callback_id == 789
684+
685+
mock_browser._connection_handler.register_callback.assert_called_with(
686+
'test_sync_event', ANY, True
687+
)

0 commit comments

Comments
 (0)