1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ from typing import TYPE_CHECKING , Generator
16+
1517import pytest
1618from selenium .webdriver .common .bidi .common import command_builder
1719
1820from appium import webdriver
19- from appium .options .common import AppiumOptions
2021from appium .webdriver .client_config import AppiumClientConfig
2122from test .functional .test_helper import is_ci
2223from test .helpers .constants import SERVER_URL_BASE
2324
24- from .helper .desired_capabilities import get_desired_capabilities
25+ from .options import make_options
26+
27+ if TYPE_CHECKING :
28+ from appium .webdriver .webdriver import WebDriver
2529
2630
2731class AppiumLogEntry :
32+ """Represents a log entry from Appium BiDi."""
33+
2834 event_class = 'log.entryAdded'
2935
3036 def __init__ (self , level , text , timestamp , source , type ):
@@ -49,36 +55,36 @@ def from_json(cls, json: dict):
4955 )
5056
5157
52- class TestChromeWithBiDi :
53- """This test requires selenium python client which supports 'command_builder'"""
58+ @pytest .fixture
59+ def driver () -> Generator ['WebDriver' , None , None ]:
60+ """Create and configure Chrome driver with BiDi support for testing."""
61+ client_config = AppiumClientConfig (remote_server_addr = SERVER_URL_BASE )
62+ client_config .timeout = 600
63+ options = make_options ()
64+ options .web_socket_url = True
65+ driver = webdriver .Remote (SERVER_URL_BASE , options = options , client_config = client_config )
5466
55- def setup_method (self ) -> None :
56- client_config = AppiumClientConfig (remote_server_addr = SERVER_URL_BASE )
57- client_config .timeout = 600
58- caps = get_desired_capabilities ()
59- caps ['webSocketUrl' ] = True
60- self .driver = webdriver .Remote (
61- SERVER_URL_BASE , options = AppiumOptions ().load_capabilities (caps ), client_config = client_config
62- )
67+ yield driver
68+
69+ driver .quit ()
6370
64- def teardown_method (self ) -> None :
65- self .driver .quit ()
6671
67- @pytest .mark .skipif (is_ci (), reason = 'Flaky on CI' )
68- def test_bidi_log (self ) -> None :
69- log_entries = []
70- bidi_log_param = {'events' : ['log.entryAdded' ], 'contexts' : ['NATIVE_APP' ]}
72+ @pytest .mark .skipif (is_ci (), reason = 'Flaky on CI' )
73+ def test_bidi_log (driver : 'WebDriver' ) -> None :
74+ """Test BiDi logging functionality with Chrome driver."""
75+ log_entries = []
76+ bidi_log_param = {'events' : ['log.entryAdded' ], 'contexts' : ['NATIVE_APP' ]}
7177
72- self . driver .script .conn .execute (command_builder ('session.subscribe' , bidi_log_param ))
78+ driver .script .conn .execute (command_builder ('session.subscribe' , bidi_log_param ))
7379
74- def _log (entry : AppiumLogEntry ):
75- # e.g. {'type': 'syslog', 'level': 'info', 'source': {'realm': ''}, 'text': '08-05 13:30:32.617 29677 29709 I appium : channel read: GET /session/d7c38859-8930-4eb0-960a-8f917c9e6a38/source', 'timestamp': 1754368241565}
76- log_entries .append (entry .json )
80+ def _log (entry : AppiumLogEntry ):
81+ # e.g. {'type': 'syslog', 'level': 'info', 'source': {'realm': ''}, 'text': '08-05 13:30:32.617 29677 29709 I appium : channel read: GET /session/d7c38859-8930-4eb0-960a-8f917c9e6a38/source', 'timestamp': 1754368241565}
82+ log_entries .append (entry .json )
7783
78- try :
79- callback_id = self . driver .script .conn .add_callback (AppiumLogEntry , _log )
80- self . driver .page_source
81- assert len (log_entries ) != 0
82- self . driver .script .conn .remove_callback (AppiumLogEntry , callback_id )
83- finally :
84- self . driver .script .conn .execute (command_builder ('session.unsubscribe' , bidi_log_param ))
84+ try :
85+ callback_id = driver .script .conn .add_callback (AppiumLogEntry , _log )
86+ driver .page_source
87+ assert len (log_entries ) != 0
88+ driver .script .conn .remove_callback (AppiumLogEntry , callback_id )
89+ finally :
90+ driver .script .conn .execute (command_builder ('session.unsubscribe' , bidi_log_param ))
0 commit comments