seleniumbase 4.41.3__py3-none-any.whl → 4.45.10__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.
Files changed (64) hide show
  1. sbase/steps.py +9 -0
  2. seleniumbase/__version__.py +1 -1
  3. seleniumbase/behave/behave_helper.py +2 -0
  4. seleniumbase/behave/behave_sb.py +21 -8
  5. seleniumbase/common/decorators.py +3 -1
  6. seleniumbase/console_scripts/run.py +1 -0
  7. seleniumbase/console_scripts/sb_caseplans.py +3 -4
  8. seleniumbase/console_scripts/sb_install.py +142 -11
  9. seleniumbase/console_scripts/sb_mkchart.py +1 -2
  10. seleniumbase/console_scripts/sb_mkdir.py +99 -29
  11. seleniumbase/console_scripts/sb_mkfile.py +1 -2
  12. seleniumbase/console_scripts/sb_mkpres.py +1 -2
  13. seleniumbase/console_scripts/sb_mkrec.py +26 -2
  14. seleniumbase/console_scripts/sb_objectify.py +4 -5
  15. seleniumbase/console_scripts/sb_print.py +1 -1
  16. seleniumbase/console_scripts/sb_recorder.py +40 -3
  17. seleniumbase/core/browser_launcher.py +474 -151
  18. seleniumbase/core/detect_b_ver.py +258 -16
  19. seleniumbase/core/log_helper.py +15 -21
  20. seleniumbase/core/mysql.py +1 -1
  21. seleniumbase/core/recorder_helper.py +3 -0
  22. seleniumbase/core/report_helper.py +9 -12
  23. seleniumbase/core/sb_cdp.py +734 -215
  24. seleniumbase/core/sb_driver.py +46 -5
  25. seleniumbase/core/session_helper.py +2 -4
  26. seleniumbase/core/tour_helper.py +1 -2
  27. seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
  28. seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  29. seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  30. seleniumbase/drivers/comet_drivers/__init__.py +0 -0
  31. seleniumbase/drivers/opera_drivers/__init__.py +0 -0
  32. seleniumbase/fixtures/base_case.py +448 -251
  33. seleniumbase/fixtures/constants.py +36 -9
  34. seleniumbase/fixtures/js_utils.py +77 -18
  35. seleniumbase/fixtures/page_actions.py +41 -13
  36. seleniumbase/fixtures/page_utils.py +19 -12
  37. seleniumbase/fixtures/shared_utils.py +64 -6
  38. seleniumbase/masterqa/master_qa.py +16 -2
  39. seleniumbase/plugins/base_plugin.py +8 -0
  40. seleniumbase/plugins/basic_test_info.py +2 -3
  41. seleniumbase/plugins/driver_manager.py +131 -5
  42. seleniumbase/plugins/page_source.py +2 -3
  43. seleniumbase/plugins/pytest_plugin.py +244 -79
  44. seleniumbase/plugins/sb_manager.py +143 -20
  45. seleniumbase/plugins/selenium_plugin.py +144 -12
  46. seleniumbase/translate/translator.py +2 -3
  47. seleniumbase/undetected/__init__.py +17 -13
  48. seleniumbase/undetected/cdp.py +1 -12
  49. seleniumbase/undetected/cdp_driver/browser.py +330 -129
  50. seleniumbase/undetected/cdp_driver/cdp_util.py +328 -61
  51. seleniumbase/undetected/cdp_driver/config.py +110 -14
  52. seleniumbase/undetected/cdp_driver/connection.py +18 -48
  53. seleniumbase/undetected/cdp_driver/element.py +105 -33
  54. seleniumbase/undetected/cdp_driver/tab.py +414 -39
  55. seleniumbase/utilities/selenium_grid/download_selenium_server.py +1 -1
  56. seleniumbase/utilities/selenium_grid/grid_hub.py +1 -2
  57. seleniumbase/utilities/selenium_grid/grid_node.py +2 -3
  58. seleniumbase/utilities/selenium_ide/convert_ide.py +2 -3
  59. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/METADATA +193 -166
  60. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/RECORD +64 -59
  61. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/licenses/LICENSE +1 -1
  62. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/WHEEL +0 -0
  63. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/entry_points.txt +0 -0
  64. {seleniumbase-4.41.3.dist-info → seleniumbase-4.45.10.dist-info}/top_level.txt +0 -0
@@ -51,12 +51,27 @@ def __activate_virtual_display_as_needed(
51
51
  headless, headed, xvfb, xvfb_metrics
52
52
  ):
53
53
  """This is only needed on Linux."""
54
+ reset_virtual_display = False
55
+ if IS_LINUX and (not headed or xvfb):
56
+ if (
57
+ not hasattr(sb_config, "_closed_connection_ids")
58
+ or not isinstance(sb_config._closed_connection_ids, list)
59
+ ):
60
+ sb_config._closed_connection_ids = []
61
+ if (
62
+ not hasattr(sb_config, "_xvfb_users")
63
+ or not isinstance(sb_config._xvfb_users, int)
64
+ ):
65
+ reset_virtual_display = True
66
+ sb_config._xvfb_users = 0
67
+ sb_config._xvfb_users += 1
54
68
  if (
55
69
  IS_LINUX
56
70
  and (not headed or xvfb)
57
71
  and (
58
72
  not hasattr(sb_config, "_virtual_display")
59
73
  or not sb_config._virtual_display
74
+ or reset_virtual_display
60
75
  )
61
76
  ):
62
77
  from sbvirtualdisplay import Display
@@ -102,7 +117,8 @@ def __activate_virtual_display_as_needed(
102
117
  _xvfb_display.start()
103
118
  if "DISPLAY" not in os.environ.keys():
104
119
  print(
105
- "\nX11 display failed! Will use regular xvfb!"
120
+ "\n X11 display failed! Is Xvfb installed? "
121
+ "\n Try this: `sudo apt install -y xvfb`"
106
122
  )
107
123
  __activate_standard_virtual_display()
108
124
  else:
@@ -121,22 +137,26 @@ def __activate_virtual_display_as_needed(
121
137
  import pyautogui
122
138
  with suppress(Exception):
123
139
  use_pyautogui_ver = constants.PyAutoGUI.VER
124
- if pyautogui.__version__ != use_pyautogui_ver:
140
+ u_pv = shared_utils.make_version_tuple(
141
+ use_pyautogui_ver
142
+ )
143
+ pv = shared_utils.make_version_tuple(
144
+ pyautogui.__version__
145
+ )
146
+ if pv < u_pv:
125
147
  del pyautogui # To get newer ver
126
148
  shared_utils.pip_install(
127
- "pyautogui", version=use_pyautogui_ver
149
+ "pyautogui", version="Latest"
128
150
  )
129
151
  import pyautogui
130
152
  pyautogui_is_installed = True
131
153
  except Exception:
132
154
  message = (
133
- "PyAutoGUI is required for UC Mode on Linux! "
155
+ "PyAutoGUI is required for CDP Mode on Linux! "
134
156
  "Installing now..."
135
157
  )
136
158
  print("\n" + message)
137
- shared_utils.pip_install(
138
- "pyautogui", version=constants.PyAutoGUI.VER
139
- )
159
+ shared_utils.pip_install("pyautogui", version="Latest")
140
160
  import pyautogui
141
161
  pyautogui_is_installed = True
142
162
  if (
@@ -258,13 +278,13 @@ async def start(
258
278
  config: Optional[Config] = None,
259
279
  *,
260
280
  user_data_dir: Optional[PathLike] = None,
261
- headless: Optional[bool] = False,
262
- incognito: Optional[bool] = False,
263
- guest: Optional[bool] = False,
281
+ headless: Optional[bool] = None,
282
+ incognito: Optional[bool] = None,
283
+ guest: Optional[bool] = None,
264
284
  browser_executable_path: Optional[PathLike] = None,
265
285
  browser_args: Optional[List[str]] = None,
266
286
  xvfb_metrics: Optional[List[str]] = None, # "Width,Height" for Linux
267
- ad_block: Optional[bool] = False,
287
+ ad_block: Optional[bool] = None,
268
288
  sandbox: Optional[bool] = True,
269
289
  lang: Optional[str] = None, # Set the Language Locale Code
270
290
  host: Optional[str] = None, # Chrome remote-debugging-host
@@ -276,7 +296,10 @@ async def start(
276
296
  proxy: Optional[str] = None, # "host:port" or "user:pass@host:port"
277
297
  tzone: Optional[str] = None, # Eg "America/New_York", "Asia/Kolkata"
278
298
  geoloc: Optional[list | tuple] = None, # Eg (48.87645, 2.26340)
299
+ mobile: Optional[bool] = None, # Use Mobile Mode with default args
300
+ disable_csp: Optional[str] = None, # Disable content security policy
279
301
  extension_dir: Optional[str] = None, # Chrome extension directory
302
+ use_chromium: Optional[str] = None, # Use the base Chromium browser
280
303
  **kwargs: Optional[dict],
281
304
  ) -> Browser:
282
305
  """
@@ -318,9 +341,235 @@ async def start(
318
341
  (For example, ensuring shadow-root is always in "open" mode.)
319
342
  :type expert: bool
320
343
  """
344
+ sys_argv = sys.argv
345
+ arg_join = " ".join(sys_argv)
346
+ if headless is None:
347
+ if "--headless" in sys_argv:
348
+ headless = True
349
+ else:
350
+ headless = False
351
+ if headed is None:
352
+ if "--gui" in sys_argv or "--headed" in sys_argv:
353
+ headed = True
354
+ else:
355
+ headed = False
356
+ if xvfb is None:
357
+ if "--xvfb" in sys_argv:
358
+ xvfb = True
359
+ else:
360
+ xvfb = False
361
+ if not hasattr(sb_config, "xvfb"):
362
+ sb_config.xvfb = xvfb
363
+ if incognito is None:
364
+ if "--incognito" in sys_argv:
365
+ incognito = True
366
+ else:
367
+ incognito = False
368
+ if guest is None:
369
+ if "--guest" in sys_argv:
370
+ guest = True
371
+ else:
372
+ guest = False
373
+ if mobile is None:
374
+ if "--mobile" in sys_argv:
375
+ mobile = True
376
+ else:
377
+ mobile = False
378
+ if mobile:
379
+ sb_config._cdp_mobile_mode = True
380
+ else:
381
+ sb_config._cdp_mobile_mode = False
382
+ if ad_block is None:
383
+ if "--ad-block" in sys_argv or "--ad_block" in sys_argv:
384
+ ad_block = True
385
+ else:
386
+ ad_block = False
387
+ if disable_csp is None:
388
+ if "--disable-csp" in sys_argv or "--disable_csp" in sys_argv:
389
+ disable_csp = True
390
+ else:
391
+ disable_csp = False
392
+ if xvfb_metrics is None and "--xvfb-metrics" in arg_join:
393
+ x_m = xvfb_metrics
394
+ count = 0
395
+ for arg in sys_argv:
396
+ if arg.startswith("--xvfb-metrics="):
397
+ x_m = arg.split("--xvfb-metrics=")[1]
398
+ break
399
+ elif arg == "--xvfb-metrics" and len(sys_argv) > count + 1:
400
+ x_m = sys_argv[count + 1]
401
+ if x_m.startswith("-"):
402
+ x_m = None
403
+ break
404
+ count += 1
405
+ if x_m:
406
+ if x_m.startswith('"') and x_m.endswith('"'):
407
+ x_m = x_m[1:-1]
408
+ elif x_m.startswith("'") and x_m.endswith("'"):
409
+ x_m = x_m[1:-1]
410
+ xvfb_metrics = x_m
411
+ if agent is None and "user_agent" not in kwargs and "--agent" in arg_join:
412
+ count = 0
413
+ for arg in sys_argv:
414
+ if arg.startswith("--agent="):
415
+ agent = arg.split("--agent=")[1]
416
+ break
417
+ elif arg == "--agent" and len(sys_argv) > count + 1:
418
+ agent = sys_argv[count + 1]
419
+ if agent.startswith("-"):
420
+ agent = None
421
+ break
422
+ count += 1
423
+ if agent:
424
+ if agent.startswith('"') and agent.endswith('"'):
425
+ agent = agent[1:-1]
426
+ elif agent.startswith("'") and agent.endswith("'"):
427
+ agent = agent[1:-1]
428
+ if (
429
+ geoloc is None
430
+ and "geolocation" not in kwargs
431
+ and "--geolocation" in arg_join
432
+ ):
433
+ count = 0
434
+ for arg in sys_argv:
435
+ if arg.startswith("--geolocation="):
436
+ geoloc = arg.split("--geolocation=")[1]
437
+ break
438
+ elif arg == "--geolocation" and len(sys_argv) > count + 1:
439
+ geoloc = sys_argv[count + 1]
440
+ if geoloc.startswith("-"):
441
+ geoloc = None
442
+ break
443
+ count += 1
444
+ if geoloc:
445
+ if geoloc.startswith('"') and geoloc.endswith('"'):
446
+ geoloc = geoloc[1:-1]
447
+ elif geoloc.startswith("'") and geoloc.endswith("'"):
448
+ geoloc = geoloc[1:-1]
449
+ if geoloc:
450
+ import ast
451
+ geoloc = ast.literal_eval(geoloc)
452
+ if not lang and "locale" not in kwargs and "locale_code" not in kwargs:
453
+ if "--locale" in arg_join:
454
+ count = 0
455
+ for arg in sys_argv:
456
+ if arg.startswith("--locale="):
457
+ lang = arg.split("--locale=")[1]
458
+ break
459
+ elif arg == "--locale" and len(sys_argv) > count + 1:
460
+ lang = sys_argv[count + 1]
461
+ if lang.startswith("-"):
462
+ lang = None
463
+ break
464
+ count += 1
465
+ elif "--lang" in arg_join:
466
+ count = 0
467
+ for arg in sys_argv:
468
+ if arg.startswith("--lang="):
469
+ lang = arg.split("--lang=")[1]
470
+ break
471
+ elif arg == "--lang" and len(sys_argv) > count + 1:
472
+ lang = sys_argv[count + 1]
473
+ if lang.startswith("-"):
474
+ lang = None
475
+ break
476
+ count += 1
477
+ if lang:
478
+ if lang.startswith('"') and lang.endswith('"'):
479
+ lang = lang[1:-1]
480
+ elif lang.startswith("'") and lang.endswith("'"):
481
+ lang = lang[1:-1]
482
+ if not browser_executable_path and "binary_location" not in kwargs:
483
+ bin_loc = None
484
+ if "--binary-location" in arg_join or "--binary_location" in arg_join:
485
+ bin_loc_cmd = "--binary-location"
486
+ if "--binary_location" in arg_join:
487
+ bin_loc_cmd = "--binary_location"
488
+ count = 0
489
+ bin_loc = None
490
+ for arg in sys_argv:
491
+ if arg.startswith("%s=" % bin_loc_cmd):
492
+ bin_loc = arg.split("%s=" % bin_loc_cmd)[1]
493
+ break
494
+ elif arg == bin_loc_cmd and len(sys_argv) > count + 1:
495
+ bin_loc = sys_argv[count + 1]
496
+ if bin_loc.startswith("-"):
497
+ bin_loc = None
498
+ break
499
+ count += 1
500
+ elif "--bl=" in arg_join:
501
+ count = 0
502
+ bin_loc = None
503
+ for arg in sys_argv:
504
+ if arg.startswith("--bl="):
505
+ bin_loc = arg.split("--bl=")[1]
506
+ break
507
+ count += 1
508
+ if bin_loc:
509
+ if bin_loc.startswith('"') and bin_loc.endswith('"'):
510
+ bin_loc = bin_loc[1:-1]
511
+ elif bin_loc.startswith("'") and bin_loc.endswith("'"):
512
+ bin_loc = bin_loc[1:-1]
513
+ if bin_loc and not os.path.exists(bin_loc):
514
+ print(" No browser executable at PATH {%s}! " % bin_loc)
515
+ print(" Using default Chrome browser instead!")
516
+ bin_loc = None
517
+ browser_executable_path = bin_loc
518
+ elif use_chromium or "--use-chromium" in arg_join:
519
+ browser_executable_path = "_chromium_"
520
+ if proxy is None and "--proxy" in arg_join:
521
+ proxy_string = None
522
+ if "--proxy=" in arg_join:
523
+ proxy_string = arg_join.split("--proxy=")[1].split(" ")[0]
524
+ elif "--proxy " in arg_join:
525
+ proxy_string = arg_join.split("--proxy ")[1].split(" ")[0]
526
+ if proxy_string:
527
+ if proxy_string.startswith('"') and proxy_string.endswith('"'):
528
+ proxy_string = proxy_string[1:-1]
529
+ elif proxy_string.startswith("'") and proxy_string.endswith("'"):
530
+ proxy_string = proxy_string[1:-1]
531
+ proxy = proxy_string
532
+ if tzone is None and "timezone" not in kwargs and "--timezone" in arg_join:
533
+ tz_string = None
534
+ if "--timezone=" in arg_join:
535
+ tz_string = arg_join.split("--timezone=")[1].split(" ")[0]
536
+ elif "--timezone " in arg_join:
537
+ tz_string = arg_join.split("--timezone ")[1].split(" ")[0]
538
+ if tz_string:
539
+ if tz_string.startswith('"') and tz_string.endswith('"'):
540
+ tz_string = proxy_string[1:-1]
541
+ elif tz_string.startswith("'") and tz_string.endswith("'"):
542
+ tz_string = proxy_string[1:-1]
543
+ tzone = tz_string
544
+ platform_var = None
545
+ if (
546
+ "platform" not in kwargs
547
+ and "plat" not in kwargs
548
+ and "--platform" in arg_join
549
+ ):
550
+ count = 0
551
+ for arg in sys_argv:
552
+ if arg.startswith("--platform="):
553
+ platform_var = arg.split("--platform=")[1]
554
+ break
555
+ elif arg == "--platform" and len(sys_argv) > count + 1:
556
+ platform_var = sys_argv[count + 1]
557
+ if platform_var.startswith("-"):
558
+ platform_var = None
559
+ break
560
+ count += 1
561
+ if platform_var:
562
+ if platform_var.startswith('"') and platform_var.endswith('"'):
563
+ platform_var = platform_var[1:-1]
564
+ elif platform_var.startswith("'") and platform_var.endswith("'"):
565
+ platform_var = platform_var[1:-1]
321
566
  if IS_LINUX and not headless and not headed and not xvfb:
322
567
  xvfb = True # The default setting on Linux
323
- __activate_virtual_display_as_needed(headless, headed, xvfb, xvfb_metrics)
568
+ if not host or not port:
569
+ # The browser hasn't been launched yet. (May need a virtual display)
570
+ __activate_virtual_display_as_needed(
571
+ headless, headed, xvfb, xvfb_metrics
572
+ )
324
573
  if proxy and "@" in str(proxy):
325
574
  user_with_pass = proxy.split("@")[0]
326
575
  if ":" in user_with_pass:
@@ -338,17 +587,70 @@ async def start(
338
587
  proxy_scheme,
339
588
  )
340
589
  if ad_block:
590
+ sb_config.ad_block_on = True
341
591
  incognito = False
342
592
  guest = False
343
593
  ad_block_zip = AD_BLOCK_ZIP_PATH
344
594
  ad_block_dir = os.path.join(DOWNLOADS_FOLDER, "ad_block")
345
595
  __unzip_to_new_folder(ad_block_zip, ad_block_dir)
346
596
  extension_dir = __add_chrome_ext_dir(extension_dir, ad_block_dir)
347
- if (
348
- "binary_location" in kwargs
349
- and not browser_executable_path
350
- ):
597
+ if disable_csp:
598
+ sb_config.disable_csp = True
599
+ if "binary_location" in kwargs and not browser_executable_path:
351
600
  browser_executable_path = kwargs["binary_location"]
601
+ if not browser_executable_path:
602
+ browser = None
603
+ if "browser" in kwargs:
604
+ browser = kwargs["browser"]
605
+ if not browser and "--browser" in arg_join:
606
+ br_string = None
607
+ if "--browser=" in arg_join:
608
+ br_string = arg_join.split("--browser=")[1].split(" ")[0]
609
+ elif "--browser " in arg_join:
610
+ br_string = arg_join.split("--browser ")[1].split(" ")[0]
611
+ if br_string:
612
+ if br_string.startswith('"') and br_string.endswith('"'):
613
+ br_string = proxy_string[1:-1]
614
+ elif br_string.startswith("'") and br_string.endswith("'"):
615
+ br_string = proxy_string[1:-1]
616
+ browser = br_string
617
+ if not browser:
618
+ if "--edge" in sys_argv:
619
+ browser = "edge"
620
+ elif "--opera" in sys_argv:
621
+ browser = "opera"
622
+ elif "--brave" in sys_argv:
623
+ browser = "brave"
624
+ elif "--comet" in sys_argv:
625
+ browser = "comet"
626
+ elif "--atlas" in sys_argv:
627
+ browser = "atlas"
628
+ else:
629
+ browser = "chrome"
630
+ sb_config._cdp_browser = browser
631
+ if browser == "comet" or browser == "atlas":
632
+ incognito = False
633
+ guest = False
634
+ with suppress(Exception):
635
+ browser_binary = detect_b_ver.get_binary_location(browser)
636
+ if browser_binary and os.path.exists(browser_binary):
637
+ browser_executable_path = browser_binary
638
+ else:
639
+ bin_loc = str(browser_executable_path).lower()
640
+ if bin_loc.endswith("opera") or bin_loc.endswith("opera.exe"):
641
+ sb_config._cdp_browser = "opera"
642
+ elif bin_loc.endswith("edge") or bin_loc.endswith("edge.exe"):
643
+ sb_config._cdp_browser = "edge"
644
+ elif bin_loc.endswith("brave") or bin_loc.endswith("brave.exe"):
645
+ sb_config._cdp_browser = "brave"
646
+ elif bin_loc.endswith("comet") or bin_loc.endswith("comet.exe"):
647
+ sb_config._cdp_browser = "comet"
648
+ elif bin_loc.endswith("atlas") or bin_loc.endswith("atlas.exe"):
649
+ sb_config._cdp_browser = "atlas"
650
+ else:
651
+ sb_config._cdp_browser = "chrome"
652
+ sb_config.incognito = incognito
653
+ sb_config.guest_mode = guest
352
654
  if not config:
353
655
  config = Config(
354
656
  user_data_dir,
@@ -404,29 +706,18 @@ async def start(
404
706
  sb_config._cdp_platform = kwargs["platform"]
405
707
  elif "plat" in kwargs:
406
708
  sb_config._cdp_platform = kwargs["plat"]
709
+ elif platform_var:
710
+ sb_config._cdp_platform = platform_var
407
711
  else:
408
712
  sb_config._cdp_platform = None
713
+ driver.page = driver.main_tab
714
+ driver.solve_captcha = driver.page.solve_captcha
409
715
  return driver
410
716
 
411
717
 
412
718
  async def start_async(*args, **kwargs) -> Browser:
413
- headless = False
414
- binary_location = None
415
- if "browser_executable_path" in kwargs:
416
- binary_location = kwargs["browser_executable_path"]
417
- if binary_location and isinstance(binary_location, str):
418
- binary_location = binary_location.strip()
419
- else:
420
- binary_location = detect_b_ver.get_binary_location("google-chrome")
421
- if binary_location and isinstance(binary_location, str):
422
- binary_location = binary_location.strip()
423
- if not os.path.exists(binary_location):
424
- binary_location = None
425
- if (
426
- shared_utils.is_chrome_130_or_newer(binary_location)
427
- and "user_data_dir" in kwargs
428
- and kwargs["user_data_dir"]
429
- ):
719
+ if "user_data_dir" in kwargs and kwargs["user_data_dir"]:
720
+ headless = False
430
721
  if "headless" in kwargs:
431
722
  headless = kwargs["headless"]
432
723
  decoy_args = kwargs
@@ -450,38 +741,14 @@ def start_sync(*args, **kwargs) -> Browser:
450
741
  loop = kwargs["loop"]
451
742
  else:
452
743
  loop = asyncio.new_event_loop()
453
- headless = False
454
- binary_location = None
455
- if "browser_executable_path" in kwargs:
456
- binary_location = kwargs["browser_executable_path"]
457
- if binary_location and isinstance(binary_location, str):
458
- binary_location = binary_location.strip()
459
- else:
460
- binary_location = detect_b_ver.get_binary_location("google-chrome")
461
- if binary_location and isinstance(binary_location, str):
462
- binary_location = binary_location.strip()
463
- if not os.path.exists(binary_location):
464
- binary_location = None
465
- if (
466
- shared_utils.is_chrome_130_or_newer(binary_location)
467
- and "user_data_dir" in kwargs
468
- and kwargs["user_data_dir"]
469
- ):
470
- if "headless" in kwargs:
471
- headless = kwargs["headless"]
472
- decoy_args = kwargs
473
- decoy_args["headless"] = True
474
- driver = loop.run_until_complete(start(**decoy_args))
475
- kwargs["headless"] = headless
476
- kwargs["user_data_dir"] = driver.config.user_data_dir
477
- time.sleep(0.2)
478
- driver.stop() # Due to Chrome-130, must stop & start
479
- time.sleep(0.1)
480
744
  return loop.run_until_complete(start(*args, **kwargs))
481
745
 
482
746
 
483
747
  async def create_from_driver(driver) -> Browser:
484
- """Create a Browser instance from a running driver instance."""
748
+ """Create a CDP Browser instance from a running UC driver.
749
+ This method is DEPRECATED in favor of activate_cdp_mode(),
750
+ which includes the option of switching between the modes,
751
+ and also properly handles configuration based on options."""
485
752
  from .config import Config
486
753
 
487
754
  conf = Config()