seleniumbase 4.42.1__py3-none-any.whl → 4.42.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.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.42.1"
2
+ __version__ = "4.42.3"
@@ -766,6 +766,8 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
766
766
  cdp.set_local_storage_item = CDPM.set_local_storage_item
767
767
  cdp.set_session_storage_item = CDPM.set_session_storage_item
768
768
  cdp.set_attributes = CDPM.set_attributes
769
+ cdp.is_attribute_present = CDPM.is_attribute_present
770
+ cdp.is_online = CDPM.is_online
769
771
  cdp.gui_press_key = CDPM.gui_press_key
770
772
  cdp.gui_press_keys = CDPM.gui_press_keys
771
773
  cdp.gui_write = CDPM.gui_write
@@ -815,10 +817,12 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
815
817
  cdp.get_screen_rect = CDPM.get_screen_rect
816
818
  cdp.get_window_rect = CDPM.get_window_rect
817
819
  cdp.get_window_size = CDPM.get_window_size
820
+ cdp.get_mfa_code = CDPM.get_mfa_code
818
821
  cdp.nested_click = CDPM.nested_click
819
822
  cdp.select_option_by_text = CDPM.select_option_by_text
820
823
  cdp.select_option_by_index = CDPM.select_option_by_index
821
824
  cdp.select_option_by_value = CDPM.select_option_by_value
825
+ cdp.enter_mfa_code = CDPM.enter_mfa_code
822
826
  cdp.flash = CDPM.flash
823
827
  cdp.highlight = CDPM.highlight
824
828
  cdp.focus = CDPM.focus
@@ -712,7 +712,10 @@ class CDPMethods():
712
712
  self.__slow_mode_pause_if_set()
713
713
  element = self.find_element(selector, timeout=timeout)
714
714
  element.scroll_into_view()
715
- element.click()
715
+ if element.tag_name == "div" or element.tag_name == "input":
716
+ element.mouse_click() # Simulated click (not PyAutoGUI)
717
+ else:
718
+ element.click()
716
719
  self.__slow_mode_pause_if_set()
717
720
  self.loop.run_until_complete(self.page.wait())
718
721
 
@@ -1393,6 +1396,17 @@ class CDPMethods():
1393
1396
  )
1394
1397
  )
1395
1398
 
1399
+ def get_mfa_code(self, totp_key=None):
1400
+ """Returns a time-based one-time password based on the Google
1401
+ Authenticator algorithm for multi-factor authentication."""
1402
+ return shared_utils.get_mfa_code(totp_key)
1403
+
1404
+ def enter_mfa_code(self, selector, totp_key=None, timeout=None):
1405
+ if not timeout:
1406
+ timeout = settings.SMALL_TIMEOUT
1407
+ mfa_code = self.get_mfa_code(totp_key)
1408
+ self.type(selector, mfa_code + "\n", timeout=timeout)
1409
+
1396
1410
  def set_locale(self, locale):
1397
1411
  """(Settings will take effect on the next page load)"""
1398
1412
  self.loop.run_until_complete(self.page.set_locale(locale))
@@ -1430,6 +1444,26 @@ class CDPMethods():
1430
1444
  with suppress(Exception):
1431
1445
  self.loop.run_until_complete(self.page.evaluate(js_code))
1432
1446
 
1447
+ def is_attribute_present(self, selector, attribute, value=None):
1448
+ try:
1449
+ element = self.find_element(selector, timeout=0.1)
1450
+ found_value = element.get_attribute(attribute)
1451
+ if found_value is None:
1452
+ return False
1453
+ if value is not None:
1454
+ if found_value == value:
1455
+ return True
1456
+ else:
1457
+ return False
1458
+ else:
1459
+ return True
1460
+ except Exception:
1461
+ return False
1462
+
1463
+ def is_online(self):
1464
+ js_code = "navigator.onLine;"
1465
+ return self.loop.run_until_complete(self.page.evaluate(js_code))
1466
+
1433
1467
  def __make_sure_pyautogui_lock_is_writable(self):
1434
1468
  with suppress(Exception):
1435
1469
  shared_utils.make_writable(constants.MultiBrowser.PYAUTOGUILOCK)
@@ -1503,6 +1503,10 @@ class BaseCase(unittest.TestCase):
1503
1503
  ):
1504
1504
  """Returns True if the element attribute/value is found.
1505
1505
  If the value is not specified, the attribute only needs to exist."""
1506
+ if self.__is_cdp_swap_needed():
1507
+ return self.cdp.is_attribute_present(
1508
+ selector, attribute, value=value
1509
+ )
1506
1510
  self.wait_for_ready_state_complete()
1507
1511
  time.sleep(0.01)
1508
1512
  selector, by = self.__recalculate_selector(selector, by)
@@ -8510,33 +8514,9 @@ class BaseCase(unittest.TestCase):
8510
8514
 
8511
8515
  def get_mfa_code(self, totp_key=None):
8512
8516
  """Same as get_totp_code() and get_google_auth_password().
8513
- Returns a time-based one-time password based on the
8514
- Google Authenticator algorithm for multi-factor authentication.
8515
- If the "totp_key" is not specified, this method defaults
8516
- to using the one provided in [seleniumbase/config/settings.py].
8517
- Google Authenticator codes expire & change at 30-sec intervals.
8518
- If the fetched password expires in the next 1.2 seconds, waits
8519
- for a new one before returning it (may take up to 1.2 seconds).
8520
- See https://pyotp.readthedocs.io/en/latest/ for details."""
8521
- import pyotp
8522
-
8523
- if not totp_key:
8524
- totp_key = settings.TOTP_KEY
8525
-
8526
- epoch_interval = time.time() / 30.0
8527
- cycle_lifespan = float(epoch_interval) - int(epoch_interval)
8528
- if float(cycle_lifespan) > 0.96:
8529
- # Password expires in the next 1.2 seconds. Wait for a new one.
8530
- for i in range(30):
8531
- time.sleep(0.04)
8532
- epoch_interval = time.time() / 30.0
8533
- cycle_lifespan = float(epoch_interval) - int(epoch_interval)
8534
- if not float(cycle_lifespan) > 0.96:
8535
- # The new password cycle has begun
8536
- break
8537
-
8538
- totp = pyotp.TOTP(totp_key)
8539
- return str(totp.now())
8517
+ Returns a time-based one-time password based on the Google
8518
+ Authenticator algorithm for multi-factor authentication."""
8519
+ return shared_utils.get_mfa_code(totp_key)
8540
8520
 
8541
8521
  def enter_mfa_code(
8542
8522
  self, selector, totp_key=None, by="css selector", timeout=None
@@ -193,6 +193,10 @@ def is_attribute_present(
193
193
  @Returns
194
194
  Boolean (is attribute present)
195
195
  """
196
+ if __is_cdp_swap_needed(driver):
197
+ return driver.cdp.is_attribute_present(
198
+ selector, attribute, value=value
199
+ )
196
200
  _reconnect_if_disconnected(driver)
197
201
  try:
198
202
  element = driver.find_element(by=by, value=selector)
@@ -7,6 +7,7 @@ import sys
7
7
  import time
8
8
  from contextlib import suppress
9
9
  from seleniumbase import config as sb_config
10
+ from seleniumbase.config import settings
10
11
  from seleniumbase.fixtures import constants
11
12
 
12
13
 
@@ -29,6 +30,34 @@ def pip_install(package, version=None):
29
30
  )
30
31
 
31
32
 
33
+ def get_mfa_code(totp_key=None):
34
+ """Returns a time-based one-time password based on the
35
+ Google Authenticator algorithm for multi-factor authentication.
36
+ If the "totp_key" is not specified, this method defaults
37
+ to using the one provided in [seleniumbase/config/settings.py].
38
+ Google Authenticator codes expire & change at 30-sec intervals.
39
+ If the fetched password expires in the next 1.2 seconds, waits
40
+ for a new one before returning it (may take up to 1.2 seconds).
41
+ See https://pyotp.readthedocs.io/en/latest/ for details."""
42
+ import pyotp
43
+
44
+ if not totp_key:
45
+ totp_key = settings.TOTP_KEY
46
+ epoch_interval = time.time() / 30.0
47
+ cycle_lifespan = float(epoch_interval) - int(epoch_interval)
48
+ if float(cycle_lifespan) > 0.96:
49
+ # Password expires in the next 1.2 seconds. Wait for a new one.
50
+ for i in range(30):
51
+ time.sleep(0.04)
52
+ epoch_interval = time.time() / 30.0
53
+ cycle_lifespan = float(epoch_interval) - int(epoch_interval)
54
+ if not float(cycle_lifespan) > 0.96:
55
+ # The new password cycle has begun
56
+ break
57
+ totp = pyotp.TOTP(totp_key)
58
+ return str(totp.now())
59
+
60
+
32
61
  def is_arm_linux():
33
62
  """Returns True if machine is ARM Linux.
34
63
  This will be useful once Google adds
@@ -350,7 +350,8 @@ class Browser:
350
350
  if _cdp_geolocation:
351
351
  await connection.send(cdp.page.navigate("about:blank"))
352
352
  await connection.set_geolocation(_cdp_geolocation)
353
- # Use the tab to navigate to new url
353
+ # This part isn't needed now, but may be needed later
354
+ """
354
355
  if (
355
356
  hasattr(sb_config, "_cdp_proxy")
356
357
  and "@" in sb_config._cdp_proxy
@@ -360,17 +361,14 @@ class Browser:
360
361
  username_and_password = sb_config._cdp_proxy.split("@")[0]
361
362
  proxy_user = username_and_password.split(":")[0]
362
363
  proxy_pass = username_and_password.split(":")[1]
363
- await connection.set_auth(
364
- proxy_user, proxy_pass, self.tabs[0]
365
- )
364
+ await connection.set_auth(proxy_user, proxy_pass, self.tabs[0])
366
365
  time.sleep(0.25)
367
- elif "auth" in kwargs and kwargs["auth"] and ":" in kwargs["auth"]:
366
+ """
367
+ if "auth" in kwargs and kwargs["auth"] and ":" in kwargs["auth"]:
368
368
  username_and_password = kwargs["auth"]
369
369
  proxy_user = username_and_password.split(":")[0]
370
370
  proxy_pass = username_and_password.split(":")[1]
371
- await connection.set_auth(
372
- proxy_user, proxy_pass, self.tabs[0]
373
- )
371
+ await connection.set_auth(proxy_user, proxy_pass, self.tabs[0])
374
372
  time.sleep(0.25)
375
373
  frame_id, loader_id, *_ = await connection.send(
376
374
  cdp.page.navigate(url)
@@ -258,13 +258,13 @@ async def start(
258
258
  config: Optional[Config] = None,
259
259
  *,
260
260
  user_data_dir: Optional[PathLike] = None,
261
- headless: Optional[bool] = False,
262
- incognito: Optional[bool] = False,
263
- guest: Optional[bool] = False,
261
+ headless: Optional[bool] = None,
262
+ incognito: Optional[bool] = None,
263
+ guest: Optional[bool] = None,
264
264
  browser_executable_path: Optional[PathLike] = None,
265
265
  browser_args: Optional[List[str]] = None,
266
266
  xvfb_metrics: Optional[List[str]] = None, # "Width,Height" for Linux
267
- ad_block: Optional[bool] = False,
267
+ ad_block: Optional[bool] = None,
268
268
  sandbox: Optional[bool] = True,
269
269
  lang: Optional[str] = None, # Set the Language Locale Code
270
270
  host: Optional[str] = None, # Chrome remote-debugging-host
@@ -318,6 +318,210 @@ async def start(
318
318
  (For example, ensuring shadow-root is always in "open" mode.)
319
319
  :type expert: bool
320
320
  """
321
+ sys_argv = sys.argv
322
+ arg_join = " ".join(sys_argv)
323
+ if headless is None:
324
+ if "--headless" in sys_argv:
325
+ headless = True
326
+ else:
327
+ headless = False
328
+ if headed is None:
329
+ if "--gui" in sys_argv or "--headed" in sys_argv:
330
+ headed = True
331
+ else:
332
+ headed = False
333
+ if xvfb is None:
334
+ if "--xvfb" in sys_argv:
335
+ xvfb = True
336
+ else:
337
+ xvfb = False
338
+ if incognito is None:
339
+ if "--incognito" in sys_argv:
340
+ incognito = True
341
+ else:
342
+ incognito = False
343
+ if guest is None:
344
+ if "--guest" in sys_argv:
345
+ guest = True
346
+ else:
347
+ guest = False
348
+ if ad_block is None:
349
+ if "--ad-block" in sys_argv or "--ad_block" in sys_argv:
350
+ ad_block = True
351
+ else:
352
+ ad_block = False
353
+ if xvfb_metrics is None and "--xvfb-metrics" in arg_join:
354
+ x_m = xvfb_metrics
355
+ count = 0
356
+ for arg in sys_argv:
357
+ if arg.startswith("--xvfb-metrics="):
358
+ x_m = arg.split("--xvfb-metrics=")[1]
359
+ break
360
+ elif arg == "--xvfb-metrics" and len(sys_argv) > count + 1:
361
+ x_m = sys_argv[count + 1]
362
+ if x_m.startswith("-"):
363
+ x_m = None
364
+ break
365
+ count += 1
366
+ if x_m:
367
+ if x_m.startswith('"') and x_m.endswith('"'):
368
+ x_m = x_m[1:-1]
369
+ elif x_m.startswith("'") and x_m.endswith("'"):
370
+ x_m = x_m[1:-1]
371
+ xvfb_metrics = x_m
372
+ if agent is None and "user_agent" not in kwargs and "--agent" in arg_join:
373
+ count = 0
374
+ for arg in sys_argv:
375
+ if arg.startswith("--agent="):
376
+ agent = arg.split("--agent=")[1]
377
+ break
378
+ elif arg == "--agent" and len(sys_argv) > count + 1:
379
+ agent = sys_argv[count + 1]
380
+ if agent.startswith("-"):
381
+ agent = None
382
+ break
383
+ count += 1
384
+ if agent:
385
+ if agent.startswith('"') and agent.endswith('"'):
386
+ agent = agent[1:-1]
387
+ elif agent.startswith("'") and agent.endswith("'"):
388
+ agent = agent[1:-1]
389
+ if (
390
+ geoloc is None
391
+ and "geolocation" not in kwargs
392
+ and "--geolocation" in arg_join
393
+ ):
394
+ count = 0
395
+ for arg in sys_argv:
396
+ if arg.startswith("--geolocation="):
397
+ geoloc = arg.split("--geolocation=")[1]
398
+ break
399
+ elif arg == "--geolocation" and len(sys_argv) > count + 1:
400
+ geoloc = sys_argv[count + 1]
401
+ if geoloc.startswith("-"):
402
+ geoloc = None
403
+ break
404
+ count += 1
405
+ if geoloc:
406
+ if geoloc.startswith('"') and geoloc.endswith('"'):
407
+ geoloc = geoloc[1:-1]
408
+ elif geoloc.startswith("'") and geoloc.endswith("'"):
409
+ geoloc = geoloc[1:-1]
410
+ if geoloc:
411
+ import ast
412
+ geoloc = ast.literal_eval(geoloc)
413
+ if not lang and "locale" not in kwargs and "locale_code" not in kwargs:
414
+ if "--locale" in arg_join:
415
+ count = 0
416
+ for arg in sys_argv:
417
+ if arg.startswith("--locale="):
418
+ lang = arg.split("--locale=")[1]
419
+ break
420
+ elif arg == "--locale" and len(sys_argv) > count + 1:
421
+ lang = sys_argv[count + 1]
422
+ if lang.startswith("-"):
423
+ lang = None
424
+ break
425
+ count += 1
426
+ elif "--lang" in arg_join:
427
+ count = 0
428
+ for arg in sys_argv:
429
+ if arg.startswith("--lang="):
430
+ lang = arg.split("--lang=")[1]
431
+ break
432
+ elif arg == "--lang" and len(sys_argv) > count + 1:
433
+ lang = sys_argv[count + 1]
434
+ if lang.startswith("-"):
435
+ lang = None
436
+ break
437
+ count += 1
438
+ if lang:
439
+ if lang.startswith('"') and lang.endswith('"'):
440
+ lang = lang[1:-1]
441
+ elif lang.startswith("'") and lang.endswith("'"):
442
+ lang = lang[1:-1]
443
+ if not browser_executable_path and "binary_location" not in kwargs:
444
+ bin_loc = None
445
+ if "--binary-location" in arg_join or "--binary_location" in arg_join:
446
+ bin_loc_cmd = "--binary-location"
447
+ if "--binary_location" in arg_join:
448
+ bin_loc_cmd = "--binary_location"
449
+ count = 0
450
+ bin_loc = None
451
+ for arg in sys_argv:
452
+ if arg.startswith("%s=" % bin_loc_cmd):
453
+ bin_loc = arg.split("%s=" % bin_loc_cmd)[1]
454
+ break
455
+ elif arg == bin_loc_cmd and len(sys_argv) > count + 1:
456
+ bin_loc = sys_argv[count + 1]
457
+ if bin_loc.startswith("-"):
458
+ bin_loc = None
459
+ break
460
+ count += 1
461
+ elif "--bl=" in arg_join:
462
+ count = 0
463
+ bin_loc = None
464
+ for arg in sys_argv:
465
+ if arg.startswith("--bl="):
466
+ bin_loc = arg.split("--bl=")[1]
467
+ break
468
+ count += 1
469
+ if bin_loc:
470
+ if bin_loc.startswith('"') and bin_loc.endswith('"'):
471
+ bin_loc = bin_loc[1:-1]
472
+ elif bin_loc.startswith("'") and bin_loc.endswith("'"):
473
+ bin_loc = bin_loc[1:-1]
474
+ if bin_loc and not os.path.exists(bin_loc):
475
+ print(" No browser executable at PATH {%s}! " % bin_loc)
476
+ print(" Using default Chrome browser instead!")
477
+ bin_loc = None
478
+ browser_executable_path = bin_loc
479
+ if proxy is None and "--proxy" in arg_join:
480
+ proxy_string = None
481
+ if "--proxy=" in arg_join:
482
+ proxy_string = arg_join.split("--proxy=")[1].split(" ")[0]
483
+ elif "--proxy " in arg_join:
484
+ proxy_string = arg_join.split("--proxy ")[1].split(" ")[0]
485
+ if proxy_string:
486
+ if proxy_string.startswith('"') and proxy_string.endswith('"'):
487
+ proxy_string = proxy_string[1:-1]
488
+ elif proxy_string.startswith("'") and proxy_string.endswith("'"):
489
+ proxy_string = proxy_string[1:-1]
490
+ proxy = proxy_string
491
+ if tzone is None and "timezone" not in kwargs and "--timezone" in arg_join:
492
+ tz_string = None
493
+ if "--timezone=" in arg_join:
494
+ tz_string = arg_join.split("--timezone=")[1].split(" ")[0]
495
+ elif "--timezone " in arg_join:
496
+ tz_string = arg_join.split("--timezone ")[1].split(" ")[0]
497
+ if tz_string:
498
+ if tz_string.startswith('"') and tz_string.endswith('"'):
499
+ tz_string = proxy_string[1:-1]
500
+ elif tz_string.startswith("'") and tz_string.endswith("'"):
501
+ tz_string = proxy_string[1:-1]
502
+ tzone = tz_string
503
+ platform_var = None
504
+ if (
505
+ "platform" not in kwargs
506
+ and "plat" not in kwargs
507
+ and "--platform" in arg_join
508
+ ):
509
+ count = 0
510
+ for arg in sys_argv:
511
+ if arg.startswith("--platform="):
512
+ platform_var = arg.split("--platform=")[1]
513
+ break
514
+ elif arg == "--platform" and len(sys_argv) > count + 1:
515
+ platform_var = sys_argv[count + 1]
516
+ if platform_var.startswith("-"):
517
+ platform_var = None
518
+ break
519
+ count += 1
520
+ if platform_var:
521
+ if platform_var.startswith('"') and platform_var.endswith('"'):
522
+ platform_var = platform_var[1:-1]
523
+ elif platform_var.startswith("'") and platform_var.endswith("'"):
524
+ platform_var = platform_var[1:-1]
321
525
  if IS_LINUX and not headless and not headed and not xvfb:
322
526
  xvfb = True # The default setting on Linux
323
527
  __activate_virtual_display_as_needed(headless, headed, xvfb, xvfb_metrics)
@@ -404,6 +608,8 @@ async def start(
404
608
  sb_config._cdp_platform = kwargs["platform"]
405
609
  elif "plat" in kwargs:
406
610
  sb_config._cdp_platform = kwargs["plat"]
611
+ elif platform_var:
612
+ sb_config._cdp_platform = platform_var
407
613
  else:
408
614
  sb_config._cdp_platform = None
409
615
  return driver
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.42.1
3
+ Version: 4.42.3
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
@@ -28,7 +28,6 @@ Classifier: Environment :: Web Environment
28
28
  Classifier: Framework :: Pytest
29
29
  Classifier: Intended Audience :: Developers
30
30
  Classifier: Intended Audience :: Information Technology
31
- Classifier: License :: OSI Approved :: MIT License
32
31
  Classifier: Operating System :: MacOS :: MacOS X
33
32
  Classifier: Operating System :: Microsoft :: Windows
34
33
  Classifier: Operating System :: POSIX :: Linux
@@ -66,7 +65,8 @@ Requires-Dist: packaging>=25.0
66
65
  Requires-Dist: setuptools~=70.2; python_version < "3.10"
67
66
  Requires-Dist: setuptools>=80.9.0; python_version >= "3.10"
68
67
  Requires-Dist: wheel>=0.45.1
69
- Requires-Dist: attrs>=25.3.0
68
+ Requires-Dist: attrs~=25.3.0; python_version < "3.9"
69
+ Requires-Dist: attrs>=25.4.0; python_version >= "3.9"
70
70
  Requires-Dist: certifi>=2025.10.5
71
71
  Requires-Dist: exceptiongroup>=1.3.0
72
72
  Requires-Dist: websockets~=13.1; python_version < "3.9"
@@ -107,7 +107,8 @@ Requires-Dist: trio==0.27.0; python_version < "3.9"
107
107
  Requires-Dist: trio<1,>=0.31.0; python_version >= "3.9"
108
108
  Requires-Dist: trio-websocket~=0.12.2
109
109
  Requires-Dist: wsproto==1.2.0
110
- Requires-Dist: websocket-client~=1.8.0
110
+ Requires-Dist: websocket-client~=1.8.0; python_version < "3.9"
111
+ Requires-Dist: websocket-client~=1.9.0; python_version >= "3.9"
111
112
  Requires-Dist: selenium==4.27.1; python_version < "3.9"
112
113
  Requires-Dist: selenium==4.32.0; python_version >= "3.9" and python_version < "3.10"
113
114
  Requires-Dist: selenium==4.36.0; python_version >= "3.10"
@@ -134,6 +135,7 @@ Requires-Dist: soupsieve~=2.8; python_version >= "3.9"
134
135
  Requires-Dist: beautifulsoup4~=4.14.2
135
136
  Requires-Dist: pyotp==2.9.0
136
137
  Requires-Dist: python-xlib==0.33; platform_system == "Linux"
138
+ Requires-Dist: PyAutoGUI>=0.9.54; platform_system == "Linux"
137
139
  Requires-Dist: markdown-it-py==3.0.0; python_version < "3.10"
138
140
  Requires-Dist: markdown-it-py==4.0.0; python_version >= "3.10"
139
141
  Requires-Dist: mdurl==0.1.2
@@ -180,12 +182,12 @@ Requires-Dist: proxy.py==2.4.3; extra == "proxy"
180
182
  Provides-Extra: psutil
181
183
  Requires-Dist: psutil==7.1.0; extra == "psutil"
182
184
  Provides-Extra: pyautogui
183
- Requires-Dist: PyAutoGUI==0.9.54; extra == "pyautogui"
185
+ Requires-Dist: PyAutoGUI>=0.9.54; platform_system != "Linux" and extra == "pyautogui"
184
186
  Provides-Extra: selenium-stealth
185
187
  Requires-Dist: selenium-stealth==1.0.6; extra == "selenium-stealth"
186
188
  Provides-Extra: selenium-wire
187
189
  Requires-Dist: selenium-wire==5.1.0; extra == "selenium-wire"
188
- Requires-Dist: pyOpenSSL==24.2.1; extra == "selenium-wire"
190
+ Requires-Dist: pyOpenSSL>=24.2.1; extra == "selenium-wire"
189
191
  Requires-Dist: pyparsing>=3.1.4; extra == "selenium-wire"
190
192
  Requires-Dist: Brotli==1.1.0; extra == "selenium-wire"
191
193
  Requires-Dist: blinker==1.7.0; extra == "selenium-wire"
@@ -194,7 +196,7 @@ Requires-Dist: hpack==4.0.0; extra == "selenium-wire"
194
196
  Requires-Dist: hyperframe==6.0.1; extra == "selenium-wire"
195
197
  Requires-Dist: kaitaistruct==0.10; extra == "selenium-wire"
196
198
  Requires-Dist: pyasn1==0.6.1; extra == "selenium-wire"
197
- Requires-Dist: zstandard==0.23.0; extra == "selenium-wire"
199
+ Requires-Dist: zstandard>=0.23.0; extra == "selenium-wire"
198
200
  Dynamic: author
199
201
  Dynamic: author-email
200
202
  Dynamic: classifier
@@ -314,7 +316,7 @@ with SB(uc=True, test=True, locale="en") as sb:
314
316
  sb.assert_text("Username", '[for="user_login"]', timeout=3)
315
317
  sb.assert_element('label[for="user_login"]')
316
318
  sb.highlight('button:contains("Sign in")')
317
- sb.highlight('h1:contains("GitLab.com")')
319
+ sb.highlight('h1:contains("GitLab")')
318
320
  sb.post_message("SeleniumBase wasn't detected", duration=4)
319
321
  ```
320
322
 
@@ -329,13 +331,11 @@ url = "https://gitlab.com/users/sign_in"
329
331
  sb = sb_cdp.Chrome(url)
330
332
  sb.sleep(2.5)
331
333
  sb.gui_click_captcha()
332
- sb.highlight('h1:contains("GitLab.com")')
334
+ sb.highlight('h1:contains("GitLab")')
333
335
  sb.highlight('button:contains("Sign in")')
334
336
  sb.driver.stop()
335
337
  ```
336
338
 
337
- > (Due to changes in Chrome 137 where the `--load-extension` switch was removed, you can't load extensions directly from this format.)
338
-
339
339
  --------
340
340
 
341
341
  <p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
@@ -3,7 +3,7 @@ sbase/__main__.py,sha256=G0bVB1-DM4PGwQ1KyOupaWCs4ePbChZNNWuX2htim5U,647
3
3
  sbase/steps.py,sha256=wiPSWZhFpBlWvkqXRJ18btpBu3nQaw9K5AzIJNAX5RM,43521
4
4
  seleniumbase/__init__.py,sha256=JFEY9P5QJqsa1M6ghzLMH2eIPQyh85iglCaQwg8Y8z4,2498
5
5
  seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
6
- seleniumbase/__version__.py,sha256=PaDBv1vq8Qcw7qMzR9vLg_YgpDZ8E2L6_LqLBj3R4C4,46
6
+ seleniumbase/__version__.py,sha256=NxDRTsK1en5AnzYTB768P_f5d5U9tzqllrffTcSIHfY,46
7
7
  seleniumbase/behave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  seleniumbase/behave/behave_helper.py,sha256=lJtagtivSbEpbRj0EKV4l4PuPU6NANONJJAnYwgVCe0,24379
9
9
  seleniumbase/behave/behave_sb.py,sha256=guLihFsr1uJ4v2AR3r3Vy_BTeHrHwy2JEJxhp-MVnZA,59872
@@ -36,7 +36,7 @@ seleniumbase/console_scripts/sb_print.py,sha256=tNy-bMDgwHJO3bZxMpmo9weSE8uhbH0C
36
36
  seleniumbase/console_scripts/sb_recorder.py,sha256=DH-n2fN7N9qyHMl7wjtn8MiliBgfw-1kwgmfg1GUuhk,10772
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=gaaqYK1UxYxsyh-3pzFVKR1_x1vEXHsfhMxA8QxR8Ng,250541
39
+ seleniumbase/core/browser_launcher.py,sha256=6o5oVuploZ-DSU3edaroFR98uqxIYyiRRP9DB-Y7xR0,250719
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
@@ -50,7 +50,7 @@ seleniumbase/core/proxy_helper.py,sha256=pZ1NboNfziHU3vWZLOZLX-qkfM3oKSnpc3omQf9
50
50
  seleniumbase/core/recorder_helper.py,sha256=gDION28OK4NAYsE-7ohKZ9Z3sxQQ0FEjf859LDpqsg4,25320
51
51
  seleniumbase/core/report_helper.py,sha256=AIl6Qava2yW1uSzbLpJBlPlYDz0KE-rVhogh8hsGWBo,12201
52
52
  seleniumbase/core/s3_manager.py,sha256=z_4qx2jI_gtK5r3niGXgEOBpfMUicUCOciowai50MP4,3529
53
- seleniumbase/core/sb_cdp.py,sha256=FpeEZ3-LB-IsIISV4QPzkaN0PcUloiPpBd2AZ78kZIA,103248
53
+ seleniumbase/core/sb_cdp.py,sha256=E_7sbQjyqDAO38IiGYSSB57xrTqxAi8nnqUEWIAXYt8,104551
54
54
  seleniumbase/core/sb_driver.py,sha256=-IQsskc7HpXQbcBL04IPjmGpyYchyo7v9OPF2WcahDw,14159
55
55
  seleniumbase/core/session_helper.py,sha256=s9zD3PVZEWVzG2h81cCUskbNWLfdjC_LwwQjKptHCak,558
56
56
  seleniumbase/core/settings_parser.py,sha256=gqVohHVlE_5L5Cqe2L24uYrRzvoK-saX8E_Df7_-_3I,7609
@@ -67,14 +67,14 @@ seleniumbase/extensions/disable_csp.zip,sha256=5RvomXnm2PdivUVcxTV6jfvD8WhTEsQYH
67
67
  seleniumbase/extensions/recorder.zip,sha256=JEE_FVEvlS63cFQbVLEroIyPSS91nWCDL0MhjVrmIpk,11813
68
68
  seleniumbase/extensions/sbase_ext.zip,sha256=3s1N8zrVaMz8RQEOIoBzC3KDjtmHwVZRvVsX25Odr_s,8175
69
69
  seleniumbase/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- seleniumbase/fixtures/base_case.py,sha256=nnPUREzeNfpnOP9q1ZO--guOtHIm3efus4WRsw5E_NQ,742045
70
+ seleniumbase/fixtures/base_case.py,sha256=wHXUqjQmALFdWTk5Lf7GX0zWLji3FqzjhnJ91RYrOII,741117
71
71
  seleniumbase/fixtures/constants.py,sha256=WMrItuNyKq3XVJ64NluLIRc4gJCxDw8K8qXED0b9S2w,13752
72
72
  seleniumbase/fixtures/css_to_xpath.py,sha256=9ouDB1xl4MJ2os6JOgTIAyHKOQfuxtxvXC3O5hSnEKA,1954
73
73
  seleniumbase/fixtures/errors.py,sha256=KyxuEVx_e3MPhVrJfNIa_3ltMpbCFxfy_jxK8RFNTns,555
74
74
  seleniumbase/fixtures/js_utils.py,sha256=Ykt019DFP8S27o8Kai_ihT01qQWo3RqHUeljqOEUdFU,52247
75
- seleniumbase/fixtures/page_actions.py,sha256=zWjIYQmBuQMP25SiqIgM0UpaNTPHHHPkbmHB-shtdaU,73073
75
+ seleniumbase/fixtures/page_actions.py,sha256=bkCo3s-t2hglV_SYTPPt849R9l0h1gKKboTmZar0n9Y,73213
76
76
  seleniumbase/fixtures/page_utils.py,sha256=H1iV8f9vDyEy87DBntyiBXC_tg8HskcebUOAJVn0hxE,12160
77
- seleniumbase/fixtures/shared_utils.py,sha256=HAjOSJQIGNG7wLbeBWAMy80x4l4stJjoxi-ZmHdzwMk,8702
77
+ seleniumbase/fixtures/shared_utils.py,sha256=LFXGGdvXhNZCShsRxyuEOcO2dcEbSkMSW5seQR2oE08,9950
78
78
  seleniumbase/fixtures/unittest_helper.py,sha256=sfZ92rZeBAn_sF_yQ3I6_I7h3lyU5-cV_UMegBNoEm8,1294
79
79
  seleniumbase/fixtures/words.py,sha256=FOA4mAYvl3EPVpBTvgvK6YwCL8BdlRCmed685kEe7Vg,7827
80
80
  seleniumbase/fixtures/xpath_to_css.py,sha256=lML56k656fElXJ4NJF07r35FjctrbgQkXUotNk7A-as,8876
@@ -117,8 +117,8 @@ seleniumbase/undetected/reactor.py,sha256=NropaXcO54pzmDq6quR27qPJxab6636H7LRAaq
117
117
  seleniumbase/undetected/webelement.py,sha256=OOpUYbEiOG52KsYYyuDW9tYLdA2SMnukvwQHUdPVn9E,1389
118
118
  seleniumbase/undetected/cdp_driver/__init__.py,sha256=Ga9alwuaZZy4_XOShc0HjgFnNqpPdrcbjAicz5gE7a4,215
119
119
  seleniumbase/undetected/cdp_driver/_contradict.py,sha256=lP4b0h5quAy573ETn_TBbYV889cL1AuPLVInpJ0ZkiU,3183
120
- seleniumbase/undetected/cdp_driver/browser.py,sha256=mVM36mFqA4ZnxBDQ5ily3dpIcZ33O5coG1boEcX4aLc,35640
121
- seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=ku3Nq8yjC6kbvVV2PB149E-TxQIIvjHDFQI2wyi0HVs,25221
120
+ seleniumbase/undetected/cdp_driver/browser.py,sha256=JQlwMuwZgK0vWlvH4SU6DA7LcZo2I4hJRUIcv4gbZCQ,35609
121
+ seleniumbase/undetected/cdp_driver/cdp_util.py,sha256=83NOk962PCiERr6YQ_QjTS5yS8Uwcnsyaw9BdgnGoAQ,33481
122
122
  seleniumbase/undetected/cdp_driver/config.py,sha256=pjcGq0azNQpNb3XT2sTjxShLEmcIPdzTzB_mitu6GkM,13557
123
123
  seleniumbase/undetected/cdp_driver/connection.py,sha256=WgZ4QamXSdTzP4Xfgkn8mxv-JFivMG6hqbyHy2_LQlg,25717
124
124
  seleniumbase/undetected/cdp_driver/element.py,sha256=FIC6v7OmumLCT-_vIc3H4oju_oBbaLpWJUJIKm2c_q4,40467
@@ -137,9 +137,9 @@ seleniumbase/utilities/selenium_grid/start-grid-hub.bat,sha256=Ftq-GrAKRYH2ssDPr
137
137
  seleniumbase/utilities/selenium_grid/start-grid-hub.sh,sha256=KADv0RUHONLL2_I443QFK8PryBpDmKn5Gy0s4o0vDSM,106
138
138
  seleniumbase/utilities/selenium_ide/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
139
  seleniumbase/utilities/selenium_ide/convert_ide.py,sha256=pZFnqEJQEKZPyNFjkLD29s2HPQgCrWW9XJWpCPhWOoM,31691
140
- seleniumbase-4.42.1.dist-info/licenses/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
141
- seleniumbase-4.42.1.dist-info/METADATA,sha256=KTI4f3tfgQDx5V1v7wzhY63IaQlGus1Nh7T-L-UvZLQ,89241
142
- seleniumbase-4.42.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
143
- seleniumbase-4.42.1.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
144
- seleniumbase-4.42.1.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
145
- seleniumbase-4.42.1.dist-info/RECORD,,
140
+ seleniumbase-4.42.3.dist-info/licenses/LICENSE,sha256=BRblZsX7HyPUjQmYTiyWr_e9tzWvmR3R4SFclM2R3W0,1085
141
+ seleniumbase-4.42.3.dist-info/METADATA,sha256=spZZe0MvPKyG3c0xO1JF1Dp_dKNSthItrviEXMnMmss,89304
142
+ seleniumbase-4.42.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
143
+ seleniumbase-4.42.3.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
144
+ seleniumbase-4.42.3.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
145
+ seleniumbase-4.42.3.dist-info/RECORD,,