14
14
from ._browser_thread import BrowserThread
15
15
16
16
_browser : BrowserThread | None = None
17
+ _last_logs : dict = {"logs" : [], "errors" : [], "url" : None }
17
18
logger = logging .getLogger (__name__ )
18
19
19
20
@@ -26,7 +27,9 @@ def get_browser() -> BrowserThread:
26
27
27
28
28
29
def _load_page (browser : Browser , url : str ) -> str :
29
- """Load a page and return its body HTML"""
30
+ """Load a page and return its body HTML, always capturing logs"""
31
+ global _last_logs
32
+
30
33
context = browser .new_context (
31
34
locale = "en-US" ,
32
35
geolocation = {"latitude" : 37.773972 , "longitude" : 13.39 },
@@ -35,7 +38,39 @@ def _load_page(browser: Browser, url: str) -> str:
35
38
36
39
logger .info (f"Loading page: { url } " )
37
40
page = context .new_page ()
38
- page .goto (url )
41
+
42
+ # Always capture logs
43
+ logs = []
44
+ page_errors = []
45
+
46
+ def on_console (msg ):
47
+ logs .append (
48
+ {
49
+ "type" : msg .type ,
50
+ "text" : msg .text ,
51
+ "location" : f"{ msg .location .get ('url' , 'unknown' )} :{ msg .location .get ('lineNumber' , 'unknown' )} :{ msg .location .get ('columnNumber' , 'unknown' )} "
52
+ if msg .location
53
+ else "unknown" ,
54
+ }
55
+ )
56
+
57
+ def on_page_error (error ):
58
+ page_errors .append (f"Page error: { error } " )
59
+
60
+ page .on ("console" , on_console )
61
+ page .on ("pageerror" , on_page_error )
62
+
63
+ # Navigate to the page
64
+ try :
65
+ page .goto (url )
66
+ # Wait for page to be fully loaded (includes network idle)
67
+ page .wait_for_load_state ("networkidle" )
68
+ except Exception as e :
69
+ page_errors .append (f"Navigation error: { str (e )} " )
70
+ # Don't re-raise, just capture the error
71
+
72
+ # Store logs globally
73
+ _last_logs = {"logs" : logs , "errors" : page_errors , "url" : url }
39
74
40
75
return page .inner_html ("body" )
41
76
@@ -47,6 +82,31 @@ def read_url(url: str) -> str:
47
82
return html_to_markdown (body_html )
48
83
49
84
85
+ def read_logs () -> str :
86
+ """Read browser console logs from the last read URL."""
87
+ global _last_logs
88
+
89
+ if not _last_logs ["url" ]:
90
+ return "No URL has been read yet."
91
+
92
+ result = [f"=== Logs for { _last_logs ['url' ]} ===" ]
93
+
94
+ if _last_logs ["logs" ]:
95
+ result .append ("\n === Console Logs ===" )
96
+ for log in _last_logs ["logs" ]:
97
+ result .append (f"[{ log ['type' ].upper ()} ] { log ['text' ]} ({ log ['location' ]} )" )
98
+
99
+ if _last_logs ["errors" ]:
100
+ result .append ("\n === Page Errors ===" )
101
+ for error in _last_logs ["errors" ]:
102
+ result .append (error )
103
+
104
+ if not _last_logs ["logs" ] and not _last_logs ["errors" ]:
105
+ result .append ("\n No logs or errors captured." )
106
+
107
+ return "\n " .join (result )
108
+
109
+
50
110
def _search_google (browser : Browser , query : str ) -> str :
51
111
query = urllib .parse .quote (query )
52
112
url = f"https://www.google.com/search?q={ query } &hl=en"
0 commit comments