1212from pydoll .commands import (
1313 BrowserCommands ,
1414 FetchCommands ,
15+ RuntimeCommands ,
1516 StorageCommands ,
1617 TargetCommands ,
1718)
1819from pydoll .protocol .fetch .events import FetchEvent
1920from pydoll .connection .connection_handler import ConnectionHandler
20- from pydoll .constants import DownloadBehavior , PermissionType
21+ from pydoll .constants import DownloadBehavior , PermissionType , NetworkErrorReason
2122
2223
2324class 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
200227async 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
489516async 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