Skip to content

Commit 2140462

Browse files
CopilotP4X-ng
andcommitted
Update CDP protocol to latest upstream spec with 2 new domains and new API endpoints
Co-authored-by: P4X-ng <223870169+P4X-ng@users.noreply.github.com>
1 parent a2ca12b commit 2140462

28 files changed

+5309
-877
lines changed

cdp/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@
5252
import cdp.schema
5353
import cdp.security
5454
import cdp.service_worker
55+
import cdp.smart_card_emulation
5556
import cdp.storage
5657
import cdp.system_info
5758
import cdp.target
5859
import cdp.tethering
5960
import cdp.tracing
6061
import cdp.web_audio
6162
import cdp.web_authn
63+
import cdp.web_mcp

cdp/audits.py

Lines changed: 227 additions & 75 deletions
Large diffs are not rendered by default.

cdp/browser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ class PermissionType(enum.Enum):
119119
IDLE_DETECTION = "idleDetection"
120120
KEYBOARD_LOCK = "keyboardLock"
121121
LOCAL_FONTS = "localFonts"
122+
LOCAL_NETWORK = "localNetwork"
122123
LOCAL_NETWORK_ACCESS = "localNetworkAccess"
124+
LOOPBACK_NETWORK = "loopbackNetwork"
123125
MIDI = "midi"
124126
MIDI_SYSEX = "midiSysex"
125127
NFC = "nfc"

cdp/css.py

Lines changed: 138 additions & 107 deletions
Large diffs are not rendered by default.

cdp/dom.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ def __repr__(self):
4747
return 'BackendNodeId({})'.format(super().__repr__())
4848

4949

50+
class StyleSheetId(str):
51+
r'''
52+
Unique identifier for a CSS stylesheet.
53+
'''
54+
def to_json(self) -> str:
55+
return self
56+
57+
@classmethod
58+
def from_json(cls, json: str) -> StyleSheetId:
59+
return cls(json)
60+
61+
def __repr__(self):
62+
return 'StyleSheetId({})'.format(super().__repr__())
63+
64+
5065
@dataclass
5166
class BackendNode:
5267
r'''
@@ -120,7 +135,6 @@ class PseudoType(enum.Enum):
120135
PICKER = "picker"
121136
PERMISSION_ICON = "permission-icon"
122137
OVERSCROLL_AREA_PARENT = "overscroll-area-parent"
123-
OVERSCROLL_CLIENT_AREA = "overscroll-client-area"
124138

125139
def to_json(self) -> str:
126140
return self.value
@@ -315,6 +329,10 @@ class Node:
315329

316330
affected_by_starting_styles: typing.Optional[bool] = None
317331

332+
adopted_style_sheets: typing.Optional[typing.List[StyleSheetId]] = None
333+
334+
is_ad_related: typing.Optional[bool] = None
335+
318336
def to_json(self) -> T_JSON_DICT:
319337
json: T_JSON_DICT = dict()
320338
json['nodeId'] = self.node_id.to_json()
@@ -377,6 +395,10 @@ def to_json(self) -> T_JSON_DICT:
377395
json['isScrollable'] = self.is_scrollable
378396
if self.affected_by_starting_styles is not None:
379397
json['affectedByStartingStyles'] = self.affected_by_starting_styles
398+
if self.adopted_style_sheets is not None:
399+
json['adoptedStyleSheets'] = [i.to_json() for i in self.adopted_style_sheets]
400+
if self.is_ad_related is not None:
401+
json['isAdRelated'] = self.is_ad_related
380402
return json
381403

382404
@classmethod
@@ -415,6 +437,8 @@ def from_json(cls, json: T_JSON_DICT) -> Node:
415437
assigned_slot=BackendNode.from_json(json['assignedSlot']) if 'assignedSlot' in json else None,
416438
is_scrollable=bool(json['isScrollable']) if 'isScrollable' in json else None,
417439
affected_by_starting_styles=bool(json['affectedByStartingStyles']) if 'affectedByStartingStyles' in json else None,
440+
adopted_style_sheets=[StyleSheetId.from_json(i) for i in json['adoptedStyleSheets']] if 'adoptedStyleSheets' in json else None,
441+
is_ad_related=bool(json['isAdRelated']) if 'isAdRelated' in json else None,
418442
)
419443

420444

@@ -1874,6 +1898,27 @@ def from_json(cls, json: T_JSON_DICT) -> AttributeModified:
18741898
)
18751899

18761900

1901+
@event_class('DOM.adoptedStyleSheetsModified')
1902+
@dataclass
1903+
class AdoptedStyleSheetsModified:
1904+
r'''
1905+
**EXPERIMENTAL**
1906+
1907+
Fired when ``Element``'s adoptedStyleSheets are modified.
1908+
'''
1909+
#: Id of the node that has changed.
1910+
node_id: NodeId
1911+
#: New adoptedStyleSheets array.
1912+
adopted_style_sheets: typing.List[StyleSheetId]
1913+
1914+
@classmethod
1915+
def from_json(cls, json: T_JSON_DICT) -> AdoptedStyleSheetsModified:
1916+
return cls(
1917+
node_id=NodeId.from_json(json['nodeId']),
1918+
adopted_style_sheets=[StyleSheetId.from_json(i) for i in json['adoptedStyleSheets']]
1919+
)
1920+
1921+
18771922
@event_class('DOM.attributeRemoved')
18781923
@dataclass
18791924
class AttributeRemoved:
@@ -2085,6 +2130,27 @@ def from_json(cls, json: T_JSON_DICT) -> ScrollableFlagUpdated:
20852130
)
20862131

20872132

2133+
@event_class('DOM.adRelatedStateUpdated')
2134+
@dataclass
2135+
class AdRelatedStateUpdated:
2136+
r'''
2137+
**EXPERIMENTAL**
2138+
2139+
Fired when a node's ad related state changes.
2140+
'''
2141+
#: The id of the node.
2142+
node_id: NodeId
2143+
#: If the node is ad related.
2144+
is_ad_related: bool
2145+
2146+
@classmethod
2147+
def from_json(cls, json: T_JSON_DICT) -> AdRelatedStateUpdated:
2148+
return cls(
2149+
node_id=NodeId.from_json(json['nodeId']),
2150+
is_ad_related=bool(json['isAdRelated'])
2151+
)
2152+
2153+
20882154
@event_class('DOM.affectedByStartingStylesFlagUpdated')
20892155
@dataclass
20902156
class AffectedByStartingStylesFlagUpdated:

cdp/emulation.py

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ class DisabledImageType(enum.Enum):
616616
Enum of image types that can be disabled.
617617
'''
618618
AVIF = "avif"
619+
JXL = "jxl"
619620
WEBP = "webp"
620621

621622
def to_json(self) -> str:
@@ -783,7 +784,9 @@ def set_device_metrics_override(
783784
screen_orientation: typing.Optional[ScreenOrientation] = None,
784785
viewport: typing.Optional[page.Viewport] = None,
785786
display_feature: typing.Optional[DisplayFeature] = None,
786-
device_posture: typing.Optional[DevicePosture] = None
787+
device_posture: typing.Optional[DevicePosture] = None,
788+
scrollbar_type: typing.Optional[str] = None,
789+
screen_orientation_lock_emulation: typing.Optional[bool] = None
787790
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
788791
r'''
789792
Overrides the values of device screen dimensions (window.screen.width, window.screen.height,
@@ -804,6 +807,8 @@ def set_device_metrics_override(
804807
:param viewport: **(EXPERIMENTAL)** *(Optional)* If set, the visible area of the page will be overridden to this viewport. This viewport change is not observed by the page, e.g. viewport-relative elements do not change positions.
805808
:param display_feature: **(DEPRECATED)** **(EXPERIMENTAL)** *(Optional)* If set, the display feature of a multi-segment screen. If not set, multi-segment support is turned-off. Deprecated, use Emulation.setDisplayFeaturesOverride.
806809
:param device_posture: **(DEPRECATED)** **(EXPERIMENTAL)** *(Optional)* If set, the posture of a foldable device. If not set the posture is set to continuous. Deprecated, use Emulation.setDevicePostureOverride.
810+
:param scrollbar_type: **(EXPERIMENTAL)** *(Optional)* Scrollbar type. Default: ```default```.
811+
:param screen_orientation_lock_emulation: **(EXPERIMENTAL)** *(Optional)* If set to true, enables screen orientation lock emulation, which intercepts screen.orientation.lock() calls from the page and reports orientation changes via screenOrientationLockChanged events. This is useful for emulating mobile device orientation lock behavior in responsive design mode.
807812
'''
808813
params: T_JSON_DICT = dict()
809814
params['width'] = width
@@ -830,6 +835,10 @@ def set_device_metrics_override(
830835
params['displayFeature'] = display_feature.to_json()
831836
if device_posture is not None:
832837
params['devicePosture'] = device_posture.to_json()
838+
if scrollbar_type is not None:
839+
params['scrollbarType'] = scrollbar_type
840+
if screen_orientation_lock_emulation is not None:
841+
params['screenOrientationLockEmulation'] = screen_orientation_lock_emulation
833842
cmd_dict: T_JSON_DICT = {
834843
'method': 'Emulation.setDeviceMetricsOverride',
835844
'params': params,
@@ -1560,7 +1569,8 @@ def set_small_viewport_height_difference_override(
15601569

15611570
def get_screen_infos() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[ScreenInfo]]:
15621571
r'''
1563-
Returns device's screen configuration.
1572+
Returns device's screen configuration. In headful mode, the physical screens configuration is returned,
1573+
whereas in headless mode, a virtual headless screen configuration is provided instead.
15641574
15651575
**EXPERIMENTAL**
15661576
@@ -1627,6 +1637,67 @@ def add_screen(
16271637
return ScreenInfo.from_json(json['screenInfo'])
16281638

16291639

1640+
def update_screen(
1641+
screen_id: ScreenId,
1642+
left: typing.Optional[int] = None,
1643+
top: typing.Optional[int] = None,
1644+
width: typing.Optional[int] = None,
1645+
height: typing.Optional[int] = None,
1646+
work_area_insets: typing.Optional[WorkAreaInsets] = None,
1647+
device_pixel_ratio: typing.Optional[float] = None,
1648+
rotation: typing.Optional[int] = None,
1649+
color_depth: typing.Optional[int] = None,
1650+
label: typing.Optional[str] = None,
1651+
is_internal: typing.Optional[bool] = None
1652+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,ScreenInfo]:
1653+
r'''
1654+
Updates specified screen parameters. Only supported in headless mode.
1655+
1656+
**EXPERIMENTAL**
1657+
1658+
:param screen_id: Target screen identifier.
1659+
:param left: *(Optional)* Offset of the left edge of the screen in pixels.
1660+
:param top: *(Optional)* Offset of the top edge of the screen in pixels.
1661+
:param width: *(Optional)* The width of the screen in pixels.
1662+
:param height: *(Optional)* The height of the screen in pixels.
1663+
:param work_area_insets: *(Optional)* Specifies the screen's work area.
1664+
:param device_pixel_ratio: *(Optional)* Specifies the screen's device pixel ratio.
1665+
:param rotation: *(Optional)* Specifies the screen's rotation angle. Available values are 0, 90, 180 and 270.
1666+
:param color_depth: *(Optional)* Specifies the screen's color depth in bits.
1667+
:param label: *(Optional)* Specifies the descriptive label for the screen.
1668+
:param is_internal: *(Optional)* Indicates whether the screen is internal to the device or external, attached to the device. Default is false.
1669+
:returns:
1670+
'''
1671+
params: T_JSON_DICT = dict()
1672+
params['screenId'] = screen_id.to_json()
1673+
if left is not None:
1674+
params['left'] = left
1675+
if top is not None:
1676+
params['top'] = top
1677+
if width is not None:
1678+
params['width'] = width
1679+
if height is not None:
1680+
params['height'] = height
1681+
if work_area_insets is not None:
1682+
params['workAreaInsets'] = work_area_insets.to_json()
1683+
if device_pixel_ratio is not None:
1684+
params['devicePixelRatio'] = device_pixel_ratio
1685+
if rotation is not None:
1686+
params['rotation'] = rotation
1687+
if color_depth is not None:
1688+
params['colorDepth'] = color_depth
1689+
if label is not None:
1690+
params['label'] = label
1691+
if is_internal is not None:
1692+
params['isInternal'] = is_internal
1693+
cmd_dict: T_JSON_DICT = {
1694+
'method': 'Emulation.updateScreen',
1695+
'params': params,
1696+
}
1697+
json = yield cmd_dict
1698+
return ScreenInfo.from_json(json['screenInfo'])
1699+
1700+
16301701
def remove_screen(
16311702
screen_id: ScreenId
16321703
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
@@ -1646,6 +1717,28 @@ def remove_screen(
16461717
json = yield cmd_dict
16471718

16481719

1720+
def set_primary_screen(
1721+
screen_id: ScreenId
1722+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
1723+
r'''
1724+
Set primary screen. Only supported in headless mode.
1725+
Note that this changes the coordinate system origin to the top-left
1726+
of the new primary screen, updating the bounds and work areas
1727+
of all existing screens accordingly.
1728+
1729+
**EXPERIMENTAL**
1730+
1731+
:param screen_id:
1732+
'''
1733+
params: T_JSON_DICT = dict()
1734+
params['screenId'] = screen_id.to_json()
1735+
cmd_dict: T_JSON_DICT = {
1736+
'method': 'Emulation.setPrimaryScreen',
1737+
'params': params,
1738+
}
1739+
json = yield cmd_dict
1740+
1741+
16491742
@event_class('Emulation.virtualTimeBudgetExpired')
16501743
@dataclass
16511744
class VirtualTimeBudgetExpired:
@@ -1661,3 +1754,26 @@ def from_json(cls, json: T_JSON_DICT) -> VirtualTimeBudgetExpired:
16611754
return cls(
16621755

16631756
)
1757+
1758+
1759+
@event_class('Emulation.screenOrientationLockChanged')
1760+
@dataclass
1761+
class ScreenOrientationLockChanged:
1762+
r'''
1763+
**EXPERIMENTAL**
1764+
1765+
Fired when a page calls screen.orientation.lock() or screen.orientation.unlock()
1766+
while device emulation is enabled. This allows the DevTools frontend to update the
1767+
emulated device orientation accordingly.
1768+
'''
1769+
#: Whether the screen orientation is currently locked.
1770+
locked: bool
1771+
#: The orientation lock type requested by the page. Only set when locked is true.
1772+
orientation: typing.Optional[ScreenOrientation]
1773+
1774+
@classmethod
1775+
def from_json(cls, json: T_JSON_DICT) -> ScreenOrientationLockChanged:
1776+
return cls(
1777+
locked=bool(json['locked']),
1778+
orientation=ScreenOrientation.from_json(json['orientation']) if 'orientation' in json else None
1779+
)

0 commit comments

Comments
 (0)