1919import pkgutil
2020from contextlib import asynccontextmanager
2121from importlib import import_module
22+ from typing import Any
23+ from typing import AsyncGenerator
24+ from typing import Dict
25+ from typing import Optional
2226
2327from selenium .webdriver .common .by import By
2428
@@ -45,10 +49,14 @@ def __init__(self, driver, bidi_session) -> None:
4549 self .cdp = bidi_session .cdp
4650 self .devtools = bidi_session .devtools
4751 _pkg = "." .join (__name__ .split ("." )[:- 1 ])
48- self ._mutation_listener_js = pkgutil .get_data (_pkg , "mutation-listener.js" ).decode ("utf8" ).strip ()
52+ # Ensure _mutation_listener_js is not None before decoding
53+ _mutation_listener_js_bytes : Optional [bytes ] = pkgutil .get_data (_pkg , "mutation-listener.js" )
54+ if _mutation_listener_js_bytes is None :
55+ raise ValueError ("Failed to load mutation-listener.js" )
56+ self ._mutation_listener_js = _mutation_listener_js_bytes .decode ("utf8" ).strip ()
4957
5058 @asynccontextmanager
51- async def mutation_events (self ) -> dict :
59+ async def mutation_events (self ) -> AsyncGenerator [ Dict [ str , Any ], None ] :
5260 """Listen for mutation events and emit them as they are found.
5361
5462 :Usage:
@@ -76,12 +84,13 @@ async def mutation_events(self) -> dict:
7684 )
7785 self .driver .pin_script (self ._mutation_listener_js , script_key )
7886 self .driver .execute_script (f"return { self ._mutation_listener_js } " )
79- event = {}
87+
88+ event : Dict [str , Any ] = {}
8089 async with runtime .wait_for (self .devtools .runtime .BindingCalled ) as evnt :
8190 yield event
8291
8392 payload = json .loads (evnt .value .payload )
84- elements : list = self .driver .find_elements (By .CSS_SELECTOR , f"*[data-__webdriver_id={ payload ['target' ]} " )
93+ elements : list = self .driver .find_elements (By .CSS_SELECTOR , f"*[data-__webdriver_id={ payload ['target' ]} ] " )
8594 if not elements :
8695 elements .append (None )
8796 event ["element" ] = elements [0 ]
@@ -90,7 +99,7 @@ async def mutation_events(self) -> dict:
9099 event ["old_value" ] = payload ["oldValue" ]
91100
92101 @asynccontextmanager
93- async def add_js_error_listener (self ):
102+ async def add_js_error_listener (self ) -> AsyncGenerator [ Dict [ str , Any ], None ] :
94103 """Listen for JS errors and when the contextmanager exits check if
95104 there were JS Errors.
96105
@@ -114,7 +123,7 @@ async def add_js_error_listener(self):
114123 js_exception .exception_details = exception .value .exception_details
115124
116125 @asynccontextmanager
117- async def add_listener (self , event_type ) -> dict :
126+ async def add_listener (self , event_type ) -> AsyncGenerator [ Dict [ str , Any ], None ] :
118127 """Listen for certain events that are passed in.
119128
120129 :Args:
@@ -134,7 +143,7 @@ async def add_listener(self, event_type) -> dict:
134143 await session .execute (self .devtools .page .enable ())
135144 session = self .cdp .get_session_context ("runtime.enable" )
136145 await session .execute (self .devtools .runtime .enable ())
137- console = {"message" : None , "level" : None }
146+ console : Dict [ str , Any ] = {"message" : None , "level" : None }
138147 async with session .wait_for (self .devtools .runtime .ConsoleAPICalled ) as messages :
139148 yield console
140149
0 commit comments