unrealon 2.0.10__py3-none-any.whl → 2.0.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unrealon-2.0.10.dist-info → unrealon-2.0.12.dist-info}/METADATA +1 -1
- {unrealon-2.0.10.dist-info → unrealon-2.0.12.dist-info}/RECORD +21 -20
- unrealon_browser/core/browser_manager.py +58 -0
- unrealon_browser/managers/logger_bridge.py +3 -3
- unrealon_browser/managers/script_manager.py +45 -26
- unrealon_browser/stealth/{bypass_techniques.pyc → bypass_techniques.py} +0 -0
- unrealon_browser/stealth/manager.py +507 -0
- unrealon_browser/stealth/nodriver_stealth.py +432 -0
- unrealon_browser/stealth/playwright_stealth.py +179 -0
- unrealon_browser/stealth/scanner_tester.py +355 -0
- unrealon_browser/stealth/undetected_chrome.py +361 -0
- unrealon_driver/__init__.py +12 -2
- unrealon_driver/driver/factory/manager_factory.py +8 -1
- unrealon_driver/managers/browser.py +16 -1
- unrealon_driver/managers/proxy.py +11 -4
- unrealon_driver/utils/__init__.py +13 -4
- unrealon_driver/utils/platform_compatibility.py +205 -0
- unrealon_browser/stealth/manager.pyc +0 -0
- unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
- unrealon_browser/stealth/playwright_stealth.pyc +0 -0
- unrealon_browser/stealth/scanner_tester.pyc +0 -0
- unrealon_browser/stealth/undetected_chrome.pyc +0 -0
- {unrealon-2.0.10.dist-info → unrealon-2.0.12.dist-info}/LICENSE +0 -0
- {unrealon-2.0.10.dist-info → unrealon-2.0.12.dist-info}/WHEEL +0 -0
- {unrealon-2.0.10.dist-info → unrealon-2.0.12.dist-info}/entry_points.txt +0 -0
- {unrealon-2.0.10.dist-info → unrealon-2.0.12.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ unrealon_browser/cli/cookies_cli.py,sha256=yhZvGrg8bknlH4zlySdi8ue-25Ue-1rI_u1G0
|
|
|
6
6
|
unrealon_browser/cli/interactive_mode.py,sha256=gLn9bMH0h0tPX3dP4i4QQxQK4Htkyg5r4KcqdMBaP6Q,12125
|
|
7
7
|
unrealon_browser/cli/main.py,sha256=XCYcTxJUqaz320KCU_JPKizYMk6bdljb8Boyok3uO-4,1353
|
|
8
8
|
unrealon_browser/core/__init__.py,sha256=uVL_t4sZelUzflWPdgrwoXGnAkSV1WNQ98-eu0QB2eM,151
|
|
9
|
-
unrealon_browser/core/browser_manager.py,sha256=
|
|
9
|
+
unrealon_browser/core/browser_manager.py,sha256=vPWQjoh_QAoKWFlKVQCPIuehNsWIY9HIN7z3QeGoxAc,32398
|
|
10
10
|
unrealon_browser/dto/__init__.py,sha256=bApqcLz-KanEi0_MCiFPrQmGBoX3VBijP7XtBUyIfjo,1636
|
|
11
11
|
unrealon_browser/dto/bot_detection.py,sha256=qXfC0HghV7m4L6qA87t3STi-166jM-QgoP6OYbCb4o4,6884
|
|
12
12
|
unrealon_browser/dto/models/config.py,sha256=Why5H3rtFclmwbdczuDfhlgf-LDz72Aa8LhDX4_ayfw,1752
|
|
@@ -18,17 +18,17 @@ unrealon_browser/dto/models/statistics.py,sha256=aIzJNV5r23VBxjhEoja4tXwI1Z7_UCw
|
|
|
18
18
|
unrealon_browser/managers/__init__.py,sha256=lpa93ggEN93ucoi4FqnCG_sn-_aRlP1As7DBRogDSsQ,591
|
|
19
19
|
unrealon_browser/managers/captcha.py,sha256=KGBO7sfq9XusAlcPByUFdIg-v6rlruzS2oHx-Zx28wo,21453
|
|
20
20
|
unrealon_browser/managers/cookies.py,sha256=r4VVnKLXH82vhU7qgtY-dF7KPf0Ie3QxGD3FEi6geFA,15085
|
|
21
|
-
unrealon_browser/managers/logger_bridge.py,sha256=
|
|
21
|
+
unrealon_browser/managers/logger_bridge.py,sha256=b6H9aq6AGv0s_g5bTH6ZFYoFINClsUejevlef3s1srw,10864
|
|
22
22
|
unrealon_browser/managers/page_wait_manager.py,sha256=UyZqiSfkjzahrxp9x1odXFIT_sFhZGvdECxWuIMCVBY,7876
|
|
23
23
|
unrealon_browser/managers/profile.py,sha256=HjddlSeUry_65WPtF8CMkT7cfJ6X3Jap9kJaaZpwtAA,18956
|
|
24
|
-
unrealon_browser/managers/script_manager.py,sha256=
|
|
24
|
+
unrealon_browser/managers/script_manager.py,sha256=hVnEWDb2LM1rfnptFo1MtE0SGcYCoFA66udykmb5e1g,11581
|
|
25
25
|
unrealon_browser/stealth/__init__.py,sha256=zUfkPPafYlPANLVQIy-Se11R_UjcJakUb3krCxxUK5Q,842
|
|
26
|
-
unrealon_browser/stealth/bypass_techniques.
|
|
27
|
-
unrealon_browser/stealth/manager.
|
|
28
|
-
unrealon_browser/stealth/nodriver_stealth.
|
|
29
|
-
unrealon_browser/stealth/playwright_stealth.
|
|
30
|
-
unrealon_browser/stealth/scanner_tester.
|
|
31
|
-
unrealon_browser/stealth/undetected_chrome.
|
|
26
|
+
unrealon_browser/stealth/bypass_techniques.py,sha256=eBOkYtWQZvw8SNGSim38VxkCsTJsx6OmjWJKR3GnSog,23582
|
|
27
|
+
unrealon_browser/stealth/manager.py,sha256=P3oFHKMpKrjl1Nw8JbtcLMNBtE5y0qOJgA-SdbAx1Y4,20435
|
|
28
|
+
unrealon_browser/stealth/nodriver_stealth.py,sha256=kYoWafDpaVBnbinLDaFNW4OstojEd54el9c1HewGIiE,14839
|
|
29
|
+
unrealon_browser/stealth/playwright_stealth.py,sha256=49zX2GbO7Iabh7TOoZqkip17cmVsMDjwPHCcs7EbizI,6683
|
|
30
|
+
unrealon_browser/stealth/scanner_tester.py,sha256=MTCKMIerOZxepfOw3tjXZo5_UOxN7JUX2jxxGFuWfig,16213
|
|
31
|
+
unrealon_browser/stealth/undetected_chrome.py,sha256=AjmxaygRmG2TNj2MAWHjB_-SoOCO8D0eDhLgtOu71Vw,13226
|
|
32
32
|
unrealon_core/__init__.py,sha256=ZAinyQDsAS63xqnl5uqUKTna9M-xFDs6fLwy8-Hh-X0,5599
|
|
33
33
|
unrealon_core/version.py,sha256=qZOlKA_Hsz7_KXsCLO_0l9Mf0u_iNTxvHZPV21DwCqs,5803
|
|
34
34
|
unrealon_core/config/__init__.py,sha256=57-KZaTDya0oyfOCfZ3pU1xLLbnZPBgqwfP9VrfhcKE,395
|
|
@@ -83,7 +83,7 @@ unrealon_core/monitoring/health_check.py,sha256=UAdZ1Of0LCWFVfVXQP0BF-4HDOe4rxyh
|
|
|
83
83
|
unrealon_core/monitoring/metrics.py,sha256=UPCRoridgGVxQ1kh--NuXzH-2dY0WyKljfXDH96OroU,11705
|
|
84
84
|
unrealon_core/utils/__init__.py,sha256=L4nJum_ekqh3Rn324pcIASfr6QQtnT_PwWKCtl2L0mU,179
|
|
85
85
|
unrealon_core/utils/time.py,sha256=27iWhOEl4wHgBOag7gqFlI0hl5cTHPnKHoe8GxmnKHA,1356
|
|
86
|
-
unrealon_driver/__init__.py,sha256=
|
|
86
|
+
unrealon_driver/__init__.py,sha256=0uwrmIEaAwpOSSTd6nv8fJinhpW2whBQHvqN430Cbz0,2130
|
|
87
87
|
unrealon_driver/core_module/__init__.py,sha256=v4bHF0eqSQBAUBBEl8RnQWrvb3LjAeIAQCeIXrRTy3w,620
|
|
88
88
|
unrealon_driver/core_module/base.py,sha256=RbC6MVQSA-1145gnDMdsMJ_QnMpQT52pIg86UfRSSMc,6135
|
|
89
89
|
unrealon_driver/core_module/config.py,sha256=N0XGWsoYmv2ruKZOZKOyfaHOZ_jstUDqH7aTqURG2TI,1023
|
|
@@ -103,7 +103,7 @@ unrealon_driver/driver/core/__init__.py,sha256=ZvJQp1zO7pj6tBNYTJk2fj-0ZMiQTQEk-
|
|
|
103
103
|
unrealon_driver/driver/core/config.py,sha256=jWJjRll19VlL4iM5Q-J3o9qwYeH89Iuj1_3KayM6fCk,5914
|
|
104
104
|
unrealon_driver/driver/core/driver.py,sha256=NI-pdhnduRyHLsfFr8HmP2gp7pR1pWB4vBIJkMJ2cls,7886
|
|
105
105
|
unrealon_driver/driver/factory/__init__.py,sha256=XrjBhOaLvC3MIG5PAFIYS_xYXFDz5JizpFvmQcwA7mU,189
|
|
106
|
-
unrealon_driver/driver/factory/manager_factory.py,sha256=
|
|
106
|
+
unrealon_driver/driver/factory/manager_factory.py,sha256=b-3tWKsnicTNygZ3zIDhBlSbGySPRPT1GYrFY32QQgo,5103
|
|
107
107
|
unrealon_driver/driver/lifecycle/__init__.py,sha256=KnkXklezAOIbXcCzEU_XSOt32z7tz1zIGclXYXTkO8k,286
|
|
108
108
|
unrealon_driver/driver/lifecycle/daemon.py,sha256=KHAzpiWFu3HRElRtzSEStmI74bMivFjfCAFlXha87KU,2609
|
|
109
109
|
unrealon_driver/driver/lifecycle/initialization.py,sha256=R4MgfkSNnfAdMO0Kp1Cx42cfNqq8VIxj_mGX7ECXad4,4406
|
|
@@ -115,19 +115,20 @@ unrealon_driver/driver/utilities/logging.py,sha256=2my2QnkAa6Hdw-TfO4oOQ94yGc-Cj
|
|
|
115
115
|
unrealon_driver/driver/utilities/serialization.py,sha256=wTCSVrEloykiGN4K1JXbk2aqNKm7W90aWXmzhcLyAZc,2123
|
|
116
116
|
unrealon_driver/managers/__init__.py,sha256=zJJsOb6Oodg7l00v4ncKUytnyeaZM887pHY8-eSuWdU,981
|
|
117
117
|
unrealon_driver/managers/base.py,sha256=GkuXillg9uqqnx6RL682fmKgK-7JyqYlH6DFUgyN4F8,5445
|
|
118
|
-
unrealon_driver/managers/browser.py,sha256=
|
|
118
|
+
unrealon_driver/managers/browser.py,sha256=bc6O2NyC4FV82mb9sat48_k8s1c3IGY4i90ddMVWRIo,5432
|
|
119
119
|
unrealon_driver/managers/cache.py,sha256=c0tPKQ5KFd_Un1U8mw3j1WPuycxg863MMWNMveVF_2I,3506
|
|
120
120
|
unrealon_driver/managers/http.py,sha256=EjlpoTRuhpsgzzrEARxRlbGczzua7hnKFVq06bvCgTM,3624
|
|
121
121
|
unrealon_driver/managers/logger.py,sha256=PL3rA9ZQl12jJU0EiPAkLwJ6eDHQfIzr8-nc8bVivKQ,10526
|
|
122
|
-
unrealon_driver/managers/proxy.py,sha256=
|
|
122
|
+
unrealon_driver/managers/proxy.py,sha256=b2w6DteMJWnwxZmL3NfwBMdE_mscchoMwPs-XFKNwnU,3855
|
|
123
123
|
unrealon_driver/managers/registry.py,sha256=--oNPU-65e8J21ubJufyEOc1TirnzJIvpvuY_j7rH7Q,2666
|
|
124
124
|
unrealon_driver/managers/threading.py,sha256=djw5cSC99dfBKmep3IJ_8IgxQceMXtNvCp5fIxHM0TY,1702
|
|
125
125
|
unrealon_driver/managers/update.py,sha256=-hohVxGXpj5bZ6ZTQN6NH1RK9Pd6GVzCMtu3GS2SdcQ,3582
|
|
126
|
-
unrealon_driver/utils/__init__.py,sha256=
|
|
126
|
+
unrealon_driver/utils/__init__.py,sha256=qMEFiXU7R8hMZ9yAgUYMZ_TF-Yqo3w9Xm7ToPO9Pew0,383
|
|
127
|
+
unrealon_driver/utils/platform_compatibility.py,sha256=kydNJhxswBq-z249YQBBVxP0QKEP3vQHuvGuYcBVH-w,7617
|
|
127
128
|
unrealon_driver/utils/time.py,sha256=Oxk1eicKeZl8ZWbf7gu1Ll716k6CpXmVj67FHSnPIsA,184
|
|
128
|
-
unrealon-2.0.
|
|
129
|
-
unrealon-2.0.
|
|
130
|
-
unrealon-2.0.
|
|
131
|
-
unrealon-2.0.
|
|
132
|
-
unrealon-2.0.
|
|
133
|
-
unrealon-2.0.
|
|
129
|
+
unrealon-2.0.12.dist-info/LICENSE,sha256=eEH8mWZW49YMpl4Sh5MtKqkZ8aVTzKQXiNPEnvL14ns,1070
|
|
130
|
+
unrealon-2.0.12.dist-info/METADATA,sha256=UDN8rMi-1DqFObmEJiMboDUzCmh_j1jQJwv6KhRsntw,15689
|
|
131
|
+
unrealon-2.0.12.dist-info/WHEEL,sha256=pL8R0wFFS65tNSRnaOVrsw9EOkOqxLrlUPenUYnJKNo,91
|
|
132
|
+
unrealon-2.0.12.dist-info/entry_points.txt,sha256=k0qM-eotpajkKUq-almJmxj9afhXprZ6IkvQkSdcKhI,104
|
|
133
|
+
unrealon-2.0.12.dist-info/top_level.txt,sha256=Gu8IeIfIVfUxdi-h-F0nKMQxo15pjhHZ0aTadXTpRE8,47
|
|
134
|
+
unrealon-2.0.12.dist-info/RECORD,,
|
|
@@ -55,6 +55,9 @@ class BrowserManager:
|
|
|
55
55
|
self._page = None
|
|
56
56
|
self._initialized = False
|
|
57
57
|
self._statistics = BrowserManagerStatistics()
|
|
58
|
+
|
|
59
|
+
# Proxy settings (can be set externally)
|
|
60
|
+
self._proxy_url: Optional[str] = None
|
|
58
61
|
|
|
59
62
|
# Initialize logger bridge first
|
|
60
63
|
self.logger_bridge = create_browser_logger_bridge(session_id=self._generate_session_id(), parser_id=self.parser_id, enable_console=True) # Use resolved parser_id
|
|
@@ -197,6 +200,12 @@ class BrowserManager:
|
|
|
197
200
|
"ignore_default_args": ["--enable-automation"],
|
|
198
201
|
**context_options, # viewport, user_agent, etc.
|
|
199
202
|
}
|
|
203
|
+
|
|
204
|
+
# Add proxy configuration for persistent context
|
|
205
|
+
if self._proxy_url:
|
|
206
|
+
proxy_config = self._get_playwright_proxy_config()
|
|
207
|
+
if proxy_config:
|
|
208
|
+
persistent_args["proxy"] = proxy_config
|
|
200
209
|
|
|
201
210
|
# Use persistent context with user_data_dir for profiles
|
|
202
211
|
if self.config.browser_type == BrowserType.CHROMIUM:
|
|
@@ -223,6 +232,12 @@ class BrowserManager:
|
|
|
223
232
|
raise ValueError(f"Unsupported browser type: {self.config.browser_type}")
|
|
224
233
|
|
|
225
234
|
# Create context without profile
|
|
235
|
+
# Add proxy configuration for context
|
|
236
|
+
if self._proxy_url:
|
|
237
|
+
proxy_config = self._get_playwright_proxy_config()
|
|
238
|
+
if proxy_config:
|
|
239
|
+
context_options["proxy"] = proxy_config
|
|
240
|
+
|
|
226
241
|
self._context = await self._browser.new_context(**context_options)
|
|
227
242
|
|
|
228
243
|
# 🔥 STEALTH ALWAYS ON - NO CONFIG NEEDED!
|
|
@@ -276,6 +291,9 @@ class BrowserManager:
|
|
|
276
291
|
# 🔥 STEALTH ALWAYS ON - ALWAYS ADD STEALTH ARGS!
|
|
277
292
|
browser_args.extend(self.stealth_manager.get_stealth_args())
|
|
278
293
|
|
|
294
|
+
# Note: Proxy configuration is now handled via Playwright API in context options
|
|
295
|
+
# instead of command line arguments for better compatibility
|
|
296
|
+
|
|
279
297
|
if self.config.disable_images:
|
|
280
298
|
browser_args.extend(
|
|
281
299
|
[
|
|
@@ -286,6 +304,46 @@ class BrowserManager:
|
|
|
286
304
|
|
|
287
305
|
args["args"] = browser_args
|
|
288
306
|
return args
|
|
307
|
+
|
|
308
|
+
def _get_playwright_proxy_config(self) -> Optional[Dict[str, Any]]:
|
|
309
|
+
"""
|
|
310
|
+
Get Playwright-compatible proxy configuration.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
Proxy configuration dict for Playwright or None if not supported
|
|
314
|
+
"""
|
|
315
|
+
if not self._proxy_url:
|
|
316
|
+
return None
|
|
317
|
+
|
|
318
|
+
try:
|
|
319
|
+
from urllib.parse import urlparse
|
|
320
|
+
|
|
321
|
+
parsed = urlparse(self._proxy_url)
|
|
322
|
+
|
|
323
|
+
# Playwright proxy configuration
|
|
324
|
+
proxy_config = {
|
|
325
|
+
"server": f"{parsed.scheme}://{parsed.hostname}:{parsed.port}"
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
# Add authentication if present
|
|
329
|
+
if parsed.username and parsed.password:
|
|
330
|
+
# WARNING: Playwright does NOT support SOCKS5 authentication!
|
|
331
|
+
if parsed.scheme == 'socks5':
|
|
332
|
+
self.logger_bridge.log_warning("⚠️ Playwright does not support SOCKS5 authentication!")
|
|
333
|
+
self.logger_bridge.log_warning("⚠️ Falling back to SOCKS5 without auth - may fail!")
|
|
334
|
+
# Return configuration without authentication for SOCKS5
|
|
335
|
+
return proxy_config
|
|
336
|
+
else:
|
|
337
|
+
# HTTP/HTTPS proxies support authentication
|
|
338
|
+
proxy_config["username"] = parsed.username
|
|
339
|
+
proxy_config["password"] = parsed.password
|
|
340
|
+
|
|
341
|
+
self.logger_bridge.log_info(f"🔒 Playwright proxy config: {proxy_config['server']}")
|
|
342
|
+
return proxy_config
|
|
343
|
+
|
|
344
|
+
except Exception as e:
|
|
345
|
+
self.logger_bridge.log_error(f"❌ Failed to parse proxy URL: {e}")
|
|
346
|
+
return None
|
|
289
347
|
|
|
290
348
|
def _get_context_options(self) -> Dict[str, Any]:
|
|
291
349
|
"""Get browser context options"""
|
|
@@ -168,17 +168,17 @@ class BrowserLoggerBridge:
|
|
|
168
168
|
)
|
|
169
169
|
|
|
170
170
|
def log_stealth_applied(self, success: bool = True) -> None:
|
|
171
|
-
"""Log stealth application
|
|
171
|
+
"""Log stealth application"""
|
|
172
172
|
self._browser_events["stealth_applied"] += 1
|
|
173
173
|
|
|
174
174
|
if success:
|
|
175
175
|
self._log_info(
|
|
176
|
-
"Stealth measures applied
|
|
176
|
+
"Stealth measures applied",
|
|
177
177
|
stealth_success=True,
|
|
178
178
|
)
|
|
179
179
|
else:
|
|
180
180
|
self._log_warning(
|
|
181
|
-
"Stealth application failed
|
|
181
|
+
"Stealth application failed",
|
|
182
182
|
stealth_success=False,
|
|
183
183
|
)
|
|
184
184
|
|
|
@@ -18,7 +18,8 @@ class ScriptManager:
|
|
|
18
18
|
def __init__(self, page: Optional[Page], logger_bridge: LoggingBridge):
|
|
19
19
|
self._page = page
|
|
20
20
|
self.logger_bridge = logger_bridge
|
|
21
|
-
|
|
21
|
+
self.allow_logging = False
|
|
22
|
+
|
|
22
23
|
# Statistics
|
|
23
24
|
self._scripts_executed = 0
|
|
24
25
|
self._scripts_successful = 0
|
|
@@ -29,7 +30,25 @@ class ScriptManager:
|
|
|
29
30
|
def update_page(self, page: Optional[Page]):
|
|
30
31
|
"""Update the page reference"""
|
|
31
32
|
self._page = page
|
|
32
|
-
|
|
33
|
+
|
|
34
|
+
def log_error(self, message: str):
|
|
35
|
+
"""Log error"""
|
|
36
|
+
if not self.allow_logging:
|
|
37
|
+
return
|
|
38
|
+
self.logger_bridge.log_error(message)
|
|
39
|
+
|
|
40
|
+
def log_info(self, message: str):
|
|
41
|
+
"""Log info"""
|
|
42
|
+
if not self.allow_logging:
|
|
43
|
+
return
|
|
44
|
+
self.logger_bridge.log_info(message)
|
|
45
|
+
|
|
46
|
+
def log_debug(self, message: str):
|
|
47
|
+
"""Log debug"""
|
|
48
|
+
if not self.allow_logging:
|
|
49
|
+
return
|
|
50
|
+
self.logger_bridge.log_debug(message)
|
|
51
|
+
|
|
33
52
|
async def execute_script(self, script: str, timeout: int = 30000) -> Any:
|
|
34
53
|
"""
|
|
35
54
|
Execute JavaScript code and return result
|
|
@@ -48,8 +67,8 @@ class ScriptManager:
|
|
|
48
67
|
self._scripts_executed += 1
|
|
49
68
|
|
|
50
69
|
try:
|
|
51
|
-
self.
|
|
52
|
-
self.
|
|
70
|
+
self.log_info(f"🔧 Executing JavaScript (timeout: {timeout}ms)")
|
|
71
|
+
self.log_debug(f"Script preview: {script[:100]}...")
|
|
53
72
|
|
|
54
73
|
# Execute script with timeout
|
|
55
74
|
result = await asyncio.wait_for(
|
|
@@ -70,8 +89,8 @@ class ScriptManager:
|
|
|
70
89
|
}
|
|
71
90
|
self._execution_history.append(execution_record)
|
|
72
91
|
|
|
73
|
-
self.
|
|
74
|
-
self.
|
|
92
|
+
self.log_info(f"✅ Script executed successfully ({duration_ms:.1f}ms)")
|
|
93
|
+
self.log_debug(f"Result type: {type(result).__name__}")
|
|
75
94
|
|
|
76
95
|
return result
|
|
77
96
|
|
|
@@ -88,7 +107,7 @@ class ScriptManager:
|
|
|
88
107
|
}
|
|
89
108
|
self._execution_history.append(execution_record)
|
|
90
109
|
|
|
91
|
-
self.
|
|
110
|
+
self.log_error(f"⏰ Script execution timeout ({timeout}ms)")
|
|
92
111
|
raise
|
|
93
112
|
|
|
94
113
|
except Exception as e:
|
|
@@ -104,7 +123,7 @@ class ScriptManager:
|
|
|
104
123
|
}
|
|
105
124
|
self._execution_history.append(execution_record)
|
|
106
125
|
|
|
107
|
-
self.
|
|
126
|
+
self.log_error(f"❌ Script execution failed: {e}")
|
|
108
127
|
raise
|
|
109
128
|
|
|
110
129
|
async def execute_api_call(self, api_url: str, headers: Dict[str, str], method: str = "GET", timeout: int = 30000) -> Dict[str, Any]:
|
|
@@ -145,14 +164,14 @@ class ScriptManager:
|
|
|
145
164
|
}})()
|
|
146
165
|
"""
|
|
147
166
|
|
|
148
|
-
self.
|
|
167
|
+
self.log_info(f"🌐 Making API call: {method} {api_url}")
|
|
149
168
|
|
|
150
169
|
result = await self.execute_script(script, timeout)
|
|
151
170
|
|
|
152
171
|
if isinstance(result, dict) and 'error' in result:
|
|
153
|
-
self.
|
|
172
|
+
self.log_error(f"❌ API call failed: {result['error']}")
|
|
154
173
|
else:
|
|
155
|
-
self.
|
|
174
|
+
self.log_info(f"✅ API call successful")
|
|
156
175
|
|
|
157
176
|
return result
|
|
158
177
|
|
|
@@ -198,17 +217,17 @@ class ScriptManager:
|
|
|
198
217
|
}})()
|
|
199
218
|
"""
|
|
200
219
|
|
|
201
|
-
self.
|
|
220
|
+
self.log_info(f"🎯 Waiting for element: {selector}")
|
|
202
221
|
|
|
203
222
|
try:
|
|
204
223
|
result = await self.execute_script(script, timeout + 1000)
|
|
205
224
|
if result:
|
|
206
|
-
self.
|
|
225
|
+
self.log_info(f"✅ Element found: {selector}")
|
|
207
226
|
else:
|
|
208
|
-
self.
|
|
227
|
+
self.log_warning(f"⏰ Element timeout: {selector}")
|
|
209
228
|
return result
|
|
210
229
|
except Exception as e:
|
|
211
|
-
self.
|
|
230
|
+
self.log_error(f"❌ Element wait failed: {selector} - {e}")
|
|
212
231
|
return False
|
|
213
232
|
|
|
214
233
|
async def inject_helper_functions(self) -> bool:
|
|
@@ -271,10 +290,10 @@ class ScriptManager:
|
|
|
271
290
|
|
|
272
291
|
try:
|
|
273
292
|
await self.execute_script(helper_script)
|
|
274
|
-
self.
|
|
293
|
+
self.log_info("🔧 Helper functions injected successfully")
|
|
275
294
|
return True
|
|
276
295
|
except Exception as e:
|
|
277
|
-
self.
|
|
296
|
+
self.log_error(f"❌ Failed to inject helper functions: {e}")
|
|
278
297
|
return False
|
|
279
298
|
|
|
280
299
|
def get_statistics(self) -> Dict[str, Any]:
|
|
@@ -294,21 +313,21 @@ class ScriptManager:
|
|
|
294
313
|
"""Print script execution statistics"""
|
|
295
314
|
stats = self.get_statistics()
|
|
296
315
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
316
|
+
print("\n🔧 Script Manager Statistics:")
|
|
317
|
+
print(f" Scripts executed: {stats['scripts_executed']}")
|
|
318
|
+
print(f" Successful: {stats['scripts_successful']}")
|
|
319
|
+
print(f" Failed: {stats['scripts_failed']}")
|
|
320
|
+
print(f" Success rate: {stats['success_rate']:.1f}%")
|
|
321
|
+
print(f" API calls made: {stats['api_calls_made']}")
|
|
303
322
|
|
|
304
323
|
# Show recent executions
|
|
305
324
|
if self._execution_history:
|
|
306
|
-
|
|
325
|
+
print(" Recent executions:")
|
|
307
326
|
for execution in self._execution_history[-3:]: # Show last 3
|
|
308
327
|
status = "✅" if execution["success"] else "❌"
|
|
309
|
-
|
|
328
|
+
print(f" {status} {execution['duration_ms']:.1f}ms")
|
|
310
329
|
|
|
311
330
|
def clear_history(self) -> None:
|
|
312
331
|
"""Clear execution history"""
|
|
313
332
|
self._execution_history.clear()
|
|
314
|
-
self.
|
|
333
|
+
self.log_info("🧹 Cleared script execution history")
|
|
Binary file
|