seleniumbase 4.16.1__py3-none-any.whl → 4.16.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sbase/steps.py CHANGED
@@ -168,6 +168,19 @@ def assert_exact_text(context, text, selector):
168
168
  sb.assert_exact_text(text, selector)
169
169
 
170
170
 
171
+ @step("Assert non-empty text in '{selector}'")
172
+ @step('Assert non-empty text in "{selector}"')
173
+ @step("Assert text in '{selector}' is not empty")
174
+ @step('Assert text in "{selector}" is not empty')
175
+ @step("Text in '{selector}' should be non-empty")
176
+ @step('Text in "{selector}" should be non-empty')
177
+ @step("Text in '{selector}' should not be empty")
178
+ @step('Text in "{selector}" should not be empty')
179
+ def assert_non_empty_text(context, selector):
180
+ sb = context.sb
181
+ sb.assert_non_empty_text(selector)
182
+
183
+
171
184
  @step("Highlight '{selector}'")
172
185
  @step('Highlight "{selector}"')
173
186
  @step("Highlight element '{selector}'")
@@ -492,6 +505,49 @@ def wait_for_text_in_element(context, text, selector):
492
505
  sb.wait_for_text(text, selector)
493
506
 
494
507
 
508
+ @step("Wait for exact text '{text}' in '{selector}'")
509
+ @step('Wait for exact text "{text}" in "{selector}"')
510
+ @step("Wait for exact text '{text}' in \"{selector}\"")
511
+ @step('Wait for exact text "{text}" in \'{selector}\'')
512
+ @step("Wait for '{selector}' to have exact text '{text}'")
513
+ @step('Wait for "{selector}" to have exact text "{text}"')
514
+ @step('Wait for "{selector}" to have exact text \'{text}\'')
515
+ @step("Wait for '{selector}' to have exact text \"{text}\"")
516
+ @step("User waits for exact text '{text}' in '{selector}'")
517
+ @step('User waits for exact text "{text}" in "{selector}"')
518
+ @step("User waits for exact text '{text}' in \"{selector}\"")
519
+ @step('User waits for exact text "{text}" in \'{selector}\'')
520
+ @step("User waits for '{selector}' to have exact text '{text}'")
521
+ @step('User waits for "{selector}" to have exact text "{text}"')
522
+ @step('User waits for "{selector}" to have exact text \'{text}\'')
523
+ @step("User waits for '{selector}' to have exact text \"{text}\"")
524
+ def wait_for_exact_text_in_element(context, text, selector):
525
+ sb = context.sb
526
+ text = normalize_text(text)
527
+ sb.wait_for_exact_text(text, selector)
528
+
529
+
530
+ @step("Wait for non-empty text in '{selector}'")
531
+ @step('Wait for non-empty text in "{selector}"')
532
+ @step("Wait for '{selector}' to have non-empty text")
533
+ @step('Wait for "{selector}" to have non-empty text')
534
+ @step("User waits for non-empty text in '{selector}'")
535
+ @step('User waits for non-empty text in "{selector}"')
536
+ @step("User waits for '{selector}' to have non-empty text")
537
+ @step('User waits for "{selector}" to have non-empty text')
538
+ @step("Wait for '{selector}' to not have text")
539
+ @step('Wait for "{selector}" to not have text')
540
+ @step("Wait for text in '{selector}' to not be empty")
541
+ @step('Wait for text in "{selector}" to not be empty')
542
+ @step("User waits for '{selector}' to not have text")
543
+ @step('User waits for "{selector}" to not have text')
544
+ @step("User waits for text in '{selector}' to not be empty")
545
+ @step('User waits for text in "{selector}" to not be empty')
546
+ def wait_for_non_empty_text_in_element(context, selector):
547
+ sb = context.sb
548
+ sb.wait_for_non_empty_text(selector)
549
+
550
+
495
551
  @step("Wait for text '{text}'")
496
552
  @step('Wait for text "{text}"')
497
553
  @step("User waits for text '{text}'")
@@ -839,12 +895,21 @@ def deferred_assert_text(context, text):
839
895
 
840
896
  @step("Deferred assert exact text '{text}' in '{selector}'")
841
897
  @step('Deferred assert exact text "{text}" in "{selector}"')
898
+ @step("Deferred assert exact text '{text}' in \"{selector}\"")
899
+ @step('Deferred assert exact text "{text}" in \'{selector}\'')
842
900
  def deferred_assert_exact_text(context, text, selector):
843
901
  sb = context.sb
844
902
  text = normalize_text(text)
845
903
  sb.deferred_assert_exact_text(text, selector)
846
904
 
847
905
 
906
+ @step("Deferred assert non-empty text in '{selector}'")
907
+ @step('Deferred assert non-empty text in "{selector}"')
908
+ def deferred_assert_non_empty_text(context, selector):
909
+ sb = context.sb
910
+ sb.deferred_assert_non_empty_text(selector)
911
+
912
+
848
913
  @step("Process deferred asserts")
849
914
  def process_deferred_asserts(context):
850
915
  sb = context.sb
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.16.1"
2
+ __version__ = "4.16.3"
@@ -435,18 +435,46 @@ def generate_gherkin(srt_actions):
435
435
  sb_actions.append('%s "%s"' % (method, action[1][0]))
436
436
  else:
437
437
  sb_actions.append("%s '%s'" % (method, action[1][0]))
438
+ elif action[0] == "asnet":
439
+ method = "Assert non-empty text in"
440
+ if '"' not in action[1]:
441
+ sb_actions.append('%s "%s"' % (method, action[1]))
442
+ elif "'" not in action[1]:
443
+ sb_actions.append("%s '%s'" % (method, action[1]))
444
+ else:
445
+ sb_actions.append(
446
+ "%s '%s'" % (method, action[1].replace("'", "\\'"))
447
+ )
438
448
  elif action[0] == "da_el":
439
449
  method = "Deferred assert element"
440
450
  if '"' not in action[1]:
441
451
  sb_actions.append('%s "%s"' % (method, action[1]))
442
- else:
452
+ elif "'" not in action[1]:
443
453
  sb_actions.append("%s '%s'" % (method, action[1]))
454
+ else:
455
+ sb_actions.append(
456
+ "%s '%s'" % (method, action[1].replace("'", "\\'"))
457
+ )
444
458
  elif action[0] == "da_ep":
445
459
  method = "Deferred assert element present"
446
460
  if '"' not in action[1]:
447
461
  sb_actions.append('%s "%s"' % (method, action[1]))
462
+ elif "'" not in action[1]:
463
+ sb_actions.append("%s '%s'" % (method, action[1]))
448
464
  else:
465
+ sb_actions.append(
466
+ "%s '%s'" % (method, action[1].replace("'", "\\'"))
467
+ )
468
+ elif action[0] == "danet":
469
+ method = "Deferred assert non-empty text in"
470
+ if '"' not in action[1]:
471
+ sb_actions.append('%s "%s"' % (method, action[1]))
472
+ elif "'" not in action[1]:
449
473
  sb_actions.append("%s '%s'" % (method, action[1]))
474
+ else:
475
+ sb_actions.append(
476
+ "%s '%s'" % (method, action[1].replace("'", "\\'"))
477
+ )
450
478
  elif action[0] == "s_scr":
451
479
  method = "Save screenshot as"
452
480
  if '"' not in action[1]:
@@ -1,4 +1,5 @@
1
1
  """ SeleniumBase Exceptions
2
+ LinkTextNotFoundException => Called when expected link text is not visible.
2
3
  NoSuchFileException => Called when self.assert_downloaded_file(...) fails.
3
4
  NoSuchOptionException => Called when select_option_by_*() lacks the option.
4
5
  NotConnectedException => Called when Internet is not reachable when needed.
@@ -6,13 +7,17 @@
6
7
  NotUsingChromiumException => Used by Chromium-only methods if not Chromium.
7
8
  OutOfScopeException => Used by BaseCase methods when setUp() is skipped.
8
9
  ProxyConnectionException => Called when the proxy connection failed.
9
- TextNotVisibleException => Called when expected text fails to appear.
10
+ TextNotVisibleException => Called when the expected text is not visible.
10
11
  TimeLimitExceededException => Called when exceeding "--time-limit=SECONDS".
11
12
  TimeoutException => Called when some timeout limit has been exceeded.
12
13
  VisualException => Called when there's a Visual Diff Assertion Failure.
13
14
  """
14
15
 
15
16
 
17
+ class LinkTextNotFoundException(Exception):
18
+ pass
19
+
20
+
16
21
  class NoSuchFileException(Exception):
17
22
  pass
18
23
 
@@ -150,15 +150,23 @@ def requests_get_with_retry(url):
150
150
  try:
151
151
  response = requests.get(url, proxies=proxies)
152
152
  except Exception:
153
- time.sleep(0.75)
154
- response = requests.get(url, proxies=proxies)
153
+ time.sleep(1.1)
154
+ try:
155
+ response = requests.get(url, proxies=proxies)
156
+ except Exception:
157
+ time.sleep(1.2)
158
+ response = requests.get(url, proxies=proxies)
155
159
  return response
156
160
  else:
157
161
  try:
158
162
  response = requests.get(url)
159
163
  except Exception:
160
- time.sleep(0.75)
161
- response = requests.get(url)
164
+ time.sleep(1.1)
165
+ try:
166
+ response = requests.get(url)
167
+ except Exception:
168
+ time.sleep(1.2)
169
+ response = requests.get(url)
162
170
  return response
163
171
 
164
172
 
@@ -256,6 +264,8 @@ def main(override=None, intel_for_uc=None):
256
264
  ).split(".")[0]
257
265
  if int(major_chrome_version) < 72:
258
266
  major_chrome_version = None
267
+ elif int(major_chrome_version) > 114:
268
+ major_chrome_version = "114"
259
269
  except Exception:
260
270
  major_chrome_version = None
261
271
  if major_chrome_version and major_chrome_version.isnumeric():
@@ -498,6 +508,12 @@ def main(override=None, intel_for_uc=None):
498
508
  url_request = requests_get_with_retry(use_version)
499
509
  if url_request.ok:
500
510
  use_version = url_request.text.split("\r")[0].split("\n")[0]
511
+ if (
512
+ int(use_version.split(".")[0]) == 115
513
+ and use_version.startswith("115.0")
514
+ and use_version != "115.0.1901.183"
515
+ ):
516
+ use_version = "115.0.1901.183"
501
517
  download_url = "https://msedgedriver.azureedge.net/%s/%s" % (
502
518
  use_version,
503
519
  file_name,
@@ -153,7 +153,7 @@ def get_uc_driver_version():
153
153
  return uc_driver_version
154
154
 
155
155
 
156
- def find_driver_version_to_use(use_version):
156
+ def find_chromedriver_version_to_use(use_version):
157
157
  # Because https://chromedriver.chromium.org/downloads stops at 114
158
158
  final_chromedriver = "114"
159
159
  if (
@@ -177,11 +177,46 @@ def has_cf(text):
177
177
  return False
178
178
 
179
179
 
180
- def uc_open(driver, url):
180
+ def uc_special_open_if_cf(driver, url):
181
181
  if (
182
182
  (url.startswith("http:") or url.startswith("https:"))
183
183
  and has_cf(requests_get(url).text)
184
184
  ):
185
+ with driver:
186
+ time.sleep(0.25)
187
+ driver.execute_script('window.open("%s","_blank");' % url)
188
+ driver.close()
189
+ driver.switch_to.window(driver.window_handles[-1])
190
+ else:
191
+ driver.open(url) # The original one
192
+ return None
193
+
194
+
195
+ def uc_open(driver, url):
196
+ if (url.startswith("http:") or url.startswith("https:")):
197
+ with driver:
198
+ time.sleep(0.25)
199
+ driver.open(url)
200
+ else:
201
+ driver.open(url) # The original one
202
+ return None
203
+
204
+
205
+ def uc_open_with_tab(driver, url):
206
+ if (url.startswith("http:") or url.startswith("https:")):
207
+ with driver:
208
+ time.sleep(0.25)
209
+ driver.execute_script('window.open("%s","_blank");' % url)
210
+ driver.close()
211
+ driver.switch_to.window(driver.window_handles[-1])
212
+ else:
213
+ driver.open(url) # The original one
214
+ return None
215
+
216
+
217
+ def uc_open_with_reconnect(driver, url):
218
+ """Open a url, then reconnect with UC before switching to the window."""
219
+ if (url.startswith("http:") or url.startswith("https:")):
185
220
  driver.execute_script('window.open("%s","_blank");' % url)
186
221
  driver.reconnect(2.65)
187
222
  driver.close()
@@ -804,6 +839,10 @@ def _set_chrome_options(
804
839
  chrome_options.add_argument("--disable-prompt-on-repost")
805
840
  chrome_options.add_argument("--dns-prefetch-disable")
806
841
  chrome_options.add_argument("--disable-translate")
842
+ chrome_options.add_argument(
843
+ '--disable-features=OptimizationHints,OptimizationHintsFetching,'
844
+ 'OptimizationGuideModelDownloading,OptimizationTargetPrediction'
845
+ )
807
846
  if binary_location:
808
847
  chrome_options.binary_location = binary_location
809
848
  if not enable_3d_apis and not is_using_uc(undetectable, browser_name):
@@ -2177,6 +2216,7 @@ def get_local_driver(
2177
2216
  if major_edge_version:
2178
2217
  use_version = major_edge_version
2179
2218
  driver_version = None
2219
+ edgedriver_upgrade_needed = False
2180
2220
  if os.path.exists(LOCAL_EDGEDRIVER):
2181
2221
  try:
2182
2222
  output = subprocess.check_output(
@@ -2191,6 +2231,11 @@ def get_local_driver(
2191
2231
  output = output.split(" ")[1].split(".")[0]
2192
2232
  elif output.split(" ")[0] == "Microsoft":
2193
2233
  # Microsoft Edge WebDriver VERSION
2234
+ if (
2235
+ "WebDriver 115.0" in output
2236
+ and "115.0.1901.183" not in output
2237
+ ):
2238
+ edgedriver_upgrade_needed = True
2194
2239
  output = output.split(" ")[3].split(".")[0]
2195
2240
  else:
2196
2241
  output = 0
@@ -2198,7 +2243,6 @@ def get_local_driver(
2198
2243
  driver_version = output
2199
2244
  except Exception:
2200
2245
  pass
2201
- edgedriver_upgrade_needed = False
2202
2246
  local_edgedriver_exists = False
2203
2247
  if LOCAL_EDGEDRIVER and os.path.exists(LOCAL_EDGEDRIVER):
2204
2248
  local_edgedriver_exists = True
@@ -2477,7 +2521,9 @@ def get_local_driver(
2477
2521
  if selenium4_or_newer:
2478
2522
  try:
2479
2523
  service = EdgeService(
2480
- executable_path=LOCAL_EDGEDRIVER, log_path=os.devnull
2524
+ executable_path=LOCAL_EDGEDRIVER,
2525
+ log_path=os.devnull,
2526
+ service_args=["--disable-build-check"],
2481
2527
  )
2482
2528
  driver = Edge(service=service, options=edge_options)
2483
2529
  except Exception as e:
@@ -2503,6 +2549,7 @@ def get_local_driver(
2503
2549
  service = EdgeService(
2504
2550
  executable_path=LOCAL_EDGEDRIVER,
2505
2551
  log_path=os.devnull,
2552
+ service_args=["--disable-build-check"],
2506
2553
  )
2507
2554
  # https://stackoverflow.com/a/56638103/7058266
2508
2555
  sys_argv = sys.argv
@@ -2576,6 +2623,7 @@ def get_local_driver(
2576
2623
  service = EdgeService(
2577
2624
  executable_path=LOCAL_EDGEDRIVER,
2578
2625
  log_path=os.devnull,
2626
+ service_args=["--disable-build-check"],
2579
2627
  )
2580
2628
  # https://stackoverflow.com/a/56638103/7058266
2581
2629
  sys_argv = sys.argv
@@ -2852,7 +2900,7 @@ def get_local_driver(
2852
2900
  from seleniumbase import config as sb_config
2853
2901
 
2854
2902
  sb_config.multi_proxy = True
2855
- use_version = find_driver_version_to_use(use_version)
2903
+ use_version = find_chromedriver_version_to_use(use_version)
2856
2904
  if (
2857
2905
  LOCAL_CHROMEDRIVER
2858
2906
  and os.path.exists(LOCAL_CHROMEDRIVER)
@@ -3007,7 +3055,7 @@ def get_local_driver(
3007
3055
  )
3008
3056
  with uc_lock: # Avoid multithreaded issues
3009
3057
  uc_driver_version = get_uc_driver_version()
3010
- use_version = find_driver_version_to_use(use_version)
3058
+ use_version = find_chromedriver_version_to_use(use_version)
3011
3059
  if (
3012
3060
  (
3013
3061
  uc_driver_version != use_version
@@ -3182,7 +3230,7 @@ def get_local_driver(
3182
3230
  and int(major_chrome_version) >= 86
3183
3231
  ):
3184
3232
  mcv = major_chrome_version
3185
- mcv = find_driver_version_to_use(mcv)
3233
+ mcv = find_chromedriver_version_to_use(mcv)
3186
3234
  headless = True
3187
3235
  headless_options = _set_chrome_options(
3188
3236
  browser_name,
@@ -3281,7 +3329,14 @@ def get_local_driver(
3281
3329
  )
3282
3330
  driver.open = driver.get # Save copy of original
3283
3331
  if uc_activated:
3284
- driver.get = lambda url: uc_open(driver, url)
3332
+ driver.get = lambda url: uc_special_open_if_cf(driver, url)
3333
+ driver.uc_open = lambda url: uc_open(driver, url)
3334
+ driver.uc_open_with_tab = (
3335
+ lambda url: uc_open_with_tab(driver, url)
3336
+ )
3337
+ driver.uc_open_with_reconnect = (
3338
+ lambda url: uc_open_with_reconnect(driver, url)
3339
+ )
3285
3340
  return driver
3286
3341
  else: # Running headless on Linux (and not using --uc)
3287
3342
  try:
@@ -463,18 +463,46 @@ def generate_sbase_code(srt_actions):
463
463
  sb_actions.append(
464
464
  "self.%s('%s')" % (method, action[1][0])
465
465
  )
466
+ elif action[0] == "asnet":
467
+ method = "assert_non_empty_text"
468
+ if '"' not in action[1]:
469
+ sb_actions.append('self.%s("%s")' % (method, action[1]))
470
+ elif "'" not in action[1]:
471
+ sb_actions.append("self.%s('%s')" % (method, action[1]))
472
+ else:
473
+ sb_actions.append(
474
+ 'self.%s("""%s""")' % (method, action[1])
475
+ )
466
476
  elif action[0] == "da_el":
467
477
  method = "deferred_assert_element"
468
478
  if '"' not in action[1]:
469
479
  sb_actions.append('self.%s("%s")' % (method, action[1]))
470
- else:
480
+ elif "'" not in action[1]:
471
481
  sb_actions.append("self.%s('%s')" % (method, action[1]))
482
+ else:
483
+ sb_actions.append(
484
+ 'self.%s("""%s""")' % (method, action[1])
485
+ )
472
486
  elif action[0] == "da_ep":
473
487
  method = "deferred_assert_element_present"
474
488
  if '"' not in action[1]:
475
489
  sb_actions.append('self.%s("%s")' % (method, action[1]))
490
+ elif "'" not in action[1]:
491
+ sb_actions.append("self.%s('%s')" % (method, action[1]))
476
492
  else:
493
+ sb_actions.append(
494
+ 'self.%s("""%s""")' % (method, action[1])
495
+ )
496
+ elif action[0] == "danet":
497
+ method = "deferred_assert_non_empty_text"
498
+ if '"' not in action[1]:
499
+ sb_actions.append('self.%s("%s")' % (method, action[1]))
500
+ elif "'" not in action[1]:
477
501
  sb_actions.append("self.%s('%s')" % (method, action[1]))
502
+ else:
503
+ sb_actions.append(
504
+ 'self.%s("""%s""")' % (method, action[1])
505
+ )
478
506
  elif action[0] == "s_scr":
479
507
  method = "save_screenshot"
480
508
  if '"' not in action[1]: