seleniumbase 4.24.11__py3-none-any.whl → 4.33.15__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. sbase/__init__.py +1 -0
  2. sbase/steps.py +7 -0
  3. seleniumbase/__init__.py +16 -7
  4. seleniumbase/__version__.py +1 -1
  5. seleniumbase/behave/behave_sb.py +97 -32
  6. seleniumbase/common/decorators.py +16 -7
  7. seleniumbase/config/proxy_list.py +3 -3
  8. seleniumbase/config/settings.py +4 -0
  9. seleniumbase/console_scripts/logo_helper.py +47 -8
  10. seleniumbase/console_scripts/run.py +345 -335
  11. seleniumbase/console_scripts/sb_behave_gui.py +5 -12
  12. seleniumbase/console_scripts/sb_caseplans.py +6 -13
  13. seleniumbase/console_scripts/sb_commander.py +5 -12
  14. seleniumbase/console_scripts/sb_install.py +62 -54
  15. seleniumbase/console_scripts/sb_mkchart.py +13 -20
  16. seleniumbase/console_scripts/sb_mkdir.py +11 -17
  17. seleniumbase/console_scripts/sb_mkfile.py +69 -43
  18. seleniumbase/console_scripts/sb_mkpres.py +13 -20
  19. seleniumbase/console_scripts/sb_mkrec.py +88 -21
  20. seleniumbase/console_scripts/sb_objectify.py +30 -30
  21. seleniumbase/console_scripts/sb_print.py +5 -12
  22. seleniumbase/console_scripts/sb_recorder.py +16 -11
  23. seleniumbase/core/browser_launcher.py +1658 -221
  24. seleniumbase/core/log_helper.py +42 -27
  25. seleniumbase/core/mysql.py +1 -4
  26. seleniumbase/core/proxy_helper.py +35 -30
  27. seleniumbase/core/recorder_helper.py +24 -5
  28. seleniumbase/core/sb_cdp.py +1951 -0
  29. seleniumbase/core/sb_driver.py +162 -8
  30. seleniumbase/core/settings_parser.py +6 -0
  31. seleniumbase/core/style_sheet.py +10 -0
  32. seleniumbase/extensions/recorder.zip +0 -0
  33. seleniumbase/fixtures/base_case.py +1225 -614
  34. seleniumbase/fixtures/constants.py +10 -1
  35. seleniumbase/fixtures/js_utils.py +171 -144
  36. seleniumbase/fixtures/page_actions.py +177 -13
  37. seleniumbase/fixtures/page_utils.py +25 -53
  38. seleniumbase/fixtures/shared_utils.py +97 -11
  39. seleniumbase/js_code/active_css_js.py +1 -1
  40. seleniumbase/js_code/recorder_js.py +1 -1
  41. seleniumbase/plugins/base_plugin.py +2 -3
  42. seleniumbase/plugins/driver_manager.py +340 -65
  43. seleniumbase/plugins/pytest_plugin.py +276 -47
  44. seleniumbase/plugins/sb_manager.py +412 -99
  45. seleniumbase/plugins/selenium_plugin.py +122 -17
  46. seleniumbase/translate/translator.py +0 -7
  47. seleniumbase/undetected/__init__.py +59 -52
  48. seleniumbase/undetected/cdp.py +0 -1
  49. seleniumbase/undetected/cdp_driver/__init__.py +1 -0
  50. seleniumbase/undetected/cdp_driver/_contradict.py +110 -0
  51. seleniumbase/undetected/cdp_driver/browser.py +829 -0
  52. seleniumbase/undetected/cdp_driver/cdp_util.py +458 -0
  53. seleniumbase/undetected/cdp_driver/config.py +334 -0
  54. seleniumbase/undetected/cdp_driver/connection.py +639 -0
  55. seleniumbase/undetected/cdp_driver/element.py +1168 -0
  56. seleniumbase/undetected/cdp_driver/tab.py +1323 -0
  57. seleniumbase/undetected/dprocess.py +4 -7
  58. seleniumbase/undetected/options.py +6 -8
  59. seleniumbase/undetected/patcher.py +11 -13
  60. seleniumbase/undetected/reactor.py +0 -1
  61. seleniumbase/undetected/webelement.py +16 -3
  62. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/LICENSE +1 -1
  63. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/METADATA +299 -252
  64. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/RECORD +67 -69
  65. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/WHEEL +1 -1
  66. sbase/ReadMe.txt +0 -2
  67. seleniumbase/ReadMe.md +0 -25
  68. seleniumbase/common/ReadMe.md +0 -71
  69. seleniumbase/console_scripts/ReadMe.md +0 -731
  70. seleniumbase/drivers/ReadMe.md +0 -27
  71. seleniumbase/extensions/ReadMe.md +0 -12
  72. seleniumbase/masterqa/ReadMe.md +0 -61
  73. seleniumbase/resources/ReadMe.md +0 -31
  74. seleniumbase/resources/favicon.ico +0 -0
  75. seleniumbase/utilities/selenium_grid/ReadMe.md +0 -84
  76. seleniumbase/utilities/selenium_ide/ReadMe.md +0 -111
  77. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/entry_points.txt +0 -0
  78. {seleniumbase-4.24.11.dist-info → seleniumbase-4.33.15.dist-info}/top_level.txt +0 -0
@@ -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
- try:
285
- if not os.path.exists(test_logpath):
293
+ if not os.path.exists(test_logpath):
294
+ with suppress(Exception):
286
295
  os.makedirs(test_logpath)
287
- except Exception:
288
- pass
289
- log_file = codecs.open(basic_file_path, "w+", "utf-8")
290
- log_file.writelines("\r\n".join(data_to_save))
291
- log_file.close()
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
- try:
309
+ with suppress(Exception):
301
310
  browser_version = get_browser_version(driver)
302
- except Exception:
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
- log_file = codecs.open(file_path, "w+", encoding="utf-8")
347
- log_file.writelines("\r\n".join(data_to_save))
348
- log_file.close()
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 = driver.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
- try:
372
- if not os.path.exists(test_logpath):
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
- html_file = codecs.open(html_file_path, "w+", "utf-8")
378
- html_file.write(page_source)
379
- html_file.close()
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 = driver.current_url
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 # Should only be reachable during multi-threaded runs
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 # Should only be reachable during multi-threaded runs
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:
@@ -35,10 +35,7 @@ class DatabaseManager:
35
35
  import cryptography # noqa: F401
36
36
  import pymysql
37
37
  except Exception:
38
- if sys.version_info < (3, 7):
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
- import threading
113
-
114
- lock = threading.RLock() # Support multi-threaded tests. Eg. "pytest -n=4"
115
- with lock:
116
- abs_path = os.path.abspath(".")
117
- downloads_path = os.path.join(abs_path, DOWNLOADS_DIR)
118
- if not os.path.exists(downloads_path):
119
- os.mkdir(downloads_path)
120
- if zip_it:
121
- zf = zipfile.ZipFile(PROXY_ZIP_PATH, mode="w")
122
- zf.writestr("background.js", background_js)
123
- zf.writestr("manifest.json", manifest_json)
124
- zf.close()
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
- manifest_file = os.path.join(proxy_ext_dir, "manifest.json")
130
- with open(manifest_file, mode="w") as f:
131
- f.write(manifest_json)
132
- proxy_host = proxy_string.split(":")[0]
133
- proxy_port = proxy_string.split(":")[1]
134
- background_file = os.path.join(proxy_ext_dir, "background.js")
135
- with open(background_file, mode="w") as f:
136
- f.write(background_js)
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
- try:
145
- if os.path.exists(PROXY_ZIP_PATH):
150
+ if os.path.exists(PROXY_ZIP_PATH):
151
+ with suppress(Exception):
146
152
  os.remove(PROXY_ZIP_PATH)
147
- if os.path.exists(PROXY_ZIP_LOCK):
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
- action[1][0] = unicodedata.normalize("NFKC", action[1][0])
426
- action[1][0] = action[1][0].replace("\n", "\\n")
427
- action[1][0] = action[1][0].replace("\u00B6", "")
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 '"' not in action[1][0] and '"' not in action[1][1]:
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 '"' not in action[1][0]:
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
  )