66import collections
77from threading import Thread , Lock , Event
88
9- from typing import Dict
9+ from typing import Dict , Callable
1010
1111import requests
1212import websocket
1515 EventHandler , PageLoadEventHandler , JavascriptDialogEventHandler
1616)
1717from browserdebuggertools .exceptions import (
18- DevToolsException , TabNotFoundError , MaxRetriesException ,
18+ DevToolsException , MaxRetriesException ,
1919 DevToolsTimeoutException , DomainNotEnabledError ,
2020 MethodNotFoundError , UnknownError , ResourceNotFoundError , MessagingThreadIsDeadError ,
2121 InvalidParametersError , WebSocketBlockedException
2222)
2323
2424
25+ def _unwrap_json_response (request : Callable ) -> Callable :
26+ def _make_request_and_check_response (* args , ** kwargs ) -> dict :
27+ response = request (* args , ** kwargs )
28+ if not response .ok :
29+ raise DevToolsException ("{} {} for url: {}" .format (
30+ response .status_code , response .reason , response .url )
31+ )
32+ return response .json ()
33+ return _make_request_and_check_response
34+
35+
2536class _WSMessageProducer (Thread ):
2637 """ Interfaces with the websocket to send messages from the send queue
2738 or put messages from the websocket into recv queue
@@ -46,22 +57,31 @@ def __init__(self, port, send_queue, on_message):
4657 def __del__ (self ):
4758 self .close ()
4859
49- def _get_websocket_url (self , port ):
50- response = requests .get (
51- "http://localhost:{}/json" .format (port ), timeout = self ._CONN_TIMEOUT
60+ def _get_websocket_url (self ) -> str :
61+ """
62+ Return debugging url for the first tab, if there is one, otherwise create a tab and return its debugging url
63+ :return: The WS end-point that can be used for devtools protocol communication
64+ """
65+ tabs = [target for target in self ._get_targets () if target ["type" ] == "page" ]
66+ if tabs :
67+ return tabs [0 ]["webSocketDebuggerUrl" ]
68+ else :
69+ return self ._create_tab ()["webSocketDebuggerUrl" ]
70+
71+ @_unwrap_json_response
72+ def _get_targets (self ):
73+ return requests .get (
74+ "http://localhost:{}/json" .format (self ._port ), timeout = self ._CONN_TIMEOUT
5275 )
53- if not response .ok :
54- raise DevToolsException ("{} {} for url: {}" .format (
55- response .status_code , response .reason , response .url )
56- )
5776
58- tabs = [target for target in response .json () if target ["type" ] == "page" ]
59- if not tabs :
60- raise TabNotFoundError ("There is no tab to connect to." )
61- return tabs [0 ]["webSocketDebuggerUrl" ]
77+ @_unwrap_json_response
78+ def _create_tab (self ):
79+ return requests .put (
80+ "http://localhost:{}/json/new" .format (self ._port ), timeout = self ._CONN_TIMEOUT
81+ )
6282
6383 def _get_websocket (self ):
64- websocket_url = self ._get_websocket_url (self . _port )
84+ websocket_url = self ._get_websocket_url ()
6585 logging .info ("Connecting to websocket %s" % websocket_url )
6686 ws = websocket .create_connection (
6787 websocket_url , timeout = self ._CONN_TIMEOUT
@@ -124,7 +144,7 @@ def run(self):
124144 self ._empty_send_queue ()
125145 self ._empty_websocket ()
126146 self .poll_signal .wait (self ._POLL_INTERVAL )
127- if self .poll_signal .isSet ():
147+ if self .poll_signal .is_set ():
128148 self .poll_signal .clear ()
129149
130150 @property
0 commit comments