seleniumbase 4.33.4__py3-none-any.whl → 4.33.6__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.
- seleniumbase/__version__.py +1 -1
- seleniumbase/console_scripts/sb_mkdir.py +1 -0
- seleniumbase/core/browser_launcher.py +115 -72
- seleniumbase/core/log_helper.py +8 -6
- seleniumbase/core/sb_cdp.py +12 -0
- seleniumbase/core/style_sheet.py +10 -0
- seleniumbase/fixtures/base_case.py +101 -74
- seleniumbase/fixtures/shared_utils.py +14 -0
- seleniumbase/plugins/pytest_plugin.py +42 -0
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.33.6.dist-info}/METADATA +3 -3
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.33.6.dist-info}/RECORD +15 -15
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.33.6.dist-info}/LICENSE +0 -0
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.33.6.dist-info}/WHEEL +0 -0
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.33.6.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.33.4.dist-info → seleniumbase-4.33.6.dist-info}/top_level.txt +0 -0
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.33.
|
2
|
+
__version__ = "4.33.6"
|
@@ -97,26 +97,12 @@ def log_d(message):
|
|
97
97
|
print(message)
|
98
98
|
|
99
99
|
|
100
|
-
def make_writable(file_path):
|
101
|
-
# Set permissions to: "If you can read it, you can write it."
|
102
|
-
mode = os.stat(file_path).st_mode
|
103
|
-
mode |= (mode & 0o444) >> 1 # copy R bits to W
|
104
|
-
os.chmod(file_path, mode)
|
105
|
-
|
106
|
-
|
107
|
-
def make_executable(file_path):
|
108
|
-
# Set permissions to: "If you can read it, you can execute it."
|
109
|
-
mode = os.stat(file_path).st_mode
|
110
|
-
mode |= (mode & 0o444) >> 2 # copy R bits to X
|
111
|
-
os.chmod(file_path, mode)
|
112
|
-
|
113
|
-
|
114
100
|
def make_driver_executable_if_not(driver_path):
|
115
101
|
# Verify driver has executable permissions. If not, add them.
|
116
102
|
permissions = oct(os.stat(driver_path)[0])[-3:]
|
117
103
|
if "4" in permissions or "6" in permissions:
|
118
104
|
# We want at least a '5' or '7' to make sure it's executable
|
119
|
-
make_executable(driver_path)
|
105
|
+
shared_utils.make_executable(driver_path)
|
120
106
|
|
121
107
|
|
122
108
|
def extend_driver(driver):
|
@@ -566,6 +552,10 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
566
552
|
for tab in driver.cdp_base.tabs[-1::-1]:
|
567
553
|
if "chrome-extension://" not in str(tab):
|
568
554
|
with gui_lock:
|
555
|
+
with suppress(Exception):
|
556
|
+
shared_utils.make_writable(
|
557
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
558
|
+
)
|
569
559
|
loop.run_until_complete(tab.activate())
|
570
560
|
break
|
571
561
|
|
@@ -580,11 +570,17 @@ def uc_open_with_cdp_mode(driver, url=None):
|
|
580
570
|
if page_tab:
|
581
571
|
loop.run_until_complete(page_tab.aopen())
|
582
572
|
with gui_lock:
|
573
|
+
with suppress(Exception):
|
574
|
+
shared_utils.make_writable(
|
575
|
+
constants.MultiBrowser.PYAUTOGUILOCK
|
576
|
+
)
|
583
577
|
loop.run_until_complete(page_tab.activate())
|
584
578
|
|
585
579
|
loop.run_until_complete(driver.cdp_base.update_targets())
|
586
580
|
page = loop.run_until_complete(driver.cdp_base.get(url))
|
587
581
|
with gui_lock:
|
582
|
+
with suppress(Exception):
|
583
|
+
shared_utils.make_writable(constants.MultiBrowser.PYAUTOGUILOCK)
|
588
584
|
loop.run_until_complete(page.activate())
|
589
585
|
loop.run_until_complete(page.wait())
|
590
586
|
if not safe_url:
|
@@ -817,6 +813,63 @@ def verify_pyautogui_has_a_headed_browser(driver):
|
|
817
813
|
)
|
818
814
|
|
819
815
|
|
816
|
+
def __install_pyautogui_if_missing():
|
817
|
+
try:
|
818
|
+
import pyautogui
|
819
|
+
with suppress(Exception):
|
820
|
+
use_pyautogui_ver = constants.PyAutoGUI.VER
|
821
|
+
if pyautogui.__version__ != use_pyautogui_ver:
|
822
|
+
del pyautogui
|
823
|
+
shared_utils.pip_install(
|
824
|
+
"pyautogui", version=use_pyautogui_ver
|
825
|
+
)
|
826
|
+
import pyautogui
|
827
|
+
except Exception:
|
828
|
+
print("\nPyAutoGUI required! Installing now...")
|
829
|
+
shared_utils.pip_install(
|
830
|
+
"pyautogui", version=constants.PyAutoGUI.VER
|
831
|
+
)
|
832
|
+
try:
|
833
|
+
import pyautogui
|
834
|
+
except Exception:
|
835
|
+
if (
|
836
|
+
IS_LINUX
|
837
|
+
and hasattr(sb_config, "xvfb")
|
838
|
+
and hasattr(sb_config, "headed")
|
839
|
+
and hasattr(sb_config, "headless")
|
840
|
+
and hasattr(sb_config, "headless2")
|
841
|
+
and (not sb_config.headed or sb_config.xvfb)
|
842
|
+
and not (sb_config.headless or sb_config.headless2)
|
843
|
+
):
|
844
|
+
from sbvirtualdisplay import Display
|
845
|
+
xvfb_width = 1366
|
846
|
+
xvfb_height = 768
|
847
|
+
if (
|
848
|
+
hasattr(sb_config, "_xvfb_width")
|
849
|
+
and sb_config._xvfb_width
|
850
|
+
and isinstance(sb_config._xvfb_width, int)
|
851
|
+
and hasattr(sb_config, "_xvfb_height")
|
852
|
+
and sb_config._xvfb_height
|
853
|
+
and isinstance(sb_config._xvfb_height, int)
|
854
|
+
):
|
855
|
+
xvfb_width = sb_config._xvfb_width
|
856
|
+
xvfb_height = sb_config._xvfb_height
|
857
|
+
if xvfb_width < 1024:
|
858
|
+
xvfb_width = 1024
|
859
|
+
sb_config._xvfb_width = xvfb_width
|
860
|
+
if xvfb_height < 768:
|
861
|
+
xvfb_height = 768
|
862
|
+
sb_config._xvfb_height = xvfb_height
|
863
|
+
with suppress(Exception):
|
864
|
+
xvfb_display = Display(
|
865
|
+
visible=True,
|
866
|
+
size=(xvfb_width, xvfb_height),
|
867
|
+
backend="xvfb",
|
868
|
+
use_xauth=True,
|
869
|
+
)
|
870
|
+
xvfb_display.start()
|
871
|
+
|
872
|
+
|
820
873
|
def install_pyautogui_if_missing(driver):
|
821
874
|
verify_pyautogui_has_a_headed_browser(driver)
|
822
875
|
pip_find_lock = fasteners.InterProcessLock(
|
@@ -826,64 +879,13 @@ def install_pyautogui_if_missing(driver):
|
|
826
879
|
with pip_find_lock:
|
827
880
|
pass
|
828
881
|
except Exception:
|
829
|
-
#
|
830
|
-
|
831
|
-
|
882
|
+
# Since missing permissions, skip the locks
|
883
|
+
__install_pyautogui_if_missing()
|
884
|
+
return
|
832
885
|
with pip_find_lock: # Prevent issues with multiple processes
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
use_pyautogui_ver = constants.PyAutoGUI.VER
|
837
|
-
if pyautogui.__version__ != use_pyautogui_ver:
|
838
|
-
del pyautogui
|
839
|
-
shared_utils.pip_install(
|
840
|
-
"pyautogui", version=use_pyautogui_ver
|
841
|
-
)
|
842
|
-
import pyautogui
|
843
|
-
except Exception:
|
844
|
-
print("\nPyAutoGUI required! Installing now...")
|
845
|
-
shared_utils.pip_install(
|
846
|
-
"pyautogui", version=constants.PyAutoGUI.VER
|
847
|
-
)
|
848
|
-
try:
|
849
|
-
import pyautogui
|
850
|
-
except Exception:
|
851
|
-
if (
|
852
|
-
IS_LINUX
|
853
|
-
and hasattr(sb_config, "xvfb")
|
854
|
-
and hasattr(sb_config, "headed")
|
855
|
-
and hasattr(sb_config, "headless")
|
856
|
-
and hasattr(sb_config, "headless2")
|
857
|
-
and (not sb_config.headed or sb_config.xvfb)
|
858
|
-
and not (sb_config.headless or sb_config.headless2)
|
859
|
-
):
|
860
|
-
from sbvirtualdisplay import Display
|
861
|
-
xvfb_width = 1366
|
862
|
-
xvfb_height = 768
|
863
|
-
if (
|
864
|
-
hasattr(sb_config, "_xvfb_width")
|
865
|
-
and sb_config._xvfb_width
|
866
|
-
and isinstance(sb_config._xvfb_width, int)
|
867
|
-
and hasattr(sb_config, "_xvfb_height")
|
868
|
-
and sb_config._xvfb_height
|
869
|
-
and isinstance(sb_config._xvfb_height, int)
|
870
|
-
):
|
871
|
-
xvfb_width = sb_config._xvfb_width
|
872
|
-
xvfb_height = sb_config._xvfb_height
|
873
|
-
if xvfb_width < 1024:
|
874
|
-
xvfb_width = 1024
|
875
|
-
sb_config._xvfb_width = xvfb_width
|
876
|
-
if xvfb_height < 768:
|
877
|
-
xvfb_height = 768
|
878
|
-
sb_config._xvfb_height = xvfb_height
|
879
|
-
with suppress(Exception):
|
880
|
-
xvfb_display = Display(
|
881
|
-
visible=True,
|
882
|
-
size=(xvfb_width, xvfb_height),
|
883
|
-
backend="xvfb",
|
884
|
-
use_xauth=True,
|
885
|
-
)
|
886
|
-
xvfb_display.start()
|
886
|
+
with suppress(Exception):
|
887
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
888
|
+
__install_pyautogui_if_missing()
|
887
889
|
|
888
890
|
|
889
891
|
def get_configured_pyautogui(pyautogui_copy):
|
@@ -1778,6 +1780,8 @@ def _add_chrome_proxy_extension(
|
|
1778
1780
|
if zip_it:
|
1779
1781
|
proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
|
1780
1782
|
with proxy_zip_lock:
|
1783
|
+
with suppress(Exception):
|
1784
|
+
shared_utils.make_writable(PROXY_ZIP_LOCK)
|
1781
1785
|
if multi_proxy:
|
1782
1786
|
_set_proxy_filenames()
|
1783
1787
|
if not os.path.exists(proxy_helper.PROXY_ZIP_PATH):
|
@@ -1789,6 +1793,8 @@ def _add_chrome_proxy_extension(
|
|
1789
1793
|
else:
|
1790
1794
|
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
1791
1795
|
with proxy_dir_lock:
|
1796
|
+
with suppress(Exception):
|
1797
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
1792
1798
|
if multi_proxy:
|
1793
1799
|
_set_proxy_filenames()
|
1794
1800
|
if not os.path.exists(proxy_helper.PROXY_DIR_PATH):
|
@@ -1814,6 +1820,8 @@ def is_using_uc(undetectable, browser_name):
|
|
1814
1820
|
def _unzip_to_new_folder(zip_file, folder):
|
1815
1821
|
proxy_dir_lock = fasteners.InterProcessLock(PROXY_DIR_LOCK)
|
1816
1822
|
with proxy_dir_lock:
|
1823
|
+
with suppress(Exception):
|
1824
|
+
shared_utils.make_writable(PROXY_DIR_LOCK)
|
1817
1825
|
if not os.path.exists(folder):
|
1818
1826
|
import zipfile
|
1819
1827
|
zip_ref = zipfile.ZipFile(zip_file, "r")
|
@@ -2923,6 +2931,8 @@ def get_remote_driver(
|
|
2923
2931
|
constants.PipInstall.FINDLOCK
|
2924
2932
|
)
|
2925
2933
|
with pip_find_lock: # Prevent issues with multiple processes
|
2934
|
+
with suppress(Exception):
|
2935
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
2926
2936
|
try:
|
2927
2937
|
from seleniumwire import webdriver
|
2928
2938
|
import blinker
|
@@ -3360,6 +3370,8 @@ def get_local_driver(
|
|
3360
3370
|
constants.PipInstall.FINDLOCK
|
3361
3371
|
)
|
3362
3372
|
with pip_find_lock: # Prevent issues with multiple processes
|
3373
|
+
with suppress(Exception):
|
3374
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
3363
3375
|
try:
|
3364
3376
|
from seleniumwire import webdriver
|
3365
3377
|
import blinker
|
@@ -3423,6 +3435,10 @@ def get_local_driver(
|
|
3423
3435
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3424
3436
|
)
|
3425
3437
|
with geckodriver_fixing_lock:
|
3438
|
+
with suppress(Exception):
|
3439
|
+
shared_utils.make_writable(
|
3440
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3441
|
+
)
|
3426
3442
|
if not geckodriver_on_path():
|
3427
3443
|
sys_args = sys.argv # Save a copy of sys args
|
3428
3444
|
log_d(
|
@@ -3725,6 +3741,10 @@ def get_local_driver(
|
|
3725
3741
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3726
3742
|
)
|
3727
3743
|
with edgedriver_fixing_lock:
|
3744
|
+
with suppress(Exception):
|
3745
|
+
shared_utils.make_writable(
|
3746
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
3747
|
+
)
|
3728
3748
|
msg = "Microsoft Edge Driver not found."
|
3729
3749
|
if edgedriver_upgrade_needed:
|
3730
3750
|
msg = "Microsoft Edge Driver update needed."
|
@@ -4108,6 +4128,10 @@ def get_local_driver(
|
|
4108
4128
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4109
4129
|
)
|
4110
4130
|
with edgedriver_fixing_lock:
|
4131
|
+
with suppress(Exception):
|
4132
|
+
shared_utils.make_writable(
|
4133
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4134
|
+
)
|
4111
4135
|
with suppress(Exception):
|
4112
4136
|
if not _was_driver_repaired():
|
4113
4137
|
_repair_edgedriver(edge_version)
|
@@ -4490,6 +4514,10 @@ def get_local_driver(
|
|
4490
4514
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4491
4515
|
)
|
4492
4516
|
with chromedriver_fixing_lock:
|
4517
|
+
with suppress(Exception):
|
4518
|
+
shared_utils.make_writable(
|
4519
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4520
|
+
)
|
4493
4521
|
msg = "chromedriver update needed. Getting it now:"
|
4494
4522
|
if not path_chromedriver:
|
4495
4523
|
msg = "chromedriver not found. Getting it now:"
|
@@ -4581,6 +4609,10 @@ def get_local_driver(
|
|
4581
4609
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4582
4610
|
)
|
4583
4611
|
with uc_lock: # Avoid multithreaded issues
|
4612
|
+
with suppress(Exception):
|
4613
|
+
shared_utils.make_writable(
|
4614
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4615
|
+
)
|
4584
4616
|
if make_uc_driver_from_chromedriver:
|
4585
4617
|
if os.path.exists(LOCAL_CHROMEDRIVER):
|
4586
4618
|
with suppress(Exception):
|
@@ -4840,6 +4872,10 @@ def get_local_driver(
|
|
4840
4872
|
if not os.path.exists(cf_lock_path):
|
4841
4873
|
# Avoid multithreaded issues
|
4842
4874
|
with cf_lock:
|
4875
|
+
with suppress(Exception):
|
4876
|
+
shared_utils.make_writable(
|
4877
|
+
cf_lock_path
|
4878
|
+
)
|
4843
4879
|
# Install Python Certificates (MAC)
|
4844
4880
|
os.system(
|
4845
4881
|
r"bash /Applications/Python*/"
|
@@ -4983,6 +5019,10 @@ def get_local_driver(
|
|
4983
5019
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
4984
5020
|
)
|
4985
5021
|
with chromedriver_fixing_lock:
|
5022
|
+
with suppress(Exception):
|
5023
|
+
shared_utils.make_writable(
|
5024
|
+
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5025
|
+
)
|
4986
5026
|
if not _was_driver_repaired():
|
4987
5027
|
_repair_chromedriver(
|
4988
5028
|
chrome_options, headless_options, mcv
|
@@ -5181,7 +5221,10 @@ def get_local_driver(
|
|
5181
5221
|
chromedr_fixing_lock = fasteners.InterProcessLock(
|
5182
5222
|
constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5183
5223
|
)
|
5224
|
+
D_F_L = constants.MultiBrowser.DRIVER_FIXING_LOCK
|
5184
5225
|
with chromedr_fixing_lock:
|
5226
|
+
with suppress(Exception):
|
5227
|
+
shared_utils.make_writable(D_F_L)
|
5185
5228
|
if not _was_driver_repaired():
|
5186
5229
|
with suppress(Exception):
|
5187
5230
|
_repair_chromedriver(
|
seleniumbase/core/log_helper.py
CHANGED
@@ -339,9 +339,10 @@ def log_skipped_test_data(test, test_logpath, driver, browser, reason):
|
|
339
339
|
data_to_save.append(" * Skip Reason: %s" % reason)
|
340
340
|
data_to_save.append("")
|
341
341
|
file_path = os.path.join(test_logpath, "skip_reason.txt")
|
342
|
-
|
343
|
-
|
344
|
-
|
342
|
+
with suppress(Exception):
|
343
|
+
log_file = codecs.open(file_path, "w+", encoding="utf-8")
|
344
|
+
log_file.writelines("\r\n".join(data_to_save))
|
345
|
+
log_file.close()
|
345
346
|
|
346
347
|
|
347
348
|
def log_page_source(test_logpath, driver, source=None):
|
@@ -368,9 +369,10 @@ def log_page_source(test_logpath, driver, source=None):
|
|
368
369
|
if not os.path.exists(test_logpath):
|
369
370
|
os.makedirs(test_logpath)
|
370
371
|
html_file_path = os.path.join(test_logpath, html_file_name)
|
371
|
-
|
372
|
-
|
373
|
-
|
372
|
+
with suppress(Exception):
|
373
|
+
html_file = codecs.open(html_file_path, "w+", encoding="utf-8")
|
374
|
+
html_file.write(page_source)
|
375
|
+
html_file.close()
|
374
376
|
|
375
377
|
|
376
378
|
def get_test_id(test):
|
seleniumbase/core/sb_cdp.py
CHANGED
@@ -1019,6 +1019,10 @@ class CDPMethods():
|
|
1019
1019
|
with suppress(Exception):
|
1020
1020
|
self.loop.run_until_complete(self.page.evaluate(js_code))
|
1021
1021
|
|
1022
|
+
def __make_sure_pyautogui_lock_is_writable(self):
|
1023
|
+
with suppress(Exception):
|
1024
|
+
shared_utils.make_writable(constants.MultiBrowser.PYAUTOGUILOCK)
|
1025
|
+
|
1022
1026
|
def __verify_pyautogui_has_a_headed_browser(self):
|
1023
1027
|
"""PyAutoGUI requires a headed browser so that it can
|
1024
1028
|
focus on the correct element when performing actions."""
|
@@ -1039,6 +1043,8 @@ class CDPMethods():
|
|
1039
1043
|
constants.PipInstall.FINDLOCK
|
1040
1044
|
)
|
1041
1045
|
with pip_find_lock: # Prevent issues with multiple processes
|
1046
|
+
with suppress(Exception):
|
1047
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
1042
1048
|
try:
|
1043
1049
|
import pyautogui
|
1044
1050
|
with suppress(Exception):
|
@@ -1124,6 +1130,7 @@ class CDPMethods():
|
|
1124
1130
|
constants.MultiBrowser.PYAUTOGUILOCK
|
1125
1131
|
)
|
1126
1132
|
with gui_lock:
|
1133
|
+
self.__make_sure_pyautogui_lock_is_writable()
|
1127
1134
|
pyautogui.press(key)
|
1128
1135
|
time.sleep(0.044)
|
1129
1136
|
self.__slow_mode_pause_if_set()
|
@@ -1137,6 +1144,7 @@ class CDPMethods():
|
|
1137
1144
|
constants.MultiBrowser.PYAUTOGUILOCK
|
1138
1145
|
)
|
1139
1146
|
with gui_lock:
|
1147
|
+
self.__make_sure_pyautogui_lock_is_writable()
|
1140
1148
|
for key in keys:
|
1141
1149
|
pyautogui.press(key)
|
1142
1150
|
time.sleep(0.044)
|
@@ -1151,6 +1159,7 @@ class CDPMethods():
|
|
1151
1159
|
constants.MultiBrowser.PYAUTOGUILOCK
|
1152
1160
|
)
|
1153
1161
|
with gui_lock:
|
1162
|
+
self.__make_sure_pyautogui_lock_is_writable()
|
1154
1163
|
pyautogui.write(text)
|
1155
1164
|
self.__slow_mode_pause_if_set()
|
1156
1165
|
self.loop.run_until_complete(self.page.wait())
|
@@ -1171,6 +1180,7 @@ class CDPMethods():
|
|
1171
1180
|
constants.MultiBrowser.PYAUTOGUILOCK
|
1172
1181
|
)
|
1173
1182
|
with gui_lock: # Prevent issues with multiple processes
|
1183
|
+
self.__make_sure_pyautogui_lock_is_writable()
|
1174
1184
|
pyautogui.moveTo(x, y, timeframe, pyautogui.easeOutQuad)
|
1175
1185
|
if timeframe >= 0.25:
|
1176
1186
|
time.sleep(0.056) # Wait if moving at human-speed
|
@@ -1191,6 +1201,7 @@ class CDPMethods():
|
|
1191
1201
|
constants.MultiBrowser.PYAUTOGUILOCK
|
1192
1202
|
)
|
1193
1203
|
with gui_lock: # Prevent issues with multiple processes
|
1204
|
+
self.__make_sure_pyautogui_lock_is_writable()
|
1194
1205
|
self.__install_pyautogui_if_missing()
|
1195
1206
|
import pyautogui
|
1196
1207
|
pyautogui = self.__get_configured_pyautogui(pyautogui)
|
@@ -1408,6 +1419,7 @@ class CDPMethods():
|
|
1408
1419
|
constants.MultiBrowser.PYAUTOGUILOCK
|
1409
1420
|
)
|
1410
1421
|
with gui_lock:
|
1422
|
+
self.__make_sure_pyautogui_lock_is_writable()
|
1411
1423
|
self.bring_active_window_to_front()
|
1412
1424
|
self.gui_hover_element(hover_selector)
|
1413
1425
|
time.sleep(0.15)
|
seleniumbase/core/style_sheet.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import sys
|
2
|
+
import textwrap
|
2
3
|
from seleniumbase.fixtures import constants
|
3
4
|
|
4
5
|
|
@@ -116,6 +117,7 @@ def get_report_style():
|
|
116
117
|
}
|
117
118
|
</style>"""
|
118
119
|
)
|
120
|
+
style = textwrap.dedent(style)
|
119
121
|
Saved.report_style = style
|
120
122
|
return style
|
121
123
|
|
@@ -132,6 +134,7 @@ def get_bt_backdrop_style():
|
|
132
134
|
box-shadow: 0 0 0 88422px rgba(0, 0, 0, 0.42);
|
133
135
|
pointer-events: auto !important;
|
134
136
|
}"""
|
137
|
+
bt_backdrop_style = textwrap.dedent(bt_backdrop_style)
|
135
138
|
Saved.bt_backdrop_style = bt_backdrop_style
|
136
139
|
return bt_backdrop_style
|
137
140
|
|
@@ -150,6 +153,7 @@ def get_dt_backdrop_style():
|
|
150
153
|
button.driver-prev-btn.driver-disabled {
|
151
154
|
visibility: hidden;
|
152
155
|
}"""
|
156
|
+
dt_backdrop_style = textwrap.dedent(dt_backdrop_style)
|
153
157
|
Saved.dt_backdrop_style = dt_backdrop_style
|
154
158
|
return dt_backdrop_style
|
155
159
|
|
@@ -167,6 +171,7 @@ def get_messenger_style():
|
|
167
171
|
box-shadow: 2px 2px 9px 4px rgba(32, 142, 120, 0.28),
|
168
172
|
2px 2px 9px 4px rgba(200, 240, 80, 0.34) !important;
|
169
173
|
}""" % font_family
|
174
|
+
messenger_style = textwrap.dedent(messenger_style)
|
170
175
|
Saved.messenger_style = messenger_style
|
171
176
|
return messenger_style
|
172
177
|
|
@@ -181,6 +186,7 @@ def get_sh_style_test():
|
|
181
186
|
scrollTo: true
|
182
187
|
}
|
183
188
|
});"""
|
189
|
+
sh_style_test = textwrap.dedent(sh_style_test)
|
184
190
|
Saved.sh_style_test = sh_style_test
|
185
191
|
return sh_style_test
|
186
192
|
|
@@ -193,6 +199,7 @@ def get_hops_backdrop_style():
|
|
193
199
|
.hopscotch-bubble-container {
|
194
200
|
font-size: 110%;
|
195
201
|
}"""
|
202
|
+
hops_backdrop_style = textwrap.dedent(hops_backdrop_style)
|
196
203
|
Saved.hops_backdrop_style = hops_backdrop_style
|
197
204
|
return hops_backdrop_style
|
198
205
|
|
@@ -227,6 +234,7 @@ def get_introjs_style():
|
|
227
234
|
box-sizing: content-box;
|
228
235
|
position: absolute;
|
229
236
|
}"""
|
237
|
+
introjs_style = textwrap.dedent(introjs_style)
|
230
238
|
Saved.introjs_style = introjs_style
|
231
239
|
return introjs_style
|
232
240
|
|
@@ -261,6 +269,7 @@ def get_sh_backdrop_style():
|
|
261
269
|
body.shepherd-active {
|
262
270
|
pointer-events: none !important;
|
263
271
|
}"""
|
272
|
+
sh_backdrop_style = textwrap.dedent(sh_backdrop_style)
|
264
273
|
Saved.sh_backdrop_style = sh_backdrop_style
|
265
274
|
return sh_backdrop_style
|
266
275
|
|
@@ -387,5 +396,6 @@ def get_pytest_style():
|
|
387
396
|
.desc.active .sort-icon {
|
388
397
|
border-top: 8px solid #999;
|
389
398
|
}"""
|
399
|
+
pytest_style = textwrap.dedent(pytest_style)
|
390
400
|
Saved.pytest_style = pytest_style
|
391
401
|
return pytest_style
|
@@ -7042,6 +7042,8 @@ class BaseCase(unittest.TestCase):
|
|
7042
7042
|
constants.PipInstall.FINDLOCK
|
7043
7043
|
)
|
7044
7044
|
with pip_find_lock:
|
7045
|
+
with suppress(Exception):
|
7046
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
7045
7047
|
if sys.version_info < (3, 9):
|
7046
7048
|
# Fix bug in newer cryptography for Python 3.7 and 3.8:
|
7047
7049
|
# "pyo3_runtime.PanicException: Python API call failed"
|
@@ -7292,6 +7294,8 @@ class BaseCase(unittest.TestCase):
|
|
7292
7294
|
constants.PipInstall.FINDLOCK
|
7293
7295
|
)
|
7294
7296
|
with pip_find_lock:
|
7297
|
+
with suppress(Exception):
|
7298
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
7295
7299
|
try:
|
7296
7300
|
from PIL import Image, ImageDraw
|
7297
7301
|
except Exception:
|
@@ -7337,6 +7341,10 @@ class BaseCase(unittest.TestCase):
|
|
7337
7341
|
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7338
7342
|
)
|
7339
7343
|
with download_file_lock:
|
7344
|
+
with suppress(Exception):
|
7345
|
+
shared_utils.make_writable(
|
7346
|
+
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7347
|
+
)
|
7340
7348
|
if not destination_folder:
|
7341
7349
|
destination_folder = constants.Files.DOWNLOADS_FOLDER
|
7342
7350
|
if not os.path.exists(destination_folder):
|
@@ -7357,6 +7365,10 @@ class BaseCase(unittest.TestCase):
|
|
7357
7365
|
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7358
7366
|
)
|
7359
7367
|
with download_file_lock:
|
7368
|
+
with suppress(Exception):
|
7369
|
+
shared_utils.make_writable(
|
7370
|
+
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7371
|
+
)
|
7360
7372
|
if not destination_folder:
|
7361
7373
|
destination_folder = constants.Files.DOWNLOADS_FOLDER
|
7362
7374
|
if not os.path.exists(destination_folder):
|
@@ -7462,6 +7474,8 @@ class BaseCase(unittest.TestCase):
|
|
7462
7474
|
constants.MultiBrowser.FILE_IO_LOCK
|
7463
7475
|
)
|
7464
7476
|
with file_io_lock:
|
7477
|
+
with suppress(Exception):
|
7478
|
+
shared_utils.make_writable(constants.MultiBrowser.FILE_IO_LOCK)
|
7465
7479
|
with open(fpath, "r") as f:
|
7466
7480
|
data = f.read().strip()
|
7467
7481
|
return data
|
@@ -13974,12 +13988,82 @@ class BaseCase(unittest.TestCase):
|
|
13974
13988
|
self.headless_active = True
|
13975
13989
|
sb_config.headless_active = True
|
13976
13990
|
|
13991
|
+
def __activate_virtual_display(self):
|
13992
|
+
if self.undetectable and not (self.headless or self.headless2):
|
13993
|
+
from sbvirtualdisplay import Display
|
13994
|
+
import Xlib.display
|
13995
|
+
try:
|
13996
|
+
if not self._xvfb_width:
|
13997
|
+
self._xvfb_width = 1366
|
13998
|
+
if not self._xvfb_height:
|
13999
|
+
self._xvfb_height = 768
|
14000
|
+
self._xvfb_display = Display(
|
14001
|
+
visible=True,
|
14002
|
+
size=(self._xvfb_width, self._xvfb_height),
|
14003
|
+
backend="xvfb",
|
14004
|
+
use_xauth=True,
|
14005
|
+
)
|
14006
|
+
self._xvfb_display.start()
|
14007
|
+
if "DISPLAY" not in os.environ.keys():
|
14008
|
+
print(
|
14009
|
+
"\nX11 display failed! Will use regular xvfb!"
|
14010
|
+
)
|
14011
|
+
self.__activate_standard_virtual_display()
|
14012
|
+
except Exception as e:
|
14013
|
+
if hasattr(e, "msg"):
|
14014
|
+
print("\n" + str(e.msg))
|
14015
|
+
else:
|
14016
|
+
print(e)
|
14017
|
+
print("\nX11 display failed! Will use regular xvfb!")
|
14018
|
+
self.__activate_standard_virtual_display()
|
14019
|
+
return
|
14020
|
+
pyautogui_is_installed = False
|
14021
|
+
try:
|
14022
|
+
import pyautogui
|
14023
|
+
with suppress(Exception):
|
14024
|
+
use_pyautogui_ver = constants.PyAutoGUI.VER
|
14025
|
+
if pyautogui.__version__ != use_pyautogui_ver:
|
14026
|
+
del pyautogui # To get newer ver
|
14027
|
+
shared_utils.pip_install(
|
14028
|
+
"pyautogui", version=use_pyautogui_ver
|
14029
|
+
)
|
14030
|
+
import pyautogui
|
14031
|
+
pyautogui_is_installed = True
|
14032
|
+
except Exception:
|
14033
|
+
message = (
|
14034
|
+
"PyAutoGUI is required for UC Mode on Linux! "
|
14035
|
+
"Installing now..."
|
14036
|
+
)
|
14037
|
+
print("\n" + message)
|
14038
|
+
shared_utils.pip_install(
|
14039
|
+
"pyautogui", version=constants.PyAutoGUI.VER
|
14040
|
+
)
|
14041
|
+
import pyautogui
|
14042
|
+
pyautogui_is_installed = True
|
14043
|
+
if (
|
14044
|
+
pyautogui_is_installed
|
14045
|
+
and hasattr(pyautogui, "_pyautogui_x11")
|
14046
|
+
):
|
14047
|
+
try:
|
14048
|
+
pyautogui._pyautogui_x11._display = (
|
14049
|
+
Xlib.display.Display(os.environ['DISPLAY'])
|
14050
|
+
)
|
14051
|
+
sb_config._pyautogui_x11_display = (
|
14052
|
+
pyautogui._pyautogui_x11._display
|
14053
|
+
)
|
14054
|
+
except Exception as e:
|
14055
|
+
if hasattr(e, "msg"):
|
14056
|
+
print("\n" + str(e.msg))
|
14057
|
+
else:
|
14058
|
+
print(e)
|
14059
|
+
else:
|
14060
|
+
self.__activate_standard_virtual_display()
|
14061
|
+
|
13977
14062
|
def __activate_virtual_display_as_needed(self):
|
13978
14063
|
"""This is only needed on Linux.
|
13979
14064
|
The "--xvfb" arg is still useful, as it prevents headless mode,
|
13980
14065
|
which is the default mode on Linux unless using another arg."""
|
13981
14066
|
if "linux" in sys.platform and (not self.headed or self.xvfb):
|
13982
|
-
from sbvirtualdisplay import Display
|
13983
14067
|
pip_find_lock = fasteners.InterProcessLock(
|
13984
14068
|
constants.PipInstall.FINDLOCK
|
13985
14069
|
)
|
@@ -13987,80 +14071,13 @@ class BaseCase(unittest.TestCase):
|
|
13987
14071
|
with pip_find_lock:
|
13988
14072
|
pass
|
13989
14073
|
except Exception:
|
13990
|
-
#
|
13991
|
-
|
13992
|
-
|
13993
|
-
mode |= (mode & 0o444) >> 1 # copy R bits to W
|
13994
|
-
os.chmod(constants.PipInstall.FINDLOCK, mode)
|
14074
|
+
# Since missing permissions, skip the locks
|
14075
|
+
self.__activate_virtual_display()
|
14076
|
+
return
|
13995
14077
|
with pip_find_lock: # Prevent issues with multiple processes
|
13996
|
-
|
13997
|
-
|
13998
|
-
|
13999
|
-
if not self._xvfb_width:
|
14000
|
-
self._xvfb_width = 1366
|
14001
|
-
if not self._xvfb_height:
|
14002
|
-
self._xvfb_height = 768
|
14003
|
-
self._xvfb_display = Display(
|
14004
|
-
visible=True,
|
14005
|
-
size=(self._xvfb_width, self._xvfb_height),
|
14006
|
-
backend="xvfb",
|
14007
|
-
use_xauth=True,
|
14008
|
-
)
|
14009
|
-
self._xvfb_display.start()
|
14010
|
-
if "DISPLAY" not in os.environ.keys():
|
14011
|
-
print(
|
14012
|
-
"\nX11 display failed! Will use regular xvfb!"
|
14013
|
-
)
|
14014
|
-
self.__activate_standard_virtual_display()
|
14015
|
-
except Exception as e:
|
14016
|
-
if hasattr(e, "msg"):
|
14017
|
-
print("\n" + str(e.msg))
|
14018
|
-
else:
|
14019
|
-
print(e)
|
14020
|
-
print("\nX11 display failed! Will use regular xvfb!")
|
14021
|
-
self.__activate_standard_virtual_display()
|
14022
|
-
return
|
14023
|
-
pyautogui_is_installed = False
|
14024
|
-
try:
|
14025
|
-
import pyautogui
|
14026
|
-
with suppress(Exception):
|
14027
|
-
use_pyautogui_ver = constants.PyAutoGUI.VER
|
14028
|
-
if pyautogui.__version__ != use_pyautogui_ver:
|
14029
|
-
del pyautogui # To get newer ver
|
14030
|
-
shared_utils.pip_install(
|
14031
|
-
"pyautogui", version=use_pyautogui_ver
|
14032
|
-
)
|
14033
|
-
import pyautogui
|
14034
|
-
pyautogui_is_installed = True
|
14035
|
-
except Exception:
|
14036
|
-
message = (
|
14037
|
-
"PyAutoGUI is required for UC Mode on Linux! "
|
14038
|
-
"Installing now..."
|
14039
|
-
)
|
14040
|
-
print("\n" + message)
|
14041
|
-
shared_utils.pip_install(
|
14042
|
-
"pyautogui", version=constants.PyAutoGUI.VER
|
14043
|
-
)
|
14044
|
-
import pyautogui
|
14045
|
-
pyautogui_is_installed = True
|
14046
|
-
if (
|
14047
|
-
pyautogui_is_installed
|
14048
|
-
and hasattr(pyautogui, "_pyautogui_x11")
|
14049
|
-
):
|
14050
|
-
try:
|
14051
|
-
pyautogui._pyautogui_x11._display = (
|
14052
|
-
Xlib.display.Display(os.environ['DISPLAY'])
|
14053
|
-
)
|
14054
|
-
sb_config._pyautogui_x11_display = (
|
14055
|
-
pyautogui._pyautogui_x11._display
|
14056
|
-
)
|
14057
|
-
except Exception as e:
|
14058
|
-
if hasattr(e, "msg"):
|
14059
|
-
print("\n" + str(e.msg))
|
14060
|
-
else:
|
14061
|
-
print(e)
|
14062
|
-
else:
|
14063
|
-
self.__activate_standard_virtual_display()
|
14078
|
+
with suppress(Exception):
|
14079
|
+
shared_utils.make_writable(constants.PipInstall.FINDLOCK)
|
14080
|
+
self.__activate_virtual_display()
|
14064
14081
|
|
14065
14082
|
def __ad_block_as_needed(self):
|
14066
14083
|
"""This is an internal method for handling ad-blocking.
|
@@ -15081,6 +15098,10 @@ class BaseCase(unittest.TestCase):
|
|
15081
15098
|
if self.dashboard:
|
15082
15099
|
if self._multithreaded:
|
15083
15100
|
with self.dash_lock:
|
15101
|
+
with suppress(Exception):
|
15102
|
+
shared_utils.make_writable(
|
15103
|
+
constants.Dashboard.LOCKFILE
|
15104
|
+
)
|
15084
15105
|
if not self._dash_initialized:
|
15085
15106
|
sb_config._dashboard_initialized = True
|
15086
15107
|
self._dash_initialized = True
|
@@ -15640,6 +15661,8 @@ class BaseCase(unittest.TestCase):
|
|
15640
15661
|
constants.Dashboard.LOCKFILE
|
15641
15662
|
)
|
15642
15663
|
with self.dash_lock:
|
15664
|
+
with suppress(Exception):
|
15665
|
+
shared_utils.make_writable(constants.Dashboard.LOCKFILE)
|
15643
15666
|
self.__process_dashboard(has_exception, init)
|
15644
15667
|
else:
|
15645
15668
|
self.__process_dashboard(has_exception, init)
|
@@ -16409,6 +16432,10 @@ class BaseCase(unittest.TestCase):
|
|
16409
16432
|
if self.dashboard:
|
16410
16433
|
if self._multithreaded:
|
16411
16434
|
with self.dash_lock:
|
16435
|
+
with suppress(Exception):
|
16436
|
+
shared_utils.make_writable(
|
16437
|
+
constants.Dashboard.LOCKFILE
|
16438
|
+
)
|
16412
16439
|
self.__process_dashboard(has_exception)
|
16413
16440
|
else:
|
16414
16441
|
self.__process_dashboard(has_exception)
|
@@ -128,6 +128,20 @@ def is_chrome_130_or_newer(self, binary_location=None):
|
|
128
128
|
return False
|
129
129
|
|
130
130
|
|
131
|
+
def make_writable(file_path):
|
132
|
+
# Set permissions to: "If you can read it, you can write it."
|
133
|
+
mode = os.stat(file_path).st_mode
|
134
|
+
mode |= (mode & 0o444) >> 1 # copy R bits to W
|
135
|
+
os.chmod(file_path, mode)
|
136
|
+
|
137
|
+
|
138
|
+
def make_executable(file_path):
|
139
|
+
# Set permissions to: "If you can read it, you can execute it."
|
140
|
+
mode = os.stat(file_path).st_mode
|
141
|
+
mode |= (mode & 0o444) >> 2 # copy R bits to X
|
142
|
+
os.chmod(file_path, mode)
|
143
|
+
|
144
|
+
|
131
145
|
def format_exc(exception, message):
|
132
146
|
"""Formats an exception message to make the output cleaner."""
|
133
147
|
from selenium.common.exceptions import ElementNotVisibleException
|
@@ -1709,6 +1709,7 @@ def pytest_configure(config):
|
|
1709
1709
|
sb_config._saved_dashboard_pie = None # Copy of pie chart for html report
|
1710
1710
|
sb_config._dash_final_summary = None # Dash status to add to html report
|
1711
1711
|
sb_config._html_report_name = None # The name of the pytest html report
|
1712
|
+
sb_config._html_report_copy = None # The copy of the pytest html report
|
1712
1713
|
|
1713
1714
|
arg_join = " ".join(sys_argv)
|
1714
1715
|
if (
|
@@ -1742,6 +1743,7 @@ def pytest_configure(config):
|
|
1742
1743
|
if sb_config.dashboard:
|
1743
1744
|
if sb_config._html_report_name == "dashboard.html":
|
1744
1745
|
sb_config._dash_is_html_report = True
|
1746
|
+
sb_config._html_report_copy = "last_report.html"
|
1745
1747
|
|
1746
1748
|
# Recorder Mode does not support multi-threaded / multi-process runs.
|
1747
1749
|
if sb_config.recorder_mode and sb_config._multithreaded:
|
@@ -2151,6 +2153,10 @@ def _perform_pytest_unconfigure_(config):
|
|
2151
2153
|
html_report_path = os.path.join(
|
2152
2154
|
abs_path, sb_config._html_report_name
|
2153
2155
|
)
|
2156
|
+
if sb_config._html_report_copy:
|
2157
|
+
html_report_path_copy = os.path.join(
|
2158
|
+
abs_path, sb_config._html_report_copy
|
2159
|
+
)
|
2154
2160
|
if (
|
2155
2161
|
sb_config._using_html_report
|
2156
2162
|
and html_report_path
|
@@ -2201,6 +2207,22 @@ def _perform_pytest_unconfigure_(config):
|
|
2201
2207
|
)
|
2202
2208
|
with open(html_report_path, "w", encoding="utf-8") as f:
|
2203
2209
|
f.write(the_html_r) # Finalize the HTML report
|
2210
|
+
with open(html_report_path_copy, "w", encoding="utf-8") as f:
|
2211
|
+
f.write(the_html_r) # Finalize the HTML report
|
2212
|
+
assets_style = "./assets/style.css"
|
2213
|
+
if os.path.exists(assets_style):
|
2214
|
+
html_style = None
|
2215
|
+
with open(assets_style, "r", encoding="utf-8") as f:
|
2216
|
+
html_style = f.read()
|
2217
|
+
if html_style:
|
2218
|
+
html_style = html_style.replace("top: -50px;", "top: 2px;")
|
2219
|
+
html_style = html_style.replace("+ 50px)", "+ 40px)")
|
2220
|
+
html_style = html_style.replace("ht: 240px;", "ht: 228px;")
|
2221
|
+
html_style = html_style.replace(
|
2222
|
+
"- 80px);", "- 80px);\n margin-bottom: -42px;"
|
2223
|
+
)
|
2224
|
+
with open(assets_style, "w", encoding="utf-8") as f:
|
2225
|
+
f.write(html_style)
|
2204
2226
|
# Done with "pytest_unconfigure" unless using the Dashboard
|
2205
2227
|
return
|
2206
2228
|
stamp = ""
|
@@ -2282,12 +2304,30 @@ def _perform_pytest_unconfigure_(config):
|
|
2282
2304
|
)
|
2283
2305
|
with open(dashboard_path, "w", encoding="utf-8") as f:
|
2284
2306
|
f.write(the_html_d) # Finalize the dashboard
|
2307
|
+
assets_style = "./assets/style.css"
|
2308
|
+
if os.path.exists(assets_style):
|
2309
|
+
html_style = None
|
2310
|
+
with open(assets_style, "r", encoding="utf-8") as f:
|
2311
|
+
html_style = f.read()
|
2312
|
+
if html_style:
|
2313
|
+
html_style = html_style.replace("top: -50px;", "top: 2px;")
|
2314
|
+
html_style = html_style.replace("+ 50px)", "+ 40px)")
|
2315
|
+
html_style = html_style.replace("ht: 240px;", "ht: 228px;")
|
2316
|
+
html_style = html_style.replace(
|
2317
|
+
"- 80px);", "- 80px);\n margin-bottom: -42px;"
|
2318
|
+
)
|
2319
|
+
with open(assets_style, "w", encoding="utf-8") as f:
|
2320
|
+
f.write(html_style)
|
2285
2321
|
# Part 2: Appending a pytest html report with dashboard data
|
2286
2322
|
html_report_path = None
|
2287
2323
|
if sb_config._html_report_name:
|
2288
2324
|
html_report_path = os.path.join(
|
2289
2325
|
abs_path, sb_config._html_report_name
|
2290
2326
|
)
|
2327
|
+
if sb_config._html_report_copy:
|
2328
|
+
html_report_path_copy = os.path.join(
|
2329
|
+
abs_path, sb_config._html_report_copy
|
2330
|
+
)
|
2291
2331
|
if (
|
2292
2332
|
sb_config._using_html_report
|
2293
2333
|
and html_report_path
|
@@ -2358,6 +2398,8 @@ def _perform_pytest_unconfigure_(config):
|
|
2358
2398
|
)
|
2359
2399
|
with open(html_report_path, "w", encoding="utf-8") as f:
|
2360
2400
|
f.write(the_html_r) # Finalize the HTML report
|
2401
|
+
with open(html_report_path_copy, "w", encoding="utf-8") as f:
|
2402
|
+
f.write(the_html_r) # Finalize the HTML report
|
2361
2403
|
except KeyboardInterrupt:
|
2362
2404
|
pass
|
2363
2405
|
except Exception:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.33.
|
3
|
+
Version: 4.33.6
|
4
4
|
Summary: A complete web automation framework for end-to-end testing.
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
6
6
|
Author: Michael Mintz
|
@@ -105,7 +105,7 @@ Requires-Dist: execnet==2.1.1
|
|
105
105
|
Requires-Dist: iniconfig==2.0.0
|
106
106
|
Requires-Dist: pluggy==1.5.0
|
107
107
|
Requires-Dist: pytest==8.3.4
|
108
|
-
Requires-Dist: pytest-html==4.
|
108
|
+
Requires-Dist: pytest-html==4.0.2
|
109
109
|
Requires-Dist: pytest-metadata==3.1.1
|
110
110
|
Requires-Dist: pytest-ordering==0.6
|
111
111
|
Requires-Dist: pytest-rerunfailures==14.0; python_version < "3.9"
|
@@ -126,7 +126,7 @@ Requires-Dist: allure-python-commons>=2.13.5; extra == "allure"
|
|
126
126
|
Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
127
127
|
Provides-Extra: coverage
|
128
128
|
Requires-Dist: coverage>=7.6.1; python_version < "3.9" and extra == "coverage"
|
129
|
-
Requires-Dist: coverage>=7.6.
|
129
|
+
Requires-Dist: coverage>=7.6.9; python_version >= "3.9" and extra == "coverage"
|
130
130
|
Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
131
131
|
Requires-Dist: pytest-cov>=6.0.0; python_version >= "3.9" and extra == "coverage"
|
132
132
|
Provides-Extra: flake8
|
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
|
|
3
3
|
sbase/steps.py,sha256=_WvAjydKqZfTdnZW9LPKkRty-g-lfdUPmLqnZj6ulcs,43013
|
4
4
|
seleniumbase/__init__.py,sha256=OtJh8nGKL4xtZpw8KPqmn7Q6R-86t4cWUDyVF5MbMTo,2398
|
5
5
|
seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
|
6
|
-
seleniumbase/__version__.py,sha256=
|
6
|
+
seleniumbase/__version__.py,sha256=tGf6JE86qsdvGT3Hg89rYziT4htXliGRqhNNRUHlu7Y,46
|
7
7
|
seleniumbase/behave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
seleniumbase/behave/behave_helper.py,sha256=elkl8P9eLulRAioLstE9baYNM9N_PHBmAOcajX-pH_Y,24198
|
9
9
|
seleniumbase/behave/behave_sb.py,sha256=-hza7Nx2U41mSObYiPMi48v3JlPh3sJO3yzP0kqZ1Gk,59174
|
@@ -27,7 +27,7 @@ seleniumbase/console_scripts/sb_caseplans.py,sha256=qlmvjQ49bOBE1Q29fVmabimkVibC
|
|
27
27
|
seleniumbase/console_scripts/sb_commander.py,sha256=yqoAK211OE6x5AWL2IAo8WojHtdkVj0AWqfoJ-ewmyo,13329
|
28
28
|
seleniumbase/console_scripts/sb_install.py,sha256=y84Zk-rcp554kcF_g97Xwl0Rn38pyH9wO5OKHX879RI,45831
|
29
29
|
seleniumbase/console_scripts/sb_mkchart.py,sha256=ep9g-9CSIwaOJKVxhB3xjRQpfsuApyN8-Dr129cNXwQ,10941
|
30
|
-
seleniumbase/console_scripts/sb_mkdir.py,sha256=
|
30
|
+
seleniumbase/console_scripts/sb_mkdir.py,sha256=SaI2wnjE5eQLxX8RPdjFjM_ghBbMm4r_vBUzU5t5dzY,29819
|
31
31
|
seleniumbase/console_scripts/sb_mkfile.py,sha256=OWYd4yFccmjrd-gNn1t1una-HDRU2_N2-r4Tg3nHsj0,17744
|
32
32
|
seleniumbase/console_scripts/sb_mkpres.py,sha256=EWFRVacjYTX49y-fEiYTZacM9_01IxuuaO4nMjHrIGo,11015
|
33
33
|
seleniumbase/console_scripts/sb_mkrec.py,sha256=PrizjTmyrROYPO0yDm-zQS3QSfsZNeAmcJKKUvfgLhc,11966
|
@@ -36,7 +36,7 @@ seleniumbase/console_scripts/sb_print.py,sha256=tNy-bMDgwHJO3bZxMpmo9weSE8uhbH0C
|
|
36
36
|
seleniumbase/console_scripts/sb_recorder.py,sha256=fnHb5-kh11Hit-E9Ha-e4QXzqLcZvtij6mb5qNd4B1Q,11032
|
37
37
|
seleniumbase/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
seleniumbase/core/application_manager.py,sha256=e_0sjtI8cjY5BNyZj1QBR0j6_oCScxGmSXYEpcYwuZE,576
|
39
|
-
seleniumbase/core/browser_launcher.py,sha256=
|
39
|
+
seleniumbase/core/browser_launcher.py,sha256=D_bfBkZsBAq5-XlI49CCdazydYHccuFJy0tPPAE3lOE,223704
|
40
40
|
seleniumbase/core/capabilities_parser.py,sha256=meIS2uHapTCq2ldfNAToC7r0cKmZDRXuYNKExM1GHDY,6038
|
41
41
|
seleniumbase/core/colored_traceback.py,sha256=DrRWfg7XEnKcgY59Xj7Jdk09H-XqHYBSUpB-DiZt6iY,2020
|
42
42
|
seleniumbase/core/create_db_tables.sql,sha256=VWPtrdiW_HQ6yETHjqTu-VIrTwvd8I8o1NfBeaVSHpU,972
|
@@ -44,17 +44,17 @@ seleniumbase/core/detect_b_ver.py,sha256=RxeGRMbBUTMrXh5KsS1P1SH7eEKYbzL1vQw1gTd
|
|
44
44
|
seleniumbase/core/download_helper.py,sha256=qSR54kQISucF4RQaLCOuuerSu6DR41juGi_30HVvWYY,2943
|
45
45
|
seleniumbase/core/encoded_images.py,sha256=rDKJ4cNJSuKiRcFViYU7bjyTS9_moI57gUPRXVg3u2k,14209
|
46
46
|
seleniumbase/core/jqc_helper.py,sha256=2DDQr9Q2jSSZqFzX588jLlUM9oJvyrRWq2aORSIPUdI,10322
|
47
|
-
seleniumbase/core/log_helper.py,sha256=
|
47
|
+
seleniumbase/core/log_helper.py,sha256=mtZLuvpy3lZpXqQ1ekng11_P5sBkyiI7eXhJGm9j15I,22693
|
48
48
|
seleniumbase/core/mysql.py,sha256=8Fzj3p5dhtDWfMpFqFYxpSwa9s1UltiHsWJ56_aPOqk,3993
|
49
49
|
seleniumbase/core/proxy_helper.py,sha256=cXhu8ErK9Vjdm82RMaQj7hEq_yUWizSp6LyiD50Ieu4,8020
|
50
50
|
seleniumbase/core/recorder_helper.py,sha256=fNGjbapXmEsht54x1o6Igk198QdnPxDDnjUOzQxNhNQ,25055
|
51
51
|
seleniumbase/core/report_helper.py,sha256=AIl6Qava2yW1uSzbLpJBlPlYDz0KE-rVhogh8hsGWBo,12201
|
52
52
|
seleniumbase/core/s3_manager.py,sha256=bkeI8I4y19ebWuQG1oEZV5qJbotC6eN8vin31OCNWJk,3521
|
53
|
-
seleniumbase/core/sb_cdp.py,sha256=
|
53
|
+
seleniumbase/core/sb_cdp.py,sha256=wieKEfVZjbzX0AivHabtHPwsfmJLvg8Ks3RMO7Qa9KE,68274
|
54
54
|
seleniumbase/core/sb_driver.py,sha256=NGa4adi8OAi2WFtFkEguXg3JCd1p-JuZweIpGNifEfU,13488
|
55
55
|
seleniumbase/core/session_helper.py,sha256=s9zD3PVZEWVzG2h81cCUskbNWLfdjC_LwwQjKptHCak,558
|
56
56
|
seleniumbase/core/settings_parser.py,sha256=KokVXpCiGZhJ-D4Bo-hizPz5r-iefzWoiTANu9zNaq4,7504
|
57
|
-
seleniumbase/core/style_sheet.py,sha256=
|
57
|
+
seleniumbase/core/style_sheet.py,sha256=QsfTBtgedfM3uTqgxtd53bhq202p9fwLMbFl9mPZgVg,11892
|
58
58
|
seleniumbase/core/testcase_manager.py,sha256=TblCfo8Zfap1Bayip-qTu9gqT-KALSwXAX4awBpnEHg,4633
|
59
59
|
seleniumbase/core/tour_helper.py,sha256=kj2cz-DGKlw9SX3tWnVp-snpk6Flvqj81-xmKdKDtg0,42555
|
60
60
|
seleniumbase/core/visual_helper.py,sha256=Dj5iJKw-bT_3e6KDqMf0sJi7xs_D96yqLcNc8fqhrjI,3408
|
@@ -65,14 +65,14 @@ seleniumbase/extensions/disable_csp.zip,sha256=YMifIIgEBiLrEFrS1sfW4Exh4br1V4oK1
|
|
65
65
|
seleniumbase/extensions/recorder.zip,sha256=OOyzF-Ize2cSRu1CqhzSAq5vusI9hqLLd2OIApUHesI,11918
|
66
66
|
seleniumbase/extensions/sbase_ext.zip,sha256=3s1N8zrVaMz8RQEOIoBzC3KDjtmHwVZRvVsX25Odr_s,8175
|
67
67
|
seleniumbase/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
|
-
seleniumbase/fixtures/base_case.py,sha256=
|
68
|
+
seleniumbase/fixtures/base_case.py,sha256=HyRCsvOPN3E3tBOOonK0698IRWd-XaxNEMcciLnj8OI,718550
|
69
69
|
seleniumbase/fixtures/constants.py,sha256=e1LppavlrAcI4XBJMq7u5j8SffaQ7SPQps1y0YvZYfY,13649
|
70
70
|
seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
|
71
71
|
seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
|
72
72
|
seleniumbase/fixtures/js_utils.py,sha256=t-hqdd75O6Kfe6y5U8986gvZGATpPfDiDnIqeZZodgw,51435
|
73
73
|
seleniumbase/fixtures/page_actions.py,sha256=dbp63c-7asYZyd8aOu57Y3dxQQozp_VJsP5h74s1kBA,66552
|
74
74
|
seleniumbase/fixtures/page_utils.py,sha256=5m7iXpikLs80TJoRO6_gEfXE1AKeQgcH1aFbR8o1C9A,12034
|
75
|
-
seleniumbase/fixtures/shared_utils.py,sha256=
|
75
|
+
seleniumbase/fixtures/shared_utils.py,sha256=uDwq23NWl3iL6uID16sv93bY8CjaMfItXBjLwjRr2tw,7985
|
76
76
|
seleniumbase/fixtures/unittest_helper.py,sha256=sfZ92rZeBAn_sF_yQ3I6_I7h3lyU5-cV_UMegBNoEm8,1294
|
77
77
|
seleniumbase/fixtures/words.py,sha256=FOA4mAYvl3EPVpBTvgvK6YwCL8BdlRCmed685kEe7Vg,7827
|
78
78
|
seleniumbase/fixtures/xpath_to_css.py,sha256=lML56k656fElXJ4NJF07r35FjctrbgQkXUotNk7A-as,8876
|
@@ -88,7 +88,7 @@ seleniumbase/plugins/basic_test_info.py,sha256=8ov6n417gPbqqvrlT4zrch7l2XcRt-GF2
|
|
88
88
|
seleniumbase/plugins/db_reporting_plugin.py,sha256=En09qUCoojrk9-vbcnsoHdSELoGmag2GDIyu3jTiJas,7331
|
89
89
|
seleniumbase/plugins/driver_manager.py,sha256=s20s0pJYaNrG0WNwyIC04oUMRVFjtm6V_nS1-EvFm7g,34492
|
90
90
|
seleniumbase/plugins/page_source.py,sha256=loTnXxOj4kxEukuTZEiGyvKBhY3KDVDMnNlHHheTBDE,1889
|
91
|
-
seleniumbase/plugins/pytest_plugin.py,sha256=
|
91
|
+
seleniumbase/plugins/pytest_plugin.py,sha256=v95Ovdwd1-Kqhf05BkDtC_YfF7_cF5v9WDnpsxT7frg,104506
|
92
92
|
seleniumbase/plugins/s3_logging_plugin.py,sha256=WDfertQgGOW_SRJpFMaekYD6vBVW9VO62POtXXy2HCM,2319
|
93
93
|
seleniumbase/plugins/sb_manager.py,sha256=qCf6RAkAfziLTGgiJvB3V416RxWoTbRLm9wc-KsB8g8,54419
|
94
94
|
seleniumbase/plugins/screen_shots.py,sha256=1hrXw-hzuZ1BR6Yh7AyWX2ABnvnP73-RCbwdz958gj4,1127
|
@@ -135,9 +135,9 @@ seleniumbase/utilities/selenium_grid/start-grid-hub.bat,sha256=Ftq-GrAKRYH2ssDPr
|
|
135
135
|
seleniumbase/utilities/selenium_grid/start-grid-hub.sh,sha256=KADv0RUHONLL2_I443QFK8PryBpDmKn5Gy0s4o0vDSM,106
|
136
136
|
seleniumbase/utilities/selenium_ide/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
137
137
|
seleniumbase/utilities/selenium_ide/convert_ide.py,sha256=pZFnqEJQEKZPyNFjkLD29s2HPQgCrWW9XJWpCPhWOoM,31691
|
138
|
-
seleniumbase-4.33.
|
139
|
-
seleniumbase-4.33.
|
140
|
-
seleniumbase-4.33.
|
141
|
-
seleniumbase-4.33.
|
142
|
-
seleniumbase-4.33.
|
143
|
-
seleniumbase-4.33.
|
138
|
+
seleniumbase-4.33.6.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
|
139
|
+
seleniumbase-4.33.6.dist-info/METADATA,sha256=U6U9MYVrwKt5UAQvZLghzL2kEkNnTEadmP6TZZrMzvI,86528
|
140
|
+
seleniumbase-4.33.6.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
141
|
+
seleniumbase-4.33.6.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
|
142
|
+
seleniumbase-4.33.6.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
|
143
|
+
seleniumbase-4.33.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|