@@ -58,8 +58,6 @@ def __init__(self, job: Job):
5858 }),
5959 }
6060 self .websock_thread_lock = threading .Lock ()
61- self .active_connections = 0
62- self .last_network_activity = time .time ()
6361 self .url_log : dict [str , Chain ] = {}
6462
6563 # Shim for _handle_message so we can log responses
@@ -140,10 +138,9 @@ def _on_screenshot(self, screenshot):
140138 def _on_cjs_screenshot (self , screenshot ):
141139 self .custom_js_screenshot = screenshot
142140
143- def _run_cdp_command (self , method : str , params : dict | None = None ) -> typing .Any :
141+ def _run_cdp_command (self , method : str , params : dict | None = None , timeout = 45 ) -> typing .Any :
144142 # Abuse brozzler's innards a bit to run a custom CDP command.
145143 # If this breaks, I was never here.
146- # TODO: Burn with fire.
147144 params = params or {}
148145 logger .debug (f"running CDP command { method } " )
149146 assert self .browser .websock_thread
@@ -155,7 +152,7 @@ def _run_cdp_command(self, method: str, params: dict | None = None) -> typing.An
155152 logger .debug ("waiting for response" )
156153 self ._wait_for (
157154 lambda : self .browser .websock_thread .received_result (msg_id ),
158- 45 ,
155+ timeout ,
159156 "CDP result"
160157 )
161158 message = self .browser .websock_thread .pop_result (msg_id )
@@ -198,8 +195,6 @@ def _best_effort_proxy_url(cls, url: str, headers: dict):
198195 def _message_handler (self , websock , json_message : str ):
199196 """
200197 Shim for browser.websock_thread._handle_message.
201-
202- Keeps track of network requests for logging and checking for idle.
203198 """
204199 # brozzler gets priority so an exception can't lose messages
205200 self .previous_message_handler (websock , json_message )
@@ -209,37 +204,27 @@ def _message_handler(self, websock, json_message: str):
209204 method = message ['method' ]
210205 params = message ['params' ]
211206 if method == "Network.requestWillBeSent" :
212- self .active_connections += 1
213207 request_id = params ['requestId' ]
214208 if request_id not in self .url_log :
215209 self .url_log [request_id ] = Chain ([], request_id )
216210 if redirect_response := params .get ("redirectResponse" ):
217211 self .url_log [request_id ].chain [- 1 ].response = Response .from_dict (redirect_response )
218212 request = Request .from_params (params )
219213 self .url_log [request_id ].chain .append (Pair (request , None ))
220- self .last_network_activity = time .time ()
221214 elif method == "Network.responseReceived" :
222215 request_id = params ['requestId' ]
223216 response = Response .from_params (params )
224217 self .url_log [request_id ].chain [- 1 ].response = response
225- self .last_network_activity = time .time ()
226218 elif method == "Network.dataReceived" :
227219 request_id = params ['requestId' ]
228220 self .url_log [request_id ].chain [- 1 ].response .length += params ['dataLength' ]
229- self .last_network_activity = time .time ()
230221 elif method == "Network.loadingFinished" :
231222 # Future: Submit log to websocket
232- self .active_connections -= 1
233- self .last_network_activity = time .time ()
234223 pass
235224 elif method == "Network.loadingFailed" :
236- self .active_connections -= 1
237- self .last_network_activity = time .time ()
238225 request_id = params ['requestId' ]
239226 error = Error (text = params ['errorText' ])
240227 self .url_log [request_id ].chain [- 1 ].response = error
241- if self .active_connections < 0 :
242- self .active_connections = 0
243228
244229 # Shamelessly stolen from brozzler's Worker._browse_page.
245230 # Apparently service workers don't get added to the right WARC:
@@ -303,7 +288,8 @@ def _run_custom_js(self):
303288 "replMode" : True ,
304289 # Makes it actually return the value
305290 "returnByValue" : True ,
306- }
291+ },
292+ timeout = 90 ,
307293 )
308294 try :
309295 custom_js_result = {
@@ -331,18 +317,6 @@ def _browser_version(self):
331317 logger .debug ("got browser version %s" , version )
332318 return version
333319
334- def _wait_for_idle (self , * , idle_time : float , timeout : int ):
335- """
336- Waits up to timeout seconds for network to have been idle for idle_time.
337- """
338- logger .debug ("waiting for network idle" )
339- def is_idle ():
340- with self .websock_thread_lock :
341- diff = time .time () - self .last_network_activity
342- return self .active_connections == 0 and diff > idle_time
343- self ._wait_for (is_idle , timeout , "idle" )
344- logger .debug ("got network idle!" )
345-
346320 def _capture_dom (self ) -> str :
347321 # First get the root node ID using DOM.getDocument (which gets the root node).
348322 logger .debug ("getting root node ID" )
@@ -352,6 +326,15 @@ def _capture_dom(self) -> str:
352326 outer_html = self ._run_cdp_command ("DOM.getOuterHTML" , {"nodeId" : root_node_id })['result' ]['outerHTML' ]
353327 return outer_html
354328
329+ def _set_metrics_override (self , width = 0 , height = 0 , device_scale_factor = 0 ):
330+ req = dict (
331+ width = width ,
332+ height = height ,
333+ deviceScaleFactor = device_scale_factor ,
334+ mobile = False ,
335+ )
336+ self ._run_cdp_command ("Emulation.setDeviceMetricsOverride" , req )
337+
355338 def _brozzle (self ) -> Result :
356339 assert self .browser .is_running ()
357340
@@ -391,13 +374,12 @@ def _brozzle(self) -> Result:
391374 )
392375 assert len (outlinks ) == 0 , "Brozzler didn't listen to us :["
393376 self .status_code : int = self .browser .websock_thread .page_status
394- try :
395- self ._wait_for_idle (idle_time = 3 , timeout = 10 )
396- except Timeout :
397- logger .info ("timed out waiting for idle; ignoring issue" )
377+ logger .debug ("waiting for idle" )
378+ self .browser ._wait_for_idle (idle_time = 3 , timeout = 10 )
398379
399380 logger .debug ("taking screenshot" )
400381 self .browser ._try_screenshot (self ._on_screenshot , full_page = True )
382+ self ._set_metrics_override ()
401383 logger .debug ("took screenshot!" )
402384
403385 outer_html = self ._capture_dom ()
@@ -408,6 +390,8 @@ def _brozzle(self) -> Result:
408390 custom_js_screenshot = None
409391 if self .job .custom_js :
410392 custom_js_result = self ._run_custom_js ()
393+ logger .debug ("waiting for idle after custom JS" )
394+ self .browser ._wait_for_idle (idle_time = 3 , timeout = 5 )
411395 self .browser ._try_screenshot (self ._on_cjs_screenshot , full_page = True )
412396 if self .custom_js_screenshot :
413397 custom_js_screenshot = base64 .b85encode (self .custom_js_screenshot ).decode ()
0 commit comments