seleniumbase 4.33.4__py3-none-any.whl → 4.33.6__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.33.4"
2
+ __version__ = "4.33.6"
@@ -259,6 +259,7 @@ def main():
259
259
  data.append("report_archives")
260
260
  data.append("archived_reports")
261
261
  data.append("html_report.html")
262
+ data.append("last_report.html")
262
263
  data.append("report.html")
263
264
  data.append("report.xml")
264
265
  data.append("dashboard.html")
@@ -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
- # Need write permissions
830
- with suppress(Exception):
831
- make_writable(constants.PipInstall.FINDLOCK)
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
- try:
834
- import pyautogui
835
- with suppress(Exception):
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(
@@ -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
- log_file = codecs.open(file_path, "w+", encoding="utf-8")
343
- log_file.writelines("\r\n".join(data_to_save))
344
- log_file.close()
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
- html_file = codecs.open(html_file_path, "w+", encoding="utf-8")
372
- html_file.write(page_source)
373
- html_file.close()
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):
@@ -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)
@@ -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
- # Need write permissions
13991
- with suppress(Exception):
13992
- mode = os.stat(constants.PipInstall.FINDLOCK).st_mode
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
- if self.undetectable and not (self.headless or self.headless2):
13997
- import Xlib.display
13998
- try:
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.4
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.1.1
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.8; python_version >= "3.9" and extra == "coverage"
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=3t809dk9kzj5i3a3T_akotf68UIRPSs5JEuU9DUeAJs,46
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=8BFbKc9ES35ruI2PlNnxADa8Ur3SMkvKu_tr85T0gyA,29783
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=1JmvPcIHSgpvI74_E9xoAEjZe79OIOWKhot6DUTfkn0,221519
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=T_nPPSRSjhqt6TTzVE6pN1owVvIeRBNF5pWK6sl4dMY,22609
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=NyiooRREzeRQYITMiE9b0WwcH3-u8tMsy-cLJSnxerc,67644
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=tPpJ1xl6Kuw425Z-3Y0OgVRLGXk_ciBDREZjXk_NuPE,11395
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=v6DxzikLVRBdTlw3diVOKAQX1bFEwCJ0sRE2MZwwao8,717844
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=WbPb15IvIWzRtMInKG8DUzJ26UZU-PixdOwTCjXQirU,7545
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=8vOTHVdX0WxfULcjPpbfwke8PR41U_RgsEslwtEyUBI,102238
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.4.dist-info/LICENSE,sha256=odSYtWibXBnQ1gBg6CnDZ82n8kLF_if5-2nbqnEyD8k,1085
139
- seleniumbase-4.33.4.dist-info/METADATA,sha256=3WfFr62LrmiR3YrgRwprGZ_dM9zYVM04ak2N1NXOdzY,86528
140
- seleniumbase-4.33.4.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
141
- seleniumbase-4.33.4.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
142
- seleniumbase-4.33.4.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
143
- seleniumbase-4.33.4.dist-info/RECORD,,
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,,