seleniumbase 4.24.11__py3-none-any.whl → 4.33.15__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.
- sbase/__init__.py +1 -0
- sbase/steps.py +7 -0
- seleniumbase/__init__.py +16 -7
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +97 -32
- seleniumbase/common/decorators.py +16 -7
- seleniumbase/config/proxy_list.py +3 -3
- seleniumbase/config/settings.py +4 -0
- seleniumbase/console_scripts/logo_helper.py +47 -8
- seleniumbase/console_scripts/run.py +345 -335
- seleniumbase/console_scripts/sb_behave_gui.py +5 -12
- seleniumbase/console_scripts/sb_caseplans.py +6 -13
- seleniumbase/console_scripts/sb_commander.py +5 -12
- seleniumbase/console_scripts/sb_install.py +62 -54
- seleniumbase/console_scripts/sb_mkchart.py +13 -20
- seleniumbase/console_scripts/sb_mkdir.py +11 -17
- seleniumbase/console_scripts/sb_mkfile.py +69 -43
- seleniumbase/console_scripts/sb_mkpres.py +13 -20
- seleniumbase/console_scripts/sb_mkrec.py +88 -21
- seleniumbase/console_scripts/sb_objectify.py +30 -30
- seleniumbase/console_scripts/sb_print.py +5 -12
- seleniumbase/console_scripts/sb_recorder.py +16 -11
- seleniumbase/core/browser_launcher.py +1658 -221
- seleniumbase/core/log_helper.py +42 -27
- seleniumbase/core/mysql.py +1 -4
- seleniumbase/core/proxy_helper.py +35 -30
- seleniumbase/core/recorder_helper.py +24 -5
- seleniumbase/core/sb_cdp.py +1951 -0
- seleniumbase/core/sb_driver.py +162 -8
- seleniumbase/core/settings_parser.py +6 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/extensions/recorder.zip +0 -0
- seleniumbase/fixtures/base_case.py +1225 -614
- seleniumbase/fixtures/constants.py +10 -1
- seleniumbase/fixtures/js_utils.py +171 -144
- seleniumbase/fixtures/page_actions.py +177 -13
- seleniumbase/fixtures/page_utils.py +25 -53
- seleniumbase/fixtures/shared_utils.py +97 -11
- seleniumbase/js_code/active_css_js.py +1 -1
- seleniumbase/js_code/recorder_js.py +1 -1
- seleniumbase/plugins/base_plugin.py +2 -3
- seleniumbase/plugins/driver_manager.py +340 -65
- seleniumbase/plugins/pytest_plugin.py +276 -47
- seleniumbase/plugins/sb_manager.py +412 -99
- seleniumbase/plugins/selenium_plugin.py +122 -17
- seleniumbase/translate/translator.py +0 -7
- seleniumbase/undetected/__init__.py +59 -52
- seleniumbase/undetected/cdp.py +0 -1
- seleniumbase/undetected/cdp_driver/__init__.py +1 -0
- seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
- seleniumbase/undetected/cdp_driver/browser.py +829 -0
- seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
- seleniumbase/undetected/cdp_driver/config.py +334 -0
- seleniumbase/undetected/cdp_driver/connection.py +639 -0
- seleniumbase/undetected/cdp_driver/element.py +1168 -0
- seleniumbase/undetected/cdp_driver/tab.py +1323 -0
- seleniumbase/undetected/dprocess.py +4 -7
- seleniumbase/undetected/options.py +6 -8
- seleniumbase/undetected/patcher.py +11 -13
- seleniumbase/undetected/reactor.py +0 -1
- seleniumbase/undetected/webelement.py +16 -3
- {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
- {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
- {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +67 -69
- {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
- sbase/ReadMe.txt +0 -2
- seleniumbase/ReadMe.md +0 -25
- seleniumbase/common/ReadMe.md +0 -71
- seleniumbase/console_scripts/ReadMe.md +0 -731
- seleniumbase/drivers/ReadMe.md +0 -27
- seleniumbase/extensions/ReadMe.md +0 -12
- seleniumbase/masterqa/ReadMe.md +0 -61
- seleniumbase/resources/ReadMe.md +0 -31
- seleniumbase/resources/favicon.ico +0 -0
- seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
- seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
- {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
seleniumbase/core/log_helper.py
CHANGED
@@ -3,9 +3,11 @@ import os
|
|
3
3
|
import shutil
|
4
4
|
import sys
|
5
5
|
import time
|
6
|
+
from contextlib import suppress
|
6
7
|
from seleniumbase import config as sb_config
|
7
8
|
from seleniumbase.config import settings
|
8
9
|
from seleniumbase.fixtures import constants
|
10
|
+
from seleniumbase.fixtures import shared_utils
|
9
11
|
|
10
12
|
python3_11_or_newer = False
|
11
13
|
if sys.version_info >= (3, 11):
|
@@ -13,6 +15,11 @@ if sys.version_info >= (3, 11):
|
|
13
15
|
py311_patch2 = constants.PatchPy311.PATCH
|
14
16
|
|
15
17
|
|
18
|
+
def __is_cdp_swap_needed(driver):
|
19
|
+
"""If the driver is disconnected, use a CDP method when available."""
|
20
|
+
return shared_utils.is_cdp_swap_needed(driver)
|
21
|
+
|
22
|
+
|
16
23
|
def log_screenshot(test_logpath, driver, screenshot=None, get=False):
|
17
24
|
screenshot_name = settings.SCREENSHOT_NAME
|
18
25
|
screenshot_path = os.path.join(test_logpath, screenshot_name)
|
@@ -32,6 +39,8 @@ def log_screenshot(test_logpath, driver, screenshot=None, get=False):
|
|
32
39
|
if screenshot != screenshot_warning:
|
33
40
|
with open(screenshot_path, "wb") as file:
|
34
41
|
file.write(screenshot)
|
42
|
+
with suppress(Exception):
|
43
|
+
shared_utils.make_writable(screenshot_path)
|
35
44
|
else:
|
36
45
|
print("WARNING: %s" % screenshot_warning)
|
37
46
|
if get:
|
@@ -281,14 +290,14 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None):
|
|
281
290
|
sb_config._report_time = the_time
|
282
291
|
sb_config._report_traceback = traceback_message
|
283
292
|
sb_config._report_exception = exc_message
|
284
|
-
|
285
|
-
|
293
|
+
if not os.path.exists(test_logpath):
|
294
|
+
with suppress(Exception):
|
286
295
|
os.makedirs(test_logpath)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
296
|
+
with suppress(Exception):
|
297
|
+
log_file = codecs.open(basic_file_path, "w+", encoding="utf-8")
|
298
|
+
log_file.writelines("\r\n".join(data_to_save))
|
299
|
+
log_file.close()
|
300
|
+
shared_utils.make_writable(basic_file_path)
|
292
301
|
|
293
302
|
|
294
303
|
def log_skipped_test_data(test, test_logpath, driver, browser, reason):
|
@@ -297,16 +306,12 @@ def log_skipped_test_data(test, test_logpath, driver, browser, reason):
|
|
297
306
|
browser_version = None
|
298
307
|
driver_version = None
|
299
308
|
driver_name = None
|
300
|
-
|
309
|
+
with suppress(Exception):
|
301
310
|
browser_version = get_browser_version(driver)
|
302
|
-
|
303
|
-
pass
|
304
|
-
try:
|
311
|
+
with suppress(Exception):
|
305
312
|
driver_name, driver_version = get_driver_name_and_version(
|
306
313
|
driver, browser
|
307
314
|
)
|
308
|
-
except Exception:
|
309
|
-
pass
|
310
315
|
if browser_version:
|
311
316
|
headless = ""
|
312
317
|
if test.headless and browser in ["chrome", "edge", "firefox"]:
|
@@ -343,9 +348,11 @@ def log_skipped_test_data(test, test_logpath, driver, browser, reason):
|
|
343
348
|
data_to_save.append(" * Skip Reason: %s" % reason)
|
344
349
|
data_to_save.append("")
|
345
350
|
file_path = os.path.join(test_logpath, "skip_reason.txt")
|
346
|
-
|
347
|
-
|
348
|
-
|
351
|
+
with suppress(Exception):
|
352
|
+
log_file = codecs.open(file_path, "w+", encoding="utf-8")
|
353
|
+
log_file.writelines("\r\n".join(data_to_save))
|
354
|
+
log_file.close()
|
355
|
+
shared_utils.make_writable(file_path)
|
349
356
|
|
350
357
|
|
351
358
|
def log_page_source(test_logpath, driver, source=None):
|
@@ -354,7 +361,11 @@ def log_page_source(test_logpath, driver, source=None):
|
|
354
361
|
page_source = source
|
355
362
|
else:
|
356
363
|
try:
|
357
|
-
page_source =
|
364
|
+
page_source = None
|
365
|
+
if __is_cdp_swap_needed(driver):
|
366
|
+
page_source = driver.cdp.get_page_source()
|
367
|
+
else:
|
368
|
+
page_source = driver.page_source
|
358
369
|
page_source = get_html_source_with_base_href(driver, page_source)
|
359
370
|
except Exception:
|
360
371
|
source = constants.Warnings.PAGE_SOURCE_UNDEFINED
|
@@ -368,15 +379,15 @@ def log_page_source(test_logpath, driver, source=None):
|
|
368
379
|
"unresponsive, or closed prematurely!</h4>"
|
369
380
|
)
|
370
381
|
)
|
371
|
-
|
372
|
-
|
382
|
+
if not os.path.exists(test_logpath):
|
383
|
+
with suppress(Exception):
|
373
384
|
os.makedirs(test_logpath)
|
374
|
-
except Exception:
|
375
|
-
pass
|
376
385
|
html_file_path = os.path.join(test_logpath, html_file_name)
|
377
|
-
|
378
|
-
|
379
|
-
|
386
|
+
with suppress(Exception):
|
387
|
+
html_file = codecs.open(html_file_path, "w+", encoding="utf-8")
|
388
|
+
html_file.write(page_source)
|
389
|
+
html_file.close()
|
390
|
+
shared_utils.make_writable(html_file_path)
|
380
391
|
|
381
392
|
|
382
393
|
def get_test_id(test):
|
@@ -446,7 +457,11 @@ def get_test_name(test):
|
|
446
457
|
|
447
458
|
def get_last_page(driver):
|
448
459
|
try:
|
449
|
-
last_page =
|
460
|
+
last_page = None
|
461
|
+
if __is_cdp_swap_needed(driver):
|
462
|
+
last_page = driver.cdp.get_current_url()
|
463
|
+
else:
|
464
|
+
last_page = driver.current_url
|
450
465
|
except Exception:
|
451
466
|
last_page = "[WARNING! Browser Not Open!]"
|
452
467
|
if len(last_page) < 5:
|
@@ -543,7 +558,7 @@ def log_folder_setup(log_path, archive_logs=False):
|
|
543
558
|
try:
|
544
559
|
os.makedirs(log_path)
|
545
560
|
except Exception:
|
546
|
-
pass #
|
561
|
+
pass # Only reachable during multi-threaded runs
|
547
562
|
else:
|
548
563
|
saved_folder = "%s/../%s/" % (log_path, constants.Logs.SAVED)
|
549
564
|
archived_folder = os.path.realpath(saved_folder) + "/"
|
@@ -551,7 +566,7 @@ def log_folder_setup(log_path, archive_logs=False):
|
|
551
566
|
try:
|
552
567
|
os.makedirs(archived_folder)
|
553
568
|
except Exception:
|
554
|
-
pass #
|
569
|
+
pass # Only reachable during multi-threaded runs
|
555
570
|
archived_logs = "%slogs_%s" % (archived_folder, int(time.time()))
|
556
571
|
if len(os.listdir(log_path)) > 0:
|
557
572
|
try:
|
seleniumbase/core/mysql.py
CHANGED
@@ -35,10 +35,7 @@ class DatabaseManager:
|
|
35
35
|
import cryptography # noqa: F401
|
36
36
|
import pymysql
|
37
37
|
except Exception:
|
38
|
-
|
39
|
-
shared_utils.pip_install("PyMySQL[rsa]", version="1.0.2")
|
40
|
-
else:
|
41
|
-
shared_utils.pip_install("PyMySQL[rsa]", version="1.1.0")
|
38
|
+
shared_utils.pip_install("PyMySQL[rsa]", version="1.1.1")
|
42
39
|
import pymysql
|
43
40
|
db_server = settings.DB_HOST
|
44
41
|
db_port = settings.DB_PORT
|
@@ -2,10 +2,12 @@ import os
|
|
2
2
|
import re
|
3
3
|
import warnings
|
4
4
|
import zipfile
|
5
|
+
from contextlib import suppress
|
5
6
|
from seleniumbase.config import proxy_list
|
6
7
|
from seleniumbase.config import settings
|
7
8
|
from seleniumbase.fixtures import constants
|
8
9
|
from seleniumbase.fixtures import page_utils
|
10
|
+
from seleniumbase.fixtures import shared_utils
|
9
11
|
|
10
12
|
DOWNLOADS_DIR = constants.Files.DOWNLOADS_FOLDER
|
11
13
|
PROXY_ZIP_PATH = os.path.join(DOWNLOADS_DIR, "proxy.zip")
|
@@ -109,31 +111,35 @@ def create_proxy_ext(
|
|
109
111
|
""""minimum_chrome_version":"22.0.0"\n"""
|
110
112
|
"""}"""
|
111
113
|
)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
proxy_ext_dir
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
114
|
+
abs_path = os.path.abspath(".")
|
115
|
+
downloads_path = os.path.join(abs_path, DOWNLOADS_DIR)
|
116
|
+
if not os.path.exists(downloads_path):
|
117
|
+
os.mkdir(downloads_path)
|
118
|
+
if zip_it:
|
119
|
+
zf = zipfile.ZipFile(PROXY_ZIP_PATH, mode="w")
|
120
|
+
zf.writestr("background.js", background_js)
|
121
|
+
zf.writestr("manifest.json", manifest_json)
|
122
|
+
zf.close()
|
123
|
+
with suppress(Exception):
|
124
|
+
shared_utils.make_writable(PROXY_ZIP_PATH)
|
125
|
+
else:
|
126
|
+
proxy_ext_dir = PROXY_DIR_PATH
|
127
|
+
if not os.path.exists(proxy_ext_dir):
|
128
|
+
os.mkdir(proxy_ext_dir)
|
129
|
+
with suppress(Exception):
|
130
|
+
shared_utils.make_writable(proxy_ext_dir)
|
131
|
+
manifest_file = os.path.join(proxy_ext_dir, "manifest.json")
|
132
|
+
with open(manifest_file, mode="w") as f:
|
133
|
+
f.write(manifest_json)
|
134
|
+
with suppress(Exception):
|
135
|
+
shared_utils.make_writable(manifest_json)
|
136
|
+
proxy_host = proxy_string.split(":")[0]
|
137
|
+
proxy_port = proxy_string.split(":")[1]
|
138
|
+
background_file = os.path.join(proxy_ext_dir, "background.js")
|
139
|
+
with open(background_file, mode="w") as f:
|
140
|
+
f.write(background_js)
|
141
|
+
with suppress(Exception):
|
142
|
+
shared_utils.make_writable(background_js)
|
137
143
|
|
138
144
|
|
139
145
|
def remove_proxy_zip_if_present():
|
@@ -141,13 +147,12 @@ def remove_proxy_zip_if_present():
|
|
141
147
|
Used in the implementation of https://stackoverflow.com/a/35293284
|
142
148
|
for https://stackoverflow.com/questions/12848327/
|
143
149
|
"""
|
144
|
-
|
145
|
-
|
150
|
+
if os.path.exists(PROXY_ZIP_PATH):
|
151
|
+
with suppress(Exception):
|
146
152
|
os.remove(PROXY_ZIP_PATH)
|
147
|
-
|
153
|
+
if os.path.exists(PROXY_ZIP_LOCK):
|
154
|
+
with suppress(Exception):
|
148
155
|
os.remove(PROXY_ZIP_LOCK)
|
149
|
-
except Exception:
|
150
|
-
pass
|
151
156
|
|
152
157
|
|
153
158
|
def validate_proxy_string(proxy_string):
|
@@ -422,9 +422,14 @@ def generate_sbase_code(srt_actions):
|
|
422
422
|
):
|
423
423
|
import unicodedata
|
424
424
|
|
425
|
-
|
426
|
-
|
427
|
-
|
425
|
+
text_list = False
|
426
|
+
try:
|
427
|
+
action[1][0] = unicodedata.normalize("NFKC", action[1][0])
|
428
|
+
action[1][0] = action[1][0].replace("\n", "\\n")
|
429
|
+
action[1][0] = action[1][0].replace("\u00B6", "")
|
430
|
+
except Exception:
|
431
|
+
text_list = True
|
432
|
+
|
428
433
|
method = "assert_text"
|
429
434
|
if action[0] == "as_et":
|
430
435
|
method = "assert_exact_text"
|
@@ -437,7 +442,17 @@ def generate_sbase_code(srt_actions):
|
|
437
442
|
elif action[0] == "da_et":
|
438
443
|
method = "deferred_assert_exact_text"
|
439
444
|
if action[1][1] != "html":
|
440
|
-
if
|
445
|
+
if text_list and '"' not in action[1][1]:
|
446
|
+
sb_actions.append(
|
447
|
+
'self.%s(%s, "%s")'
|
448
|
+
% (method, action[1][0], action[1][1])
|
449
|
+
)
|
450
|
+
elif text_list and "'" not in action[1][1]:
|
451
|
+
sb_actions.append(
|
452
|
+
"self.%s(%s, '%s')"
|
453
|
+
% (method, action[1][0], action[1][1])
|
454
|
+
)
|
455
|
+
elif '"' not in action[1][0] and '"' not in action[1][1]:
|
441
456
|
sb_actions.append(
|
442
457
|
'self.%s("%s", "%s")'
|
443
458
|
% (method, action[1][0], action[1][1])
|
@@ -458,7 +473,11 @@ def generate_sbase_code(srt_actions):
|
|
458
473
|
% (method, action[1][0], action[1][1])
|
459
474
|
)
|
460
475
|
else:
|
461
|
-
if
|
476
|
+
if text_list:
|
477
|
+
sb_actions.append(
|
478
|
+
'self.%s(%s)' % (method, action[1][0])
|
479
|
+
)
|
480
|
+
elif '"' not in action[1][0]:
|
462
481
|
sb_actions.append(
|
463
482
|
'self.%s("%s")' % (method, action[1][0])
|
464
483
|
)
|