Skip to content

Commit fbf2143

Browse files
committed
Update CDP Mode
1 parent 916bdb1 commit fbf2143

File tree

5 files changed

+75
-20
lines changed

5 files changed

+75
-20
lines changed

examples/cdp_mode/ReadMe.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ sb.cdp.go_back()
384384
sb.cdp.go_forward()
385385
sb.cdp.get_navigation_history()
386386
sb.cdp.tile_windows(windows=None, max_columns=0)
387+
sb.cdp.grant_permissions(permissions, origin=None)
388+
sb.cdp.grant_all_permissions()
387389
sb.cdp.get_all_cookies(*args, **kwargs)
388390
sb.cdp.set_all_cookies(*args, **kwargs)
389391
sb.cdp.save_cookies(*args, **kwargs)

seleniumbase/core/browser_launcher.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,8 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
679679
cdp.go_forward = CDPM.go_forward
680680
cdp.get_navigation_history = CDPM.get_navigation_history
681681
cdp.tile_windows = CDPM.tile_windows
682+
cdp.grant_permissions = CDPM.grant_permissions
683+
cdp.grant_all_permissions = CDPM.grant_all_permissions
682684
cdp.get_all_cookies = CDPM.get_all_cookies
683685
cdp.set_all_cookies = CDPM.set_all_cookies
684686
cdp.save_cookies = CDPM.save_cookies
@@ -2144,6 +2146,7 @@ def _set_chrome_options(
21442146
prefs["download.prompt_for_download"] = False
21452147
prefs["download_bubble.partial_view_enabled"] = False
21462148
prefs["credentials_enable_service"] = False
2149+
prefs["autofill.credit_card_enabled"] = False
21472150
prefs["local_discovery.notifications_enabled"] = False
21482151
prefs["safebrowsing.enabled"] = False # Prevent PW "data breach" pop-ups
21492152
prefs["safebrowsing.disable_download_protection"] = True
@@ -4002,6 +4005,7 @@ def get_local_driver(
40024005
"download.directory_upgrade": True,
40034006
"download.prompt_for_download": False,
40044007
"credentials_enable_service": False,
4008+
"autofill.credit_card_enabled": False,
40054009
"local_discovery.notifications_enabled": False,
40064010
"safebrowsing.disable_download_protection": True,
40074011
"safebrowsing.enabled": False, # Prevent PW "data breach" pop-ups

seleniumbase/core/sb_cdp.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,23 @@ def tile_windows(self, windows=None, max_columns=0):
645645
driver.tile_windows(windows, max_columns)
646646
)
647647

648+
def grant_permissions(self, permissions, origin=None):
649+
"""Grant specific permissions to the current window.
650+
Applies to all origins if no origin is specified."""
651+
driver = self.driver
652+
if hasattr(driver, "cdp_base"):
653+
driver = driver.cdp_base
654+
return self.loop.run_until_complete(
655+
driver.grant_permissions(permissions, origin)
656+
)
657+
658+
def grant_all_permissions(self):
659+
"""Grant all permissions to the current window for all origins."""
660+
driver = self.driver
661+
if hasattr(driver, "cdp_base"):
662+
driver = driver.cdp_base
663+
return self.loop.run_until_complete(driver.grant_all_permissions())
664+
648665
def get_all_cookies(self, *args, **kwargs):
649666
driver = self.driver
650667
if hasattr(driver, "cdp_base"):
@@ -681,9 +698,7 @@ def clear_cookies(self):
681698
driver = self.driver
682699
if hasattr(driver, "cdp_base"):
683700
driver = driver.cdp_base
684-
return self.loop.run_until_complete(
685-
driver.cookies.clear()
686-
)
701+
return self.loop.run_until_complete(driver.cookies.clear())
687702

688703
def sleep(self, seconds):
689704
time.sleep(seconds)
@@ -702,9 +717,7 @@ def get_active_element_css(self):
702717

703718
js_code = active_css_js.get_active_element_css
704719
js_code = js_code.replace("return getBestSelector", "getBestSelector")
705-
return self.loop.run_until_complete(
706-
self.page.evaluate(js_code)
707-
)
720+
return self.loop.run_until_complete(self.page.evaluate(js_code))
708721

709722
def click(self, selector, timeout=None):
710723
if not timeout:
@@ -978,17 +991,13 @@ def evaluate(self, expression):
978991
"\n".join(exp_list[0:-1]) + "\n"
979992
+ exp_list[-1].strip()[len("return "):]
980993
).strip()
981-
return self.loop.run_until_complete(
982-
self.page.evaluate(expression)
983-
)
994+
return self.loop.run_until_complete(self.page.evaluate(expression))
984995

985996
def js_dumps(self, obj_name):
986997
"""Similar to evaluate(), but for dictionary results."""
987998
if obj_name.startswith("return "):
988999
obj_name = obj_name[len("return "):]
989-
return self.loop.run_until_complete(
990-
self.page.js_dumps(obj_name)
991-
)
1000+
return self.loop.run_until_complete(self.page.js_dumps(obj_name))
9921001

9931002
def maximize(self):
9941003
if self.get_window()[1].window_state.value == "maximized":
@@ -1309,6 +1318,8 @@ def get_element_attributes(self, selector):
13091318
)
13101319

13111320
def get_element_attribute(self, selector, attribute):
1321+
"""Find an element and return the value of an attribute.
1322+
Raises an exception if there's no such element or attribute."""
13121323
attributes = self.get_element_attributes(selector)
13131324
with suppress(Exception):
13141325
return attributes[attribute]
@@ -1319,6 +1330,9 @@ def get_element_attribute(self, selector, attribute):
13191330
return value
13201331

13211332
def get_attribute(self, selector, attribute):
1333+
"""Find an element and return the value of an attribute.
1334+
If the element doesn't exist: Raises an exception.
1335+
If the attribute doesn't exist: Returns None."""
13221336
return self.find_element(selector).get_attribute(attribute)
13231337

13241338
def get_element_html(self, selector):

seleniumbase/fixtures/base_case.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1910,7 +1910,10 @@ def get_attribute(
19101910
timeout = self.__get_new_timeout(timeout)
19111911
selector, by = self.__recalculate_selector(selector, by)
19121912
if self.__is_cdp_swap_needed():
1913-
return self.cdp.get_element_attribute(selector, attribute)
1913+
if hard_fail:
1914+
return self.cdp.get_element_attribute(selector, attribute)
1915+
else:
1916+
return self.cdp.get_attribute(selector, attribute)
19141917
self.wait_for_ready_state_complete()
19151918
time.sleep(0.01)
19161919
if self.__is_shadow_selector(selector):

seleniumbase/undetected/cdp_driver/browser.py

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import warnings
1717
from collections import defaultdict
1818
from seleniumbase import config as sb_config
19-
from typing import List, Set, Tuple, Union
19+
from typing import List, Optional, Required, Set, Tuple, Union
2020
import mycdp as cdp
2121
from . import cdp_util as util
2222
from . import tab
@@ -504,10 +504,22 @@ async def start(self=None) -> Browser:
504504
# self.connection.handlers[cdp.inspector.Detached] = [self.stop]
505505
# return self
506506

507+
async def grant_permissions(
508+
self,
509+
permissions: Required[List[str] | str],
510+
origin: Optional[str] = None,
511+
):
512+
"""Grant specific permissions to the current window.
513+
Applies to all origins if no origin is specified."""
514+
if isinstance(permissions, str):
515+
permissions = [permissions]
516+
await self.connection.send(
517+
cdp.browser.grant_permissions(permissions, origin)
518+
)
519+
507520
async def grant_all_permissions(self):
508521
"""
509522
Grant permissions for:
510-
accessibilityEvents
511523
audioCapture
512524
backgroundSync
513525
backgroundFetch
@@ -524,19 +536,39 @@ async def grant_all_permissions(self):
524536
notifications
525537
paymentHandler
526538
periodicBackgroundSync
527-
protectedMediaIdentifier
528539
sensors
529540
storageAccess
530541
topLevelStorageAccess
531542
videoCapture
532-
videoCapturePanTiltZoom
533543
wakeLockScreen
534544
wakeLockSystem
535545
windowManagement
536546
"""
537-
permissions = list(cdp.browser.PermissionType)
538-
permissions.remove(cdp.browser.PermissionType.FLASH)
539-
permissions.remove(cdp.browser.PermissionType.CAPTURED_SURFACE_CONTROL)
547+
permissions = [
548+
"audioCapture",
549+
"backgroundSync",
550+
"backgroundFetch",
551+
"clipboardReadWrite",
552+
"clipboardSanitizedWrite",
553+
"displayCapture",
554+
"durableStorage",
555+
"geolocation",
556+
"idleDetection",
557+
"localFonts",
558+
"midi",
559+
"midiSysex",
560+
"nfc",
561+
"notifications",
562+
"paymentHandler",
563+
"periodicBackgroundSync",
564+
"sensors",
565+
"storageAccess",
566+
"topLevelStorageAccess",
567+
"videoCapture",
568+
"wakeLockScreen",
569+
"wakeLockSystem",
570+
"windowManagement",
571+
]
540572
await self.connection.send(cdp.browser.grant_permissions(permissions))
541573

542574
async def tile_windows(self, windows=None, max_columns: int = 0):

0 commit comments

Comments
 (0)