diff --git a/chromewhip/protocol/accessibility.py b/chromewhip/protocol/accessibility.py index 5e68567..9db27d4 100644 --- a/chromewhip/protocol/accessibility.py +++ b/chromewhip/protocol/accessibility.py @@ -67,7 +67,7 @@ def __init__(self, # AXProperty: class AXProperty(ChromeTypeBase): def __init__(self, - name: Union['str'], + name: Union['AXPropertyName'], value: Union['AXValue'], ): @@ -90,20 +90,8 @@ def __init__(self, self.sources = sources -# AXGlobalStates: States which apply to every AX node. -AXGlobalStates = str - -# AXLiveRegionAttributes: Attributes which apply to nodes in live regions. -AXLiveRegionAttributes = str - -# AXWidgetAttributes: Attributes which apply to widgets. -AXWidgetAttributes = str - -# AXWidgetStates: States which apply to widgets. -AXWidgetStates = str - -# AXRelationshipAttributes: Relationships between elements other than parent/child/sibling. -AXRelationshipAttributes = str +# AXPropertyName: Values of AXProperty name: from 'busy' to 'roledescription' - states which apply to every AXnode, from 'live' to 'root' - attributes which apply to nodes in live regions, from'autocomplete' to 'valuetext' - attributes which apply to widgets, from 'checked' to 'selected'- states which apply to widgets, from 'activedescendant' to 'owns' - relationships betweenelements other than parent/child/sibling. +AXPropertyName = str # AXNode: A node in the accessibility tree. class AXNode(ChromeTypeBase): diff --git a/chromewhip/protocol/animation.py b/chromewhip/protocol/animation.py index d978de8..0025995 100644 --- a/chromewhip/protocol/animation.py +++ b/chromewhip/protocol/animation.py @@ -94,16 +94,6 @@ def __init__(self, class Animation(PayloadMixin): """ """ - @classmethod - def enable(cls): - """Enables animation domain notifications. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - @classmethod def disable(cls): """Disables animation domain notifications. @@ -115,31 +105,11 @@ def disable(cls): ) @classmethod - def getPlaybackRate(cls): - """Gets the playback rate of the document timeline. - """ - return ( - cls.build_send_payload("getPlaybackRate", { - }), - cls.convert_payload({ - "playbackRate": { - "class": float, - "optional": False - }, - }) - ) - - @classmethod - def setPlaybackRate(cls, - playbackRate: Union['float'], - ): - """Sets the playback rate of the document timeline. - :param playbackRate: Playback rate for animations on page - :type playbackRate: float + def enable(cls): + """Enables animation domain notifications. """ return ( - cls.build_send_payload("setPlaybackRate", { - "playbackRate": playbackRate, + cls.build_send_payload("enable", { }), None ) @@ -165,45 +135,53 @@ def getCurrentTime(cls, ) @classmethod - def setPaused(cls, - animations: Union['[]'], - paused: Union['bool'], - ): - """Sets the paused state of a set of animations. - :param animations: Animations to set the pause state of. + def getPlaybackRate(cls): + """Gets the playback rate of the document timeline. + """ + return ( + cls.build_send_payload("getPlaybackRate", { + }), + cls.convert_payload({ + "playbackRate": { + "class": float, + "optional": False + }, + }) + ) + + @classmethod + def releaseAnimations(cls, + animations: Union['[]'], + ): + """Releases a set of animations to no longer be manipulated. + :param animations: List of animation ids to seek. :type animations: [] - :param paused: Paused state to set to. - :type paused: bool """ return ( - cls.build_send_payload("setPaused", { + cls.build_send_payload("releaseAnimations", { "animations": animations, - "paused": paused, }), None ) @classmethod - def setTiming(cls, - animationId: Union['str'], - duration: Union['float'], - delay: Union['float'], - ): - """Sets the timing of an animation node. + def resolveAnimation(cls, + animationId: Union['str'], + ): + """Gets the remote object of the Animation. :param animationId: Animation id. :type animationId: str - :param duration: Duration of the animation. - :type duration: float - :param delay: Delay of the animation. - :type delay: float """ return ( - cls.build_send_payload("setTiming", { + cls.build_send_payload("resolveAnimation", { "animationId": animationId, - "duration": duration, - "delay": delay, }), - None + cls.convert_payload({ + "remoteObject": { + "class": Runtime.RemoteObject, + "optional": False + }, + }) ) @classmethod @@ -226,45 +204,67 @@ def seekAnimations(cls, ) @classmethod - def releaseAnimations(cls, - animations: Union['[]'], - ): - """Releases a set of animations to no longer be manipulated. - :param animations: List of animation ids to seek. + def setPaused(cls, + animations: Union['[]'], + paused: Union['bool'], + ): + """Sets the paused state of a set of animations. + :param animations: Animations to set the pause state of. :type animations: [] + :param paused: Paused state to set to. + :type paused: bool """ return ( - cls.build_send_payload("releaseAnimations", { + cls.build_send_payload("setPaused", { "animations": animations, + "paused": paused, }), None ) @classmethod - def resolveAnimation(cls, - animationId: Union['str'], - ): - """Gets the remote object of the Animation. + def setPlaybackRate(cls, + playbackRate: Union['float'], + ): + """Sets the playback rate of the document timeline. + :param playbackRate: Playback rate for animations on page + :type playbackRate: float + """ + return ( + cls.build_send_payload("setPlaybackRate", { + "playbackRate": playbackRate, + }), + None + ) + + @classmethod + def setTiming(cls, + animationId: Union['str'], + duration: Union['float'], + delay: Union['float'], + ): + """Sets the timing of an animation node. :param animationId: Animation id. :type animationId: str + :param duration: Duration of the animation. + :type duration: float + :param delay: Delay of the animation. + :type delay: float """ return ( - cls.build_send_payload("resolveAnimation", { + cls.build_send_payload("setTiming", { "animationId": animationId, + "duration": duration, + "delay": delay, }), - cls.convert_payload({ - "remoteObject": { - "class": Runtime.RemoteObject, - "optional": False - }, - }) + None ) -class AnimationCreatedEvent(BaseEvent): +class AnimationCanceledEvent(BaseEvent): - js_name = 'Animation.animationCreated' + js_name = 'Animation.animationCanceled' hashable = ['id'] is_hashable = True @@ -285,21 +285,21 @@ def build_hash(cls, id): return h -class AnimationStartedEvent(BaseEvent): +class AnimationCreatedEvent(BaseEvent): - js_name = 'Animation.animationStarted' - hashable = ['animationId'] + js_name = 'Animation.animationCreated' + hashable = ['id'] is_hashable = True def __init__(self, - animation: Union['Animation', dict], + id: Union['str', dict], ): - if isinstance(animation, dict): - animation = Animation(**animation) - self.animation = animation + if isinstance(id, dict): + id = str(**id) + self.id = id @classmethod - def build_hash(cls, animationId): + def build_hash(cls, id): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -308,21 +308,21 @@ def build_hash(cls, animationId): return h -class AnimationCanceledEvent(BaseEvent): +class AnimationStartedEvent(BaseEvent): - js_name = 'Animation.animationCanceled' - hashable = ['id'] + js_name = 'Animation.animationStarted' + hashable = ['animationId'] is_hashable = True def __init__(self, - id: Union['str', dict], + animation: Union['Animation', dict], ): - if isinstance(id, dict): - id = str(**id) - self.id = id + if isinstance(animation, dict): + animation = Animation(**animation) + self.animation = animation @classmethod - def build_hash(cls, id): + def build_hash(cls, animationId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) diff --git a/chromewhip/protocol/applicationcache.py b/chromewhip/protocol/applicationcache.py index 207afc5..f9c3fc9 100644 --- a/chromewhip/protocol/applicationcache.py +++ b/chromewhip/protocol/applicationcache.py @@ -60,28 +60,49 @@ class ApplicationCache(PayloadMixin): """ """ @classmethod - def getFramesWithManifests(cls): - """Returns array of frame identifiers with manifest urls for each frame containing a document associated with some application cache. + def enable(cls): + """Enables application cache domain notifications. """ return ( - cls.build_send_payload("getFramesWithManifests", { + cls.build_send_payload("enable", { + }), + None + ) + + @classmethod + def getApplicationCacheForFrame(cls, + frameId: Union['Page.FrameId'], + ): + """Returns relevant application cache data for the document in given frame. + :param frameId: Identifier of the frame containing document whose application cache is retrieved. + :type frameId: Page.FrameId + """ + return ( + cls.build_send_payload("getApplicationCacheForFrame", { + "frameId": frameId, }), cls.convert_payload({ - "frameIds": { - "class": [FrameWithManifest], + "applicationCache": { + "class": ApplicationCache, "optional": False }, }) ) @classmethod - def enable(cls): - """Enables application cache domain notifications. + def getFramesWithManifests(cls): + """Returns array of frame identifiers with manifest urls for each frame containing a document +associated with some application cache. """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("getFramesWithManifests", { }), - None + cls.convert_payload({ + "frameIds": { + "class": [FrameWithManifest], + "optional": False + }, + }) ) @classmethod @@ -104,26 +125,6 @@ def getManifestForFrame(cls, }) ) - @classmethod - def getApplicationCacheForFrame(cls, - frameId: Union['Page.FrameId'], - ): - """Returns relevant application cache data for the document in given frame. - :param frameId: Identifier of the frame containing document whose application cache is retrieved. - :type frameId: Page.FrameId - """ - return ( - cls.build_send_payload("getApplicationCacheForFrame", { - "frameId": frameId, - }), - cls.convert_payload({ - "applicationCache": { - "class": ApplicationCache, - "optional": False - }, - }) - ) - class ApplicationCacheStatusUpdatedEvent(BaseEvent): diff --git a/chromewhip/protocol/audits.py b/chromewhip/protocol/audits.py index 4a8be73..b6f9894 100644 --- a/chromewhip/protocol/audits.py +++ b/chromewhip/protocol/audits.py @@ -24,7 +24,8 @@ def getEncodedResponse(cls, quality: Optional['float'] = None, sizeOnly: Optional['bool'] = None, ): - """Returns the response body and size if it were re-encoded with the specified settings. Only applies to images. + """Returns the response body and size if it were re-encoded with the specified settings. Only +applies to images. :param requestId: Identifier of the network request to get content for. :type requestId: Network.RequestId :param encoding: The encoding to use. diff --git a/chromewhip/protocol/browser.py b/chromewhip/protocol/browser.py index 682e971..320623d 100644 --- a/chromewhip/protocol/browser.py +++ b/chromewhip/protocol/browser.py @@ -36,6 +36,34 @@ def __init__(self, self.windowState = windowState +# Bucket: Chrome histogram bucket. +class Bucket(ChromeTypeBase): + def __init__(self, + low: Union['int'], + high: Union['int'], + count: Union['int'], + ): + + self.low = low + self.high = high + self.count = count + + +# Histogram: Chrome histogram. +class Histogram(ChromeTypeBase): + def __init__(self, + name: Union['str'], + sum: Union['int'], + count: Union['int'], + buckets: Union['[Bucket]'], + ): + + self.name = name + self.sum = sum + self.count = count + self.buckets = buckets + + class Browser(PayloadMixin): """ The Browser domain defines methods and events for browser managing. """ @@ -49,30 +77,6 @@ def close(cls): None ) - @classmethod - def getWindowForTarget(cls, - targetId: Union['Target.TargetID'], - ): - """Get the browser window that contains the devtools target. - :param targetId: Devtools agent host id. - :type targetId: Target.TargetID - """ - return ( - cls.build_send_payload("getWindowForTarget", { - "targetId": targetId, - }), - cls.convert_payload({ - "windowId": { - "class": WindowID, - "optional": False - }, - "bounds": { - "class": Bounds, - "optional": False - }, - }) - ) - @classmethod def getVersion(cls): """Returns version information. @@ -105,22 +109,45 @@ def getVersion(cls): ) @classmethod - def setWindowBounds(cls, - windowId: Union['WindowID'], - bounds: Union['Bounds'], - ): - """Set position and/or size of the browser window. - :param windowId: Browser window id. - :type windowId: WindowID - :param bounds: New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged. - :type bounds: Bounds + def getHistograms(cls, + query: Optional['str'] = None, + ): + """Get Chrome histograms. + :param query: Requested substring in name. Only histograms which have query as a +substring in their name are extracted. An empty or absent query returns +all histograms. + :type query: str """ return ( - cls.build_send_payload("setWindowBounds", { - "windowId": windowId, - "bounds": bounds, + cls.build_send_payload("getHistograms", { + "query": query, }), - None + cls.convert_payload({ + "histograms": { + "class": [Histogram], + "optional": False + }, + }) + ) + + @classmethod + def getHistogram(cls, + name: Union['str'], + ): + """Get a Chrome histogram by name. + :param name: Requested histogram name. + :type name: str + """ + return ( + cls.build_send_payload("getHistogram", { + "name": name, + }), + cls.convert_payload({ + "histogram": { + "class": Histogram, + "optional": False + }, + }) ) @classmethod @@ -143,3 +170,47 @@ def getWindowBounds(cls, }) ) + @classmethod + def getWindowForTarget(cls, + targetId: Union['Target.TargetID'], + ): + """Get the browser window that contains the devtools target. + :param targetId: Devtools agent host id. + :type targetId: Target.TargetID + """ + return ( + cls.build_send_payload("getWindowForTarget", { + "targetId": targetId, + }), + cls.convert_payload({ + "windowId": { + "class": WindowID, + "optional": False + }, + "bounds": { + "class": Bounds, + "optional": False + }, + }) + ) + + @classmethod + def setWindowBounds(cls, + windowId: Union['WindowID'], + bounds: Union['Bounds'], + ): + """Set position and/or size of the browser window. + :param windowId: Browser window id. + :type windowId: WindowID + :param bounds: New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined +with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged. + :type bounds: Bounds + """ + return ( + cls.build_send_payload("setWindowBounds", { + "windowId": windowId, + "bounds": bounds, + }), + None + ) + diff --git a/chromewhip/protocol/cachestorage.py b/chromewhip/protocol/cachestorage.py index 79e99c4..6d3bbbb 100644 --- a/chromewhip/protocol/cachestorage.py +++ b/chromewhip/protocol/cachestorage.py @@ -73,58 +73,6 @@ def __init__(self, class CacheStorage(PayloadMixin): """ """ - @classmethod - def requestCacheNames(cls, - securityOrigin: Union['str'], - ): - """Requests cache names. - :param securityOrigin: Security origin. - :type securityOrigin: str - """ - return ( - cls.build_send_payload("requestCacheNames", { - "securityOrigin": securityOrigin, - }), - cls.convert_payload({ - "caches": { - "class": [Cache], - "optional": False - }, - }) - ) - - @classmethod - def requestEntries(cls, - cacheId: Union['CacheId'], - skipCount: Union['int'], - pageSize: Union['int'], - ): - """Requests data from cache. - :param cacheId: ID of cache to get entries from. - :type cacheId: CacheId - :param skipCount: Number of records to skip. - :type skipCount: int - :param pageSize: Number of records to fetch. - :type pageSize: int - """ - return ( - cls.build_send_payload("requestEntries", { - "cacheId": cacheId, - "skipCount": skipCount, - "pageSize": pageSize, - }), - cls.convert_payload({ - "cacheDataEntries": { - "class": [DataEntry], - "optional": False - }, - "hasMore": { - "class": bool, - "optional": False - }, - }) - ) - @classmethod def deleteCache(cls, cacheId: Union['CacheId'], @@ -159,6 +107,26 @@ def deleteEntry(cls, None ) + @classmethod + def requestCacheNames(cls, + securityOrigin: Union['str'], + ): + """Requests cache names. + :param securityOrigin: Security origin. + :type securityOrigin: str + """ + return ( + cls.build_send_payload("requestCacheNames", { + "securityOrigin": securityOrigin, + }), + cls.convert_payload({ + "caches": { + "class": [Cache], + "optional": False + }, + }) + ) + @classmethod def requestCachedResponse(cls, cacheId: Union['CacheId'], @@ -183,3 +151,35 @@ def requestCachedResponse(cls, }) ) + @classmethod + def requestEntries(cls, + cacheId: Union['CacheId'], + skipCount: Union['int'], + pageSize: Union['int'], + ): + """Requests data from cache. + :param cacheId: ID of cache to get entries from. + :type cacheId: CacheId + :param skipCount: Number of records to skip. + :type skipCount: int + :param pageSize: Number of records to fetch. + :type pageSize: int + """ + return ( + cls.build_send_payload("requestEntries", { + "cacheId": cacheId, + "skipCount": skipCount, + "pageSize": pageSize, + }), + cls.convert_payload({ + "cacheDataEntries": { + "class": [DataEntry], + "optional": False + }, + "hasMore": { + "class": bool, + "optional": False + }, + }) + ) + diff --git a/chromewhip/protocol/console.py b/chromewhip/protocol/console.py index 43ff90c..e45e6ce 100644 --- a/chromewhip/protocol/console.py +++ b/chromewhip/protocol/console.py @@ -37,11 +37,11 @@ class Console(PayloadMixin): """ This domain is deprecated - use Runtime or Log instead. """ @classmethod - def enable(cls): - """Enables console domain, sends the messages collected so far to the client by means of the messageAdded notification. + def clearMessages(cls): + """Does nothing. """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("clearMessages", { }), None ) @@ -57,11 +57,12 @@ def disable(cls): ) @classmethod - def clearMessages(cls): - """Does nothing. + def enable(cls): + """Enables console domain, sends the messages collected so far to the client by means of the +`messageAdded` notification. """ return ( - cls.build_send_payload("clearMessages", { + cls.build_send_payload("enable", { }), None ) diff --git a/chromewhip/protocol/css.py b/chromewhip/protocol/css.py index cf744ff..9c65b8c 100644 --- a/chromewhip/protocol/css.py +++ b/chromewhip/protocol/css.py @@ -17,7 +17,7 @@ # StyleSheetId: StyleSheetId = str -# StyleSheetOrigin: Stylesheet type: "injected" for stylesheets injected via extension, "user-agent" for user-agent stylesheets, "inspector" for stylesheets created by the inspector (i.e. those holding the "via inspector" rules), "regular" for regular stylesheets. +# StyleSheetOrigin: Stylesheet type: "injected" for stylesheets injected via extension, "user-agent" for user-agentstylesheets, "inspector" for stylesheets created by the inspector (i.e. those holding the "viainspector" rules), "regular" for regular stylesheets. StyleSheetOrigin = str # PseudoElementMatches: CSS rule collection for a single pseudo style. @@ -319,16 +319,80 @@ def __init__(self, class CSS(PayloadMixin): - """ This domain exposes CSS read/write operations. All CSS objects (stylesheets, rules, and styles) have an associated id used in subsequent operations on the related object. Each object type has a specific id structure, and those are not interchangeable between objects of different kinds. CSS objects can be loaded using the get*ForNode() calls (which accept a DOM node id). A client can also keep track of stylesheets via the styleSheetAdded/styleSheetRemoved events and subsequently load the required stylesheet contents using the getStyleSheet[Text]() methods. + """ This domain exposes CSS read/write operations. All CSS objects (stylesheets, rules, and styles) +have an associated `id` used in subsequent operations on the related object. Each object type has +a specific `id` structure, and those are not interchangeable between objects of different kinds. +CSS objects can be loaded using the `get*ForNode()` calls (which accept a DOM node id). A client +can also keep track of stylesheets via the `styleSheetAdded`/`styleSheetRemoved` events and +subsequently load the required stylesheet contents using the `getStyleSheet[Text]()` methods. """ @classmethod - def enable(cls): - """Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been enabled until the result of this command is received. + def addRule(cls, + styleSheetId: Union['StyleSheetId'], + ruleText: Union['str'], + location: Union['SourceRange'], + ): + """Inserts a new rule with the given `ruleText` in a stylesheet with given `styleSheetId`, at the +position specified by `location`. + :param styleSheetId: The css style sheet identifier where a new rule should be inserted. + :type styleSheetId: StyleSheetId + :param ruleText: The text of a new rule. + :type ruleText: str + :param location: Text position of a new rule in the target style sheet. + :type location: SourceRange """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("addRule", { + "styleSheetId": styleSheetId, + "ruleText": ruleText, + "location": location, }), - None + cls.convert_payload({ + "rule": { + "class": CSSRule, + "optional": False + }, + }) + ) + + @classmethod + def collectClassNames(cls, + styleSheetId: Union['StyleSheetId'], + ): + """Returns all class names from specified stylesheet. + :param styleSheetId: + :type styleSheetId: StyleSheetId + """ + return ( + cls.build_send_payload("collectClassNames", { + "styleSheetId": styleSheetId, + }), + cls.convert_payload({ + "classNames": { + "class": [], + "optional": False + }, + }) + ) + + @classmethod + def createStyleSheet(cls, + frameId: Union['Page.FrameId'], + ): + """Creates a new special "via-inspector" stylesheet in the frame with given `frameId`. + :param frameId: Identifier of the frame where "via-inspector" stylesheet should be created. + :type frameId: Page.FrameId + """ + return ( + cls.build_send_payload("createStyleSheet", { + "frameId": frameId, + }), + cls.convert_payload({ + "styleSheetId": { + "class": StyleSheetId, + "optional": False + }, + }) ) @classmethod @@ -342,41 +406,84 @@ def disable(cls): ) @classmethod - def getMatchedStylesForNode(cls, - nodeId: Union['DOM.NodeId'], - ): - """Returns requested styles for a DOM node identified by nodeId. - :param nodeId: + def enable(cls): + """Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been +enabled until the result of this command is received. + """ + return ( + cls.build_send_payload("enable", { + }), + None + ) + + @classmethod + def forcePseudoState(cls, + nodeId: Union['DOM.NodeId'], + forcedPseudoClasses: Union['[]'], + ): + """Ensures that the given node will have specified pseudo-classes whenever its style is computed by +the browser. + :param nodeId: The element id for which to force the pseudo state. :type nodeId: DOM.NodeId + :param forcedPseudoClasses: Element pseudo classes to force when computing the element's style. + :type forcedPseudoClasses: [] """ return ( - cls.build_send_payload("getMatchedStylesForNode", { + cls.build_send_payload("forcePseudoState", { + "nodeId": nodeId, + "forcedPseudoClasses": forcedPseudoClasses, + }), + None + ) + + @classmethod + def getBackgroundColors(cls, + nodeId: Union['DOM.NodeId'], + ): + """ + :param nodeId: Id of the node to get background colors for. + :type nodeId: DOM.NodeId + """ + return ( + cls.build_send_payload("getBackgroundColors", { "nodeId": nodeId, }), cls.convert_payload({ - "inlineStyle": { - "class": CSSStyle, - "optional": True - }, - "attributesStyle": { - "class": CSSStyle, + "backgroundColors": { + "class": [], "optional": True }, - "matchedCSSRules": { - "class": [RuleMatch], + "computedFontSize": { + "class": str, "optional": True }, - "pseudoElements": { - "class": [PseudoElementMatches], + "computedFontWeight": { + "class": str, "optional": True }, - "inherited": { - "class": [InheritedStyleEntry], + "computedBodyFontSize": { + "class": str, "optional": True }, - "cssKeyframesRules": { - "class": [CSSKeyframesRule], - "optional": True + }) + ) + + @classmethod + def getComputedStyleForNode(cls, + nodeId: Union['DOM.NodeId'], + ): + """Returns the computed style for a DOM node identified by `nodeId`. + :param nodeId: + :type nodeId: DOM.NodeId + """ + return ( + cls.build_send_payload("getComputedStyleForNode", { + "nodeId": nodeId, + }), + cls.convert_payload({ + "computedStyle": { + "class": [CSSComputedStyleProperty], + "optional": False }, }) ) @@ -385,7 +492,8 @@ def getMatchedStylesForNode(cls, def getInlineStylesForNode(cls, nodeId: Union['DOM.NodeId'], ): - """Returns the styles defined inline (explicitly in the "style" attribute and implicitly, using DOM attributes) for a DOM node identified by nodeId. + """Returns the styles defined inline (explicitly in the "style" attribute and implicitly, using DOM +attributes) for a DOM node identified by `nodeId`. :param nodeId: :type nodeId: DOM.NodeId """ @@ -406,20 +514,55 @@ def getInlineStylesForNode(cls, ) @classmethod - def getComputedStyleForNode(cls, + def getMatchedStylesForNode(cls, nodeId: Union['DOM.NodeId'], ): - """Returns the computed style for a DOM node identified by nodeId. + """Returns requested styles for a DOM node identified by `nodeId`. :param nodeId: :type nodeId: DOM.NodeId """ return ( - cls.build_send_payload("getComputedStyleForNode", { + cls.build_send_payload("getMatchedStylesForNode", { "nodeId": nodeId, }), cls.convert_payload({ - "computedStyle": { - "class": [CSSComputedStyleProperty], + "inlineStyle": { + "class": CSSStyle, + "optional": True + }, + "attributesStyle": { + "class": CSSStyle, + "optional": True + }, + "matchedCSSRules": { + "class": [RuleMatch], + "optional": True + }, + "pseudoElements": { + "class": [PseudoElementMatches], + "optional": True + }, + "inherited": { + "class": [InheritedStyleEntry], + "optional": True + }, + "cssKeyframesRules": { + "class": [CSSKeyframesRule], + "optional": True + }, + }) + ) + + @classmethod + def getMediaQueries(cls): + """Returns all media queries parsed by the rendering engine. + """ + return ( + cls.build_send_payload("getMediaQueries", { + }), + cls.convert_payload({ + "medias": { + "class": [CSSMedia], "optional": False }, }) @@ -429,7 +572,8 @@ def getComputedStyleForNode(cls, def getPlatformFontsForNode(cls, nodeId: Union['DOM.NodeId'], ): - """Requests information about platform fonts which we used to render child TextNodes in the given node. + """Requests information about platform fonts which we used to render child TextNodes in the given +node. :param nodeId: :type nodeId: DOM.NodeId """ @@ -466,75 +610,27 @@ def getStyleSheetText(cls, ) @classmethod - def collectClassNames(cls, - styleSheetId: Union['StyleSheetId'], - ): - """Returns all class names from specified stylesheet. - :param styleSheetId: - :type styleSheetId: StyleSheetId - """ - return ( - cls.build_send_payload("collectClassNames", { - "styleSheetId": styleSheetId, - }), - cls.convert_payload({ - "classNames": { - "class": [], - "optional": False - }, - }) - ) - - @classmethod - def setStyleSheetText(cls, - styleSheetId: Union['StyleSheetId'], - text: Union['str'], - ): - """Sets the new stylesheet text. - :param styleSheetId: - :type styleSheetId: StyleSheetId - :param text: - :type text: str - """ - return ( - cls.build_send_payload("setStyleSheetText", { - "styleSheetId": styleSheetId, - "text": text, - }), - cls.convert_payload({ - "sourceMapURL": { - "class": str, - "optional": True - }, - }) - ) - - @classmethod - def setRuleSelector(cls, - styleSheetId: Union['StyleSheetId'], - range: Union['SourceRange'], - selector: Union['str'], - ): - """Modifies the rule selector. - :param styleSheetId: - :type styleSheetId: StyleSheetId - :param range: - :type range: SourceRange - :param selector: - :type selector: str + def setEffectivePropertyValueForNode(cls, + nodeId: Union['DOM.NodeId'], + propertyName: Union['str'], + value: Union['str'], + ): + """Find a rule with the given active property for the given node and set the new value for this +property + :param nodeId: The element id for which to set property. + :type nodeId: DOM.NodeId + :param propertyName: + :type propertyName: str + :param value: + :type value: str """ return ( - cls.build_send_payload("setRuleSelector", { - "styleSheetId": styleSheetId, - "range": range, - "selector": selector, + cls.build_send_payload("setEffectivePropertyValueForNode", { + "nodeId": nodeId, + "propertyName": propertyName, + "value": value, }), - cls.convert_payload({ - "selectorList": { - "class": SelectorList, - "optional": False - }, - }) + None ) @classmethod @@ -565,26 +661,6 @@ def setKeyframeKey(cls, }) ) - @classmethod - def setStyleTexts(cls, - edits: Union['[StyleDeclarationEdit]'], - ): - """Applies specified style edits one after another in the given order. - :param edits: - :type edits: [StyleDeclarationEdit] - """ - return ( - cls.build_send_payload("setStyleTexts", { - "edits": edits, - }), - cls.convert_payload({ - "styles": { - "class": [CSSStyle], - "optional": False - }, - }) - ) - @classmethod def setMediaText(cls, styleSheetId: Union['StyleSheetId'], @@ -614,142 +690,77 @@ def setMediaText(cls, ) @classmethod - def createStyleSheet(cls, - frameId: Union['Page.FrameId'], - ): - """Creates a new special "via-inspector" stylesheet in the frame with given frameId. - :param frameId: Identifier of the frame where "via-inspector" stylesheet should be created. - :type frameId: Page.FrameId + def setRuleSelector(cls, + styleSheetId: Union['StyleSheetId'], + range: Union['SourceRange'], + selector: Union['str'], + ): + """Modifies the rule selector. + :param styleSheetId: + :type styleSheetId: StyleSheetId + :param range: + :type range: SourceRange + :param selector: + :type selector: str """ return ( - cls.build_send_payload("createStyleSheet", { - "frameId": frameId, + cls.build_send_payload("setRuleSelector", { + "styleSheetId": styleSheetId, + "range": range, + "selector": selector, }), cls.convert_payload({ - "styleSheetId": { - "class": StyleSheetId, + "selectorList": { + "class": SelectorList, "optional": False }, }) ) @classmethod - def addRule(cls, - styleSheetId: Union['StyleSheetId'], - ruleText: Union['str'], - location: Union['SourceRange'], - ): - """Inserts a new rule with the given ruleText in a stylesheet with given styleSheetId, at the position specified by location. - :param styleSheetId: The css style sheet identifier where a new rule should be inserted. + def setStyleSheetText(cls, + styleSheetId: Union['StyleSheetId'], + text: Union['str'], + ): + """Sets the new stylesheet text. + :param styleSheetId: :type styleSheetId: StyleSheetId - :param ruleText: The text of a new rule. - :type ruleText: str - :param location: Text position of a new rule in the target style sheet. - :type location: SourceRange + :param text: + :type text: str """ return ( - cls.build_send_payload("addRule", { + cls.build_send_payload("setStyleSheetText", { "styleSheetId": styleSheetId, - "ruleText": ruleText, - "location": location, + "text": text, }), cls.convert_payload({ - "rule": { - "class": CSSRule, - "optional": False + "sourceMapURL": { + "class": str, + "optional": True }, }) ) @classmethod - def forcePseudoState(cls, - nodeId: Union['DOM.NodeId'], - forcedPseudoClasses: Union['[]'], - ): - """Ensures that the given node will have specified pseudo-classes whenever its style is computed by the browser. - :param nodeId: The element id for which to force the pseudo state. - :type nodeId: DOM.NodeId - :param forcedPseudoClasses: Element pseudo classes to force when computing the element's style. - :type forcedPseudoClasses: [] - """ - return ( - cls.build_send_payload("forcePseudoState", { - "nodeId": nodeId, - "forcedPseudoClasses": forcedPseudoClasses, - }), - None - ) - - @classmethod - def getMediaQueries(cls): - """Returns all media queries parsed by the rendering engine. + def setStyleTexts(cls, + edits: Union['[StyleDeclarationEdit]'], + ): + """Applies specified style edits one after another in the given order. + :param edits: + :type edits: [StyleDeclarationEdit] """ return ( - cls.build_send_payload("getMediaQueries", { + cls.build_send_payload("setStyleTexts", { + "edits": edits, }), cls.convert_payload({ - "medias": { - "class": [CSSMedia], + "styles": { + "class": [CSSStyle], "optional": False }, }) ) - @classmethod - def setEffectivePropertyValueForNode(cls, - nodeId: Union['DOM.NodeId'], - propertyName: Union['str'], - value: Union['str'], - ): - """Find a rule with the given active property for the given node and set the new value for this property - :param nodeId: The element id for which to set property. - :type nodeId: DOM.NodeId - :param propertyName: - :type propertyName: str - :param value: - :type value: str - """ - return ( - cls.build_send_payload("setEffectivePropertyValueForNode", { - "nodeId": nodeId, - "propertyName": propertyName, - "value": value, - }), - None - ) - - @classmethod - def getBackgroundColors(cls, - nodeId: Union['DOM.NodeId'], - ): - """ - :param nodeId: Id of the node to get background colors for. - :type nodeId: DOM.NodeId - """ - return ( - cls.build_send_payload("getBackgroundColors", { - "nodeId": nodeId, - }), - cls.convert_payload({ - "backgroundColors": { - "class": [], - "optional": True - }, - "computedFontSize": { - "class": str, - "optional": True - }, - "computedFontWeight": { - "class": str, - "optional": True - }, - "computedBodyFontSize": { - "class": str, - "optional": True - }, - }) - ) - @classmethod def startRuleUsageTracking(cls): """Enables the selector recording. @@ -761,14 +772,14 @@ def startRuleUsageTracking(cls): ) @classmethod - def takeCoverageDelta(cls): - """Obtain list of rules that became used since last call to this method (or since start of coverage instrumentation) + def stopRuleUsageTracking(cls): + """The list of rules with an indication of whether these were used """ return ( - cls.build_send_payload("takeCoverageDelta", { + cls.build_send_payload("stopRuleUsageTracking", { }), cls.convert_payload({ - "coverage": { + "ruleUsage": { "class": [RuleUsage], "optional": False }, @@ -776,14 +787,15 @@ def takeCoverageDelta(cls): ) @classmethod - def stopRuleUsageTracking(cls): - """The list of rules with an indication of whether these were used + def takeCoverageDelta(cls): + """Obtain list of rules that became used since last call to this method (or since start of coverage +instrumentation) """ return ( - cls.build_send_payload("stopRuleUsageTracking", { + cls.build_send_payload("takeCoverageDelta", { }), cls.convert_payload({ - "ruleUsage": { + "coverage": { "class": [RuleUsage], "optional": False }, @@ -792,9 +804,9 @@ def stopRuleUsageTracking(cls): -class MediaQueryResultChangedEvent(BaseEvent): +class FontsUpdatedEvent(BaseEvent): - js_name = 'Css.mediaQueryResultChanged' + js_name = 'Css.fontsUpdated' hashable = [] is_hashable = False @@ -806,9 +818,9 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class FontsUpdatedEvent(BaseEvent): +class MediaQueryResultChangedEvent(BaseEvent): - js_name = 'Css.fontsUpdated' + js_name = 'Css.mediaQueryResultChanged' hashable = [] is_hashable = False @@ -820,6 +832,24 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') +class StyleSheetAddedEvent(BaseEvent): + + js_name = 'Css.styleSheetAdded' + hashable = [] + is_hashable = False + + def __init__(self, + header: Union['CSSStyleSheetHeader', dict], + ): + if isinstance(header, dict): + header = CSSStyleSheetHeader(**header) + self.header = header + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + class StyleSheetChangedEvent(BaseEvent): js_name = 'Css.styleSheetChanged' @@ -843,24 +873,6 @@ def build_hash(cls, styleSheetId): return h -class StyleSheetAddedEvent(BaseEvent): - - js_name = 'Css.styleSheetAdded' - hashable = [] - is_hashable = False - - def __init__(self, - header: Union['CSSStyleSheetHeader', dict], - ): - if isinstance(header, dict): - header = CSSStyleSheetHeader(**header) - self.header = header - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - class StyleSheetRemovedEvent(BaseEvent): js_name = 'Css.styleSheetRemoved' diff --git a/chromewhip/protocol/database.py b/chromewhip/protocol/database.py index 4db7c7c..b5608cf 100644 --- a/chromewhip/protocol/database.py +++ b/chromewhip/protocol/database.py @@ -45,16 +45,6 @@ def __init__(self, class Database(PayloadMixin): """ """ - @classmethod - def enable(cls): - """Enables database tracking, database events will now be delivered to the client. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - @classmethod def disable(cls): """Disables database tracking, prevents database events from being sent to the client. @@ -66,23 +56,13 @@ def disable(cls): ) @classmethod - def getDatabaseTableNames(cls, - databaseId: Union['DatabaseId'], - ): - """ - :param databaseId: - :type databaseId: DatabaseId + def enable(cls): + """Enables database tracking, database events will now be delivered to the client. """ return ( - cls.build_send_payload("getDatabaseTableNames", { - "databaseId": databaseId, + cls.build_send_payload("enable", { }), - cls.convert_payload({ - "tableNames": { - "class": [], - "optional": False - }, - }) + None ) @classmethod @@ -117,6 +97,26 @@ def executeSQL(cls, }) ) + @classmethod + def getDatabaseTableNames(cls, + databaseId: Union['DatabaseId'], + ): + """ + :param databaseId: + :type databaseId: DatabaseId + """ + return ( + cls.build_send_payload("getDatabaseTableNames", { + "databaseId": databaseId, + }), + cls.convert_payload({ + "tableNames": { + "class": [], + "optional": False + }, + }) + ) + class AddDatabaseEvent(BaseEvent): diff --git a/chromewhip/protocol/debugger.py b/chromewhip/protocol/debugger.py index 3385c3a..5c6549f 100644 --- a/chromewhip/protocol/debugger.py +++ b/chromewhip/protocol/debugger.py @@ -111,14 +111,24 @@ def __init__(self, class Debugger(PayloadMixin): - """ Debugger domain exposes JavaScript debugging capabilities. It allows setting and removing breakpoints, stepping through execution, exploring stack traces, etc. + """ Debugger domain exposes JavaScript debugging capabilities. It allows setting and removing +breakpoints, stepping through execution, exploring stack traces, etc. """ @classmethod - def enable(cls): - """Enables debugger for the given page. Clients should not assume that the debugging has been enabled until the result for this command is received. + def continueToLocation(cls, + location: Union['Location'], + targetCallFrames: Optional['str'] = None, + ): + """Continues execution until specific location is reached. + :param location: Location to continue to. + :type location: Location + :param targetCallFrames: + :type targetCallFrames: str """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("continueToLocation", { + "location": location, + "targetCallFrames": targetCallFrames, }), None ) @@ -134,132 +144,88 @@ def disable(cls): ) @classmethod - def setBreakpointsActive(cls, - active: Union['bool'], - ): - """Activates / deactivates all breakpoints on the page. - :param active: New value for breakpoints active state. - :type active: bool - """ - return ( - cls.build_send_payload("setBreakpointsActive", { - "active": active, - }), - None - ) - - @classmethod - def setSkipAllPauses(cls, - skip: Union['bool'], - ): - """Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc). - :param skip: New value for skip pauses state. - :type skip: bool - """ - return ( - cls.build_send_payload("setSkipAllPauses", { - "skip": skip, - }), - None - ) - - @classmethod - def setBreakpointByUrl(cls, - lineNumber: Union['int'], - url: Optional['str'] = None, - urlRegex: Optional['str'] = None, - scriptHash: Optional['str'] = None, - columnNumber: Optional['int'] = None, - condition: Optional['str'] = None, - ): - """Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this command is issued, all existing parsed scripts will have breakpoints resolved and returned in locations property. Further matching script parsing will result in subsequent breakpointResolved events issued. This logical breakpoint will survive page reloads. - :param lineNumber: Line number to set breakpoint at. - :type lineNumber: int - :param url: URL of the resources to set breakpoint on. - :type url: str - :param urlRegex: Regex pattern for the URLs of the resources to set breakpoints on. Either url or urlRegex must be specified. - :type urlRegex: str - :param scriptHash: Script hash of the resources to set breakpoint on. - :type scriptHash: str - :param columnNumber: Offset in the line to set breakpoint at. - :type columnNumber: int - :param condition: Expression to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this expression evaluates to true. - :type condition: str + def enable(cls): + """Enables debugger for the given page. Clients should not assume that the debugging has been +enabled until the result for this command is received. """ return ( - cls.build_send_payload("setBreakpointByUrl", { - "lineNumber": lineNumber, - "url": url, - "urlRegex": urlRegex, - "scriptHash": scriptHash, - "columnNumber": columnNumber, - "condition": condition, + cls.build_send_payload("enable", { }), cls.convert_payload({ - "breakpointId": { - "class": BreakpointId, - "optional": False - }, - "locations": { - "class": [Location], + "debuggerId": { + "class": Runtime.UniqueDebuggerId, "optional": False }, }) ) @classmethod - def setBreakpoint(cls, - location: Union['Location'], - condition: Optional['str'] = None, - ): - """Sets JavaScript breakpoint at a given location. - :param location: Location to set breakpoint in. - :type location: Location - :param condition: Expression to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this expression evaluates to true. - :type condition: str + def evaluateOnCallFrame(cls, + callFrameId: Union['CallFrameId'], + expression: Union['str'], + objectGroup: Optional['str'] = None, + includeCommandLineAPI: Optional['bool'] = None, + silent: Optional['bool'] = None, + returnByValue: Optional['bool'] = None, + generatePreview: Optional['bool'] = None, + throwOnSideEffect: Optional['bool'] = None, + ): + """Evaluates expression on a given call frame. + :param callFrameId: Call frame identifier to evaluate on. + :type callFrameId: CallFrameId + :param expression: Expression to evaluate. + :type expression: str + :param objectGroup: String object group name to put result into (allows rapid releasing resulting object handles +using `releaseObjectGroup`). + :type objectGroup: str + :param includeCommandLineAPI: Specifies whether command line API should be available to the evaluated expression, defaults +to false. + :type includeCommandLineAPI: bool + :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause +execution. Overrides `setPauseOnException` state. + :type silent: bool + :param returnByValue: Whether the result is expected to be a JSON object that should be sent by value. + :type returnByValue: bool + :param generatePreview: Whether preview should be generated for the result. + :type generatePreview: bool + :param throwOnSideEffect: Whether to throw an exception if side effect cannot be ruled out during evaluation. + :type throwOnSideEffect: bool """ return ( - cls.build_send_payload("setBreakpoint", { - "location": location, - "condition": condition, + cls.build_send_payload("evaluateOnCallFrame", { + "callFrameId": callFrameId, + "expression": expression, + "objectGroup": objectGroup, + "includeCommandLineAPI": includeCommandLineAPI, + "silent": silent, + "returnByValue": returnByValue, + "generatePreview": generatePreview, + "throwOnSideEffect": throwOnSideEffect, }), cls.convert_payload({ - "breakpointId": { - "class": BreakpointId, + "result": { + "class": Runtime.RemoteObject, "optional": False }, - "actualLocation": { - "class": Location, - "optional": False + "exceptionDetails": { + "class": Runtime.ExceptionDetails, + "optional": True }, }) ) - @classmethod - def removeBreakpoint(cls, - breakpointId: Union['BreakpointId'], - ): - """Removes JavaScript breakpoint. - :param breakpointId: - :type breakpointId: BreakpointId - """ - return ( - cls.build_send_payload("removeBreakpoint", { - "breakpointId": breakpointId, - }), - None - ) - @classmethod def getPossibleBreakpoints(cls, start: Union['Location'], end: Optional['Location'] = None, restrictToFunction: Optional['bool'] = None, ): - """Returns possible locations for breakpoint. scriptId in start and end range locations should be the same. + """Returns possible locations for breakpoint. scriptId in start and end range locations should be +the same. :param start: Start of range to search possible breakpoint locations in. :type start: Location - :param end: End of range to search possible breakpoint locations in (excluding). When not specified, end of scripts is used as end of range. + :param end: End of range to search possible breakpoint locations in (excluding). When not specified, end +of scripts is used as end of range. :type end: Location :param restrictToFunction: Only consider locations which are in the same (non-nested) function as start. :type restrictToFunction: bool @@ -279,72 +245,111 @@ def getPossibleBreakpoints(cls, ) @classmethod - def continueToLocation(cls, - location: Union['Location'], - targetCallFrames: Optional['str'] = None, - ): - """Continues execution until specific location is reached. - :param location: Location to continue to. - :type location: Location - :param targetCallFrames: - :type targetCallFrames: str + def getScriptSource(cls, + scriptId: Union['Runtime.ScriptId'], + ): + """Returns source for the script with given id. + :param scriptId: Id of the script to get source for. + :type scriptId: Runtime.ScriptId """ return ( - cls.build_send_payload("continueToLocation", { - "location": location, - "targetCallFrames": targetCallFrames, + cls.build_send_payload("getScriptSource", { + "scriptId": scriptId, }), - None + cls.convert_payload({ + "scriptSource": { + "class": str, + "optional": False + }, + }) ) @classmethod - def stepOver(cls): - """Steps over the statement. + def getStackTrace(cls, + stackTraceId: Union['Runtime.StackTraceId'], + ): + """Returns stack trace with given `stackTraceId`. + :param stackTraceId: + :type stackTraceId: Runtime.StackTraceId """ return ( - cls.build_send_payload("stepOver", { + cls.build_send_payload("getStackTrace", { + "stackTraceId": stackTraceId, }), - None + cls.convert_payload({ + "stackTrace": { + "class": Runtime.StackTrace, + "optional": False + }, + }) ) @classmethod - def stepInto(cls): - """Steps into the function call. + def pause(cls): + """Stops on the next JavaScript statement. """ return ( - cls.build_send_payload("stepInto", { + cls.build_send_payload("pause", { }), None ) @classmethod - def stepOut(cls): - """Steps out of the function call. + def pauseOnAsyncCall(cls, + parentStackTraceId: Union['Runtime.StackTraceId'], + ): + """ + :param parentStackTraceId: Debugger will pause when async call with given stack trace is started. + :type parentStackTraceId: Runtime.StackTraceId """ return ( - cls.build_send_payload("stepOut", { + cls.build_send_payload("pauseOnAsyncCall", { + "parentStackTraceId": parentStackTraceId, }), None ) @classmethod - def pause(cls): - """Stops on the next JavaScript statement. + def removeBreakpoint(cls, + breakpointId: Union['BreakpointId'], + ): + """Removes JavaScript breakpoint. + :param breakpointId: + :type breakpointId: BreakpointId """ return ( - cls.build_send_payload("pause", { + cls.build_send_payload("removeBreakpoint", { + "breakpointId": breakpointId, }), None ) @classmethod - def scheduleStepIntoAsync(cls): - """Steps into next scheduled async task if any is scheduled before next pause. Returns success when async task is actually scheduled, returns error if no task were scheduled or another scheduleStepIntoAsync was called. + def restartFrame(cls, + callFrameId: Union['CallFrameId'], + ): + """Restarts particular call frame from the beginning. + :param callFrameId: Call frame identifier to evaluate on. + :type callFrameId: CallFrameId """ return ( - cls.build_send_payload("scheduleStepIntoAsync", { + cls.build_send_payload("restartFrame", { + "callFrameId": callFrameId, }), - None + cls.convert_payload({ + "callFrames": { + "class": [CallFrame], + "optional": False + }, + "asyncStackTrace": { + "class": Runtime.StackTrace, + "optional": True + }, + "asyncStackTraceId": { + "class": Runtime.StackTraceId, + "optional": True + }, + }) ) @classmethod @@ -357,6 +362,19 @@ def resume(cls): None ) + @classmethod + def scheduleStepIntoAsync(cls): + """This method is deprecated - use Debugger.stepInto with breakOnAsyncCall and +Debugger.pauseOnAsyncTask instead. Steps into next scheduled async task if any is scheduled +before next pause. Returns success when async task is actually scheduled, returns error if no +task were scheduled or another scheduleStepIntoAsync was called. + """ + return ( + cls.build_send_payload("scheduleStepIntoAsync", { + }), + None + ) + @classmethod def searchInContent(cls, scriptId: Union['Runtime.ScriptId'], @@ -390,94 +408,159 @@ def searchInContent(cls, ) @classmethod - def setScriptSource(cls, - scriptId: Union['Runtime.ScriptId'], - scriptSource: Union['str'], - dryRun: Optional['bool'] = None, - ): - """Edits JavaScript source live. - :param scriptId: Id of the script to edit. + def setAsyncCallStackDepth(cls, + maxDepth: Union['int'], + ): + """Enables or disables async call stacks tracking. + :param maxDepth: Maximum depth of async call stacks. Setting to `0` will effectively disable collecting async +call stacks (default). + :type maxDepth: int + """ + return ( + cls.build_send_payload("setAsyncCallStackDepth", { + "maxDepth": maxDepth, + }), + None + ) + + @classmethod + def setBlackboxPatterns(cls, + patterns: Union['[]'], + ): + """Replace previous blackbox patterns with passed ones. Forces backend to skip stepping/pausing in +scripts with url matching one of the patterns. VM will try to leave blackboxed script by +performing 'step in' several times, finally resorting to 'step out' if unsuccessful. + :param patterns: Array of regexps that will be used to check script url for blackbox state. + :type patterns: [] + """ + return ( + cls.build_send_payload("setBlackboxPatterns", { + "patterns": patterns, + }), + None + ) + + @classmethod + def setBlackboxedRanges(cls, + scriptId: Union['Runtime.ScriptId'], + positions: Union['[ScriptPosition]'], + ): + """Makes backend skip steps in the script in blackboxed ranges. VM will try leave blacklisted +scripts by performing 'step in' several times, finally resorting to 'step out' if unsuccessful. +Positions array contains positions where blackbox state is changed. First interval isn't +blackboxed. Array should be sorted. + :param scriptId: Id of the script. :type scriptId: Runtime.ScriptId - :param scriptSource: New content of the script. - :type scriptSource: str - :param dryRun: If true the change will not actually be applied. Dry run may be used to get result description without actually modifying the code. - :type dryRun: bool + :param positions: + :type positions: [ScriptPosition] """ return ( - cls.build_send_payload("setScriptSource", { + cls.build_send_payload("setBlackboxedRanges", { "scriptId": scriptId, - "scriptSource": scriptSource, - "dryRun": dryRun, + "positions": positions, }), - cls.convert_payload({ - "callFrames": { - "class": [CallFrame], - "optional": True - }, - "stackChanged": { - "class": bool, - "optional": True - }, - "asyncStackTrace": { - "class": Runtime.StackTrace, - "optional": True - }, - "exceptionDetails": { - "class": Runtime.ExceptionDetails, - "optional": True - }, - }) + None ) @classmethod - def restartFrame(cls, - callFrameId: Union['CallFrameId'], - ): - """Restarts particular call frame from the beginning. - :param callFrameId: Call frame identifier to evaluate on. - :type callFrameId: CallFrameId + def setBreakpoint(cls, + location: Union['Location'], + condition: Optional['str'] = None, + ): + """Sets JavaScript breakpoint at a given location. + :param location: Location to set breakpoint in. + :type location: Location + :param condition: Expression to use as a breakpoint condition. When specified, debugger will only stop on the +breakpoint if this expression evaluates to true. + :type condition: str """ return ( - cls.build_send_payload("restartFrame", { - "callFrameId": callFrameId, + cls.build_send_payload("setBreakpoint", { + "location": location, + "condition": condition, }), cls.convert_payload({ - "callFrames": { - "class": [CallFrame], + "breakpointId": { + "class": BreakpointId, "optional": False }, - "asyncStackTrace": { - "class": Runtime.StackTrace, - "optional": True + "actualLocation": { + "class": Location, + "optional": False }, }) ) @classmethod - def getScriptSource(cls, - scriptId: Union['Runtime.ScriptId'], - ): - """Returns source for the script with given id. - :param scriptId: Id of the script to get source for. - :type scriptId: Runtime.ScriptId + def setBreakpointByUrl(cls, + lineNumber: Union['int'], + url: Optional['str'] = None, + urlRegex: Optional['str'] = None, + scriptHash: Optional['str'] = None, + columnNumber: Optional['int'] = None, + condition: Optional['str'] = None, + ): + """Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this +command is issued, all existing parsed scripts will have breakpoints resolved and returned in +`locations` property. Further matching script parsing will result in subsequent +`breakpointResolved` events issued. This logical breakpoint will survive page reloads. + :param lineNumber: Line number to set breakpoint at. + :type lineNumber: int + :param url: URL of the resources to set breakpoint on. + :type url: str + :param urlRegex: Regex pattern for the URLs of the resources to set breakpoints on. Either `url` or +`urlRegex` must be specified. + :type urlRegex: str + :param scriptHash: Script hash of the resources to set breakpoint on. + :type scriptHash: str + :param columnNumber: Offset in the line to set breakpoint at. + :type columnNumber: int + :param condition: Expression to use as a breakpoint condition. When specified, debugger will only stop on the +breakpoint if this expression evaluates to true. + :type condition: str """ return ( - cls.build_send_payload("getScriptSource", { - "scriptId": scriptId, + cls.build_send_payload("setBreakpointByUrl", { + "lineNumber": lineNumber, + "url": url, + "urlRegex": urlRegex, + "scriptHash": scriptHash, + "columnNumber": columnNumber, + "condition": condition, }), cls.convert_payload({ - "scriptSource": { - "class": str, + "breakpointId": { + "class": BreakpointId, + "optional": False + }, + "locations": { + "class": [Location], "optional": False }, }) ) + @classmethod + def setBreakpointsActive(cls, + active: Union['bool'], + ): + """Activates / deactivates all breakpoints on the page. + :param active: New value for breakpoints active state. + :type active: bool + """ + return ( + cls.build_send_payload("setBreakpointsActive", { + "active": active, + }), + None + ) + @classmethod def setPauseOnExceptions(cls, state: Union['str'], ): - """Defines pause on exceptions state. Can be set to stop on all exceptions, uncaught exceptions or no exceptions. Initial pause on exceptions state is none. + """Defines pause on exceptions state. Can be set to stop on all exceptions, uncaught exceptions or +no exceptions. Initial pause on exceptions state is `none`. :param state: Pause on exceptions mode. :type state: str """ @@ -489,49 +572,57 @@ def setPauseOnExceptions(cls, ) @classmethod - def evaluateOnCallFrame(cls, - callFrameId: Union['CallFrameId'], - expression: Union['str'], - objectGroup: Optional['str'] = None, - includeCommandLineAPI: Optional['bool'] = None, - silent: Optional['bool'] = None, - returnByValue: Optional['bool'] = None, - generatePreview: Optional['bool'] = None, - throwOnSideEffect: Optional['bool'] = None, - ): - """Evaluates expression on a given call frame. - :param callFrameId: Call frame identifier to evaluate on. - :type callFrameId: CallFrameId - :param expression: Expression to evaluate. - :type expression: str - :param objectGroup: String object group name to put result into (allows rapid releasing resulting object handles using releaseObjectGroup). - :type objectGroup: str - :param includeCommandLineAPI: Specifies whether command line API should be available to the evaluated expression, defaults to false. - :type includeCommandLineAPI: bool - :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides setPauseOnException state. - :type silent: bool - :param returnByValue: Whether the result is expected to be a JSON object that should be sent by value. - :type returnByValue: bool - :param generatePreview: Whether preview should be generated for the result. - :type generatePreview: bool - :param throwOnSideEffect: Whether to throw an exception if side effect cannot be ruled out during evaluation. - :type throwOnSideEffect: bool + def setReturnValue(cls, + newValue: Union['Runtime.CallArgument'], + ): + """Changes return value in top frame. Available only at return break position. + :param newValue: New return value. + :type newValue: Runtime.CallArgument + """ + return ( + cls.build_send_payload("setReturnValue", { + "newValue": newValue, + }), + None + ) + + @classmethod + def setScriptSource(cls, + scriptId: Union['Runtime.ScriptId'], + scriptSource: Union['str'], + dryRun: Optional['bool'] = None, + ): + """Edits JavaScript source live. + :param scriptId: Id of the script to edit. + :type scriptId: Runtime.ScriptId + :param scriptSource: New content of the script. + :type scriptSource: str + :param dryRun: If true the change will not actually be applied. Dry run may be used to get result +description without actually modifying the code. + :type dryRun: bool """ return ( - cls.build_send_payload("evaluateOnCallFrame", { - "callFrameId": callFrameId, - "expression": expression, - "objectGroup": objectGroup, - "includeCommandLineAPI": includeCommandLineAPI, - "silent": silent, - "returnByValue": returnByValue, - "generatePreview": generatePreview, - "throwOnSideEffect": throwOnSideEffect, + cls.build_send_payload("setScriptSource", { + "scriptId": scriptId, + "scriptSource": scriptSource, + "dryRun": dryRun, }), cls.convert_payload({ - "result": { - "class": Runtime.RemoteObject, - "optional": False + "callFrames": { + "class": [CallFrame], + "optional": True + }, + "stackChanged": { + "class": bool, + "optional": True + }, + "asyncStackTrace": { + "class": Runtime.StackTrace, + "optional": True + }, + "asyncStackTraceId": { + "class": Runtime.StackTraceId, + "optional": True }, "exceptionDetails": { "class": Runtime.ExceptionDetails, @@ -540,6 +631,21 @@ def evaluateOnCallFrame(cls, }) ) + @classmethod + def setSkipAllPauses(cls, + skip: Union['bool'], + ): + """Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc). + :param skip: New value for skip pauses state. + :type skip: bool + """ + return ( + cls.build_send_payload("setSkipAllPauses", { + "skip": skip, + }), + None + ) + @classmethod def setVariableValue(cls, scopeNumber: Union['int'], @@ -547,8 +653,10 @@ def setVariableValue(cls, newValue: Union['Runtime.CallArgument'], callFrameId: Union['CallFrameId'], ): - """Changes value of variable in a callframe. Object-based scopes are not supported and must be mutated manually. - :param scopeNumber: 0-based number of scope as was listed in scope chain. Only 'local', 'closure' and 'catch' scope types are allowed. Other scopes could be manipulated manually. + """Changes value of variable in a callframe. Object-based scopes are not supported and must be +mutated manually. + :param scopeNumber: 0-based number of scope as was listed in scope chain. Only 'local', 'closure' and 'catch' +scope types are allowed. Other scopes could be manipulated manually. :type scopeNumber: int :param variableName: Variable name. :type variableName: str @@ -568,59 +676,134 @@ def setVariableValue(cls, ) @classmethod - def setAsyncCallStackDepth(cls, - maxDepth: Union['int'], - ): - """Enables or disables async call stacks tracking. - :param maxDepth: Maximum depth of async call stacks. Setting to 0 will effectively disable collecting async call stacks (default). - :type maxDepth: int + def stepInto(cls, + breakOnAsyncCall: Optional['bool'] = None, + ): + """Steps into the function call. + :param breakOnAsyncCall: Debugger will issue additional Debugger.paused notification if any async task is scheduled +before next pause. + :type breakOnAsyncCall: bool """ return ( - cls.build_send_payload("setAsyncCallStackDepth", { - "maxDepth": maxDepth, + cls.build_send_payload("stepInto", { + "breakOnAsyncCall": breakOnAsyncCall, }), None ) @classmethod - def setBlackboxPatterns(cls, - patterns: Union['[]'], - ): - """Replace previous blackbox patterns with passed ones. Forces backend to skip stepping/pausing in scripts with url matching one of the patterns. VM will try to leave blackboxed script by performing 'step in' several times, finally resorting to 'step out' if unsuccessful. - :param patterns: Array of regexps that will be used to check script url for blackbox state. - :type patterns: [] + def stepOut(cls): + """Steps out of the function call. """ return ( - cls.build_send_payload("setBlackboxPatterns", { - "patterns": patterns, + cls.build_send_payload("stepOut", { }), None ) @classmethod - def setBlackboxedRanges(cls, - scriptId: Union['Runtime.ScriptId'], - positions: Union['[ScriptPosition]'], - ): - """Makes backend skip steps in the script in blackboxed ranges. VM will try leave blacklisted scripts by performing 'step in' several times, finally resorting to 'step out' if unsuccessful. Positions array contains positions where blackbox state is changed. First interval isn't blackboxed. Array should be sorted. - :param scriptId: Id of the script. - :type scriptId: Runtime.ScriptId - :param positions: - :type positions: [ScriptPosition] + def stepOver(cls): + """Steps over the statement. """ return ( - cls.build_send_payload("setBlackboxedRanges", { - "scriptId": scriptId, - "positions": positions, + cls.build_send_payload("stepOver", { }), None ) -class ScriptParsedEvent(BaseEvent): +class BreakpointResolvedEvent(BaseEvent): - js_name = 'Debugger.scriptParsed' + js_name = 'Debugger.breakpointResolved' + hashable = ['breakpointId'] + is_hashable = True + + def __init__(self, + breakpointId: Union['BreakpointId', dict], + location: Union['Location', dict], + ): + if isinstance(breakpointId, dict): + breakpointId = BreakpointId(**breakpointId) + self.breakpointId = breakpointId + if isinstance(location, dict): + location = Location(**location) + self.location = location + + @classmethod + def build_hash(cls, breakpointId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class PausedEvent(BaseEvent): + + js_name = 'Debugger.paused' + hashable = ['asyncStackTraceId', 'asyncCallStackTraceId'] + is_hashable = True + + def __init__(self, + callFrames: Union['[CallFrame]', dict], + reason: Union['str', dict], + data: Union['dict', dict, None] = None, + hitBreakpoints: Union['[]', dict, None] = None, + asyncStackTrace: Union['Runtime.StackTrace', dict, None] = None, + asyncStackTraceId: Union['Runtime.StackTraceId', dict, None] = None, + asyncCallStackTraceId: Union['Runtime.StackTraceId', dict, None] = None, + ): + if isinstance(callFrames, dict): + callFrames = [CallFrame](**callFrames) + self.callFrames = callFrames + if isinstance(reason, dict): + reason = str(**reason) + self.reason = reason + if isinstance(data, dict): + data = dict(**data) + self.data = data + if isinstance(hitBreakpoints, dict): + hitBreakpoints = [](**hitBreakpoints) + self.hitBreakpoints = hitBreakpoints + if isinstance(asyncStackTrace, dict): + asyncStackTrace = Runtime.StackTrace(**asyncStackTrace) + self.asyncStackTrace = asyncStackTrace + if isinstance(asyncStackTraceId, dict): + asyncStackTraceId = Runtime.StackTraceId(**asyncStackTraceId) + self.asyncStackTraceId = asyncStackTraceId + if isinstance(asyncCallStackTraceId, dict): + asyncCallStackTraceId = Runtime.StackTraceId(**asyncCallStackTraceId) + self.asyncCallStackTraceId = asyncCallStackTraceId + + @classmethod + def build_hash(cls, asyncStackTraceId, asyncCallStackTraceId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class ResumedEvent(BaseEvent): + + js_name = 'Debugger.resumed' + hashable = [] + is_hashable = False + + def __init__(self): + pass + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + +class ScriptFailedToParseEvent(BaseEvent): + + js_name = 'Debugger.scriptFailedToParse' hashable = ['executionContextId', 'scriptId'] is_hashable = True @@ -634,7 +817,6 @@ def __init__(self, executionContextId: Union['Runtime.ExecutionContextId', dict], hash: Union['str', dict], executionContextAuxData: Union['dict', dict, None] = None, - isLiveEdit: Union['bool', dict, None] = None, sourceMapURL: Union['str', dict, None] = None, hasSourceURL: Union['bool', dict, None] = None, isModule: Union['bool', dict, None] = None, @@ -668,9 +850,6 @@ def __init__(self, if isinstance(executionContextAuxData, dict): executionContextAuxData = dict(**executionContextAuxData) self.executionContextAuxData = executionContextAuxData - if isinstance(isLiveEdit, dict): - isLiveEdit = bool(**isLiveEdit) - self.isLiveEdit = isLiveEdit if isinstance(sourceMapURL, dict): sourceMapURL = str(**sourceMapURL) self.sourceMapURL = sourceMapURL @@ -697,9 +876,9 @@ def build_hash(cls, executionContextId, scriptId): return h -class ScriptFailedToParseEvent(BaseEvent): +class ScriptParsedEvent(BaseEvent): - js_name = 'Debugger.scriptFailedToParse' + js_name = 'Debugger.scriptParsed' hashable = ['executionContextId', 'scriptId'] is_hashable = True @@ -713,6 +892,7 @@ def __init__(self, executionContextId: Union['Runtime.ExecutionContextId', dict], hash: Union['str', dict], executionContextAuxData: Union['dict', dict, None] = None, + isLiveEdit: Union['bool', dict, None] = None, sourceMapURL: Union['str', dict, None] = None, hasSourceURL: Union['bool', dict, None] = None, isModule: Union['bool', dict, None] = None, @@ -746,6 +926,9 @@ def __init__(self, if isinstance(executionContextAuxData, dict): executionContextAuxData = dict(**executionContextAuxData) self.executionContextAuxData = executionContextAuxData + if isinstance(isLiveEdit, dict): + isLiveEdit = bool(**isLiveEdit) + self.isLiveEdit = isLiveEdit if isinstance(sourceMapURL, dict): sourceMapURL = str(**sourceMapURL) self.sourceMapURL = sourceMapURL @@ -770,78 +953,3 @@ def build_hash(cls, executionContextId, scriptId): h = '{}:{}'.format(cls.js_name, serialized_id_params) log.debug('generated hash = %s' % h) return h - - -class BreakpointResolvedEvent(BaseEvent): - - js_name = 'Debugger.breakpointResolved' - hashable = ['breakpointId'] - is_hashable = True - - def __init__(self, - breakpointId: Union['BreakpointId', dict], - location: Union['Location', dict], - ): - if isinstance(breakpointId, dict): - breakpointId = BreakpointId(**breakpointId) - self.breakpointId = breakpointId - if isinstance(location, dict): - location = Location(**location) - self.location = location - - @classmethod - def build_hash(cls, breakpointId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - -class PausedEvent(BaseEvent): - - js_name = 'Debugger.paused' - hashable = [] - is_hashable = False - - def __init__(self, - callFrames: Union['[CallFrame]', dict], - reason: Union['str', dict], - data: Union['dict', dict, None] = None, - hitBreakpoints: Union['[]', dict, None] = None, - asyncStackTrace: Union['Runtime.StackTrace', dict, None] = None, - ): - if isinstance(callFrames, dict): - callFrames = [CallFrame](**callFrames) - self.callFrames = callFrames - if isinstance(reason, dict): - reason = str(**reason) - self.reason = reason - if isinstance(data, dict): - data = dict(**data) - self.data = data - if isinstance(hitBreakpoints, dict): - hitBreakpoints = [](**hitBreakpoints) - self.hitBreakpoints = hitBreakpoints - if isinstance(asyncStackTrace, dict): - asyncStackTrace = Runtime.StackTrace(**asyncStackTrace) - self.asyncStackTrace = asyncStackTrace - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class ResumedEvent(BaseEvent): - - js_name = 'Debugger.resumed' - hashable = [] - is_hashable = False - - def __init__(self): - pass - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') diff --git a/chromewhip/protocol/deviceorientation.py b/chromewhip/protocol/deviceorientation.py index b2e7631..2173557 100644 --- a/chromewhip/protocol/deviceorientation.py +++ b/chromewhip/protocol/deviceorientation.py @@ -16,6 +16,16 @@ class DeviceOrientation(PayloadMixin): """ """ + @classmethod + def clearDeviceOrientationOverride(cls): + """Clears the overridden Device Orientation. + """ + return ( + cls.build_send_payload("clearDeviceOrientationOverride", { + }), + None + ) + @classmethod def setDeviceOrientationOverride(cls, alpha: Union['float'], @@ -39,13 +49,3 @@ def setDeviceOrientationOverride(cls, None ) - @classmethod - def clearDeviceOrientationOverride(cls): - """Clears the overridden Device Orientation. - """ - return ( - cls.build_send_payload("clearDeviceOrientationOverride", { - }), - None - ) - diff --git a/chromewhip/protocol/dom.py b/chromewhip/protocol/dom.py index 867fcdc..5dd3476 100644 --- a/chromewhip/protocol/dom.py +++ b/chromewhip/protocol/dom.py @@ -17,7 +17,7 @@ # NodeId: Unique DOM node identifier. NodeId = int -# BackendNodeId: Unique DOM node identifier used to reference a node that may not have been pushed to the front-end. +# BackendNodeId: Unique DOM node identifier used to reference a node that may not have been pushed to thefront-end. BackendNodeId = int # BackendNode: Backend node with a friendly name. @@ -39,7 +39,7 @@ def __init__(self, # ShadowRootType: Shadow root type. ShadowRootType = str -# Node: DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type. +# Node: DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes.DOMNode is a base node mirror type. class Node(ChromeTypeBase): def __init__(self, nodeId: Union['NodeId'], @@ -170,46 +170,97 @@ def __init__(self, class DOM(PayloadMixin): - """ This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object that has an id. This id can be used to get additional information on the Node, resolve it into the JavaScript object wrapper, etc. It is important that client receives DOM events only for the nodes that are known to the client. Backend keeps track of the nodes that were sent to the client and never sends the same node twice. It is client's responsibility to collect information about the nodes that were sent to the client.

Note that iframe owner elements will return corresponding document elements as their child nodes.

+ """ This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object +that has an `id`. This `id` can be used to get additional information on the Node, resolve it into +the JavaScript object wrapper, etc. It is important that client receives DOM events only for the +nodes that are known to the client. Backend keeps track of the nodes that were sent to the client +and never sends the same node twice. It is client's responsibility to collect information about +the nodes that were sent to the client.

Note that `iframe` owner elements will return +corresponding document elements as their child nodes.

""" @classmethod - def enable(cls): - """Enables DOM agent for the given page. + def collectClassNamesFromSubtree(cls, + nodeId: Union['NodeId'], + ): + """Collects class names for the node with given id and all of it's child nodes. + :param nodeId: Id of the node to collect class names. + :type nodeId: NodeId """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("collectClassNamesFromSubtree", { + "nodeId": nodeId, }), - None + cls.convert_payload({ + "classNames": { + "class": [], + "optional": False + }, + }) ) @classmethod - def disable(cls): - """Disables DOM agent for the given page. + def copyTo(cls, + nodeId: Union['NodeId'], + targetNodeId: Union['NodeId'], + insertBeforeNodeId: Optional['NodeId'] = None, + ): + """Creates a deep copy of the specified node and places it into the target container before the +given anchor. + :param nodeId: Id of the node to copy. + :type nodeId: NodeId + :param targetNodeId: Id of the element to drop the copy into. + :type targetNodeId: NodeId + :param insertBeforeNodeId: Drop the copy before this node (if absent, the copy becomes the last child of +`targetNodeId`). + :type insertBeforeNodeId: NodeId """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("copyTo", { + "nodeId": nodeId, + "targetNodeId": targetNodeId, + "insertBeforeNodeId": insertBeforeNodeId, }), - None + cls.convert_payload({ + "nodeId": { + "class": NodeId, + "optional": False + }, + }) ) @classmethod - def getDocument(cls, - depth: Optional['int'] = None, - pierce: Optional['bool'] = None, - ): - """Returns the root DOM node (and optionally the subtree) to the caller. - :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0. + def describeNode(cls, + nodeId: Optional['NodeId'] = None, + backendNodeId: Optional['BackendNodeId'] = None, + objectId: Optional['Runtime.RemoteObjectId'] = None, + depth: Optional['int'] = None, + pierce: Optional['bool'] = None, + ): + """Describes node given its id, does not require domain to be enabled. Does not start tracking any +objects, can be used for automation. + :param nodeId: Identifier of the node. + :type nodeId: NodeId + :param backendNodeId: Identifier of the backend node. + :type backendNodeId: BackendNodeId + :param objectId: JavaScript object id of the node wrapper. + :type objectId: Runtime.RemoteObjectId + :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the +entire subtree or provide an integer larger than 0. :type depth: int - :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false). + :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree +(default is false). :type pierce: bool """ return ( - cls.build_send_payload("getDocument", { + cls.build_send_payload("describeNode", { + "nodeId": nodeId, + "backendNodeId": backendNodeId, + "objectId": objectId, "depth": depth, "pierce": pierce, }), cls.convert_payload({ - "root": { + "node": { "class": Node, "optional": False }, @@ -217,241 +268,190 @@ def getDocument(cls, ) @classmethod - def getFlattenedDocument(cls, - depth: Optional['int'] = None, - pierce: Optional['bool'] = None, - ): - """Returns the root DOM node (and optionally the subtree) to the caller. - :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0. - :type depth: int - :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false). - :type pierce: bool + def disable(cls): + """Disables DOM agent for the given page. """ return ( - cls.build_send_payload("getFlattenedDocument", { - "depth": depth, - "pierce": pierce, + cls.build_send_payload("disable", { }), - cls.convert_payload({ - "nodes": { - "class": [Node], - "optional": False - }, - }) + None ) @classmethod - def collectClassNamesFromSubtree(cls, - nodeId: Union['NodeId'], - ): - """Collects class names for the node with given id and all of it's child nodes. - :param nodeId: Id of the node to collect class names. - :type nodeId: NodeId + def discardSearchResults(cls, + searchId: Union['str'], + ): + """Discards search results from the session with the given id. `getSearchResults` should no longer +be called for that search. + :param searchId: Unique search session identifier. + :type searchId: str """ return ( - cls.build_send_payload("collectClassNamesFromSubtree", { - "nodeId": nodeId, + cls.build_send_payload("discardSearchResults", { + "searchId": searchId, }), - cls.convert_payload({ - "classNames": { - "class": [], - "optional": False - }, - }) + None ) @classmethod - def requestChildNodes(cls, - nodeId: Union['NodeId'], - depth: Optional['int'] = None, - pierce: Optional['bool'] = None, - ): - """Requests that children of the node with given id are returned to the caller in form of setChildNodes events where not only immediate children are retrieved, but all children down to the specified depth. - :param nodeId: Id of the node to get children for. - :type nodeId: NodeId - :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0. - :type depth: int - :param pierce: Whether or not iframes and shadow roots should be traversed when returning the sub-tree (default is false). - :type pierce: bool + def enable(cls): + """Enables DOM agent for the given page. """ return ( - cls.build_send_payload("requestChildNodes", { - "nodeId": nodeId, - "depth": depth, - "pierce": pierce, + cls.build_send_payload("enable", { }), None ) @classmethod - def querySelector(cls, - nodeId: Union['NodeId'], - selector: Union['str'], - ): - """Executes querySelector on a given node. - :param nodeId: Id of the node to query upon. + def focus(cls, + nodeId: Optional['NodeId'] = None, + backendNodeId: Optional['BackendNodeId'] = None, + objectId: Optional['Runtime.RemoteObjectId'] = None, + ): + """Focuses the given element. + :param nodeId: Identifier of the node. :type nodeId: NodeId - :param selector: Selector string. - :type selector: str + :param backendNodeId: Identifier of the backend node. + :type backendNodeId: BackendNodeId + :param objectId: JavaScript object id of the node wrapper. + :type objectId: Runtime.RemoteObjectId """ return ( - cls.build_send_payload("querySelector", { + cls.build_send_payload("focus", { "nodeId": nodeId, - "selector": selector, + "backendNodeId": backendNodeId, + "objectId": objectId, }), - cls.convert_payload({ - "nodeId": { - "class": NodeId, - "optional": False - }, - }) + None ) @classmethod - def querySelectorAll(cls, - nodeId: Union['NodeId'], - selector: Union['str'], - ): - """Executes querySelectorAll on a given node. - :param nodeId: Id of the node to query upon. + def getAttributes(cls, + nodeId: Union['NodeId'], + ): + """Returns attributes for the specified node. + :param nodeId: Id of the node to retrieve attibutes for. :type nodeId: NodeId - :param selector: Selector string. - :type selector: str """ return ( - cls.build_send_payload("querySelectorAll", { + cls.build_send_payload("getAttributes", { "nodeId": nodeId, - "selector": selector, }), cls.convert_payload({ - "nodeIds": { - "class": [NodeId], + "attributes": { + "class": [], "optional": False }, }) ) @classmethod - def setNodeName(cls, - nodeId: Union['NodeId'], - name: Union['str'], + def getBoxModel(cls, + nodeId: Optional['NodeId'] = None, + backendNodeId: Optional['BackendNodeId'] = None, + objectId: Optional['Runtime.RemoteObjectId'] = None, ): - """Sets node name for a node with given id. - :param nodeId: Id of the node to set name for. + """Returns boxes for the given node. + :param nodeId: Identifier of the node. :type nodeId: NodeId - :param name: New node's name. - :type name: str + :param backendNodeId: Identifier of the backend node. + :type backendNodeId: BackendNodeId + :param objectId: JavaScript object id of the node wrapper. + :type objectId: Runtime.RemoteObjectId """ return ( - cls.build_send_payload("setNodeName", { + cls.build_send_payload("getBoxModel", { "nodeId": nodeId, - "name": name, + "backendNodeId": backendNodeId, + "objectId": objectId, }), cls.convert_payload({ - "nodeId": { - "class": NodeId, + "model": { + "class": BoxModel, "optional": False }, }) ) @classmethod - def setNodeValue(cls, - nodeId: Union['NodeId'], - value: Union['str'], - ): - """Sets node value for a node with given id. - :param nodeId: Id of the node to set value for. - :type nodeId: NodeId - :param value: New node's value. - :type value: str - """ - return ( - cls.build_send_payload("setNodeValue", { - "nodeId": nodeId, - "value": value, - }), - None - ) - - @classmethod - def removeNode(cls, - nodeId: Union['NodeId'], - ): - """Removes node with given id. - :param nodeId: Id of the node to remove. - :type nodeId: NodeId - """ - return ( - cls.build_send_payload("removeNode", { - "nodeId": nodeId, - }), - None - ) - - @classmethod - def setAttributeValue(cls, - nodeId: Union['NodeId'], - name: Union['str'], - value: Union['str'], - ): - """Sets attribute for an element with given id. - :param nodeId: Id of the element to set attribute for. - :type nodeId: NodeId - :param name: Attribute name. - :type name: str - :param value: Attribute value. - :type value: str + def getDocument(cls, + depth: Optional['int'] = None, + pierce: Optional['bool'] = None, + ): + """Returns the root DOM node (and optionally the subtree) to the caller. + :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the +entire subtree or provide an integer larger than 0. + :type depth: int + :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree +(default is false). + :type pierce: bool """ return ( - cls.build_send_payload("setAttributeValue", { - "nodeId": nodeId, - "name": name, - "value": value, + cls.build_send_payload("getDocument", { + "depth": depth, + "pierce": pierce, }), - None + cls.convert_payload({ + "root": { + "class": Node, + "optional": False + }, + }) ) @classmethod - def setAttributesAsText(cls, - nodeId: Union['NodeId'], - text: Union['str'], - name: Optional['str'] = None, - ): - """Sets attributes on element with given id. This method is useful when user edits some existing attribute value and types in several attribute name/value pairs. - :param nodeId: Id of the element to set attributes for. - :type nodeId: NodeId - :param text: Text with a number of attributes. Will parse this text using HTML parser. - :type text: str - :param name: Attribute name to replace with new attributes derived from text in case text parsed successfully. - :type name: str + def getFlattenedDocument(cls, + depth: Optional['int'] = None, + pierce: Optional['bool'] = None, + ): + """Returns the root DOM node (and optionally the subtree) to the caller. + :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the +entire subtree or provide an integer larger than 0. + :type depth: int + :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree +(default is false). + :type pierce: bool """ return ( - cls.build_send_payload("setAttributesAsText", { - "nodeId": nodeId, - "text": text, - "name": name, + cls.build_send_payload("getFlattenedDocument", { + "depth": depth, + "pierce": pierce, }), - None + cls.convert_payload({ + "nodes": { + "class": [Node], + "optional": False + }, + }) ) @classmethod - def removeAttribute(cls, - nodeId: Union['NodeId'], - name: Union['str'], - ): - """Removes attribute with given name from an element with given id. - :param nodeId: Id of the element to remove attribute from. - :type nodeId: NodeId - :param name: Name of the attribute to remove. - :type name: str + def getNodeForLocation(cls, + x: Union['int'], + y: Union['int'], + includeUserAgentShadowDOM: Optional['bool'] = None, + ): + """Returns node id at given location. + :param x: X coordinate. + :type x: int + :param y: Y coordinate. + :type y: int + :param includeUserAgentShadowDOM: False to skip to the nearest non-UA shadow root ancestor (default: false). + :type includeUserAgentShadowDOM: bool """ return ( - cls.build_send_payload("removeAttribute", { - "nodeId": nodeId, - "name": name, + cls.build_send_payload("getNodeForLocation", { + "x": x, + "y": y, + "includeUserAgentShadowDOM": includeUserAgentShadowDOM, }), - None + cls.convert_payload({ + "nodeId": { + "class": NodeId, + "optional": False + }, + }) ) @classmethod @@ -483,47 +483,20 @@ def getOuterHTML(cls, ) @classmethod - def setOuterHTML(cls, - nodeId: Union['NodeId'], - outerHTML: Union['str'], - ): - """Sets node HTML markup, returns new node id. - :param nodeId: Id of the node to set markup for. + def getRelayoutBoundary(cls, + nodeId: Union['NodeId'], + ): + """Returns the id of the nearest ancestor that is a relayout boundary. + :param nodeId: Id of the node. :type nodeId: NodeId - :param outerHTML: Outer HTML markup to set. - :type outerHTML: str """ return ( - cls.build_send_payload("setOuterHTML", { + cls.build_send_payload("getRelayoutBoundary", { "nodeId": nodeId, - "outerHTML": outerHTML, - }), - None - ) - - @classmethod - def performSearch(cls, - query: Union['str'], - includeUserAgentShadowDOM: Optional['bool'] = None, - ): - """Searches for a given string in the DOM tree. Use getSearchResults to access search results or cancelSearch to end this search session. - :param query: Plain text or query selector or XPath search query. - :type query: str - :param includeUserAgentShadowDOM: True to search in user agent shadow DOM. - :type includeUserAgentShadowDOM: bool - """ - return ( - cls.build_send_payload("performSearch", { - "query": query, - "includeUserAgentShadowDOM": includeUserAgentShadowDOM, }), cls.convert_payload({ - "searchId": { - "class": str, - "optional": False - }, - "resultCount": { - "class": int, + "nodeId": { + "class": NodeId, "optional": False }, }) @@ -535,7 +508,8 @@ def getSearchResults(cls, fromIndex: Union['int'], toIndex: Union['int'], ): - """Returns search results from given fromIndex to given toIndex from the search with the given identifier. + """Returns search results from given `fromIndex` to given `toIndex` from the search with the given +identifier. :param searchId: Unique search session identifier. :type searchId: str :param fromIndex: Start index of the search result to be returned. @@ -558,38 +532,23 @@ def getSearchResults(cls, ) @classmethod - def discardSearchResults(cls, - searchId: Union['str'], - ): - """Discards search results from the session with the given id. getSearchResults should no longer be called for that search. - :param searchId: Unique search session identifier. - :type searchId: str + def hideHighlight(cls): + """Hides any highlight. """ return ( - cls.build_send_payload("discardSearchResults", { - "searchId": searchId, + cls.build_send_payload("hideHighlight", { }), None ) @classmethod - def requestNode(cls, - objectId: Union['Runtime.RemoteObjectId'], - ): - """Requests that the node is sent to the caller given the JavaScript node object reference. All nodes that form the path from the node to the root are also sent to the client as a series of setChildNodes notifications. - :param objectId: JavaScript object id to convert into node. - :type objectId: Runtime.RemoteObjectId + def highlightNode(cls): + """Highlights DOM node. """ return ( - cls.build_send_payload("requestNode", { - "objectId": objectId, + cls.build_send_payload("highlightNode", { }), - cls.convert_payload({ - "nodeId": { - "class": NodeId, - "optional": False - }, - }) + None ) @classmethod @@ -603,23 +562,71 @@ def highlightRect(cls): ) @classmethod - def highlightNode(cls): - """Highlights DOM node. + def markUndoableState(cls): + """Marks last undoable state. """ return ( - cls.build_send_payload("highlightNode", { + cls.build_send_payload("markUndoableState", { }), None ) @classmethod - def hideHighlight(cls): - """Hides any highlight. + def moveTo(cls, + nodeId: Union['NodeId'], + targetNodeId: Union['NodeId'], + insertBeforeNodeId: Optional['NodeId'] = None, + ): + """Moves node into the new container, places it before the given anchor. + :param nodeId: Id of the node to move. + :type nodeId: NodeId + :param targetNodeId: Id of the element to drop the moved node into. + :type targetNodeId: NodeId + :param insertBeforeNodeId: Drop node before this one (if absent, the moved node becomes the last child of +`targetNodeId`). + :type insertBeforeNodeId: NodeId """ return ( - cls.build_send_payload("hideHighlight", { + cls.build_send_payload("moveTo", { + "nodeId": nodeId, + "targetNodeId": targetNodeId, + "insertBeforeNodeId": insertBeforeNodeId, }), - None + cls.convert_payload({ + "nodeId": { + "class": NodeId, + "optional": False + }, + }) + ) + + @classmethod + def performSearch(cls, + query: Union['str'], + includeUserAgentShadowDOM: Optional['bool'] = None, + ): + """Searches for a given string in the DOM tree. Use `getSearchResults` to access search results or +`cancelSearch` to end this search session. + :param query: Plain text or query selector or XPath search query. + :type query: str + :param includeUserAgentShadowDOM: True to search in user agent shadow DOM. + :type includeUserAgentShadowDOM: bool + """ + return ( + cls.build_send_payload("performSearch", { + "query": query, + "includeUserAgentShadowDOM": includeUserAgentShadowDOM, + }), + cls.convert_payload({ + "searchId": { + "class": str, + "optional": False + }, + "resultCount": { + "class": int, + "optional": False + }, + }) ) @classmethod @@ -663,87 +670,137 @@ def pushNodesByBackendIdsToFrontend(cls, ) @classmethod - def setInspectedNode(cls, + def querySelector(cls, + nodeId: Union['NodeId'], + selector: Union['str'], + ): + """Executes `querySelector` on a given node. + :param nodeId: Id of the node to query upon. + :type nodeId: NodeId + :param selector: Selector string. + :type selector: str + """ + return ( + cls.build_send_payload("querySelector", { + "nodeId": nodeId, + "selector": selector, + }), + cls.convert_payload({ + "nodeId": { + "class": NodeId, + "optional": False + }, + }) + ) + + @classmethod + def querySelectorAll(cls, nodeId: Union['NodeId'], + selector: Union['str'], ): - """Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions). - :param nodeId: DOM node id to be accessible by means of $x command line API. + """Executes `querySelectorAll` on a given node. + :param nodeId: Id of the node to query upon. + :type nodeId: NodeId + :param selector: Selector string. + :type selector: str + """ + return ( + cls.build_send_payload("querySelectorAll", { + "nodeId": nodeId, + "selector": selector, + }), + cls.convert_payload({ + "nodeIds": { + "class": [NodeId], + "optional": False + }, + }) + ) + + @classmethod + def redo(cls): + """Re-does the last undone action. + """ + return ( + cls.build_send_payload("redo", { + }), + None + ) + + @classmethod + def removeAttribute(cls, + nodeId: Union['NodeId'], + name: Union['str'], + ): + """Removes attribute with given name from an element with given id. + :param nodeId: Id of the element to remove attribute from. :type nodeId: NodeId + :param name: Name of the attribute to remove. + :type name: str """ return ( - cls.build_send_payload("setInspectedNode", { + cls.build_send_payload("removeAttribute", { "nodeId": nodeId, + "name": name, }), None ) @classmethod - def resolveNode(cls, - nodeId: Optional['NodeId'] = None, - backendNodeId: Optional['DOM.BackendNodeId'] = None, - objectGroup: Optional['str'] = None, - ): - """Resolves the JavaScript node object for a given NodeId or BackendNodeId. - :param nodeId: Id of the node to resolve. + def removeNode(cls, + nodeId: Union['NodeId'], + ): + """Removes node with given id. + :param nodeId: Id of the node to remove. :type nodeId: NodeId - :param backendNodeId: Backend identifier of the node to resolve. - :type backendNodeId: DOM.BackendNodeId - :param objectGroup: Symbolic group name that can be used to release multiple objects. - :type objectGroup: str """ return ( - cls.build_send_payload("resolveNode", { + cls.build_send_payload("removeNode", { "nodeId": nodeId, - "backendNodeId": backendNodeId, - "objectGroup": objectGroup, }), - cls.convert_payload({ - "object": { - "class": Runtime.RemoteObject, - "optional": False - }, - }) + None ) @classmethod - def getAttributes(cls, - nodeId: Union['NodeId'], - ): - """Returns attributes for the specified node. - :param nodeId: Id of the node to retrieve attibutes for. + def requestChildNodes(cls, + nodeId: Union['NodeId'], + depth: Optional['int'] = None, + pierce: Optional['bool'] = None, + ): + """Requests that children of the node with given id are returned to the caller in form of +`setChildNodes` events where not only immediate children are retrieved, but all children down to +the specified depth. + :param nodeId: Id of the node to get children for. :type nodeId: NodeId + :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the +entire subtree or provide an integer larger than 0. + :type depth: int + :param pierce: Whether or not iframes and shadow roots should be traversed when returning the sub-tree +(default is false). + :type pierce: bool """ return ( - cls.build_send_payload("getAttributes", { + cls.build_send_payload("requestChildNodes", { "nodeId": nodeId, + "depth": depth, + "pierce": pierce, }), - cls.convert_payload({ - "attributes": { - "class": [], - "optional": False - }, - }) + None ) @classmethod - def copyTo(cls, - nodeId: Union['NodeId'], - targetNodeId: Union['NodeId'], - insertBeforeNodeId: Optional['NodeId'] = None, - ): - """Creates a deep copy of the specified node and places it into the target container before the given anchor. - :param nodeId: Id of the node to copy. - :type nodeId: NodeId - :param targetNodeId: Id of the element to drop the copy into. - :type targetNodeId: NodeId - :param insertBeforeNodeId: Drop the copy before this node (if absent, the copy becomes the last child of targetNodeId). - :type insertBeforeNodeId: NodeId + def requestNode(cls, + objectId: Union['Runtime.RemoteObjectId'], + ): + """Requests that the node is sent to the caller given the JavaScript node object reference. All +nodes that form the path from the node to the root are also sent to the client as a series of +`setChildNodes` notifications. + :param objectId: JavaScript object id to convert into node. + :type objectId: Runtime.RemoteObjectId """ return ( - cls.build_send_payload("copyTo", { - "nodeId": nodeId, - "targetNodeId": targetNodeId, - "insertBeforeNodeId": insertBeforeNodeId, + cls.build_send_payload("requestNode", { + "objectId": objectId, }), cls.convert_payload({ "nodeId": { @@ -754,82 +811,77 @@ def copyTo(cls, ) @classmethod - def moveTo(cls, - nodeId: Union['NodeId'], - targetNodeId: Union['NodeId'], - insertBeforeNodeId: Optional['NodeId'] = None, - ): - """Moves node into the new container, places it before the given anchor. - :param nodeId: Id of the node to move. + def resolveNode(cls, + nodeId: Optional['NodeId'] = None, + backendNodeId: Optional['DOM.BackendNodeId'] = None, + objectGroup: Optional['str'] = None, + ): + """Resolves the JavaScript node object for a given NodeId or BackendNodeId. + :param nodeId: Id of the node to resolve. :type nodeId: NodeId - :param targetNodeId: Id of the element to drop the moved node into. - :type targetNodeId: NodeId - :param insertBeforeNodeId: Drop node before this one (if absent, the moved node becomes the last child of targetNodeId). - :type insertBeforeNodeId: NodeId + :param backendNodeId: Backend identifier of the node to resolve. + :type backendNodeId: DOM.BackendNodeId + :param objectGroup: Symbolic group name that can be used to release multiple objects. + :type objectGroup: str """ return ( - cls.build_send_payload("moveTo", { + cls.build_send_payload("resolveNode", { "nodeId": nodeId, - "targetNodeId": targetNodeId, - "insertBeforeNodeId": insertBeforeNodeId, + "backendNodeId": backendNodeId, + "objectGroup": objectGroup, }), cls.convert_payload({ - "nodeId": { - "class": NodeId, + "object": { + "class": Runtime.RemoteObject, "optional": False }, }) ) @classmethod - def undo(cls): - """Undoes the last performed action. - """ - return ( - cls.build_send_payload("undo", { - }), - None - ) - - @classmethod - def redo(cls): - """Re-does the last undone action. - """ - return ( - cls.build_send_payload("redo", { - }), - None - ) - - @classmethod - def markUndoableState(cls): - """Marks last undoable state. + def setAttributeValue(cls, + nodeId: Union['NodeId'], + name: Union['str'], + value: Union['str'], + ): + """Sets attribute for an element with given id. + :param nodeId: Id of the element to set attribute for. + :type nodeId: NodeId + :param name: Attribute name. + :type name: str + :param value: Attribute value. + :type value: str """ return ( - cls.build_send_payload("markUndoableState", { + cls.build_send_payload("setAttributeValue", { + "nodeId": nodeId, + "name": name, + "value": value, }), None ) @classmethod - def focus(cls, - nodeId: Optional['NodeId'] = None, - backendNodeId: Optional['BackendNodeId'] = None, - objectId: Optional['Runtime.RemoteObjectId'] = None, - ): - """Focuses the given element. - :param nodeId: Identifier of the node. + def setAttributesAsText(cls, + nodeId: Union['NodeId'], + text: Union['str'], + name: Optional['str'] = None, + ): + """Sets attributes on element with given id. This method is useful when user edits some existing +attribute value and types in several attribute name/value pairs. + :param nodeId: Id of the element to set attributes for. :type nodeId: NodeId - :param backendNodeId: Identifier of the backend node. - :type backendNodeId: BackendNodeId - :param objectId: JavaScript object id of the node wrapper. - :type objectId: Runtime.RemoteObjectId + :param text: Text with a number of attributes. Will parse this text using HTML parser. + :type text: str + :param name: Attribute name to replace with new attributes derived from text in case text parsed +successfully. + :type name: str """ return ( - cls.build_send_payload("focus", { + cls.build_send_payload("setAttributesAsText", { "nodeId": nodeId, - "backendNodeId": backendNodeId, - "objectId": objectId, + "text": text, + "name": name, }), None ) @@ -862,112 +914,108 @@ def setFileInputFiles(cls, ) @classmethod - def getBoxModel(cls, - nodeId: Optional['NodeId'] = None, - backendNodeId: Optional['BackendNodeId'] = None, - objectId: Optional['Runtime.RemoteObjectId'] = None, + def setInspectedNode(cls, + nodeId: Union['NodeId'], + ): + """Enables console to refer to the node with given id via $x (see Command Line API for more details +$x functions). + :param nodeId: DOM node id to be accessible by means of $x command line API. + :type nodeId: NodeId + """ + return ( + cls.build_send_payload("setInspectedNode", { + "nodeId": nodeId, + }), + None + ) + + @classmethod + def setNodeName(cls, + nodeId: Union['NodeId'], + name: Union['str'], ): - """Returns boxes for the given node. - :param nodeId: Identifier of the node. + """Sets node name for a node with given id. + :param nodeId: Id of the node to set name for. :type nodeId: NodeId - :param backendNodeId: Identifier of the backend node. - :type backendNodeId: BackendNodeId - :param objectId: JavaScript object id of the node wrapper. - :type objectId: Runtime.RemoteObjectId + :param name: New node's name. + :type name: str """ return ( - cls.build_send_payload("getBoxModel", { + cls.build_send_payload("setNodeName", { "nodeId": nodeId, - "backendNodeId": backendNodeId, - "objectId": objectId, + "name": name, }), cls.convert_payload({ - "model": { - "class": BoxModel, + "nodeId": { + "class": NodeId, "optional": False }, }) ) @classmethod - def getNodeForLocation(cls, - x: Union['int'], - y: Union['int'], - includeUserAgentShadowDOM: Optional['bool'] = None, - ): - """Returns node id at given location. - :param x: X coordinate. - :type x: int - :param y: Y coordinate. - :type y: int - :param includeUserAgentShadowDOM: False to skip to the nearest non-UA shadow root ancestor (default: false). - :type includeUserAgentShadowDOM: bool + def setNodeValue(cls, + nodeId: Union['NodeId'], + value: Union['str'], + ): + """Sets node value for a node with given id. + :param nodeId: Id of the node to set value for. + :type nodeId: NodeId + :param value: New node's value. + :type value: str + """ + return ( + cls.build_send_payload("setNodeValue", { + "nodeId": nodeId, + "value": value, + }), + None + ) + + @classmethod + def setOuterHTML(cls, + nodeId: Union['NodeId'], + outerHTML: Union['str'], + ): + """Sets node HTML markup, returns new node id. + :param nodeId: Id of the node to set markup for. + :type nodeId: NodeId + :param outerHTML: Outer HTML markup to set. + :type outerHTML: str """ return ( - cls.build_send_payload("getNodeForLocation", { - "x": x, - "y": y, - "includeUserAgentShadowDOM": includeUserAgentShadowDOM, + cls.build_send_payload("setOuterHTML", { + "nodeId": nodeId, + "outerHTML": outerHTML, }), - cls.convert_payload({ - "nodeId": { - "class": NodeId, - "optional": False - }, - }) + None ) @classmethod - def getRelayoutBoundary(cls, - nodeId: Union['NodeId'], - ): - """Returns the id of the nearest ancestor that is a relayout boundary. - :param nodeId: Id of the node. - :type nodeId: NodeId + def undo(cls): + """Undoes the last performed action. """ return ( - cls.build_send_payload("getRelayoutBoundary", { - "nodeId": nodeId, + cls.build_send_payload("undo", { }), - cls.convert_payload({ - "nodeId": { - "class": NodeId, - "optional": False - }, - }) + None ) @classmethod - def describeNode(cls, - nodeId: Optional['NodeId'] = None, - backendNodeId: Optional['BackendNodeId'] = None, - objectId: Optional['Runtime.RemoteObjectId'] = None, - depth: Optional['int'] = None, - pierce: Optional['bool'] = None, - ): - """Describes node given its id, does not require domain to be enabled. Does not start tracking any objects, can be used for automation. - :param nodeId: Identifier of the node. - :type nodeId: NodeId - :param backendNodeId: Identifier of the backend node. - :type backendNodeId: BackendNodeId - :param objectId: JavaScript object id of the node wrapper. - :type objectId: Runtime.RemoteObjectId - :param depth: The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0. - :type depth: int - :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false). - :type pierce: bool + def getFrameOwner(cls, + frameId: Union['Page.FrameId'], + ): + """Returns iframe node that owns iframe with the given domain. + :param frameId: + :type frameId: Page.FrameId """ return ( - cls.build_send_payload("describeNode", { - "nodeId": nodeId, - "backendNodeId": backendNodeId, - "objectId": objectId, - "depth": depth, - "pierce": pierce, + cls.build_send_payload("getFrameOwner", { + "frameId": frameId, }), cls.convert_payload({ - "node": { - "class": Node, + "nodeId": { + "class": NodeId, "optional": False }, }) @@ -975,47 +1023,6 @@ def describeNode(cls, -class DocumentUpdatedEvent(BaseEvent): - - js_name = 'Dom.documentUpdated' - hashable = [] - is_hashable = False - - def __init__(self): - pass - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class SetChildNodesEvent(BaseEvent): - - js_name = 'Dom.setChildNodes' - hashable = ['parentId'] - is_hashable = True - - def __init__(self, - parentId: Union['NodeId', dict], - nodes: Union['[Node]', dict], - ): - if isinstance(parentId, dict): - parentId = NodeId(**parentId) - self.parentId = parentId - if isinstance(nodes, dict): - nodes = [Node](**nodes) - self.nodes = nodes - - @classmethod - def build_hash(cls, parentId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - class AttributeModifiedEvent(BaseEvent): js_name = 'Dom.attributeModified' @@ -1074,29 +1081,6 @@ def build_hash(cls, nodeId): return h -class InlineStyleInvalidatedEvent(BaseEvent): - - js_name = 'Dom.inlineStyleInvalidated' - hashable = ['nodeIds'] - is_hashable = True - - def __init__(self, - nodeIds: Union['[NodeId]', dict], - ): - if isinstance(nodeIds, dict): - nodeIds = [NodeId](**nodeIds) - self.nodeIds = nodeIds - - @classmethod - def build_hash(cls, nodeIds): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - class CharacterDataModifiedEvent(BaseEvent): js_name = 'Dom.characterDataModified' @@ -1154,7 +1138,7 @@ def build_hash(cls, nodeId): class ChildNodeInsertedEvent(BaseEvent): js_name = 'Dom.childNodeInserted' - hashable = ['parentNodeId', 'previousNodeId'] + hashable = ['previousNodeId', 'parentNodeId'] is_hashable = True def __init__(self, @@ -1173,7 +1157,7 @@ def __init__(self, self.node = node @classmethod - def build_hash(cls, parentNodeId, previousNodeId): + def build_hash(cls, previousNodeId, parentNodeId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1185,7 +1169,7 @@ def build_hash(cls, parentNodeId, previousNodeId): class ChildNodeRemovedEvent(BaseEvent): js_name = 'Dom.childNodeRemoved' - hashable = ['parentNodeId', 'nodeId'] + hashable = ['nodeId', 'parentNodeId'] is_hashable = True def __init__(self, @@ -1200,7 +1184,7 @@ def __init__(self, self.nodeId = nodeId @classmethod - def build_hash(cls, parentNodeId, nodeId): + def build_hash(cls, nodeId, parentNodeId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1209,25 +1193,25 @@ def build_hash(cls, parentNodeId, nodeId): return h -class ShadowRootPushedEvent(BaseEvent): +class DistributedNodesUpdatedEvent(BaseEvent): - js_name = 'Dom.shadowRootPushed' - hashable = ['hostId'] + js_name = 'Dom.distributedNodesUpdated' + hashable = ['insertionPointId'] is_hashable = True def __init__(self, - hostId: Union['NodeId', dict], - root: Union['Node', dict], + insertionPointId: Union['NodeId', dict], + distributedNodes: Union['[BackendNode]', dict], ): - if isinstance(hostId, dict): - hostId = NodeId(**hostId) - self.hostId = hostId - if isinstance(root, dict): - root = Node(**root) - self.root = root + if isinstance(insertionPointId, dict): + insertionPointId = NodeId(**insertionPointId) + self.insertionPointId = insertionPointId + if isinstance(distributedNodes, dict): + distributedNodes = [BackendNode](**distributedNodes) + self.distributedNodes = distributedNodes @classmethod - def build_hash(cls, hostId): + def build_hash(cls, insertionPointId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1236,25 +1220,35 @@ def build_hash(cls, hostId): return h -class ShadowRootPoppedEvent(BaseEvent): +class DocumentUpdatedEvent(BaseEvent): - js_name = 'Dom.shadowRootPopped' - hashable = ['rootId', 'hostId'] + js_name = 'Dom.documentUpdated' + hashable = [] + is_hashable = False + + def __init__(self): + pass + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + +class InlineStyleInvalidatedEvent(BaseEvent): + + js_name = 'Dom.inlineStyleInvalidated' + hashable = ['nodeIds'] is_hashable = True def __init__(self, - hostId: Union['NodeId', dict], - rootId: Union['NodeId', dict], + nodeIds: Union['[NodeId]', dict], ): - if isinstance(hostId, dict): - hostId = NodeId(**hostId) - self.hostId = hostId - if isinstance(rootId, dict): - rootId = NodeId(**rootId) - self.rootId = rootId + if isinstance(nodeIds, dict): + nodeIds = [NodeId](**nodeIds) + self.nodeIds = nodeIds @classmethod - def build_hash(cls, rootId, hostId): + def build_hash(cls, nodeIds): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1317,25 +1311,79 @@ def build_hash(cls, parentId, pseudoElementId): return h -class DistributedNodesUpdatedEvent(BaseEvent): +class SetChildNodesEvent(BaseEvent): - js_name = 'Dom.distributedNodesUpdated' - hashable = ['insertionPointId'] + js_name = 'Dom.setChildNodes' + hashable = ['parentId'] is_hashable = True def __init__(self, - insertionPointId: Union['NodeId', dict], - distributedNodes: Union['[BackendNode]', dict], + parentId: Union['NodeId', dict], + nodes: Union['[Node]', dict], ): - if isinstance(insertionPointId, dict): - insertionPointId = NodeId(**insertionPointId) - self.insertionPointId = insertionPointId - if isinstance(distributedNodes, dict): - distributedNodes = [BackendNode](**distributedNodes) - self.distributedNodes = distributedNodes + if isinstance(parentId, dict): + parentId = NodeId(**parentId) + self.parentId = parentId + if isinstance(nodes, dict): + nodes = [Node](**nodes) + self.nodes = nodes @classmethod - def build_hash(cls, insertionPointId): + def build_hash(cls, parentId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class ShadowRootPoppedEvent(BaseEvent): + + js_name = 'Dom.shadowRootPopped' + hashable = ['hostId', 'rootId'] + is_hashable = True + + def __init__(self, + hostId: Union['NodeId', dict], + rootId: Union['NodeId', dict], + ): + if isinstance(hostId, dict): + hostId = NodeId(**hostId) + self.hostId = hostId + if isinstance(rootId, dict): + rootId = NodeId(**rootId) + self.rootId = rootId + + @classmethod + def build_hash(cls, hostId, rootId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class ShadowRootPushedEvent(BaseEvent): + + js_name = 'Dom.shadowRootPushed' + hashable = ['hostId'] + is_hashable = True + + def __init__(self, + hostId: Union['NodeId', dict], + root: Union['Node', dict], + ): + if isinstance(hostId, dict): + hostId = NodeId(**hostId) + self.hostId = hostId + if isinstance(root, dict): + root = Node(**root) + self.root = root + + @classmethod + def build_hash(cls, hostId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) diff --git a/chromewhip/protocol/domdebugger.py b/chromewhip/protocol/domdebugger.py index ab43bfb..b72757e 100644 --- a/chromewhip/protocol/domdebugger.py +++ b/chromewhip/protocol/domdebugger.py @@ -46,25 +46,37 @@ def __init__(self, class DOMDebugger(PayloadMixin): - """ DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript execution will stop on these operations as if there was a regular breakpoint set. + """ DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript +execution will stop on these operations as if there was a regular breakpoint set. """ @classmethod - def setDOMBreakpoint(cls, - nodeId: Union['DOM.NodeId'], - type: Union['DOMBreakpointType'], - ): - """Sets breakpoint on particular operation with DOM. - :param nodeId: Identifier of the node to set breakpoint on. - :type nodeId: DOM.NodeId - :param type: Type of the operation to stop upon. - :type type: DOMBreakpointType + def getEventListeners(cls, + objectId: Union['Runtime.RemoteObjectId'], + depth: Optional['int'] = None, + pierce: Optional['bool'] = None, + ): + """Returns event listeners of the given object. + :param objectId: Identifier of the object to return listeners for. + :type objectId: Runtime.RemoteObjectId + :param depth: The maximum depth at which Node children should be retrieved, defaults to 1. Use -1 for the +entire subtree or provide an integer larger than 0. + :type depth: int + :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree +(default is false). Reports listeners for all contexts if pierce is enabled. + :type pierce: bool """ return ( - cls.build_send_payload("setDOMBreakpoint", { - "nodeId": nodeId, - "type": type, + cls.build_send_payload("getEventListeners", { + "objectId": objectId, + "depth": depth, + "pierce": pierce, }), - None + cls.convert_payload({ + "listeners": { + "class": [EventListener], + "optional": False + }, + }) ) @classmethod @@ -72,7 +84,7 @@ def removeDOMBreakpoint(cls, nodeId: Union['DOM.NodeId'], type: Union['DOMBreakpointType'], ): - """Removes DOM breakpoint that was set using setDOMBreakpoint. + """Removes DOM breakpoint that was set using `setDOMBreakpoint`. :param nodeId: Identifier of the node to remove breakpoint from. :type nodeId: DOM.NodeId :param type: Type of the breakpoint to remove. @@ -86,25 +98,6 @@ def removeDOMBreakpoint(cls, None ) - @classmethod - def setEventListenerBreakpoint(cls, - eventName: Union['str'], - targetName: Optional['str'] = None, - ): - """Sets breakpoint on particular DOM event. - :param eventName: DOM Event name to stop on (any DOM event will do). - :type eventName: str - :param targetName: EventTarget interface name to stop on. If equal to "*" or not provided, will stop on any EventTarget. - :type targetName: str - """ - return ( - cls.build_send_payload("setEventListenerBreakpoint", { - "eventName": eventName, - "targetName": targetName, - }), - None - ) - @classmethod def removeEventListenerBreakpoint(cls, eventName: Union['str'], @@ -125,90 +118,101 @@ def removeEventListenerBreakpoint(cls, ) @classmethod - def setInstrumentationBreakpoint(cls, - eventName: Union['str'], - ): - """Sets breakpoint on particular native event. + def removeInstrumentationBreakpoint(cls, + eventName: Union['str'], + ): + """Removes breakpoint on particular native event. :param eventName: Instrumentation name to stop on. :type eventName: str """ return ( - cls.build_send_payload("setInstrumentationBreakpoint", { + cls.build_send_payload("removeInstrumentationBreakpoint", { "eventName": eventName, }), None ) @classmethod - def removeInstrumentationBreakpoint(cls, - eventName: Union['str'], - ): - """Removes breakpoint on particular native event. - :param eventName: Instrumentation name to stop on. - :type eventName: str + def removeXHRBreakpoint(cls, + url: Union['str'], + ): + """Removes breakpoint from XMLHttpRequest. + :param url: Resource URL substring. + :type url: str """ return ( - cls.build_send_payload("removeInstrumentationBreakpoint", { - "eventName": eventName, + cls.build_send_payload("removeXHRBreakpoint", { + "url": url, }), None ) @classmethod - def setXHRBreakpoint(cls, - url: Union['str'], + def setDOMBreakpoint(cls, + nodeId: Union['DOM.NodeId'], + type: Union['DOMBreakpointType'], ): - """Sets breakpoint on XMLHttpRequest. - :param url: Resource URL substring. All XHRs having this substring in the URL will get stopped upon. - :type url: str + """Sets breakpoint on particular operation with DOM. + :param nodeId: Identifier of the node to set breakpoint on. + :type nodeId: DOM.NodeId + :param type: Type of the operation to stop upon. + :type type: DOMBreakpointType """ return ( - cls.build_send_payload("setXHRBreakpoint", { - "url": url, + cls.build_send_payload("setDOMBreakpoint", { + "nodeId": nodeId, + "type": type, }), None ) @classmethod - def removeXHRBreakpoint(cls, - url: Union['str'], - ): - """Removes breakpoint from XMLHttpRequest. - :param url: Resource URL substring. - :type url: str + def setEventListenerBreakpoint(cls, + eventName: Union['str'], + targetName: Optional['str'] = None, + ): + """Sets breakpoint on particular DOM event. + :param eventName: DOM Event name to stop on (any DOM event will do). + :type eventName: str + :param targetName: EventTarget interface name to stop on. If equal to `"*"` or not provided, will stop on any +EventTarget. + :type targetName: str """ return ( - cls.build_send_payload("removeXHRBreakpoint", { - "url": url, + cls.build_send_payload("setEventListenerBreakpoint", { + "eventName": eventName, + "targetName": targetName, }), None ) @classmethod - def getEventListeners(cls, - objectId: Union['Runtime.RemoteObjectId'], - depth: Optional['int'] = None, - pierce: Optional['bool'] = None, - ): - """Returns event listeners of the given object. - :param objectId: Identifier of the object to return listeners for. - :type objectId: Runtime.RemoteObjectId - :param depth: The maximum depth at which Node children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0. - :type depth: int - :param pierce: Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false). Reports listeners for all contexts if pierce is enabled. - :type pierce: bool + def setInstrumentationBreakpoint(cls, + eventName: Union['str'], + ): + """Sets breakpoint on particular native event. + :param eventName: Instrumentation name to stop on. + :type eventName: str """ return ( - cls.build_send_payload("getEventListeners", { - "objectId": objectId, - "depth": depth, - "pierce": pierce, + cls.build_send_payload("setInstrumentationBreakpoint", { + "eventName": eventName, }), - cls.convert_payload({ - "listeners": { - "class": [EventListener], - "optional": False - }, - }) + None + ) + + @classmethod + def setXHRBreakpoint(cls, + url: Union['str'], + ): + """Sets breakpoint on XMLHttpRequest. + :param url: Resource URL substring. All XHRs having this substring in the URL will get stopped upon. + :type url: str + """ + return ( + cls.build_send_payload("setXHRBreakpoint", { + "url": url, + }), + None ) diff --git a/chromewhip/protocol/domsnapshot.py b/chromewhip/protocol/domsnapshot.py index 0edbc2a..571c939 100644 --- a/chromewhip/protocol/domsnapshot.py +++ b/chromewhip/protocol/domsnapshot.py @@ -14,6 +14,7 @@ log = logging.getLogger(__name__) from chromewhip.protocol import css as CSS from chromewhip.protocol import dom as DOM +from chromewhip.protocol import domdebugger as DOMDebugger from chromewhip.protocol import page as Page # DOMNode: A Node in the DOM tree. @@ -43,6 +44,8 @@ def __init__(self, templateContentIndex: Optional['int'] = None, pseudoType: Optional['DOM.PseudoType'] = None, isClickable: Optional['bool'] = None, + eventListeners: Optional['[DOMDebugger.EventListener]'] = None, + currentSourceURL: Optional['str'] = None, ): self.nodeType = nodeType @@ -69,9 +72,11 @@ def __init__(self, self.templateContentIndex = templateContentIndex self.pseudoType = pseudoType self.isClickable = isClickable + self.eventListeners = eventListeners + self.currentSourceURL = currentSourceURL -# InlineTextBox: Details of post layout rendered text positions. The exact layout should not be regarded as stable and may change between versions. +# InlineTextBox: Details of post layout rendered text positions. The exact layout should not be regarded asstable and may change between versions. class InlineTextBox(ChromeTypeBase): def __init__(self, boundingBox: Union['DOM.Rect'], @@ -127,14 +132,21 @@ class DOMSnapshot(PayloadMixin): @classmethod def getSnapshot(cls, computedStyleWhitelist: Union['[]'], + includeEventListeners: Optional['bool'] = None, ): - """Returns a document snapshot, including the full DOM tree of the root node (including iframes, template contents, and imported documents) in a flattened array, as well as layout and white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is flattened. + """Returns a document snapshot, including the full DOM tree of the root node (including iframes, +template contents, and imported documents) in a flattened array, as well as layout and +white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is +flattened. :param computedStyleWhitelist: Whitelist of computed styles to return. :type computedStyleWhitelist: [] + :param includeEventListeners: Whether or not to retrieve details of DOM listeners (default false). + :type includeEventListeners: bool """ return ( cls.build_send_payload("getSnapshot", { "computedStyleWhitelist": computedStyleWhitelist, + "includeEventListeners": includeEventListeners, }), cls.convert_payload({ "domNodes": { diff --git a/chromewhip/protocol/domstorage.py b/chromewhip/protocol/domstorage.py index 467b082..248c03c 100644 --- a/chromewhip/protocol/domstorage.py +++ b/chromewhip/protocol/domstorage.py @@ -31,11 +31,16 @@ class DOMStorage(PayloadMixin): """ Query and modify DOM storage. """ @classmethod - def enable(cls): - """Enables storage tracking, storage events will now be delivered to the client. + def clear(cls, + storageId: Union['StorageId'], + ): + """ + :param storageId: + :type storageId: StorageId """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("clear", { + "storageId": storageId, }), None ) @@ -51,16 +56,11 @@ def disable(cls): ) @classmethod - def clear(cls, - storageId: Union['StorageId'], - ): - """ - :param storageId: - :type storageId: StorageId + def enable(cls): + """Enables storage tracking, storage events will now be delivered to the client. """ return ( - cls.build_send_payload("clear", { - "storageId": storageId, + cls.build_send_payload("enable", { }), None ) @@ -86,61 +86,69 @@ def getDOMStorageItems(cls, ) @classmethod - def setDOMStorageItem(cls, - storageId: Union['StorageId'], - key: Union['str'], - value: Union['str'], - ): + def removeDOMStorageItem(cls, + storageId: Union['StorageId'], + key: Union['str'], + ): """ :param storageId: :type storageId: StorageId :param key: :type key: str - :param value: - :type value: str """ return ( - cls.build_send_payload("setDOMStorageItem", { + cls.build_send_payload("removeDOMStorageItem", { "storageId": storageId, "key": key, - "value": value, }), None ) @classmethod - def removeDOMStorageItem(cls, - storageId: Union['StorageId'], - key: Union['str'], - ): + def setDOMStorageItem(cls, + storageId: Union['StorageId'], + key: Union['str'], + value: Union['str'], + ): """ :param storageId: :type storageId: StorageId :param key: :type key: str + :param value: + :type value: str """ return ( - cls.build_send_payload("removeDOMStorageItem", { + cls.build_send_payload("setDOMStorageItem", { "storageId": storageId, "key": key, + "value": value, }), None ) -class DomStorageItemsClearedEvent(BaseEvent): +class DomStorageItemAddedEvent(BaseEvent): - js_name = 'Domstorage.domStorageItemsCleared' + js_name = 'Domstorage.domStorageItemAdded' hashable = ['storageId'] is_hashable = True def __init__(self, storageId: Union['StorageId', dict], + key: Union['str', dict], + newValue: Union['str', dict], ): if isinstance(storageId, dict): storageId = StorageId(**storageId) self.storageId = storageId + if isinstance(key, dict): + key = str(**key) + self.key = key + if isinstance(newValue, dict): + newValue = str(**newValue) + self.newValue = newValue @classmethod def build_hash(cls, storageId): @@ -179,15 +187,16 @@ def build_hash(cls, storageId): return h -class DomStorageItemAddedEvent(BaseEvent): +class DomStorageItemUpdatedEvent(BaseEvent): - js_name = 'Domstorage.domStorageItemAdded' + js_name = 'Domstorage.domStorageItemUpdated' hashable = ['storageId'] is_hashable = True def __init__(self, storageId: Union['StorageId', dict], key: Union['str', dict], + oldValue: Union['str', dict], newValue: Union['str', dict], ): if isinstance(storageId, dict): @@ -196,6 +205,9 @@ def __init__(self, if isinstance(key, dict): key = str(**key) self.key = key + if isinstance(oldValue, dict): + oldValue = str(**oldValue) + self.oldValue = oldValue if isinstance(newValue, dict): newValue = str(**newValue) self.newValue = newValue @@ -210,30 +222,18 @@ def build_hash(cls, storageId): return h -class DomStorageItemUpdatedEvent(BaseEvent): +class DomStorageItemsClearedEvent(BaseEvent): - js_name = 'Domstorage.domStorageItemUpdated' + js_name = 'Domstorage.domStorageItemsCleared' hashable = ['storageId'] is_hashable = True def __init__(self, storageId: Union['StorageId', dict], - key: Union['str', dict], - oldValue: Union['str', dict], - newValue: Union['str', dict], ): if isinstance(storageId, dict): storageId = StorageId(**storageId) self.storageId = storageId - if isinstance(key, dict): - key = str(**key) - self.key = key - if isinstance(oldValue, dict): - oldValue = str(**oldValue) - self.oldValue = oldValue - if isinstance(newValue, dict): - newValue = str(**newValue) - self.newValue = newValue @classmethod def build_hash(cls, storageId): diff --git a/chromewhip/protocol/emulation.py b/chromewhip/protocol/emulation.py index 06ad022..f0d50cb 100644 --- a/chromewhip/protocol/emulation.py +++ b/chromewhip/protocol/emulation.py @@ -14,6 +14,7 @@ log = logging.getLogger(__name__) from chromewhip.protocol import dom as DOM from chromewhip.protocol import page as Page +from chromewhip.protocol import runtime as Runtime # ScreenOrientation: Screen orientation. class ScreenOrientation(ChromeTypeBase): @@ -26,12 +27,89 @@ def __init__(self, self.angle = angle -# VirtualTimePolicy: advance: If the scheduler runs out of immediate work, the virtual time base may fast forward to allow the next delayed task (if any) to run; pause: The virtual time base may not advance; pauseIfNetworkFetchesPending: The virtual time base may not advance if there are any pending resource fetches. +# VirtualTimePolicy: advance: If the scheduler runs out of immediate work, the virtual time base may fast forward toallow the next delayed task (if any) to run; pause: The virtual time base may not advance;pauseIfNetworkFetchesPending: The virtual time base may not advance if there are any pendingresource fetches. VirtualTimePolicy = str class Emulation(PayloadMixin): """ This domain emulates different environments for the page. """ + @classmethod + def canEmulate(cls): + """Tells whether emulation is supported. + """ + return ( + cls.build_send_payload("canEmulate", { + }), + cls.convert_payload({ + "result": { + "class": bool, + "optional": False + }, + }) + ) + + @classmethod + def clearDeviceMetricsOverride(cls): + """Clears the overriden device metrics. + """ + return ( + cls.build_send_payload("clearDeviceMetricsOverride", { + }), + None + ) + + @classmethod + def clearGeolocationOverride(cls): + """Clears the overriden Geolocation Position and Error. + """ + return ( + cls.build_send_payload("clearGeolocationOverride", { + }), + None + ) + + @classmethod + def resetPageScaleFactor(cls): + """Requests that page scale factor is reset to initial values. + """ + return ( + cls.build_send_payload("resetPageScaleFactor", { + }), + None + ) + + @classmethod + def setCPUThrottlingRate(cls, + rate: Union['float'], + ): + """Enables CPU throttling to emulate slow CPUs. + :param rate: Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc). + :type rate: float + """ + return ( + cls.build_send_payload("setCPUThrottlingRate", { + "rate": rate, + }), + None + ) + + @classmethod + def setDefaultBackgroundColorOverride(cls, + color: Optional['DOM.RGBA'] = None, + ): + """Sets or clears an override of the default background color of the frame. This override is used +if the content does not specify one. + :param color: RGBA of the default background color. If not specified, any existing override will be +cleared. + :type color: DOM.RGBA + """ + return ( + cls.build_send_payload("setDefaultBackgroundColorOverride", { + "color": color, + }), + None + ) + @classmethod def setDeviceMetricsOverride(cls, width: Union['int'], @@ -47,14 +125,17 @@ def setDeviceMetricsOverride(cls, screenOrientation: Optional['ScreenOrientation'] = None, viewport: Optional['Page.Viewport'] = None, ): - """Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media query results). + """Overrides the values of device screen dimensions (window.screen.width, window.screen.height, +window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media +query results). :param width: Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override. :type width: int :param height: Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override. :type height: int :param deviceScaleFactor: Overriding device scale factor value. 0 disables the override. :type deviceScaleFactor: float - :param mobile: Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more. + :param mobile: Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text +autosizing and more. :type mobile: bool :param scale: Scale to apply to resulting view image. :type scale: float @@ -70,7 +151,8 @@ def setDeviceMetricsOverride(cls, :type dontSetVisibleSize: bool :param screenOrientation: Screen orientation override. :type screenOrientation: ScreenOrientation - :param viewport: 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. + :param viewport: 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. :type viewport: Page.Viewport """ return ( @@ -92,70 +174,35 @@ def setDeviceMetricsOverride(cls, ) @classmethod - def clearDeviceMetricsOverride(cls): - """Clears the overriden device metrics. - """ - return ( - cls.build_send_payload("clearDeviceMetricsOverride", { - }), - None - ) - - @classmethod - def resetPageScaleFactor(cls): - """Requests that page scale factor is reset to initial values. - """ - return ( - cls.build_send_payload("resetPageScaleFactor", { - }), - None - ) - - @classmethod - def setPageScaleFactor(cls, - pageScaleFactor: Union['float'], - ): - """Sets a specified page scale factor. - :param pageScaleFactor: Page scale factor. - :type pageScaleFactor: float + def setEmitTouchEventsForMouse(cls, + enabled: Union['bool'], + configuration: Optional['str'] = None, + ): """ - return ( - cls.build_send_payload("setPageScaleFactor", { - "pageScaleFactor": pageScaleFactor, - }), - None - ) - - @classmethod - def setVisibleSize(cls, - width: Union['int'], - height: Union['int'], - ): - """Resizes the frame/viewport of the page. Note that this does not affect the frame's container (e.g. browser window). Can be used to produce screenshots of the specified size. Not supported on Android. - :param width: Frame width (DIP). - :type width: int - :param height: Frame height (DIP). - :type height: int + :param enabled: Whether touch emulation based on mouse input should be enabled. + :type enabled: bool + :param configuration: Touch/gesture events configuration. Default: current platform. + :type configuration: str """ return ( - cls.build_send_payload("setVisibleSize", { - "width": width, - "height": height, + cls.build_send_payload("setEmitTouchEventsForMouse", { + "enabled": enabled, + "configuration": configuration, }), None ) @classmethod - def setScriptExecutionDisabled(cls, - value: Union['bool'], - ): - """Switches script execution in the page. - :param value: Whether script execution should be disabled in the page. - :type value: bool + def setEmulatedMedia(cls, + media: Union['str'], + ): + """Emulates the given media for CSS media queries. + :param media: Media type to emulate. Empty string disables the override. + :type media: str """ return ( - cls.build_send_payload("setScriptExecutionDisabled", { - "value": value, + cls.build_send_payload("setEmulatedMedia", { + "media": media, }), None ) @@ -166,7 +213,8 @@ def setGeolocationOverride(cls, longitude: Optional['float'] = None, accuracy: Optional['float'] = None, ): - """Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position unavailable. + """Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position +unavailable. :param latitude: Mock latitude :type latitude: float :param longitude: Mock longitude @@ -184,179 +232,154 @@ def setGeolocationOverride(cls, ) @classmethod - def clearGeolocationOverride(cls): - """Clears the overriden Geolocation Position and Error. + def setNavigatorOverrides(cls, + platform: Union['str'], + ): + """Overrides value returned by the javascript navigator object. + :param platform: The platform navigator.platform should return. + :type platform: str """ return ( - cls.build_send_payload("clearGeolocationOverride", { + cls.build_send_payload("setNavigatorOverrides", { + "platform": platform, }), None ) @classmethod - def setTouchEmulationEnabled(cls, - enabled: Union['bool'], - maxTouchPoints: Optional['int'] = None, - ): - """Enables touch on platforms which do not support them. - :param enabled: Whether the touch event emulation should be enabled. - :type enabled: bool - :param maxTouchPoints: Maximum touch points supported. Defaults to one. - :type maxTouchPoints: int + def setPageScaleFactor(cls, + pageScaleFactor: Union['float'], + ): + """Sets a specified page scale factor. + :param pageScaleFactor: Page scale factor. + :type pageScaleFactor: float """ return ( - cls.build_send_payload("setTouchEmulationEnabled", { - "enabled": enabled, - "maxTouchPoints": maxTouchPoints, + cls.build_send_payload("setPageScaleFactor", { + "pageScaleFactor": pageScaleFactor, }), None ) @classmethod - def setEmitTouchEventsForMouse(cls, - enabled: Union['bool'], - configuration: Optional['str'] = None, + def setScriptExecutionDisabled(cls, + value: Union['bool'], ): - """ - :param enabled: Whether touch emulation based on mouse input should be enabled. - :type enabled: bool - :param configuration: Touch/gesture events configuration. Default: current platform. - :type configuration: str - """ - return ( - cls.build_send_payload("setEmitTouchEventsForMouse", { - "enabled": enabled, - "configuration": configuration, - }), - None - ) - - @classmethod - def setEmulatedMedia(cls, - media: Union['str'], - ): - """Emulates the given media for CSS media queries. - :param media: Media type to emulate. Empty string disables the override. - :type media: str + """Switches script execution in the page. + :param value: Whether script execution should be disabled in the page. + :type value: bool """ return ( - cls.build_send_payload("setEmulatedMedia", { - "media": media, + cls.build_send_payload("setScriptExecutionDisabled", { + "value": value, }), None ) @classmethod - def setCPUThrottlingRate(cls, - rate: Union['float'], - ): - """Enables CPU throttling to emulate slow CPUs. - :param rate: Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc). - :type rate: float + def setTouchEmulationEnabled(cls, + enabled: Union['bool'], + maxTouchPoints: Optional['int'] = None, + ): + """Enables touch on platforms which do not support them. + :param enabled: Whether the touch event emulation should be enabled. + :type enabled: bool + :param maxTouchPoints: Maximum touch points supported. Defaults to one. + :type maxTouchPoints: int """ return ( - cls.build_send_payload("setCPUThrottlingRate", { - "rate": rate, + cls.build_send_payload("setTouchEmulationEnabled", { + "enabled": enabled, + "maxTouchPoints": maxTouchPoints, }), None ) - @classmethod - def canEmulate(cls): - """Tells whether emulation is supported. - """ - return ( - cls.build_send_payload("canEmulate", { - }), - cls.convert_payload({ - "result": { - "class": bool, - "optional": False - }, - }) - ) - @classmethod def setVirtualTimePolicy(cls, policy: Union['VirtualTimePolicy'], - budget: Optional['int'] = None, + budget: Optional['float'] = None, maxVirtualTimeTaskStarvationCount: Optional['int'] = None, + waitForNavigation: Optional['bool'] = None, ): - """Turns on virtual time for all frames (replacing real-time with a synthetic time source) and sets the current virtual time policy. Note this supersedes any previous time budget. + """Turns on virtual time for all frames (replacing real-time with a synthetic time source) and sets +the current virtual time policy. Note this supersedes any previous time budget. :param policy: :type policy: VirtualTimePolicy - :param budget: If set, after this many virtual milliseconds have elapsed virtual time will be paused and a virtualTimeBudgetExpired event is sent. - :type budget: int - :param maxVirtualTimeTaskStarvationCount: If set this specifies the maximum number of tasks that can be run before virtual is forced forwards to prevent deadlock. + :param budget: If set, after this many virtual milliseconds have elapsed virtual time will be paused and a +virtualTimeBudgetExpired event is sent. + :type budget: float + :param maxVirtualTimeTaskStarvationCount: If set this specifies the maximum number of tasks that can be run before virtual is forced +forwards to prevent deadlock. :type maxVirtualTimeTaskStarvationCount: int + :param waitForNavigation: If set the virtual time policy change should be deferred until any frame starts navigating. +Note any previous deferred policy change is superseded. + :type waitForNavigation: bool """ return ( cls.build_send_payload("setVirtualTimePolicy", { "policy": policy, "budget": budget, "maxVirtualTimeTaskStarvationCount": maxVirtualTimeTaskStarvationCount, + "waitForNavigation": waitForNavigation, }), - None - ) - - @classmethod - def setNavigatorOverrides(cls, - platform: Union['str'], - ): - """Overrides value returned by the javascript navigator object. - :param platform: The platform navigator.platform should return. - :type platform: str - """ - return ( - cls.build_send_payload("setNavigatorOverrides", { - "platform": platform, - }), - None + cls.convert_payload({ + "virtualTimeBase": { + "class": Runtime.Timestamp, + "optional": False + }, + }) ) @classmethod - def setDefaultBackgroundColorOverride(cls, - color: Optional['DOM.RGBA'] = None, - ): - """Sets or clears an override of the default background color of the frame. This override is used if the content does not specify one. - :param color: RGBA of the default background color. If not specified, any existing override will be cleared. - :type color: DOM.RGBA + def setVisibleSize(cls, + width: Union['int'], + height: Union['int'], + ): + """Resizes the frame/viewport of the page. Note that this does not affect the frame's container +(e.g. browser window). Can be used to produce screenshots of the specified size. Not supported +on Android. + :param width: Frame width (DIP). + :type width: int + :param height: Frame height (DIP). + :type height: int """ return ( - cls.build_send_payload("setDefaultBackgroundColorOverride", { - "color": color, + cls.build_send_payload("setVisibleSize", { + "width": width, + "height": height, }), None ) -class VirtualTimeBudgetExpiredEvent(BaseEvent): +class VirtualTimeAdvancedEvent(BaseEvent): - js_name = 'Emulation.virtualTimeBudgetExpired' + js_name = 'Emulation.virtualTimeAdvanced' hashable = [] is_hashable = False - def __init__(self): - pass + def __init__(self, + virtualTimeElapsed: Union['float', dict], + ): + if isinstance(virtualTimeElapsed, dict): + virtualTimeElapsed = float(**virtualTimeElapsed) + self.virtualTimeElapsed = virtualTimeElapsed @classmethod def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class VirtualTimeAdvancedEvent(BaseEvent): +class VirtualTimeBudgetExpiredEvent(BaseEvent): - js_name = 'Emulation.virtualTimeAdvanced' + js_name = 'Emulation.virtualTimeBudgetExpired' hashable = [] is_hashable = False - def __init__(self, - virtualTimeElapsed: Union['int', dict], - ): - if isinstance(virtualTimeElapsed, dict): - virtualTimeElapsed = int(**virtualTimeElapsed) - self.virtualTimeElapsed = virtualTimeElapsed + def __init__(self): + pass @classmethod def build_hash(cls): @@ -370,10 +393,10 @@ class VirtualTimePausedEvent(BaseEvent): is_hashable = False def __init__(self, - virtualTimeElapsed: Union['int', dict], + virtualTimeElapsed: Union['float', dict], ): if isinstance(virtualTimeElapsed, dict): - virtualTimeElapsed = int(**virtualTimeElapsed) + virtualTimeElapsed = float(**virtualTimeElapsed) self.virtualTimeElapsed = virtualTimeElapsed @classmethod diff --git a/chromewhip/protocol/headlessexperimental.py b/chromewhip/protocol/headlessexperimental.py index c0750fc..1e343ee 100644 --- a/chromewhip/protocol/headlessexperimental.py +++ b/chromewhip/protocol/headlessexperimental.py @@ -29,41 +29,32 @@ def __init__(self, class HeadlessExperimental(PayloadMixin): """ This domain provides experimental commands only supported in headless mode. """ - @classmethod - def enable(cls): - """Enables headless events for the target. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - - @classmethod - def disable(cls): - """Disables headless events for the target. - """ - return ( - cls.build_send_payload("disable", { - }), - None - ) - @classmethod def beginFrame(cls, frameTime: Optional['Runtime.Timestamp'] = None, deadline: Optional['Runtime.Timestamp'] = None, interval: Optional['float'] = None, + noDisplayUpdates: Optional['bool'] = None, screenshot: Optional['ScreenshotParams'] = None, ): - """Sends a BeginFrame to the target and returns when the frame was completed. Optionally captures a screenshot from the resulting frame. Requires that the target was created with enabled BeginFrameControl. - :param frameTime: Timestamp of this BeginFrame (milliseconds since epoch). If not set, the current time will be used. + """Sends a BeginFrame to the target and returns when the frame was completed. Optionally captures a +screenshot from the resulting frame. Requires that the target was created with enabled +BeginFrameControl. + :param frameTime: Timestamp of this BeginFrame (milliseconds since epoch). If not set, the current time will +be used. :type frameTime: Runtime.Timestamp - :param deadline: Deadline of this BeginFrame (milliseconds since epoch). If not set, the deadline will be calculated from the frameTime and interval. + :param deadline: Deadline of this BeginFrame (milliseconds since epoch). If not set, the deadline will be +calculated from the frameTime and interval. :type deadline: Runtime.Timestamp - :param interval: The interval between BeginFrames that is reported to the compositor, in milliseconds. Defaults to a 60 frames/second interval, i.e. about 16.666 milliseconds. + :param interval: The interval between BeginFrames that is reported to the compositor, in milliseconds. +Defaults to a 60 frames/second interval, i.e. about 16.666 milliseconds. :type interval: float - :param screenshot: If set, a screenshot of the frame will be captured and returned in the response. Otherwise, no screenshot will be captured. + :param noDisplayUpdates: Whether updates should not be committed and drawn onto the display. False by default. If +true, only side effects of the BeginFrame will be run, such as layout and animations, but +any visual updates may not be visible on the display or in screenshots. + :type noDisplayUpdates: bool + :param screenshot: If set, a screenshot of the frame will be captured and returned in the response. Otherwise, +no screenshot will be captured. :type screenshot: ScreenshotParams """ return ( @@ -71,6 +62,7 @@ def beginFrame(cls, "frameTime": frameTime, "deadline": deadline, "interval": interval, + "noDisplayUpdates": noDisplayUpdates, "screenshot": screenshot, }), cls.convert_payload({ @@ -89,34 +81,54 @@ def beginFrame(cls, }) ) + @classmethod + def disable(cls): + """Disables headless events for the target. + """ + return ( + cls.build_send_payload("disable", { + }), + None + ) + + @classmethod + def enable(cls): + """Enables headless events for the target. + """ + return ( + cls.build_send_payload("enable", { + }), + None + ) + -class NeedsBeginFramesChangedEvent(BaseEvent): +class MainFrameReadyForScreenshotsEvent(BaseEvent): - js_name = 'Headlessexperimental.needsBeginFramesChanged' + js_name = 'Headlessexperimental.mainFrameReadyForScreenshots' hashable = [] is_hashable = False - def __init__(self, - needsBeginFrames: Union['bool', dict], - ): - if isinstance(needsBeginFrames, dict): - needsBeginFrames = bool(**needsBeginFrames) - self.needsBeginFrames = needsBeginFrames + def __init__(self): + pass @classmethod def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class MainFrameReadyForScreenshotsEvent(BaseEvent): +class NeedsBeginFramesChangedEvent(BaseEvent): - js_name = 'Headlessexperimental.mainFrameReadyForScreenshots' + js_name = 'Headlessexperimental.needsBeginFramesChanged' hashable = [] is_hashable = False - def __init__(self): - pass + def __init__(self, + needsBeginFrames: Union['bool', dict], + ): + if isinstance(needsBeginFrames, dict): + needsBeginFrames = bool(**needsBeginFrames) + self.needsBeginFrames = needsBeginFrames @classmethod def build_hash(cls): diff --git a/chromewhip/protocol/heapprofiler.py b/chromewhip/protocol/heapprofiler.py index a27f969..fca0d5c 100644 --- a/chromewhip/protocol/heapprofiler.py +++ b/chromewhip/protocol/heapprofiler.py @@ -43,78 +43,69 @@ class HeapProfiler(PayloadMixin): """ """ @classmethod - def enable(cls): - """ - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - - @classmethod - def disable(cls): - """ + def addInspectedHeapObject(cls, + heapObjectId: Union['HeapSnapshotObjectId'], + ): + """Enables console to refer to the node with given id via $x (see Command Line API for more details +$x functions). + :param heapObjectId: Heap snapshot object id to be accessible by means of $x command line API. + :type heapObjectId: HeapSnapshotObjectId """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("addInspectedHeapObject", { + "heapObjectId": heapObjectId, }), None ) @classmethod - def startTrackingHeapObjects(cls, - trackAllocations: Optional['bool'] = None, - ): + def collectGarbage(cls): """ - :param trackAllocations: - :type trackAllocations: bool """ return ( - cls.build_send_payload("startTrackingHeapObjects", { - "trackAllocations": trackAllocations, + cls.build_send_payload("collectGarbage", { }), None ) @classmethod - def stopTrackingHeapObjects(cls, - reportProgress: Optional['bool'] = None, - ): + def disable(cls): """ - :param reportProgress: If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken when the tracking is stopped. - :type reportProgress: bool """ return ( - cls.build_send_payload("stopTrackingHeapObjects", { - "reportProgress": reportProgress, + cls.build_send_payload("disable", { }), None ) @classmethod - def takeHeapSnapshot(cls, - reportProgress: Optional['bool'] = None, - ): + def enable(cls): """ - :param reportProgress: If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken. - :type reportProgress: bool """ return ( - cls.build_send_payload("takeHeapSnapshot", { - "reportProgress": reportProgress, + cls.build_send_payload("enable", { }), None ) @classmethod - def collectGarbage(cls): + def getHeapObjectId(cls, + objectId: Union['Runtime.RemoteObjectId'], + ): """ + :param objectId: Identifier of the object to get heap object id for. + :type objectId: Runtime.RemoteObjectId """ return ( - cls.build_send_payload("collectGarbage", { + cls.build_send_payload("getHeapObjectId", { + "objectId": objectId, }), - None + cls.convert_payload({ + "heapSnapshotObjectId": { + "class": HeapSnapshotObjectId, + "optional": False + }, + }) ) @classmethod @@ -142,35 +133,15 @@ def getObjectByHeapObjectId(cls, ) @classmethod - def addInspectedHeapObject(cls, - heapObjectId: Union['HeapSnapshotObjectId'], - ): - """Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions). - :param heapObjectId: Heap snapshot object id to be accessible by means of $x command line API. - :type heapObjectId: HeapSnapshotObjectId - """ - return ( - cls.build_send_payload("addInspectedHeapObject", { - "heapObjectId": heapObjectId, - }), - None - ) - - @classmethod - def getHeapObjectId(cls, - objectId: Union['Runtime.RemoteObjectId'], - ): + def getSamplingProfile(cls): """ - :param objectId: Identifier of the object to get heap object id for. - :type objectId: Runtime.RemoteObjectId """ return ( - cls.build_send_payload("getHeapObjectId", { - "objectId": objectId, + cls.build_send_payload("getSamplingProfile", { }), cls.convert_payload({ - "heapSnapshotObjectId": { - "class": HeapSnapshotObjectId, + "profile": { + "class": SamplingHeapProfile, "optional": False }, }) @@ -181,7 +152,8 @@ def startSampling(cls, samplingInterval: Optional['float'] = None, ): """ - :param samplingInterval: Average sample interval in bytes. Poisson distribution is used for the intervals. The default value is 32768 bytes. + :param samplingInterval: Average sample interval in bytes. Poisson distribution is used for the intervals. The +default value is 32768 bytes. :type samplingInterval: float """ return ( @@ -191,6 +163,21 @@ def startSampling(cls, None ) + @classmethod + def startTrackingHeapObjects(cls, + trackAllocations: Optional['bool'] = None, + ): + """ + :param trackAllocations: + :type trackAllocations: bool + """ + return ( + cls.build_send_payload("startTrackingHeapObjects", { + "trackAllocations": trackAllocations, + }), + None + ) + @classmethod def stopSampling(cls): """ @@ -206,6 +193,37 @@ def stopSampling(cls): }) ) + @classmethod + def stopTrackingHeapObjects(cls, + reportProgress: Optional['bool'] = None, + ): + """ + :param reportProgress: If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken +when the tracking is stopped. + :type reportProgress: bool + """ + return ( + cls.build_send_payload("stopTrackingHeapObjects", { + "reportProgress": reportProgress, + }), + None + ) + + @classmethod + def takeHeapSnapshot(cls, + reportProgress: Optional['bool'] = None, + ): + """ + :param reportProgress: If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken. + :type reportProgress: bool + """ + return ( + cls.build_send_payload("takeHeapSnapshot", { + "reportProgress": reportProgress, + }), + None + ) + class AddHeapSnapshotChunkEvent(BaseEvent): @@ -226,40 +244,18 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class ResetProfilesEvent(BaseEvent): - - js_name = 'Heapprofiler.resetProfiles' - hashable = [] - is_hashable = False - - def __init__(self): - pass - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class ReportHeapSnapshotProgressEvent(BaseEvent): +class HeapStatsUpdateEvent(BaseEvent): - js_name = 'Heapprofiler.reportHeapSnapshotProgress' + js_name = 'Heapprofiler.heapStatsUpdate' hashable = [] is_hashable = False def __init__(self, - done: Union['int', dict], - total: Union['int', dict], - finished: Union['bool', dict, None] = None, + statsUpdate: Union['[]', dict], ): - if isinstance(done, dict): - done = int(**done) - self.done = done - if isinstance(total, dict): - total = int(**total) - self.total = total - if isinstance(finished, dict): - finished = bool(**finished) - self.finished = finished + if isinstance(statsUpdate, dict): + statsUpdate = [](**statsUpdate) + self.statsUpdate = statsUpdate @classmethod def build_hash(cls): @@ -293,18 +289,40 @@ def build_hash(cls, lastSeenObjectId): return h -class HeapStatsUpdateEvent(BaseEvent): +class ReportHeapSnapshotProgressEvent(BaseEvent): - js_name = 'Heapprofiler.heapStatsUpdate' + js_name = 'Heapprofiler.reportHeapSnapshotProgress' hashable = [] is_hashable = False def __init__(self, - statsUpdate: Union['[]', dict], + done: Union['int', dict], + total: Union['int', dict], + finished: Union['bool', dict, None] = None, ): - if isinstance(statsUpdate, dict): - statsUpdate = [](**statsUpdate) - self.statsUpdate = statsUpdate + if isinstance(done, dict): + done = int(**done) + self.done = done + if isinstance(total, dict): + total = int(**total) + self.total = total + if isinstance(finished, dict): + finished = bool(**finished) + self.finished = finished + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + +class ResetProfilesEvent(BaseEvent): + + js_name = 'Heapprofiler.resetProfiles' + hashable = [] + is_hashable = False + + def __init__(self): + pass @classmethod def build_hash(cls): diff --git a/chromewhip/protocol/indexeddb.py b/chromewhip/protocol/indexeddb.py index c868478..9444a51 100644 --- a/chromewhip/protocol/indexeddb.py +++ b/chromewhip/protocol/indexeddb.py @@ -119,67 +119,92 @@ class IndexedDB(PayloadMixin): """ """ @classmethod - def enable(cls): - """Enables events from backend. + def clearObjectStore(cls, + securityOrigin: Union['str'], + databaseName: Union['str'], + objectStoreName: Union['str'], + ): + """Clears all entries from an object store. + :param securityOrigin: Security origin. + :type securityOrigin: str + :param databaseName: Database name. + :type databaseName: str + :param objectStoreName: Object store name. + :type objectStoreName: str """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("clearObjectStore", { + "securityOrigin": securityOrigin, + "databaseName": databaseName, + "objectStoreName": objectStoreName, }), None ) @classmethod - def disable(cls): - """Disables events from backend. + def deleteDatabase(cls, + securityOrigin: Union['str'], + databaseName: Union['str'], + ): + """Deletes a database. + :param securityOrigin: Security origin. + :type securityOrigin: str + :param databaseName: Database name. + :type databaseName: str """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("deleteDatabase", { + "securityOrigin": securityOrigin, + "databaseName": databaseName, }), None ) @classmethod - def requestDatabaseNames(cls, - securityOrigin: Union['str'], - ): - """Requests database names for given security origin. - :param securityOrigin: Security origin. + def deleteObjectStoreEntries(cls, + securityOrigin: Union['str'], + databaseName: Union['str'], + objectStoreName: Union['str'], + keyRange: Union['KeyRange'], + ): + """Delete a range of entries from an object store + :param securityOrigin: :type securityOrigin: str + :param databaseName: + :type databaseName: str + :param objectStoreName: + :type objectStoreName: str + :param keyRange: Range of entry keys to delete + :type keyRange: KeyRange """ return ( - cls.build_send_payload("requestDatabaseNames", { + cls.build_send_payload("deleteObjectStoreEntries", { "securityOrigin": securityOrigin, + "databaseName": databaseName, + "objectStoreName": objectStoreName, + "keyRange": keyRange, }), - cls.convert_payload({ - "databaseNames": { - "class": [], - "optional": False - }, - }) + None ) @classmethod - def requestDatabase(cls, - securityOrigin: Union['str'], - databaseName: Union['str'], - ): - """Requests database with given name in given frame. - :param securityOrigin: Security origin. - :type securityOrigin: str - :param databaseName: Database name. - :type databaseName: str + def disable(cls): + """Disables events from backend. """ return ( - cls.build_send_payload("requestDatabase", { - "securityOrigin": securityOrigin, - "databaseName": databaseName, + cls.build_send_payload("disable", { }), - cls.convert_payload({ - "databaseWithObjectStores": { - "class": DatabaseWithObjectStores, - "optional": False - }, - }) + None + ) + + @classmethod + def enable(cls): + """Enables events from backend. + """ + return ( + cls.build_send_payload("enable", { + }), + None ) @classmethod @@ -231,46 +256,46 @@ def requestData(cls, ) @classmethod - def clearObjectStore(cls, - securityOrigin: Union['str'], - databaseName: Union['str'], - objectStoreName: Union['str'], - ): - """Clears all entries from an object store. + def requestDatabase(cls, + securityOrigin: Union['str'], + databaseName: Union['str'], + ): + """Requests database with given name in given frame. :param securityOrigin: Security origin. :type securityOrigin: str :param databaseName: Database name. :type databaseName: str - :param objectStoreName: Object store name. - :type objectStoreName: str """ return ( - cls.build_send_payload("clearObjectStore", { + cls.build_send_payload("requestDatabase", { "securityOrigin": securityOrigin, "databaseName": databaseName, - "objectStoreName": objectStoreName, }), cls.convert_payload({ + "databaseWithObjectStores": { + "class": DatabaseWithObjectStores, + "optional": False + }, }) ) @classmethod - def deleteDatabase(cls, - securityOrigin: Union['str'], - databaseName: Union['str'], - ): - """Deletes a database. + def requestDatabaseNames(cls, + securityOrigin: Union['str'], + ): + """Requests database names for given security origin. :param securityOrigin: Security origin. :type securityOrigin: str - :param databaseName: Database name. - :type databaseName: str """ return ( - cls.build_send_payload("deleteDatabase", { + cls.build_send_payload("requestDatabaseNames", { "securityOrigin": securityOrigin, - "databaseName": databaseName, }), cls.convert_payload({ + "databaseNames": { + "class": [], + "optional": False + }, }) ) diff --git a/chromewhip/protocol/input.py b/chromewhip/protocol/input.py index dd76b95..3745d15 100644 --- a/chromewhip/protocol/input.py +++ b/chromewhip/protocol/input.py @@ -43,21 +43,6 @@ def __init__(self, class Input(PayloadMixin): """ """ - @classmethod - def setIgnoreInputEvents(cls, - ignore: Union['bool'], - ): - """Ignores input events (useful while auditing page). - :param ignore: Ignores input events processing when set to true. - :type ignore: bool - """ - return ( - cls.build_send_payload("setIgnoreInputEvents", { - "ignore": ignore, - }), - None - ) - @classmethod def dispatchKeyEvent(cls, type: Union['str'], @@ -78,19 +63,23 @@ def dispatchKeyEvent(cls, """Dispatches a key event to the page. :param type: Type of the key event. :type type: str - :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0). + :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 +(default: 0). :type modifiers: int :param timestamp: Time at which the event occurred. :type timestamp: TimeSinceEpoch - :param text: Text as generated by processing a virtual key code with a keyboard layout. Not needed for for keyUp and rawKeyDown events (default: "") + :param text: Text as generated by processing a virtual key code with a keyboard layout. Not needed for +for `keyUp` and `rawKeyDown` events (default: "") :type text: str - :param unmodifiedText: Text that would have been generated by the keyboard if no modifiers were pressed (except for shift). Useful for shortcut (accelerator) key handling (default: ""). + :param unmodifiedText: Text that would have been generated by the keyboard if no modifiers were pressed (except for +shift). Useful for shortcut (accelerator) key handling (default: ""). :type unmodifiedText: str :param keyIdentifier: Unique key identifier (e.g., 'U+0041') (default: ""). :type keyIdentifier: str :param code: Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: ""). :type code: str - :param key: Unique DOM defined string value describing the meaning of the key in the context of active modifiers, keyboard layout, etc (e.g., 'AltGr') (default: ""). + :param key: Unique DOM defined string value describing the meaning of the key in the context of active +modifiers, keyboard layout, etc (e.g., 'AltGr') (default: ""). :type key: str :param windowsVirtualKeyCode: Windows virtual key code (default: 0). :type windowsVirtualKeyCode: int @@ -102,7 +91,8 @@ def dispatchKeyEvent(cls, :type isKeypad: bool :param isSystemKey: Whether the event was a system key event (default: false). :type isSystemKey: bool - :param location: Whether the event was from the left or right side of the keyboard. 1=Left, 2=Right (default: 0). + :param location: Whether the event was from the left or right side of the keyboard. 1=Left, 2=Right (default: +0). :type location: int """ return ( @@ -142,9 +132,11 @@ def dispatchMouseEvent(cls, :type type: str :param x: X coordinate of the event relative to the main frame's viewport in CSS pixels. :type x: float - :param y: Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport. + :param y: Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to +the top of the viewport and Y increases as it proceeds towards the bottom of the viewport. :type y: float - :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0). + :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 +(default: 0). :type modifiers: int :param timestamp: Time at which the event occurred. :type timestamp: TimeSinceEpoch @@ -180,11 +172,15 @@ def dispatchTouchEvent(cls, timestamp: Optional['TimeSinceEpoch'] = None, ): """Dispatches a touch event to the page. - :param type: Type of the touch event. TouchEnd and TouchCancel must not contain any touch points, while TouchStart and TouchMove must contains at least one. + :param type: Type of the touch event. TouchEnd and TouchCancel must not contain any touch points, while +TouchStart and TouchMove must contains at least one. :type type: str - :param touchPoints: Active touch points on the touch device. One event per any changed point (compared to previous touch event in a sequence) is generated, emulating pressing/moving/releasing points one by one. + :param touchPoints: Active touch points on the touch device. One event per any changed point (compared to +previous touch event in a sequence) is generated, emulating pressing/moving/releasing points +one by one. :type touchPoints: [TouchPoint] - :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0). + :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 +(default: 0). :type modifiers: int :param timestamp: Time at which the event occurred. :type timestamp: TimeSinceEpoch @@ -226,7 +222,8 @@ def emulateTouchFromMouseEvent(cls, :type deltaX: float :param deltaY: Y delta in DIP for mouse wheel event (default: 0). :type deltaY: float - :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0). + :param modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 +(default: 0). :type modifiers: int :param clickCount: Number of times the mouse button was clicked (default: 0). :type clickCount: int @@ -246,6 +243,21 @@ def emulateTouchFromMouseEvent(cls, None ) + @classmethod + def setIgnoreInputEvents(cls, + ignore: Union['bool'], + ): + """Ignores input events (useful while auditing page). + :param ignore: Ignores input events processing when set to true. + :type ignore: bool + """ + return ( + cls.build_send_payload("setIgnoreInputEvents", { + "ignore": ignore, + }), + None + ) + @classmethod def synthesizePinchGesture(cls, x: Union['float'], @@ -263,7 +275,8 @@ def synthesizePinchGesture(cls, :type scaleFactor: float :param relativeSpeed: Relative pointer speed in pixels per second (default: 800). :type relativeSpeed: int - :param gestureSourceType: Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type). + :param gestureSourceType: Which type of input events to be generated (default: 'default', which queries the platform +for the preferred input type). :type gestureSourceType: GestureSourceType """ return ( @@ -301,15 +314,18 @@ def synthesizeScrollGesture(cls, :type xDistance: float :param yDistance: The distance to scroll along the Y axis (positive to scroll up). :type yDistance: float - :param xOverscroll: The number of additional pixels to scroll back along the X axis, in addition to the given distance. + :param xOverscroll: The number of additional pixels to scroll back along the X axis, in addition to the given +distance. :type xOverscroll: float - :param yOverscroll: The number of additional pixels to scroll back along the Y axis, in addition to the given distance. + :param yOverscroll: The number of additional pixels to scroll back along the Y axis, in addition to the given +distance. :type yOverscroll: float :param preventFling: Prevent fling (default: true). :type preventFling: bool :param speed: Swipe speed in pixels per second (default: 800). :type speed: int - :param gestureSourceType: Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type). + :param gestureSourceType: Which type of input events to be generated (default: 'default', which queries the platform +for the preferred input type). :type gestureSourceType: GestureSourceType :param repeatCount: The number of times to repeat the gesture (default: 0). :type repeatCount: int @@ -353,7 +369,8 @@ def synthesizeTapGesture(cls, :type duration: int :param tapCount: Number of times to perform the tap (e.g. 2 for double tap, default: 1). :type tapCount: int - :param gestureSourceType: Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type). + :param gestureSourceType: Which type of input events to be generated (default: 'default', which queries the platform +for the preferred input type). :type gestureSourceType: GestureSourceType """ return ( diff --git a/chromewhip/protocol/inspector.py b/chromewhip/protocol/inspector.py index 98a824c..8999834 100644 --- a/chromewhip/protocol/inspector.py +++ b/chromewhip/protocol/inspector.py @@ -17,21 +17,21 @@ class Inspector(PayloadMixin): """ """ @classmethod - def enable(cls): - """Enables inspector domain notifications. + def disable(cls): + """Disables inspector domain notifications. """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("disable", { }), None ) @classmethod - def disable(cls): - """Disables inspector domain notifications. + def enable(cls): + """Enables inspector domain notifications. """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("enable", { }), None ) diff --git a/chromewhip/protocol/io.py b/chromewhip/protocol/io.py index 3ef93e9..aa7b6bc 100644 --- a/chromewhip/protocol/io.py +++ b/chromewhip/protocol/io.py @@ -13,12 +13,27 @@ log = logging.getLogger(__name__) -# StreamHandle: This is either obtained from another method or specifed as blob:<uuid> where <uuid> is an UUID of a Blob. +# StreamHandle: This is either obtained from another method or specifed as `blob:<uuid>` where`<uuid>` is an UUID of a Blob. StreamHandle = str class IO(PayloadMixin): """ Input/Output operations for streams produced by DevTools. """ + @classmethod + def close(cls, + handle: Union['StreamHandle'], + ): + """Close the stream, discard any temporary backing storage. + :param handle: Handle of the stream to close. + :type handle: StreamHandle + """ + return ( + cls.build_send_payload("close", { + "handle": handle, + }), + None + ) + @classmethod def read(cls, handle: Union['StreamHandle'], @@ -28,7 +43,8 @@ def read(cls, """Read a chunk of the stream :param handle: Handle of the stream to read. :type handle: StreamHandle - :param offset: Seek to the specified offset before reading (if not specificed, proceed with offset following the last read). + :param offset: Seek to the specified offset before reading (if not specificed, proceed with offset +following the last read). :type offset: int :param size: Maximum number of bytes to read (left upon the agent discretion if not specified). :type size: int @@ -55,21 +71,6 @@ def read(cls, }) ) - @classmethod - def close(cls, - handle: Union['StreamHandle'], - ): - """Close the stream, discard any temporary backing storage. - :param handle: Handle of the stream to close. - :type handle: StreamHandle - """ - return ( - cls.build_send_payload("close", { - "handle": handle, - }), - None - ) - @classmethod def resolveBlob(cls, objectId: Union['Runtime.RemoteObjectId'], diff --git a/chromewhip/protocol/layertree.py b/chromewhip/protocol/layertree.py index bc1089c..86e3a7e 100644 --- a/chromewhip/protocol/layertree.py +++ b/chromewhip/protocol/layertree.py @@ -104,26 +104,6 @@ def __init__(self, class LayerTree(PayloadMixin): """ """ - @classmethod - def enable(cls): - """Enables compositing tree inspection. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - - @classmethod - def disable(cls): - """Disables compositing tree inspection. - """ - return ( - cls.build_send_payload("disable", { - }), - None - ) - @classmethod def compositingReasons(cls, layerId: Union['LayerId'], @@ -145,23 +125,23 @@ def compositingReasons(cls, ) @classmethod - def makeSnapshot(cls, - layerId: Union['LayerId'], - ): - """Returns the layer snapshot identifier. - :param layerId: The id of the layer. - :type layerId: LayerId + def disable(cls): + """Disables compositing tree inspection. """ return ( - cls.build_send_payload("makeSnapshot", { - "layerId": layerId, + cls.build_send_payload("disable", { }), - cls.convert_payload({ - "snapshotId": { - "class": SnapshotId, - "optional": False - }, - }) + None + ) + + @classmethod + def enable(cls): + """Enables compositing tree inspection. + """ + return ( + cls.build_send_payload("enable", { + }), + None ) @classmethod @@ -185,18 +165,23 @@ def loadSnapshot(cls, ) @classmethod - def releaseSnapshot(cls, - snapshotId: Union['SnapshotId'], - ): - """Releases layer snapshot captured by the back-end. - :param snapshotId: The id of the layer snapshot. - :type snapshotId: SnapshotId + def makeSnapshot(cls, + layerId: Union['LayerId'], + ): + """Returns the layer snapshot identifier. + :param layerId: The id of the layer. + :type layerId: LayerId """ return ( - cls.build_send_payload("releaseSnapshot", { - "snapshotId": snapshotId, + cls.build_send_payload("makeSnapshot", { + "layerId": layerId, }), - None + cls.convert_payload({ + "snapshotId": { + "class": SnapshotId, + "optional": False + }, + }) ) @classmethod @@ -231,6 +216,21 @@ def profileSnapshot(cls, }) ) + @classmethod + def releaseSnapshot(cls, + snapshotId: Union['SnapshotId'], + ): + """Releases layer snapshot captured by the back-end. + :param snapshotId: The id of the layer snapshot. + :type snapshotId: SnapshotId + """ + return ( + cls.build_send_payload("releaseSnapshot", { + "snapshotId": snapshotId, + }), + None + ) + @classmethod def replaySnapshot(cls, snapshotId: Union['SnapshotId'], @@ -285,24 +285,6 @@ def snapshotCommandLog(cls, -class LayerTreeDidChangeEvent(BaseEvent): - - js_name = 'Layertree.layerTreeDidChange' - hashable = [] - is_hashable = False - - def __init__(self, - layers: Union['[Layer]', dict, None] = None, - ): - if isinstance(layers, dict): - layers = [Layer](**layers) - self.layers = layers - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - class LayerPaintedEvent(BaseEvent): js_name = 'Layertree.layerPainted' @@ -328,3 +310,21 @@ def build_hash(cls, layerId): h = '{}:{}'.format(cls.js_name, serialized_id_params) log.debug('generated hash = %s' % h) return h + + +class LayerTreeDidChangeEvent(BaseEvent): + + js_name = 'Layertree.layerTreeDidChange' + hashable = [] + is_hashable = False + + def __init__(self, + layers: Union['[Layer]', dict, None] = None, + ): + if isinstance(layers, dict): + layers = [Layer](**layers) + self.layers = layers + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') diff --git a/chromewhip/protocol/log.py b/chromewhip/protocol/log.py index da189c9..1bbf4e4 100644 --- a/chromewhip/protocol/log.py +++ b/chromewhip/protocol/log.py @@ -57,11 +57,11 @@ class Log(PayloadMixin): """ Provides access to log entries. """ @classmethod - def enable(cls): - """Enables log domain, sends the entries collected so far to the client by means of the entryAdded notification. + def clear(cls): + """Clears the log. """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("clear", { }), None ) @@ -77,11 +77,12 @@ def disable(cls): ) @classmethod - def clear(cls): - """Clears the log. + def enable(cls): + """Enables log domain, sends the entries collected so far to the client by means of the +`entryAdded` notification. """ return ( - cls.build_send_payload("clear", { + cls.build_send_payload("enable", { }), None ) diff --git a/chromewhip/protocol/memory.py b/chromewhip/protocol/memory.py index 4baf4d4..ca77acb 100644 --- a/chromewhip/protocol/memory.py +++ b/chromewhip/protocol/memory.py @@ -16,6 +16,28 @@ # PressureLevel: Memory pressure level. PressureLevel = str +# SamplingProfileNode: Heap profile sample. +class SamplingProfileNode(ChromeTypeBase): + def __init__(self, + size: Union['float'], + count: Union['float'], + stack: Union['[]'], + ): + + self.size = size + self.count = count + self.stack = stack + + +# SamplingProfile: Array of heap profile samples. +class SamplingProfile(ChromeTypeBase): + def __init__(self, + samples: Union['[SamplingProfileNode]'], + ): + + self.samples = samples + + class Memory(PayloadMixin): """ """ @@ -82,3 +104,47 @@ def simulatePressureNotification(cls, None ) + @classmethod + def startSampling(cls, + samplingInterval: Optional['int'] = None, + suppressRandomness: Optional['bool'] = None, + ): + """Start collecting native memory profile. + :param samplingInterval: Average number of bytes between samples. + :type samplingInterval: int + :param suppressRandomness: Do not randomize intervals between samples. + :type suppressRandomness: bool + """ + return ( + cls.build_send_payload("startSampling", { + "samplingInterval": samplingInterval, + "suppressRandomness": suppressRandomness, + }), + None + ) + + @classmethod + def stopSampling(cls): + """Stop collecting native memory profile. + """ + return ( + cls.build_send_payload("stopSampling", { + }), + None + ) + + @classmethod + def getSamplingProfile(cls): + """Retrieve collected native memory profile. + """ + return ( + cls.build_send_payload("getSamplingProfile", { + }), + cls.convert_payload({ + "profile": { + "class": SamplingProfile, + "optional": False + }, + }) + ) + diff --git a/chromewhip/protocol/network.py b/chromewhip/protocol/network.py index 76ef8a7..64d321c 100644 --- a/chromewhip/protocol/network.py +++ b/chromewhip/protocol/network.py @@ -12,6 +12,7 @@ from chromewhip.helpers import PayloadMixin, BaseEvent, ChromeTypeBase log = logging.getLogger(__name__) +from chromewhip.protocol import debugger as Debugger from chromewhip.protocol import runtime as Runtime from chromewhip.protocol import security as Security from chromewhip.protocol import page as Page @@ -40,7 +41,7 @@ # ConnectionType: The underlying connection technology that the browser is supposedly using. ConnectionType = str -# CookieSameSite: Represents the cookie's 'SameSite' status: https://tools.ietf.org/html/draft-west-first-party-cookies +# CookieSameSite: Represents the cookie's 'SameSite' status:https://tools.ietf.org/html/draft-west-first-party-cookies CookieSameSite = str # ResourceTiming: Timing information for the request. @@ -94,6 +95,7 @@ def __init__(self, initialPriority: Union['ResourcePriority'], referrerPolicy: Union['str'], postData: Optional['str'] = None, + hasPostData: Optional['bool'] = None, mixedContentType: Optional['Security.MixedContentType'] = None, isLinkPreload: Optional['bool'] = None, ): @@ -102,6 +104,7 @@ def __init__(self, self.method = method self.headers = headers self.postData = postData + self.hasPostData = hasPostData self.mixedContentType = mixedContentType self.initialPriority = initialPriority self.referrerPolicy = referrerPolicy @@ -175,8 +178,8 @@ def __init__(self, mimeType: Union['str'], connectionReused: Union['bool'], connectionId: Union['float'], - securityState: Union['Security.SecurityState'], encodedDataLength: Union['float'], + securityState: Union['Security.SecurityState'], headersText: Optional['str'] = None, requestHeaders: Optional['Headers'] = None, requestHeadersText: Optional['str'] = None, @@ -361,188 +364,277 @@ def __init__(self, self.password = password +# InterceptionStage: Stages of the interception to begin intercepting. Request will intercept before the request issent. Response will intercept after the response is received. +InterceptionStage = str + # RequestPattern: Request pattern for interception. class RequestPattern(ChromeTypeBase): def __init__(self, urlPattern: Optional['str'] = None, resourceType: Optional['Page.ResourceType'] = None, + interceptionStage: Optional['InterceptionStage'] = None, ): self.urlPattern = urlPattern self.resourceType = resourceType + self.interceptionStage = interceptionStage class Network(PayloadMixin): - """ Network domain allows tracking network activities of the page. It exposes information about http, file, data and other requests and responses, their headers, bodies, timing, etc. + """ Network domain allows tracking network activities of the page. It exposes information about http, +file, data and other requests and responses, their headers, bodies, timing, etc. """ @classmethod - def enable(cls, - maxTotalBufferSize: Optional['int'] = None, - maxResourceBufferSize: Optional['int'] = None, - ): - """Enables network tracking, network events will now be delivered to the client. - :param maxTotalBufferSize: Buffer size in bytes to use when preserving network payloads (XHRs, etc). - :type maxTotalBufferSize: int - :param maxResourceBufferSize: Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc). - :type maxResourceBufferSize: int + def canClearBrowserCache(cls): + """Tells whether clearing browser cache is supported. """ return ( - cls.build_send_payload("enable", { - "maxTotalBufferSize": maxTotalBufferSize, - "maxResourceBufferSize": maxResourceBufferSize, + cls.build_send_payload("canClearBrowserCache", { }), - None + cls.convert_payload({ + "result": { + "class": bool, + "optional": False + }, + }) ) @classmethod - def disable(cls): - """Disables network tracking, prevents network events from being sent to the client. + def canClearBrowserCookies(cls): + """Tells whether clearing browser cookies is supported. """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("canClearBrowserCookies", { }), - None + cls.convert_payload({ + "result": { + "class": bool, + "optional": False + }, + }) ) @classmethod - def setUserAgentOverride(cls, - userAgent: Union['str'], - ): - """Allows overriding user agent with the given string. - :param userAgent: User agent to use. - :type userAgent: str + def canEmulateNetworkConditions(cls): + """Tells whether emulation of network conditions is supported. """ return ( - cls.build_send_payload("setUserAgentOverride", { - "userAgent": userAgent, + cls.build_send_payload("canEmulateNetworkConditions", { + }), + cls.convert_payload({ + "result": { + "class": bool, + "optional": False + }, + }) + ) + + @classmethod + def clearBrowserCache(cls): + """Clears browser cache. + """ + return ( + cls.build_send_payload("clearBrowserCache", { }), None ) @classmethod - def setExtraHTTPHeaders(cls, - headers: Union['Headers'], - ): - """Specifies whether to always send extra HTTP headers with the requests from this page. - :param headers: Map with extra HTTP headers. - :type headers: Headers + def clearBrowserCookies(cls): + """Clears browser cookies. """ return ( - cls.build_send_payload("setExtraHTTPHeaders", { - "headers": headers, + cls.build_send_payload("clearBrowserCookies", { }), None ) @classmethod - def getResponseBody(cls, - requestId: Union['RequestId'], - ): - """Returns content served for the given request. - :param requestId: Identifier of the network request to get content for. - :type requestId: RequestId + def continueInterceptedRequest(cls, + interceptionId: Union['InterceptionId'], + errorReason: Optional['ErrorReason'] = None, + rawResponse: Optional['str'] = None, + url: Optional['str'] = None, + method: Optional['str'] = None, + postData: Optional['str'] = None, + headers: Optional['Headers'] = None, + authChallengeResponse: Optional['AuthChallengeResponse'] = None, + ): + """Response to Network.requestIntercepted which either modifies the request to continue with any +modifications, or blocks it, or completes it with the provided response bytes. If a network +fetch occurs as a result which encounters a redirect an additional Network.requestIntercepted +event will be sent with the same InterceptionId. + :param interceptionId: + :type interceptionId: InterceptionId + :param errorReason: If set this causes the request to fail with the given reason. Passing `Aborted` for requests +marked with `isNavigationRequest` also cancels the navigation. Must not be set in response +to an authChallenge. + :type errorReason: ErrorReason + :param rawResponse: If set the requests completes using with the provided base64 encoded raw response, including +HTTP status line and headers etc... Must not be set in response to an authChallenge. + :type rawResponse: str + :param url: If set the request url will be modified in a way that's not observable by page. Must not be +set in response to an authChallenge. + :type url: str + :param method: If set this allows the request method to be overridden. Must not be set in response to an +authChallenge. + :type method: str + :param postData: If set this allows postData to be set. Must not be set in response to an authChallenge. + :type postData: str + :param headers: If set this allows the request headers to be changed. Must not be set in response to an +authChallenge. + :type headers: Headers + :param authChallengeResponse: Response to a requestIntercepted with an authChallenge. Must not be set otherwise. + :type authChallengeResponse: AuthChallengeResponse """ return ( - cls.build_send_payload("getResponseBody", { - "requestId": requestId, + cls.build_send_payload("continueInterceptedRequest", { + "interceptionId": interceptionId, + "errorReason": errorReason, + "rawResponse": rawResponse, + "url": url, + "method": method, + "postData": postData, + "headers": headers, + "authChallengeResponse": authChallengeResponse, }), - cls.convert_payload({ - "body": { - "class": str, - "optional": False - }, - "base64Encoded": { - "class": bool, - "optional": False - }, - }) + None ) @classmethod - def setBlockedURLs(cls, - urls: Union['[]'], - ): - """Blocks URLs from loading. - :param urls: URL patterns to block. Wildcards ('*') are allowed. - :type urls: [] + def deleteCookies(cls, + name: Union['str'], + url: Optional['str'] = None, + domain: Optional['str'] = None, + path: Optional['str'] = None, + ): + """Deletes browser cookies with matching name and url or domain/path pair. + :param name: Name of the cookies to remove. + :type name: str + :param url: If specified, deletes all the cookies with the given name where domain and path match +provided URL. + :type url: str + :param domain: If specified, deletes only cookies with the exact domain. + :type domain: str + :param path: If specified, deletes only cookies with the exact path. + :type path: str """ return ( - cls.build_send_payload("setBlockedURLs", { - "urls": urls, + cls.build_send_payload("deleteCookies", { + "name": name, + "url": url, + "domain": domain, + "path": path, }), None ) @classmethod - def replayXHR(cls, - requestId: Union['RequestId'], - ): - """This method sends a new XMLHttpRequest which is identical to the original one. The following parameters should be identical: method, url, async, request body, extra headers, withCredentials attribute, user, password. - :param requestId: Identifier of XHR to replay. - :type requestId: RequestId + def disable(cls): + """Disables network tracking, prevents network events from being sent to the client. """ return ( - cls.build_send_payload("replayXHR", { - "requestId": requestId, + cls.build_send_payload("disable", { }), None ) @classmethod - def canClearBrowserCache(cls): - """Tells whether clearing browser cache is supported. + def emulateNetworkConditions(cls, + offline: Union['bool'], + latency: Union['float'], + downloadThroughput: Union['float'], + uploadThroughput: Union['float'], + connectionType: Optional['ConnectionType'] = None, + ): + """Activates emulation of network conditions. + :param offline: True to emulate internet disconnection. + :type offline: bool + :param latency: Minimum latency from request sent to response headers received (ms). + :type latency: float + :param downloadThroughput: Maximal aggregated download throughput (bytes/sec). -1 disables download throttling. + :type downloadThroughput: float + :param uploadThroughput: Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling. + :type uploadThroughput: float + :param connectionType: Connection type if known. + :type connectionType: ConnectionType """ return ( - cls.build_send_payload("canClearBrowserCache", { + cls.build_send_payload("emulateNetworkConditions", { + "offline": offline, + "latency": latency, + "downloadThroughput": downloadThroughput, + "uploadThroughput": uploadThroughput, + "connectionType": connectionType, }), - cls.convert_payload({ - "result": { - "class": bool, - "optional": False - }, - }) + None ) @classmethod - def clearBrowserCache(cls): - """Clears browser cache. + def enable(cls, + maxTotalBufferSize: Optional['int'] = None, + maxResourceBufferSize: Optional['int'] = None, + maxPostDataSize: Optional['int'] = None, + ): + """Enables network tracking, network events will now be delivered to the client. + :param maxTotalBufferSize: Buffer size in bytes to use when preserving network payloads (XHRs, etc). + :type maxTotalBufferSize: int + :param maxResourceBufferSize: Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc). + :type maxResourceBufferSize: int + :param maxPostDataSize: Longest post body size (in bytes) that would be included in requestWillBeSent notification + :type maxPostDataSize: int """ return ( - cls.build_send_payload("clearBrowserCache", { + cls.build_send_payload("enable", { + "maxTotalBufferSize": maxTotalBufferSize, + "maxResourceBufferSize": maxResourceBufferSize, + "maxPostDataSize": maxPostDataSize, }), None ) @classmethod - def canClearBrowserCookies(cls): - """Tells whether clearing browser cookies is supported. + def getAllCookies(cls): + """Returns all browser cookies. Depending on the backend support, will return detailed cookie +information in the `cookies` field. """ return ( - cls.build_send_payload("canClearBrowserCookies", { + cls.build_send_payload("getAllCookies", { }), cls.convert_payload({ - "result": { - "class": bool, + "cookies": { + "class": [Cookie], "optional": False }, }) ) @classmethod - def clearBrowserCookies(cls): - """Clears browser cookies. + def getCertificate(cls, + origin: Union['str'], + ): + """Returns the DER-encoded certificate. + :param origin: Origin to get certificate for. + :type origin: str """ return ( - cls.build_send_payload("clearBrowserCookies", { + cls.build_send_payload("getCertificate", { + "origin": origin, }), - None + cls.convert_payload({ + "tableNames": { + "class": [], + "optional": False + }, + }) ) @classmethod def getCookies(cls, urls: Optional['[]'] = None, ): - """Returns all browser cookies for the current URL. Depending on the backend support, will return detailed cookie information in the cookies field. + """Returns all browser cookies for the current URL. Depending on the backend support, will return +detailed cookie information in the `cookies` field. :param urls: The list of URLs for which applicable cookies will be fetched :type urls: [] """ @@ -559,43 +651,163 @@ def getCookies(cls, ) @classmethod - def getAllCookies(cls): - """Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the cookies field. + def getResponseBody(cls, + requestId: Union['RequestId'], + ): + """Returns content served for the given request. + :param requestId: Identifier of the network request to get content for. + :type requestId: RequestId """ return ( - cls.build_send_payload("getAllCookies", { + cls.build_send_payload("getResponseBody", { + "requestId": requestId, }), cls.convert_payload({ - "cookies": { - "class": [Cookie], + "body": { + "class": str, + "optional": False + }, + "base64Encoded": { + "class": bool, "optional": False }, }) ) @classmethod - def deleteCookies(cls, - name: Union['str'], - url: Optional['str'] = None, - domain: Optional['str'] = None, - path: Optional['str'] = None, - ): - """Deletes browser cookies with matching name and url or domain/path pair. - :param name: Name of the cookies to remove. - :type name: str - :param url: If specified, deletes all the cookies with the given name where domain and path match provided URL. - :type url: str - :param domain: If specified, deletes only cookies with the exact domain. - :type domain: str - :param path: If specified, deletes only cookies with the exact path. - :type path: str + def getRequestPostData(cls, + requestId: Union['RequestId'], + ): + """Returns post data sent with the request. Returns an error when no data was sent with the request. + :param requestId: Identifier of the network request to get content for. + :type requestId: RequestId """ return ( - cls.build_send_payload("deleteCookies", { - "name": name, - "url": url, - "domain": domain, - "path": path, + cls.build_send_payload("getRequestPostData", { + "requestId": requestId, + }), + cls.convert_payload({ + "postData": { + "class": str, + "optional": False + }, + }) + ) + + @classmethod + def getResponseBodyForInterception(cls, + interceptionId: Union['InterceptionId'], + ): + """Returns content served for the given currently intercepted request. + :param interceptionId: Identifier for the intercepted request to get body for. + :type interceptionId: InterceptionId + """ + return ( + cls.build_send_payload("getResponseBodyForInterception", { + "interceptionId": interceptionId, + }), + cls.convert_payload({ + "body": { + "class": str, + "optional": False + }, + "base64Encoded": { + "class": bool, + "optional": False + }, + }) + ) + + @classmethod + def replayXHR(cls, + requestId: Union['RequestId'], + ): + """This method sends a new XMLHttpRequest which is identical to the original one. The following +parameters should be identical: method, url, async, request body, extra headers, withCredentials +attribute, user, password. + :param requestId: Identifier of XHR to replay. + :type requestId: RequestId + """ + return ( + cls.build_send_payload("replayXHR", { + "requestId": requestId, + }), + None + ) + + @classmethod + def searchInResponseBody(cls, + requestId: Union['RequestId'], + query: Union['str'], + caseSensitive: Optional['bool'] = None, + isRegex: Optional['bool'] = None, + ): + """Searches for given string in response content. + :param requestId: Identifier of the network response to search. + :type requestId: RequestId + :param query: String to search for. + :type query: str + :param caseSensitive: If true, search is case sensitive. + :type caseSensitive: bool + :param isRegex: If true, treats string parameter as regex. + :type isRegex: bool + """ + return ( + cls.build_send_payload("searchInResponseBody", { + "requestId": requestId, + "query": query, + "caseSensitive": caseSensitive, + "isRegex": isRegex, + }), + cls.convert_payload({ + "result": { + "class": [Debugger.SearchMatch], + "optional": False + }, + }) + ) + + @classmethod + def setBlockedURLs(cls, + urls: Union['[]'], + ): + """Blocks URLs from loading. + :param urls: URL patterns to block. Wildcards ('*') are allowed. + :type urls: [] + """ + return ( + cls.build_send_payload("setBlockedURLs", { + "urls": urls, + }), + None + ) + + @classmethod + def setBypassServiceWorker(cls, + bypass: Union['bool'], + ): + """Toggles ignoring of service worker for each request. + :param bypass: Bypass service worker and load from network. + :type bypass: bool + """ + return ( + cls.build_send_payload("setBypassServiceWorker", { + "bypass": bypass, + }), + None + ) + + @classmethod + def setCacheDisabled(cls, + cacheDisabled: Union['bool'], + ): + """Toggles ignoring cache for each request. If `true`, cache will not be used. + :param cacheDisabled: Cache disabled state. + :type cacheDisabled: bool + """ + return ( + cls.build_send_payload("setCacheDisabled", { + "cacheDisabled": cacheDisabled, }), None ) @@ -617,7 +829,8 @@ def setCookie(cls, :type name: str :param value: Cookie value. :type value: str - :param url: The request-URI to associate with the setting of the cookie. This value can affect the default domain and path values of the created cookie. + :param url: The request-URI to associate with the setting of the cookie. This value can affect the +default domain and path values of the created cookie. :type url: str :param domain: Cookie domain. :type domain: str @@ -667,82 +880,6 @@ def setCookies(cls, None ) - @classmethod - def canEmulateNetworkConditions(cls): - """Tells whether emulation of network conditions is supported. - """ - return ( - cls.build_send_payload("canEmulateNetworkConditions", { - }), - cls.convert_payload({ - "result": { - "class": bool, - "optional": False - }, - }) - ) - - @classmethod - def emulateNetworkConditions(cls, - offline: Union['bool'], - latency: Union['float'], - downloadThroughput: Union['float'], - uploadThroughput: Union['float'], - connectionType: Optional['ConnectionType'] = None, - ): - """Activates emulation of network conditions. - :param offline: True to emulate internet disconnection. - :type offline: bool - :param latency: Minimum latency from request sent to response headers received (ms). - :type latency: float - :param downloadThroughput: Maximal aggregated download throughput (bytes/sec). -1 disables download throttling. - :type downloadThroughput: float - :param uploadThroughput: Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling. - :type uploadThroughput: float - :param connectionType: Connection type if known. - :type connectionType: ConnectionType - """ - return ( - cls.build_send_payload("emulateNetworkConditions", { - "offline": offline, - "latency": latency, - "downloadThroughput": downloadThroughput, - "uploadThroughput": uploadThroughput, - "connectionType": connectionType, - }), - None - ) - - @classmethod - def setCacheDisabled(cls, - cacheDisabled: Union['bool'], - ): - """Toggles ignoring cache for each request. If true, cache will not be used. - :param cacheDisabled: Cache disabled state. - :type cacheDisabled: bool - """ - return ( - cls.build_send_payload("setCacheDisabled", { - "cacheDisabled": cacheDisabled, - }), - None - ) - - @classmethod - def setBypassServiceWorker(cls, - bypass: Union['bool'], - ): - """Toggles ignoring of service worker for each request. - :param bypass: Bypass service worker and load from network. - :type bypass: bool - """ - return ( - cls.build_send_payload("setBypassServiceWorker", { - "bypass": bypass, - }), - None - ) - @classmethod def setDataSizeLimitsForTest(cls, maxTotalSize: Union['int'], @@ -763,23 +900,18 @@ def setDataSizeLimitsForTest(cls, ) @classmethod - def getCertificate(cls, - origin: Union['str'], - ): - """Returns the DER-encoded certificate. - :param origin: Origin to get certificate for. - :type origin: str + def setExtraHTTPHeaders(cls, + headers: Union['Headers'], + ): + """Specifies whether to always send extra HTTP headers with the requests from this page. + :param headers: Map with extra HTTP headers. + :type headers: Headers """ return ( - cls.build_send_payload("getCertificate", { - "origin": origin, + cls.build_send_payload("setExtraHTTPHeaders", { + "headers": headers, }), - cls.convert_payload({ - "tableNames": { - "class": [], - "optional": False - }, - }) + None ) @classmethod @@ -787,7 +919,8 @@ def setRequestInterception(cls, patterns: Union['[RequestPattern]'], ): """Sets the requests to intercept that match a the provided patterns and optionally resource types. - :param patterns: Requests matching any of these patterns will be forwarded and wait for the corresponding continueInterceptedRequest call. + :param patterns: Requests matching any of these patterns will be forwarded and wait for the corresponding +continueInterceptedRequest call. :type patterns: [RequestPattern] """ return ( @@ -798,70 +931,46 @@ def setRequestInterception(cls, ) @classmethod - def continueInterceptedRequest(cls, - interceptionId: Union['InterceptionId'], - errorReason: Optional['ErrorReason'] = None, - rawResponse: Optional['str'] = None, - url: Optional['str'] = None, - method: Optional['str'] = None, - postData: Optional['str'] = None, - headers: Optional['Headers'] = None, - authChallengeResponse: Optional['AuthChallengeResponse'] = None, - ): - """Response to Network.requestIntercepted which either modifies the request to continue with any modifications, or blocks it, or completes it with the provided response bytes. If a network fetch occurs as a result which encounters a redirect an additional Network.requestIntercepted event will be sent with the same InterceptionId. - :param interceptionId: - :type interceptionId: InterceptionId - :param errorReason: If set this causes the request to fail with the given reason. Passing Aborted for requests marked with isNavigationRequest also cancels the navigation. Must not be set in response to an authChallenge. - :type errorReason: ErrorReason - :param rawResponse: If set the requests completes using with the provided base64 encoded raw response, including HTTP status line and headers etc... Must not be set in response to an authChallenge. - :type rawResponse: str - :param url: If set the request url will be modified in a way that's not observable by page. Must not be set in response to an authChallenge. - :type url: str - :param method: If set this allows the request method to be overridden. Must not be set in response to an authChallenge. - :type method: str - :param postData: If set this allows postData to be set. Must not be set in response to an authChallenge. - :type postData: str - :param headers: If set this allows the request headers to be changed. Must not be set in response to an authChallenge. - :type headers: Headers - :param authChallengeResponse: Response to a requestIntercepted with an authChallenge. Must not be set otherwise. - :type authChallengeResponse: AuthChallengeResponse + def setUserAgentOverride(cls, + userAgent: Union['str'], + ): + """Allows overriding user agent with the given string. + :param userAgent: User agent to use. + :type userAgent: str """ return ( - cls.build_send_payload("continueInterceptedRequest", { - "interceptionId": interceptionId, - "errorReason": errorReason, - "rawResponse": rawResponse, - "url": url, - "method": method, - "postData": postData, - "headers": headers, - "authChallengeResponse": authChallengeResponse, + cls.build_send_payload("setUserAgentOverride", { + "userAgent": userAgent, }), None ) -class ResourceChangedPriorityEvent(BaseEvent): +class DataReceivedEvent(BaseEvent): - js_name = 'Network.resourceChangedPriority' + js_name = 'Network.dataReceived' hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], - newPriority: Union['ResourcePriority', dict], timestamp: Union['MonotonicTime', dict], + dataLength: Union['int', dict], + encodedDataLength: Union['int', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) self.requestId = requestId - if isinstance(newPriority, dict): - newPriority = ResourcePriority(**newPriority) - self.newPriority = newPriority if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp + if isinstance(dataLength, dict): + dataLength = int(**dataLength) + self.dataLength = dataLength + if isinstance(encodedDataLength, dict): + encodedDataLength = int(**encodedDataLength) + self.encodedDataLength = encodedDataLength @classmethod def build_hash(cls, requestId): @@ -873,57 +982,174 @@ def build_hash(cls, requestId): return h -class RequestWillBeSentEvent(BaseEvent): +class EventSourceMessageReceivedEvent(BaseEvent): - js_name = 'Network.requestWillBeSent' - hashable = ['loaderId', 'frameId', 'requestId'] + js_name = 'Network.eventSourceMessageReceived' + hashable = ['requestId', 'eventId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], - loaderId: Union['LoaderId', dict], - documentURL: Union['str', dict], - request: Union['Request', dict], timestamp: Union['MonotonicTime', dict], - wallTime: Union['TimeSinceEpoch', dict], - initiator: Union['Initiator', dict], - redirectResponse: Union['Response', dict, None] = None, - type: Union['Page.ResourceType', dict, None] = None, - frameId: Union['Page.FrameId', dict, None] = None, + eventName: Union['str', dict], + eventId: Union['str', dict], + data: Union['str', dict], + ): + if isinstance(requestId, dict): + requestId = RequestId(**requestId) + self.requestId = requestId + if isinstance(timestamp, dict): + timestamp = MonotonicTime(**timestamp) + self.timestamp = timestamp + if isinstance(eventName, dict): + eventName = str(**eventName) + self.eventName = eventName + if isinstance(eventId, dict): + eventId = str(**eventId) + self.eventId = eventId + if isinstance(data, dict): + data = str(**data) + self.data = data + + @classmethod + def build_hash(cls, requestId, eventId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class LoadingFailedEvent(BaseEvent): + + js_name = 'Network.loadingFailed' + hashable = ['requestId'] + is_hashable = True + + def __init__(self, + requestId: Union['RequestId', dict], + timestamp: Union['MonotonicTime', dict], + type: Union['Page.ResourceType', dict], + errorText: Union['str', dict], + canceled: Union['bool', dict, None] = None, + blockedReason: Union['BlockedReason', dict, None] = None, ): if isinstance(requestId, dict): requestId = RequestId(**requestId) self.requestId = requestId - if isinstance(loaderId, dict): - loaderId = LoaderId(**loaderId) - self.loaderId = loaderId - if isinstance(documentURL, dict): - documentURL = str(**documentURL) - self.documentURL = documentURL - if isinstance(request, dict): - request = Request(**request) - self.request = request if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp - if isinstance(wallTime, dict): - wallTime = TimeSinceEpoch(**wallTime) - self.wallTime = wallTime - if isinstance(initiator, dict): - initiator = Initiator(**initiator) - self.initiator = initiator - if isinstance(redirectResponse, dict): - redirectResponse = Response(**redirectResponse) - self.redirectResponse = redirectResponse if isinstance(type, dict): type = Page.ResourceType(**type) self.type = type + if isinstance(errorText, dict): + errorText = str(**errorText) + self.errorText = errorText + if isinstance(canceled, dict): + canceled = bool(**canceled) + self.canceled = canceled + if isinstance(blockedReason, dict): + blockedReason = BlockedReason(**blockedReason) + self.blockedReason = blockedReason + + @classmethod + def build_hash(cls, requestId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class LoadingFinishedEvent(BaseEvent): + + js_name = 'Network.loadingFinished' + hashable = ['requestId'] + is_hashable = True + + def __init__(self, + requestId: Union['RequestId', dict], + timestamp: Union['MonotonicTime', dict], + encodedDataLength: Union['float', dict], + blockedCrossSiteDocument: Union['bool', dict, None] = None, + ): + if isinstance(requestId, dict): + requestId = RequestId(**requestId) + self.requestId = requestId + if isinstance(timestamp, dict): + timestamp = MonotonicTime(**timestamp) + self.timestamp = timestamp + if isinstance(encodedDataLength, dict): + encodedDataLength = float(**encodedDataLength) + self.encodedDataLength = encodedDataLength + if isinstance(blockedCrossSiteDocument, dict): + blockedCrossSiteDocument = bool(**blockedCrossSiteDocument) + self.blockedCrossSiteDocument = blockedCrossSiteDocument + + @classmethod + def build_hash(cls, requestId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class RequestInterceptedEvent(BaseEvent): + + js_name = 'Network.requestIntercepted' + hashable = ['interceptionId', 'frameId'] + is_hashable = True + + def __init__(self, + interceptionId: Union['InterceptionId', dict], + request: Union['Request', dict], + frameId: Union['Page.FrameId', dict], + resourceType: Union['Page.ResourceType', dict], + isNavigationRequest: Union['bool', dict], + redirectUrl: Union['str', dict, None] = None, + authChallenge: Union['AuthChallenge', dict, None] = None, + responseErrorReason: Union['ErrorReason', dict, None] = None, + responseStatusCode: Union['int', dict, None] = None, + responseHeaders: Union['Headers', dict, None] = None, + ): + if isinstance(interceptionId, dict): + interceptionId = InterceptionId(**interceptionId) + self.interceptionId = interceptionId + if isinstance(request, dict): + request = Request(**request) + self.request = request if isinstance(frameId, dict): frameId = Page.FrameId(**frameId) self.frameId = frameId + if isinstance(resourceType, dict): + resourceType = Page.ResourceType(**resourceType) + self.resourceType = resourceType + if isinstance(isNavigationRequest, dict): + isNavigationRequest = bool(**isNavigationRequest) + self.isNavigationRequest = isNavigationRequest + if isinstance(redirectUrl, dict): + redirectUrl = str(**redirectUrl) + self.redirectUrl = redirectUrl + if isinstance(authChallenge, dict): + authChallenge = AuthChallenge(**authChallenge) + self.authChallenge = authChallenge + if isinstance(responseErrorReason, dict): + responseErrorReason = ErrorReason(**responseErrorReason) + self.responseErrorReason = responseErrorReason + if isinstance(responseStatusCode, dict): + responseStatusCode = int(**responseStatusCode) + self.responseStatusCode = responseStatusCode + if isinstance(responseHeaders, dict): + responseHeaders = Headers(**responseHeaders) + self.responseHeaders = responseHeaders @classmethod - def build_hash(cls, loaderId, frameId, requestId): + def build_hash(cls, interceptionId, frameId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -955,18 +1181,22 @@ def build_hash(cls, requestId): return h -class ResponseReceivedEvent(BaseEvent): +class RequestWillBeSentEvent(BaseEvent): - js_name = 'Network.responseReceived' - hashable = ['loaderId', 'frameId', 'requestId'] + js_name = 'Network.requestWillBeSent' + hashable = ['requestId', 'loaderId', 'frameId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], loaderId: Union['LoaderId', dict], + documentURL: Union['str', dict], + request: Union['Request', dict], timestamp: Union['MonotonicTime', dict], - type: Union['Page.ResourceType', dict], - response: Union['Response', dict], + wallTime: Union['TimeSinceEpoch', dict], + initiator: Union['Initiator', dict], + redirectResponse: Union['Response', dict, None] = None, + type: Union['Page.ResourceType', dict, None] = None, frameId: Union['Page.FrameId', dict, None] = None, ): if isinstance(requestId, dict): @@ -975,56 +1205,33 @@ def __init__(self, if isinstance(loaderId, dict): loaderId = LoaderId(**loaderId) self.loaderId = loaderId + if isinstance(documentURL, dict): + documentURL = str(**documentURL) + self.documentURL = documentURL + if isinstance(request, dict): + request = Request(**request) + self.request = request if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp + if isinstance(wallTime, dict): + wallTime = TimeSinceEpoch(**wallTime) + self.wallTime = wallTime + if isinstance(initiator, dict): + initiator = Initiator(**initiator) + self.initiator = initiator + if isinstance(redirectResponse, dict): + redirectResponse = Response(**redirectResponse) + self.redirectResponse = redirectResponse if isinstance(type, dict): type = Page.ResourceType(**type) self.type = type - if isinstance(response, dict): - response = Response(**response) - self.response = response if isinstance(frameId, dict): frameId = Page.FrameId(**frameId) self.frameId = frameId @classmethod - def build_hash(cls, loaderId, frameId, requestId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - -class DataReceivedEvent(BaseEvent): - - js_name = 'Network.dataReceived' - hashable = ['requestId'] - is_hashable = True - - def __init__(self, - requestId: Union['RequestId', dict], - timestamp: Union['MonotonicTime', dict], - dataLength: Union['int', dict], - encodedDataLength: Union['int', dict], - ): - if isinstance(requestId, dict): - requestId = RequestId(**requestId) - self.requestId = requestId - if isinstance(timestamp, dict): - timestamp = MonotonicTime(**timestamp) - self.timestamp = timestamp - if isinstance(dataLength, dict): - dataLength = int(**dataLength) - self.dataLength = dataLength - if isinstance(encodedDataLength, dict): - encodedDataLength = int(**encodedDataLength) - self.encodedDataLength = encodedDataLength - - @classmethod - def build_hash(cls, requestId): + def build_hash(cls, requestId, loaderId, frameId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1033,26 +1240,26 @@ def build_hash(cls, requestId): return h -class LoadingFinishedEvent(BaseEvent): +class ResourceChangedPriorityEvent(BaseEvent): - js_name = 'Network.loadingFinished' + js_name = 'Network.resourceChangedPriority' hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], + newPriority: Union['ResourcePriority', dict], timestamp: Union['MonotonicTime', dict], - encodedDataLength: Union['float', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) self.requestId = requestId + if isinstance(newPriority, dict): + newPriority = ResourcePriority(**newPriority) + self.newPriority = newPriority if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp - if isinstance(encodedDataLength, dict): - encodedDataLength = float(**encodedDataLength) - self.encodedDataLength = encodedDataLength @classmethod def build_hash(cls, requestId): @@ -1064,76 +1271,41 @@ def build_hash(cls, requestId): return h -class LoadingFailedEvent(BaseEvent): +class ResponseReceivedEvent(BaseEvent): - js_name = 'Network.loadingFailed' - hashable = ['requestId'] + js_name = 'Network.responseReceived' + hashable = ['requestId', 'loaderId', 'frameId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], + loaderId: Union['LoaderId', dict], timestamp: Union['MonotonicTime', dict], type: Union['Page.ResourceType', dict], - errorText: Union['str', dict], - canceled: Union['bool', dict, None] = None, - blockedReason: Union['BlockedReason', dict, None] = None, + response: Union['Response', dict], + frameId: Union['Page.FrameId', dict, None] = None, ): if isinstance(requestId, dict): requestId = RequestId(**requestId) self.requestId = requestId + if isinstance(loaderId, dict): + loaderId = LoaderId(**loaderId) + self.loaderId = loaderId if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp if isinstance(type, dict): type = Page.ResourceType(**type) self.type = type - if isinstance(errorText, dict): - errorText = str(**errorText) - self.errorText = errorText - if isinstance(canceled, dict): - canceled = bool(**canceled) - self.canceled = canceled - if isinstance(blockedReason, dict): - blockedReason = BlockedReason(**blockedReason) - self.blockedReason = blockedReason - - @classmethod - def build_hash(cls, requestId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - -class WebSocketWillSendHandshakeRequestEvent(BaseEvent): - - js_name = 'Network.webSocketWillSendHandshakeRequest' - hashable = ['requestId'] - is_hashable = True - - def __init__(self, - requestId: Union['RequestId', dict], - timestamp: Union['MonotonicTime', dict], - wallTime: Union['TimeSinceEpoch', dict], - request: Union['WebSocketRequest', dict], - ): - if isinstance(requestId, dict): - requestId = RequestId(**requestId) - self.requestId = requestId - if isinstance(timestamp, dict): - timestamp = MonotonicTime(**timestamp) - self.timestamp = timestamp - if isinstance(wallTime, dict): - wallTime = TimeSinceEpoch(**wallTime) - self.wallTime = wallTime - if isinstance(request, dict): - request = WebSocketRequest(**request) - self.request = request + if isinstance(response, dict): + response = Response(**response) + self.response = response + if isinstance(frameId, dict): + frameId = Page.FrameId(**frameId) + self.frameId = frameId @classmethod - def build_hash(cls, requestId): + def build_hash(cls, requestId, loaderId, frameId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1142,16 +1314,15 @@ def build_hash(cls, requestId): return h -class WebSocketHandshakeResponseReceivedEvent(BaseEvent): +class WebSocketClosedEvent(BaseEvent): - js_name = 'Network.webSocketHandshakeResponseReceived' + js_name = 'Network.webSocketClosed' hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], timestamp: Union['MonotonicTime', dict], - response: Union['WebSocketResponse', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) @@ -1159,9 +1330,6 @@ def __init__(self, if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp - if isinstance(response, dict): - response = WebSocketResponse(**response) - self.response = response @classmethod def build_hash(cls, requestId): @@ -1204,15 +1372,16 @@ def build_hash(cls, requestId): return h -class WebSocketClosedEvent(BaseEvent): +class WebSocketFrameErrorEvent(BaseEvent): - js_name = 'Network.webSocketClosed' + js_name = 'Network.webSocketFrameError' hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], timestamp: Union['MonotonicTime', dict], + errorMessage: Union['str', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) @@ -1220,6 +1389,9 @@ def __init__(self, if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp + if isinstance(errorMessage, dict): + errorMessage = str(**errorMessage) + self.errorMessage = errorMessage @classmethod def build_hash(cls, requestId): @@ -1262,16 +1434,16 @@ def build_hash(cls, requestId): return h -class WebSocketFrameErrorEvent(BaseEvent): +class WebSocketFrameSentEvent(BaseEvent): - js_name = 'Network.webSocketFrameError' + js_name = 'Network.webSocketFrameSent' hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], timestamp: Union['MonotonicTime', dict], - errorMessage: Union['str', dict], + response: Union['WebSocketFrame', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) @@ -1279,9 +1451,9 @@ def __init__(self, if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp - if isinstance(errorMessage, dict): - errorMessage = str(**errorMessage) - self.errorMessage = errorMessage + if isinstance(response, dict): + response = WebSocketFrame(**response) + self.response = response @classmethod def build_hash(cls, requestId): @@ -1293,16 +1465,16 @@ def build_hash(cls, requestId): return h -class WebSocketFrameSentEvent(BaseEvent): +class WebSocketHandshakeResponseReceivedEvent(BaseEvent): - js_name = 'Network.webSocketFrameSent' + js_name = 'Network.webSocketHandshakeResponseReceived' hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], timestamp: Union['MonotonicTime', dict], - response: Union['WebSocketFrame', dict], + response: Union['WebSocketResponse', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) @@ -1311,7 +1483,7 @@ def __init__(self, timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp if isinstance(response, dict): - response = WebSocketFrame(**response) + response = WebSocketResponse(**response) self.response = response @classmethod @@ -1324,18 +1496,17 @@ def build_hash(cls, requestId): return h -class EventSourceMessageReceivedEvent(BaseEvent): +class WebSocketWillSendHandshakeRequestEvent(BaseEvent): - js_name = 'Network.eventSourceMessageReceived' - hashable = ['eventId', 'requestId'] + js_name = 'Network.webSocketWillSendHandshakeRequest' + hashable = ['requestId'] is_hashable = True def __init__(self, requestId: Union['RequestId', dict], timestamp: Union['MonotonicTime', dict], - eventName: Union['str', dict], - eventId: Union['str', dict], - data: Union['str', dict], + wallTime: Union['TimeSinceEpoch', dict], + request: Union['WebSocketRequest', dict], ): if isinstance(requestId, dict): requestId = RequestId(**requestId) @@ -1343,73 +1514,15 @@ def __init__(self, if isinstance(timestamp, dict): timestamp = MonotonicTime(**timestamp) self.timestamp = timestamp - if isinstance(eventName, dict): - eventName = str(**eventName) - self.eventName = eventName - if isinstance(eventId, dict): - eventId = str(**eventId) - self.eventId = eventId - if isinstance(data, dict): - data = str(**data) - self.data = data - - @classmethod - def build_hash(cls, eventId, requestId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - -class RequestInterceptedEvent(BaseEvent): - - js_name = 'Network.requestIntercepted' - hashable = ['frameId', 'interceptionId'] - is_hashable = True - - def __init__(self, - interceptionId: Union['InterceptionId', dict], - request: Union['Request', dict], - frameId: Union['Page.FrameId', dict], - resourceType: Union['Page.ResourceType', dict], - isNavigationRequest: Union['bool', dict], - redirectHeaders: Union['Headers', dict, None] = None, - redirectStatusCode: Union['int', dict, None] = None, - redirectUrl: Union['str', dict, None] = None, - authChallenge: Union['AuthChallenge', dict, None] = None, - ): - if isinstance(interceptionId, dict): - interceptionId = InterceptionId(**interceptionId) - self.interceptionId = interceptionId + if isinstance(wallTime, dict): + wallTime = TimeSinceEpoch(**wallTime) + self.wallTime = wallTime if isinstance(request, dict): - request = Request(**request) + request = WebSocketRequest(**request) self.request = request - if isinstance(frameId, dict): - frameId = Page.FrameId(**frameId) - self.frameId = frameId - if isinstance(resourceType, dict): - resourceType = Page.ResourceType(**resourceType) - self.resourceType = resourceType - if isinstance(isNavigationRequest, dict): - isNavigationRequest = bool(**isNavigationRequest) - self.isNavigationRequest = isNavigationRequest - if isinstance(redirectHeaders, dict): - redirectHeaders = Headers(**redirectHeaders) - self.redirectHeaders = redirectHeaders - if isinstance(redirectStatusCode, dict): - redirectStatusCode = int(**redirectStatusCode) - self.redirectStatusCode = redirectStatusCode - if isinstance(redirectUrl, dict): - redirectUrl = str(**redirectUrl) - self.redirectUrl = redirectUrl - if isinstance(authChallenge, dict): - authChallenge = AuthChallenge(**authChallenge) - self.authChallenge = authChallenge @classmethod - def build_hash(cls, frameId, interceptionId): + def build_hash(cls, requestId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) diff --git a/chromewhip/protocol/overlay.py b/chromewhip/protocol/overlay.py index 00c7f43..8fb9f97 100644 --- a/chromewhip/protocol/overlay.py +++ b/chromewhip/protocol/overlay.py @@ -55,16 +55,6 @@ def __init__(self, class Overlay(PayloadMixin): """ This domain provides various functionality related to drawing atop the inspected page. """ - @classmethod - def enable(cls): - """Enables domain notifications. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - @classmethod def disable(cls): """Disables domain notifications. @@ -76,125 +66,115 @@ def disable(cls): ) @classmethod - def setShowPaintRects(cls, - result: Union['bool'], - ): - """Requests that backend shows paint rectangles - :param result: True for showing paint rectangles - :type result: bool - """ - return ( - cls.build_send_payload("setShowPaintRects", { - "result": result, - }), - None - ) - - @classmethod - def setShowDebugBorders(cls, - show: Union['bool'], - ): - """Requests that backend shows debug borders on layers - :param show: True for showing debug borders - :type show: bool - """ - return ( - cls.build_send_payload("setShowDebugBorders", { - "show": show, - }), - None - ) - - @classmethod - def setShowFPSCounter(cls, - show: Union['bool'], - ): - """Requests that backend shows the FPS counter - :param show: True for showing the FPS counter - :type show: bool + def enable(cls): + """Enables domain notifications. """ return ( - cls.build_send_payload("setShowFPSCounter", { - "show": show, + cls.build_send_payload("enable", { }), None ) @classmethod - def setShowScrollBottleneckRects(cls, - show: Union['bool'], - ): - """Requests that backend shows scroll bottleneck rects - :param show: True for showing scroll bottleneck rects - :type show: bool + def getHighlightObjectForTest(cls, + nodeId: Union['DOM.NodeId'], + ): + """For testing. + :param nodeId: Id of the node to get highlight object for. + :type nodeId: DOM.NodeId """ return ( - cls.build_send_payload("setShowScrollBottleneckRects", { - "show": show, + cls.build_send_payload("getHighlightObjectForTest", { + "nodeId": nodeId, }), - None + cls.convert_payload({ + "highlight": { + "class": dict, + "optional": False + }, + }) ) @classmethod - def setShowViewportSizeOnResize(cls, - show: Union['bool'], - ): - """Paints viewport size upon main frame resize. - :param show: Whether to paint size or not. - :type show: bool + def hideHighlight(cls): + """Hides any highlight. """ return ( - cls.build_send_payload("setShowViewportSizeOnResize", { - "show": show, + cls.build_send_payload("hideHighlight", { }), None ) @classmethod - def setPausedInDebuggerMessage(cls, - message: Optional['str'] = None, - ): - """ - :param message: The message to display, also triggers resume and step over controls. - :type message: str + def highlightFrame(cls, + frameId: Union['Page.FrameId'], + contentColor: Optional['DOM.RGBA'] = None, + contentOutlineColor: Optional['DOM.RGBA'] = None, + ): + """Highlights owner element of the frame with given id. + :param frameId: Identifier of the frame to highlight. + :type frameId: Page.FrameId + :param contentColor: The content box highlight fill color (default: transparent). + :type contentColor: DOM.RGBA + :param contentOutlineColor: The content box highlight outline color (default: transparent). + :type contentOutlineColor: DOM.RGBA """ return ( - cls.build_send_payload("setPausedInDebuggerMessage", { - "message": message, + cls.build_send_payload("highlightFrame", { + "frameId": frameId, + "contentColor": contentColor, + "contentOutlineColor": contentOutlineColor, }), None ) @classmethod - def setSuspended(cls, - suspended: Union['bool'], - ): - """ - :param suspended: Whether overlay should be suspended and not consume any resources until resumed. - :type suspended: bool + def highlightNode(cls, + highlightConfig: Union['HighlightConfig'], + nodeId: Optional['DOM.NodeId'] = None, + backendNodeId: Optional['DOM.BackendNodeId'] = None, + objectId: Optional['Runtime.RemoteObjectId'] = None, + ): + """Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or +objectId must be specified. + :param highlightConfig: A descriptor for the highlight appearance. + :type highlightConfig: HighlightConfig + :param nodeId: Identifier of the node to highlight. + :type nodeId: DOM.NodeId + :param backendNodeId: Identifier of the backend node to highlight. + :type backendNodeId: DOM.BackendNodeId + :param objectId: JavaScript object id of the node to be highlighted. + :type objectId: Runtime.RemoteObjectId """ return ( - cls.build_send_payload("setSuspended", { - "suspended": suspended, + cls.build_send_payload("highlightNode", { + "highlightConfig": highlightConfig, + "nodeId": nodeId, + "backendNodeId": backendNodeId, + "objectId": objectId, }), None ) @classmethod - def setInspectMode(cls, - mode: Union['InspectMode'], - highlightConfig: Optional['HighlightConfig'] = None, - ): - """Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. Backend then generates 'inspectNodeRequested' event upon element selection. - :param mode: Set an inspection mode. - :type mode: InspectMode - :param highlightConfig: A descriptor for the highlight appearance of hovered-over nodes. May be omitted if enabled == false. - :type highlightConfig: HighlightConfig + def highlightQuad(cls, + quad: Union['DOM.Quad'], + color: Optional['DOM.RGBA'] = None, + outlineColor: Optional['DOM.RGBA'] = None, + ): + """Highlights given quad. Coordinates are absolute with respect to the main frame viewport. + :param quad: Quad to highlight + :type quad: DOM.Quad + :param color: The highlight fill color (default: transparent). + :type color: DOM.RGBA + :param outlineColor: The highlight outline color (default: transparent). + :type outlineColor: DOM.RGBA """ return ( - cls.build_send_payload("setInspectMode", { - "mode": mode, - "highlightConfig": highlightConfig, + cls.build_send_payload("highlightQuad", { + "quad": quad, + "color": color, + "outlineColor": outlineColor, }), None ) @@ -235,125 +215,148 @@ def highlightRect(cls, ) @classmethod - def highlightQuad(cls, - quad: Union['DOM.Quad'], - color: Optional['DOM.RGBA'] = None, - outlineColor: Optional['DOM.RGBA'] = None, - ): - """Highlights given quad. Coordinates are absolute with respect to the main frame viewport. - :param quad: Quad to highlight - :type quad: DOM.Quad - :param color: The highlight fill color (default: transparent). - :type color: DOM.RGBA - :param outlineColor: The highlight outline color (default: transparent). - :type outlineColor: DOM.RGBA + def setInspectMode(cls, + mode: Union['InspectMode'], + highlightConfig: Optional['HighlightConfig'] = None, + ): + """Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. +Backend then generates 'inspectNodeRequested' event upon element selection. + :param mode: Set an inspection mode. + :type mode: InspectMode + :param highlightConfig: A descriptor for the highlight appearance of hovered-over nodes. May be omitted if `enabled +== false`. + :type highlightConfig: HighlightConfig """ return ( - cls.build_send_payload("highlightQuad", { - "quad": quad, - "color": color, - "outlineColor": outlineColor, + cls.build_send_payload("setInspectMode", { + "mode": mode, + "highlightConfig": highlightConfig, }), None ) @classmethod - def highlightNode(cls, - highlightConfig: Union['HighlightConfig'], - nodeId: Optional['DOM.NodeId'] = None, - backendNodeId: Optional['DOM.BackendNodeId'] = None, - objectId: Optional['Runtime.RemoteObjectId'] = None, - ): - """Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or objectId must be specified. - :param highlightConfig: A descriptor for the highlight appearance. - :type highlightConfig: HighlightConfig - :param nodeId: Identifier of the node to highlight. - :type nodeId: DOM.NodeId - :param backendNodeId: Identifier of the backend node to highlight. - :type backendNodeId: DOM.BackendNodeId - :param objectId: JavaScript object id of the node to be highlighted. - :type objectId: Runtime.RemoteObjectId + def setPausedInDebuggerMessage(cls, + message: Optional['str'] = None, + ): + """ + :param message: The message to display, also triggers resume and step over controls. + :type message: str """ return ( - cls.build_send_payload("highlightNode", { - "highlightConfig": highlightConfig, - "nodeId": nodeId, - "backendNodeId": backendNodeId, - "objectId": objectId, + cls.build_send_payload("setPausedInDebuggerMessage", { + "message": message, }), None ) @classmethod - def highlightFrame(cls, - frameId: Union['Page.FrameId'], - contentColor: Optional['DOM.RGBA'] = None, - contentOutlineColor: Optional['DOM.RGBA'] = None, - ): - """Highlights owner element of the frame with given id. - :param frameId: Identifier of the frame to highlight. - :type frameId: Page.FrameId - :param contentColor: The content box highlight fill color (default: transparent). - :type contentColor: DOM.RGBA - :param contentOutlineColor: The content box highlight outline color (default: transparent). - :type contentOutlineColor: DOM.RGBA + def setShowDebugBorders(cls, + show: Union['bool'], + ): + """Requests that backend shows debug borders on layers + :param show: True for showing debug borders + :type show: bool """ return ( - cls.build_send_payload("highlightFrame", { - "frameId": frameId, - "contentColor": contentColor, - "contentOutlineColor": contentOutlineColor, + cls.build_send_payload("setShowDebugBorders", { + "show": show, }), None ) @classmethod - def hideHighlight(cls): - """Hides any highlight. + def setShowFPSCounter(cls, + show: Union['bool'], + ): + """Requests that backend shows the FPS counter + :param show: True for showing the FPS counter + :type show: bool """ return ( - cls.build_send_payload("hideHighlight", { + cls.build_send_payload("setShowFPSCounter", { + "show": show, }), None ) @classmethod - def getHighlightObjectForTest(cls, - nodeId: Union['DOM.NodeId'], - ): - """For testing. - :param nodeId: Id of the node to get highlight object for. - :type nodeId: DOM.NodeId + def setShowPaintRects(cls, + result: Union['bool'], + ): + """Requests that backend shows paint rectangles + :param result: True for showing paint rectangles + :type result: bool """ return ( - cls.build_send_payload("getHighlightObjectForTest", { - "nodeId": nodeId, + cls.build_send_payload("setShowPaintRects", { + "result": result, }), - cls.convert_payload({ - "highlight": { - "class": dict, - "optional": False - }, - }) + None ) + @classmethod + def setShowScrollBottleneckRects(cls, + show: Union['bool'], + ): + """Requests that backend shows scroll bottleneck rects + :param show: True for showing scroll bottleneck rects + :type show: bool + """ + return ( + cls.build_send_payload("setShowScrollBottleneckRects", { + "show": show, + }), + None + ) + @classmethod + def setShowViewportSizeOnResize(cls, + show: Union['bool'], + ): + """Paints viewport size upon main frame resize. + :param show: Whether to paint size or not. + :type show: bool + """ + return ( + cls.build_send_payload("setShowViewportSizeOnResize", { + "show": show, + }), + None + ) -class NodeHighlightRequestedEvent(BaseEvent): + @classmethod + def setSuspended(cls, + suspended: Union['bool'], + ): + """ + :param suspended: Whether overlay should be suspended and not consume any resources until resumed. + :type suspended: bool + """ + return ( + cls.build_send_payload("setSuspended", { + "suspended": suspended, + }), + None + ) - js_name = 'Overlay.nodeHighlightRequested' - hashable = ['nodeId'] + + +class InspectNodeRequestedEvent(BaseEvent): + + js_name = 'Overlay.inspectNodeRequested' + hashable = ['backendNodeId'] is_hashable = True def __init__(self, - nodeId: Union['DOM.NodeId', dict], + backendNodeId: Union['DOM.BackendNodeId', dict], ): - if isinstance(nodeId, dict): - nodeId = DOM.NodeId(**nodeId) - self.nodeId = nodeId + if isinstance(backendNodeId, dict): + backendNodeId = DOM.BackendNodeId(**backendNodeId) + self.backendNodeId = backendNodeId @classmethod - def build_hash(cls, nodeId): + def build_hash(cls, backendNodeId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -362,21 +365,21 @@ def build_hash(cls, nodeId): return h -class InspectNodeRequestedEvent(BaseEvent): +class NodeHighlightRequestedEvent(BaseEvent): - js_name = 'Overlay.inspectNodeRequested' - hashable = ['backendNodeId'] + js_name = 'Overlay.nodeHighlightRequested' + hashable = ['nodeId'] is_hashable = True def __init__(self, - backendNodeId: Union['DOM.BackendNodeId', dict], + nodeId: Union['DOM.NodeId', dict], ): - if isinstance(backendNodeId, dict): - backendNodeId = DOM.BackendNodeId(**backendNodeId) - self.backendNodeId = backendNodeId + if isinstance(nodeId, dict): + nodeId = DOM.NodeId(**nodeId) + self.nodeId = nodeId @classmethod - def build_hash(cls, backendNodeId): + def build_hash(cls, nodeId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) diff --git a/chromewhip/protocol/page.py b/chromewhip/protocol/page.py index afcb461..d8f9129 100644 --- a/chromewhip/protocol/page.py +++ b/chromewhip/protocol/page.py @@ -210,26 +210,6 @@ def __init__(self, class Page(PayloadMixin): """ Actions and events related to the inspected page belong to the page domain. """ - @classmethod - def enable(cls): - """Enables page domain notifications. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - - @classmethod - def disable(cls): - """Disables page domain notifications. - """ - return ( - cls.build_send_payload("disable", { - }), - None - ) - @classmethod def addScriptToEvaluateOnLoad(cls, scriptSource: Union['str'], @@ -250,21 +230,6 @@ def addScriptToEvaluateOnLoad(cls, }) ) - @classmethod - def removeScriptToEvaluateOnLoad(cls, - identifier: Union['ScriptIdentifier'], - ): - """Deprecated, please use removeScriptToEvaluateOnNewDocument instead. - :param identifier: - :type identifier: ScriptIdentifier - """ - return ( - cls.build_send_payload("removeScriptToEvaluateOnLoad", { - "identifier": identifier, - }), - None - ) - @classmethod def addScriptToEvaluateOnNewDocument(cls, source: Union['str'], @@ -286,204 +251,179 @@ def addScriptToEvaluateOnNewDocument(cls, ) @classmethod - def removeScriptToEvaluateOnNewDocument(cls, - identifier: Union['ScriptIdentifier'], - ): - """Removes given script from the list. - :param identifier: - :type identifier: ScriptIdentifier + def bringToFront(cls): + """Brings page to front (activates tab). """ return ( - cls.build_send_payload("removeScriptToEvaluateOnNewDocument", { - "identifier": identifier, + cls.build_send_payload("bringToFront", { }), None ) @classmethod - def setAutoAttachToCreatedPages(cls, - autoAttach: Union['bool'], - ): - """Controls whether browser will open a new inspector window for connected pages. - :param autoAttach: If true, browser will open a new inspector window for every page created from this one. - :type autoAttach: bool + def captureScreenshot(cls, + format: Optional['str'] = None, + quality: Optional['int'] = None, + clip: Optional['Viewport'] = None, + fromSurface: Optional['bool'] = None, + ): + """Capture page screenshot. + :param format: Image compression format (defaults to png). + :type format: str + :param quality: Compression quality from range [0..100] (jpeg only). + :type quality: int + :param clip: Capture the screenshot of a given region only. + :type clip: Viewport + :param fromSurface: Capture the screenshot from the surface, rather than the view. Defaults to true. + :type fromSurface: bool """ return ( - cls.build_send_payload("setAutoAttachToCreatedPages", { - "autoAttach": autoAttach, + cls.build_send_payload("captureScreenshot", { + "format": format, + "quality": quality, + "clip": clip, + "fromSurface": fromSurface, }), - None + cls.convert_payload({ + "data": { + "class": str, + "optional": False + }, + }) ) @classmethod - def setLifecycleEventsEnabled(cls, - enabled: Union['bool'], - ): - """Controls whether page will emit lifecycle events. - :param enabled: If true, starts emitting lifecycle events. - :type enabled: bool + def clearDeviceMetricsOverride(cls): + """Clears the overriden device metrics. """ return ( - cls.build_send_payload("setLifecycleEventsEnabled", { - "enabled": enabled, + cls.build_send_payload("clearDeviceMetricsOverride", { }), None ) @classmethod - def reload(cls, - ignoreCache: Optional['bool'] = None, - scriptToEvaluateOnLoad: Optional['str'] = None, - ): - """Reloads given page optionally ignoring the cache. - :param ignoreCache: If true, browser cache is ignored (as if the user pressed Shift+refresh). - :type ignoreCache: bool - :param scriptToEvaluateOnLoad: If set, the script will be injected into all frames of the inspected page after reload. - :type scriptToEvaluateOnLoad: str + def clearDeviceOrientationOverride(cls): + """Clears the overridden Device Orientation. """ return ( - cls.build_send_payload("reload", { - "ignoreCache": ignoreCache, - "scriptToEvaluateOnLoad": scriptToEvaluateOnLoad, + cls.build_send_payload("clearDeviceOrientationOverride", { }), None ) @classmethod - def setAdBlockingEnabled(cls, - enabled: Union['bool'], - ): - """Enable Chrome's experimental ad filter on all sites. - :param enabled: Whether to block ads. - :type enabled: bool + def clearGeolocationOverride(cls): + """Clears the overriden Geolocation Position and Error. """ return ( - cls.build_send_payload("setAdBlockingEnabled", { - "enabled": enabled, + cls.build_send_payload("clearGeolocationOverride", { }), None ) @classmethod - def navigate(cls, - url: Union['str'], - referrer: Optional['str'] = None, - transitionType: Optional['TransitionType'] = None, - ): - """Navigates current page to the given URL. - :param url: URL to navigate the page to. - :type url: str - :param referrer: Referrer URL. - :type referrer: str - :param transitionType: Intended transition type. - :type transitionType: TransitionType + def createIsolatedWorld(cls, + frameId: Union['FrameId'], + worldName: Optional['str'] = None, + grantUniveralAccess: Optional['bool'] = None, + ): + """Creates an isolated world for the given frame. + :param frameId: Id of the frame in which the isolated world should be created. + :type frameId: FrameId + :param worldName: An optional name which is reported in the Execution Context. + :type worldName: str + :param grantUniveralAccess: Whether or not universal access should be granted to the isolated world. This is a powerful +option, use with caution. + :type grantUniveralAccess: bool """ return ( - cls.build_send_payload("navigate", { - "url": url, - "referrer": referrer, - "transitionType": transitionType, + cls.build_send_payload("createIsolatedWorld", { + "frameId": frameId, + "worldName": worldName, + "grantUniveralAccess": grantUniveralAccess, }), cls.convert_payload({ - "frameId": { - "class": FrameId, - "optional": False - }, - "loaderId": { - "class": Network.LoaderId, + "executionContextId": { + "class": Runtime.ExecutionContextId, "optional": False }, }) ) @classmethod - def stopLoading(cls): - """Force the page stop all navigations and pending resource fetches. + def deleteCookie(cls, + cookieName: Union['str'], + url: Union['str'], + ): + """Deletes browser cookie with given name, domain and path. + :param cookieName: Name of the cookie to remove. + :type cookieName: str + :param url: URL to match cooke domain and path. + :type url: str """ return ( - cls.build_send_payload("stopLoading", { + cls.build_send_payload("deleteCookie", { + "cookieName": cookieName, + "url": url, }), None ) @classmethod - def getNavigationHistory(cls): - """Returns navigation history for the current page. + def disable(cls): + """Disables page domain notifications. """ return ( - cls.build_send_payload("getNavigationHistory", { + cls.build_send_payload("disable", { }), - cls.convert_payload({ - "currentIndex": { - "class": int, - "optional": False - }, - "entries": { - "class": [NavigationEntry], - "optional": False - }, - }) + None ) @classmethod - def navigateToHistoryEntry(cls, - entryId: Union['int'], - ): - """Navigates current page to the given history entry. - :param entryId: Unique id of the entry to navigate to. - :type entryId: int + def enable(cls): + """Enables page domain notifications. """ return ( - cls.build_send_payload("navigateToHistoryEntry", { - "entryId": entryId, + cls.build_send_payload("enable", { }), None ) @classmethod - def getCookies(cls): - """Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the cookies field. + def getAppManifest(cls): + """ """ return ( - cls.build_send_payload("getCookies", { + cls.build_send_payload("getAppManifest", { }), cls.convert_payload({ - "cookies": { - "class": [Network.Cookie], + "url": { + "class": str, + "optional": False + }, + "errors": { + "class": [AppManifestError], "optional": False }, + "data": { + "class": str, + "optional": True + }, }) ) @classmethod - def deleteCookie(cls, - cookieName: Union['str'], - url: Union['str'], - ): - """Deletes browser cookie with given name, domain and path. - :param cookieName: Name of the cookie to remove. - :type cookieName: str - :param url: URL to match cooke domain and path. - :type url: str - """ - return ( - cls.build_send_payload("deleteCookie", { - "cookieName": cookieName, - "url": url, - }), - None - ) - - @classmethod - def getResourceTree(cls): - """Returns present frame / resource tree structure. + def getCookies(cls): + """Returns all browser cookies. Depending on the backend support, will return detailed cookie +information in the `cookies` field. """ return ( - cls.build_send_payload("getResourceTree", { + cls.build_send_payload("getCookies", { }), cls.convert_payload({ - "frameTree": { - "class": FrameResourceTree, + "cookies": { + "class": [Network.Cookie], "optional": False }, }) @@ -505,24 +445,66 @@ def getFrameTree(cls): ) @classmethod - def getResourceContent(cls, - frameId: Union['FrameId'], - url: Union['str'], - ): - """Returns content of the given resource. - :param frameId: Frame id to get resource for. - :type frameId: FrameId - :param url: URL of the resource to get content for. - :type url: str + def getLayoutMetrics(cls): + """Returns metrics relating to the layouting of the page, such as viewport bounds/scale. """ return ( - cls.build_send_payload("getResourceContent", { - "frameId": frameId, - "url": url, + cls.build_send_payload("getLayoutMetrics", { }), cls.convert_payload({ - "content": { - "class": str, + "layoutViewport": { + "class": LayoutViewport, + "optional": False + }, + "visualViewport": { + "class": VisualViewport, + "optional": False + }, + "contentSize": { + "class": DOM.Rect, + "optional": False + }, + }) + ) + + @classmethod + def getNavigationHistory(cls): + """Returns navigation history for the current page. + """ + return ( + cls.build_send_payload("getNavigationHistory", { + }), + cls.convert_payload({ + "currentIndex": { + "class": int, + "optional": False + }, + "entries": { + "class": [NavigationEntry], + "optional": False + }, + }) + ) + + @classmethod + def getResourceContent(cls, + frameId: Union['FrameId'], + url: Union['str'], + ): + """Returns content of the given resource. + :param frameId: Frame id to get resource for. + :type frameId: FrameId + :param url: URL of the resource to get content for. + :type url: str + """ + return ( + cls.build_send_payload("getResourceContent", { + "frameId": frameId, + "url": url, + }), + cls.convert_payload({ + "content": { + "class": str, "optional": False }, "base64Encoded": { @@ -532,6 +514,249 @@ def getResourceContent(cls, }) ) + @classmethod + def getResourceTree(cls): + """Returns present frame / resource tree structure. + """ + return ( + cls.build_send_payload("getResourceTree", { + }), + cls.convert_payload({ + "frameTree": { + "class": FrameResourceTree, + "optional": False + }, + }) + ) + + @classmethod + def handleJavaScriptDialog(cls, + accept: Union['bool'], + promptText: Optional['str'] = None, + ): + """Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload). + :param accept: Whether to accept or dismiss the dialog. + :type accept: bool + :param promptText: The text to enter into the dialog prompt before accepting. Used only if this is a prompt +dialog. + :type promptText: str + """ + return ( + cls.build_send_payload("handleJavaScriptDialog", { + "accept": accept, + "promptText": promptText, + }), + None + ) + + @classmethod + def navigate(cls, + url: Union['str'], + referrer: Optional['str'] = None, + transitionType: Optional['TransitionType'] = None, + ): + """Navigates current page to the given URL. + :param url: URL to navigate the page to. + :type url: str + :param referrer: Referrer URL. + :type referrer: str + :param transitionType: Intended transition type. + :type transitionType: TransitionType + """ + return ( + cls.build_send_payload("navigate", { + "url": url, + "referrer": referrer, + "transitionType": transitionType, + }), + cls.convert_payload({ + "frameId": { + "class": FrameId, + "optional": False + }, + "loaderId": { + "class": Network.LoaderId, + "optional": True + }, + "errorText": { + "class": str, + "optional": True + }, + }) + ) + + @classmethod + def navigateToHistoryEntry(cls, + entryId: Union['int'], + ): + """Navigates current page to the given history entry. + :param entryId: Unique id of the entry to navigate to. + :type entryId: int + """ + return ( + cls.build_send_payload("navigateToHistoryEntry", { + "entryId": entryId, + }), + None + ) + + @classmethod + def printToPDF(cls, + landscape: Optional['bool'] = None, + displayHeaderFooter: Optional['bool'] = None, + printBackground: Optional['bool'] = None, + scale: Optional['float'] = None, + paperWidth: Optional['float'] = None, + paperHeight: Optional['float'] = None, + marginTop: Optional['float'] = None, + marginBottom: Optional['float'] = None, + marginLeft: Optional['float'] = None, + marginRight: Optional['float'] = None, + pageRanges: Optional['str'] = None, + ignoreInvalidPageRanges: Optional['bool'] = None, + headerTemplate: Optional['str'] = None, + footerTemplate: Optional['str'] = None, + ): + """Print page as PDF. + :param landscape: Paper orientation. Defaults to false. + :type landscape: bool + :param displayHeaderFooter: Display header and footer. Defaults to false. + :type displayHeaderFooter: bool + :param printBackground: Print background graphics. Defaults to false. + :type printBackground: bool + :param scale: Scale of the webpage rendering. Defaults to 1. + :type scale: float + :param paperWidth: Paper width in inches. Defaults to 8.5 inches. + :type paperWidth: float + :param paperHeight: Paper height in inches. Defaults to 11 inches. + :type paperHeight: float + :param marginTop: Top margin in inches. Defaults to 1cm (~0.4 inches). + :type marginTop: float + :param marginBottom: Bottom margin in inches. Defaults to 1cm (~0.4 inches). + :type marginBottom: float + :param marginLeft: Left margin in inches. Defaults to 1cm (~0.4 inches). + :type marginLeft: float + :param marginRight: Right margin in inches. Defaults to 1cm (~0.4 inches). + :type marginRight: float + :param pageRanges: Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means +print all pages. + :type pageRanges: str + :param ignoreInvalidPageRanges: Whether to silently ignore invalid but successfully parsed page ranges, such as '3-2'. +Defaults to false. + :type ignoreInvalidPageRanges: bool + :param headerTemplate: HTML template for the print header. Should be valid HTML markup with following +classes used to inject printing values into them: +- date - formatted print date +- title - document title +- url - document location +- pageNumber - current page number +- totalPages - total pages in the document + +For example, would generate span containing the title. + :type headerTemplate: str + :param footerTemplate: HTML template for the print footer. Should use the same format as the `headerTemplate`. + :type footerTemplate: str + """ + return ( + cls.build_send_payload("printToPDF", { + "landscape": landscape, + "displayHeaderFooter": displayHeaderFooter, + "printBackground": printBackground, + "scale": scale, + "paperWidth": paperWidth, + "paperHeight": paperHeight, + "marginTop": marginTop, + "marginBottom": marginBottom, + "marginLeft": marginLeft, + "marginRight": marginRight, + "pageRanges": pageRanges, + "ignoreInvalidPageRanges": ignoreInvalidPageRanges, + "headerTemplate": headerTemplate, + "footerTemplate": footerTemplate, + }), + cls.convert_payload({ + "data": { + "class": str, + "optional": False + }, + }) + ) + + @classmethod + def reload(cls, + ignoreCache: Optional['bool'] = None, + scriptToEvaluateOnLoad: Optional['str'] = None, + ): + """Reloads given page optionally ignoring the cache. + :param ignoreCache: If true, browser cache is ignored (as if the user pressed Shift+refresh). + :type ignoreCache: bool + :param scriptToEvaluateOnLoad: If set, the script will be injected into all frames of the inspected page after reload. +Argument will be ignored if reloading dataURL origin. + :type scriptToEvaluateOnLoad: str + """ + return ( + cls.build_send_payload("reload", { + "ignoreCache": ignoreCache, + "scriptToEvaluateOnLoad": scriptToEvaluateOnLoad, + }), + None + ) + + @classmethod + def removeScriptToEvaluateOnLoad(cls, + identifier: Union['ScriptIdentifier'], + ): + """Deprecated, please use removeScriptToEvaluateOnNewDocument instead. + :param identifier: + :type identifier: ScriptIdentifier + """ + return ( + cls.build_send_payload("removeScriptToEvaluateOnLoad", { + "identifier": identifier, + }), + None + ) + + @classmethod + def removeScriptToEvaluateOnNewDocument(cls, + identifier: Union['ScriptIdentifier'], + ): + """Removes given script from the list. + :param identifier: + :type identifier: ScriptIdentifier + """ + return ( + cls.build_send_payload("removeScriptToEvaluateOnNewDocument", { + "identifier": identifier, + }), + None + ) + + @classmethod + def requestAppBanner(cls): + """ + """ + return ( + cls.build_send_payload("requestAppBanner", { + }), + None + ) + + @classmethod + def screencastFrameAck(cls, + sessionId: Union['int'], + ): + """Acknowledges that a screencast frame has been received by the frontend. + :param sessionId: Frame number. + :type sessionId: int + """ + return ( + cls.build_send_payload("screencastFrameAck", { + "sessionId": sessionId, + }), + None + ) + @classmethod def searchInResource(cls, frameId: Union['FrameId'], @@ -569,20 +794,16 @@ def searchInResource(cls, ) @classmethod - def setDocumentContent(cls, - frameId: Union['FrameId'], - html: Union['str'], - ): - """Sets given markup as the document's HTML. - :param frameId: Frame id to set HTML for. - :type frameId: FrameId - :param html: HTML content to set. - :type html: str + def setAdBlockingEnabled(cls, + enabled: Union['bool'], + ): + """Enable Chrome's experimental ad filter on all sites. + :param enabled: Whether to block ads. + :type enabled: bool """ return ( - cls.build_send_payload("setDocumentContent", { - "frameId": frameId, - "html": html, + cls.build_send_payload("setAdBlockingEnabled", { + "enabled": enabled, }), None ) @@ -602,14 +823,17 @@ def setDeviceMetricsOverride(cls, screenOrientation: Optional['Emulation.ScreenOrientation'] = None, viewport: Optional['Viewport'] = None, ): - """Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media query results). + """Overrides the values of device screen dimensions (window.screen.width, window.screen.height, +window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media +query results). :param width: Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override. :type width: int :param height: Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override. :type height: int :param deviceScaleFactor: Overriding device scale factor value. 0 disables the override. :type deviceScaleFactor: float - :param mobile: Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more. + :param mobile: Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text +autosizing and more. :type mobile: bool :param scale: Scale to apply to resulting view image. :type scale: float @@ -647,77 +871,102 @@ def setDeviceMetricsOverride(cls, ) @classmethod - def clearDeviceMetricsOverride(cls): - """Clears the overriden device metrics. + def setDeviceOrientationOverride(cls, + alpha: Union['float'], + beta: Union['float'], + gamma: Union['float'], + ): + """Overrides the Device Orientation. + :param alpha: Mock alpha + :type alpha: float + :param beta: Mock beta + :type beta: float + :param gamma: Mock gamma + :type gamma: float """ return ( - cls.build_send_payload("clearDeviceMetricsOverride", { + cls.build_send_payload("setDeviceOrientationOverride", { + "alpha": alpha, + "beta": beta, + "gamma": gamma, }), None ) @classmethod - def setGeolocationOverride(cls, - latitude: Optional['float'] = None, - longitude: Optional['float'] = None, - accuracy: Optional['float'] = None, - ): - """Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position unavailable. - :param latitude: Mock latitude - :type latitude: float - :param longitude: Mock longitude - :type longitude: float - :param accuracy: Mock accuracy - :type accuracy: float + def setDocumentContent(cls, + frameId: Union['FrameId'], + html: Union['str'], + ): + """Sets given markup as the document's HTML. + :param frameId: Frame id to set HTML for. + :type frameId: FrameId + :param html: HTML content to set. + :type html: str """ return ( - cls.build_send_payload("setGeolocationOverride", { - "latitude": latitude, - "longitude": longitude, - "accuracy": accuracy, + cls.build_send_payload("setDocumentContent", { + "frameId": frameId, + "html": html, }), None ) @classmethod - def clearGeolocationOverride(cls): - """Clears the overriden Geolocation Position and Error. + def setDownloadBehavior(cls, + behavior: Union['str'], + downloadPath: Optional['str'] = None, + ): + """Set the behavior when downloading a file. + :param behavior: Whether to allow all or deny all download requests, or use default Chrome behavior if +available (otherwise deny). + :type behavior: str + :param downloadPath: The default path to save downloaded files to. This is requred if behavior is set to 'allow' + :type downloadPath: str """ - return ( - cls.build_send_payload("clearGeolocationOverride", { - }), - None - ) - - @classmethod - def setDeviceOrientationOverride(cls, - alpha: Union['float'], - beta: Union['float'], - gamma: Union['float'], - ): - """Overrides the Device Orientation. - :param alpha: Mock alpha - :type alpha: float - :param beta: Mock beta - :type beta: float - :param gamma: Mock gamma - :type gamma: float + return ( + cls.build_send_payload("setDownloadBehavior", { + "behavior": behavior, + "downloadPath": downloadPath, + }), + None + ) + + @classmethod + def setGeolocationOverride(cls, + latitude: Optional['float'] = None, + longitude: Optional['float'] = None, + accuracy: Optional['float'] = None, + ): + """Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position +unavailable. + :param latitude: Mock latitude + :type latitude: float + :param longitude: Mock longitude + :type longitude: float + :param accuracy: Mock accuracy + :type accuracy: float """ return ( - cls.build_send_payload("setDeviceOrientationOverride", { - "alpha": alpha, - "beta": beta, - "gamma": gamma, + cls.build_send_payload("setGeolocationOverride", { + "latitude": latitude, + "longitude": longitude, + "accuracy": accuracy, }), None ) @classmethod - def clearDeviceOrientationOverride(cls): - """Clears the overridden Device Orientation. + def setLifecycleEventsEnabled(cls, + enabled: Union['bool'], + ): + """Controls whether page will emit lifecycle events. + :param enabled: If true, starts emitting lifecycle events. + :type enabled: bool """ return ( - cls.build_send_payload("clearDeviceOrientationOverride", { + cls.build_send_payload("setLifecycleEventsEnabled", { + "enabled": enabled, }), None ) @@ -741,102 +990,6 @@ def setTouchEmulationEnabled(cls, None ) - @classmethod - def captureScreenshot(cls, - format: Optional['str'] = None, - quality: Optional['int'] = None, - clip: Optional['Viewport'] = None, - fromSurface: Optional['bool'] = None, - ): - """Capture page screenshot. - :param format: Image compression format (defaults to png). - :type format: str - :param quality: Compression quality from range [0..100] (jpeg only). - :type quality: int - :param clip: Capture the screenshot of a given region only. - :type clip: Viewport - :param fromSurface: Capture the screenshot from the surface, rather than the view. Defaults to true. - :type fromSurface: bool - """ - return ( - cls.build_send_payload("captureScreenshot", { - "format": format, - "quality": quality, - "clip": clip, - "fromSurface": fromSurface, - }), - cls.convert_payload({ - "data": { - "class": str, - "optional": False - }, - }) - ) - - @classmethod - def printToPDF(cls, - landscape: Optional['bool'] = None, - displayHeaderFooter: Optional['bool'] = None, - printBackground: Optional['bool'] = None, - scale: Optional['float'] = None, - paperWidth: Optional['float'] = None, - paperHeight: Optional['float'] = None, - marginTop: Optional['float'] = None, - marginBottom: Optional['float'] = None, - marginLeft: Optional['float'] = None, - marginRight: Optional['float'] = None, - pageRanges: Optional['str'] = None, - ignoreInvalidPageRanges: Optional['bool'] = None, - ): - """Print page as PDF. - :param landscape: Paper orientation. Defaults to false. - :type landscape: bool - :param displayHeaderFooter: Display header and footer. Defaults to false. - :type displayHeaderFooter: bool - :param printBackground: Print background graphics. Defaults to false. - :type printBackground: bool - :param scale: Scale of the webpage rendering. Defaults to 1. - :type scale: float - :param paperWidth: Paper width in inches. Defaults to 8.5 inches. - :type paperWidth: float - :param paperHeight: Paper height in inches. Defaults to 11 inches. - :type paperHeight: float - :param marginTop: Top margin in inches. Defaults to 1cm (~0.4 inches). - :type marginTop: float - :param marginBottom: Bottom margin in inches. Defaults to 1cm (~0.4 inches). - :type marginBottom: float - :param marginLeft: Left margin in inches. Defaults to 1cm (~0.4 inches). - :type marginLeft: float - :param marginRight: Right margin in inches. Defaults to 1cm (~0.4 inches). - :type marginRight: float - :param pageRanges: Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages. - :type pageRanges: str - :param ignoreInvalidPageRanges: Whether to silently ignore invalid but successfully parsed page ranges, such as '3-2'. Defaults to false. - :type ignoreInvalidPageRanges: bool - """ - return ( - cls.build_send_payload("printToPDF", { - "landscape": landscape, - "displayHeaderFooter": displayHeaderFooter, - "printBackground": printBackground, - "scale": scale, - "paperWidth": paperWidth, - "paperHeight": paperHeight, - "marginTop": marginTop, - "marginBottom": marginBottom, - "marginLeft": marginLeft, - "marginRight": marginRight, - "pageRanges": pageRanges, - "ignoreInvalidPageRanges": ignoreInvalidPageRanges, - }), - cls.convert_payload({ - "data": { - "class": str, - "optional": False - }, - }) - ) - @classmethod def startScreencast(cls, format: Optional['str'] = None, @@ -845,7 +998,7 @@ def startScreencast(cls, maxHeight: Optional['int'] = None, everyNthFrame: Optional['int'] = None, ): - """Starts sending each frame using the screencastFrame event. + """Starts sending each frame using the `screencastFrame` event. :param format: Image compression format. :type format: str :param quality: Compression quality from range [0..100]. @@ -869,158 +1022,31 @@ def startScreencast(cls, ) @classmethod - def stopScreencast(cls): - """Stops sending each frame in the screencastFrame. - """ - return ( - cls.build_send_payload("stopScreencast", { - }), - None - ) - - @classmethod - def screencastFrameAck(cls, - sessionId: Union['int'], - ): - """Acknowledges that a screencast frame has been received by the frontend. - :param sessionId: Frame number. - :type sessionId: int - """ - return ( - cls.build_send_payload("screencastFrameAck", { - "sessionId": sessionId, - }), - None - ) - - @classmethod - def handleJavaScriptDialog(cls, - accept: Union['bool'], - promptText: Optional['str'] = None, - ): - """Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload). - :param accept: Whether to accept or dismiss the dialog. - :type accept: bool - :param promptText: The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog. - :type promptText: str - """ - return ( - cls.build_send_payload("handleJavaScriptDialog", { - "accept": accept, - "promptText": promptText, - }), - None - ) - - @classmethod - def getAppManifest(cls): - """ - """ - return ( - cls.build_send_payload("getAppManifest", { - }), - cls.convert_payload({ - "url": { - "class": str, - "optional": False - }, - "errors": { - "class": [AppManifestError], - "optional": False - }, - "data": { - "class": str, - "optional": True - }, - }) - ) - - @classmethod - def requestAppBanner(cls): - """ + def stopLoading(cls): + """Force the page stop all navigations and pending resource fetches. """ return ( - cls.build_send_payload("requestAppBanner", { + cls.build_send_payload("stopLoading", { }), None ) @classmethod - def getLayoutMetrics(cls): - """Returns metrics relating to the layouting of the page, such as viewport bounds/scale. - """ - return ( - cls.build_send_payload("getLayoutMetrics", { - }), - cls.convert_payload({ - "layoutViewport": { - "class": LayoutViewport, - "optional": False - }, - "visualViewport": { - "class": VisualViewport, - "optional": False - }, - "contentSize": { - "class": DOM.Rect, - "optional": False - }, - }) - ) - - @classmethod - def createIsolatedWorld(cls, - frameId: Union['FrameId'], - worldName: Optional['str'] = None, - grantUniveralAccess: Optional['bool'] = None, - ): - """Creates an isolated world for the given frame. - :param frameId: Id of the frame in which the isolated world should be created. - :type frameId: FrameId - :param worldName: An optional name which is reported in the Execution Context. - :type worldName: str - :param grantUniveralAccess: Whether or not universal access should be granted to the isolated world. This is a powerful option, use with caution. - :type grantUniveralAccess: bool - """ - return ( - cls.build_send_payload("createIsolatedWorld", { - "frameId": frameId, - "worldName": worldName, - "grantUniveralAccess": grantUniveralAccess, - }), - cls.convert_payload({ - "executionContextId": { - "class": Runtime.ExecutionContextId, - "optional": False - }, - }) - ) - - @classmethod - def bringToFront(cls): - """Brings page to front (activates tab). + def crash(cls): + """Crashes renderer on the IO thread, generates minidumps. """ return ( - cls.build_send_payload("bringToFront", { + cls.build_send_payload("crash", { }), None ) @classmethod - def setDownloadBehavior(cls, - behavior: Union['str'], - downloadPath: Optional['str'] = None, - ): - """Set the behavior when downloading a file. - :param behavior: Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny). - :type behavior: str - :param downloadPath: The default path to save downloaded files to. This is requred if behavior is set to 'allow' - :type downloadPath: str + def stopScreencast(cls): + """Stops sending each frame in the `screencastFrame`. """ return ( - cls.build_send_payload("setDownloadBehavior", { - "behavior": behavior, - "downloadPath": downloadPath, + cls.build_send_payload("stopScreencast", { }), None ) @@ -1045,63 +1071,10 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class LoadEventFiredEvent(BaseEvent): - - js_name = 'Page.loadEventFired' - hashable = [] - is_hashable = False - - def __init__(self, - timestamp: Union['Network.MonotonicTime', dict], - ): - if isinstance(timestamp, dict): - timestamp = Network.MonotonicTime(**timestamp) - self.timestamp = timestamp - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class LifecycleEventEvent(BaseEvent): - - js_name = 'Page.lifecycleEvent' - hashable = ['frameId', 'loaderId'] - is_hashable = True - - def __init__(self, - frameId: Union['FrameId', dict], - loaderId: Union['Network.LoaderId', dict], - name: Union['str', dict], - timestamp: Union['Network.MonotonicTime', dict], - ): - if isinstance(frameId, dict): - frameId = FrameId(**frameId) - self.frameId = frameId - if isinstance(loaderId, dict): - loaderId = Network.LoaderId(**loaderId) - self.loaderId = loaderId - if isinstance(name, dict): - name = str(**name) - self.name = name - if isinstance(timestamp, dict): - timestamp = Network.MonotonicTime(**timestamp) - self.timestamp = timestamp - - @classmethod - def build_hash(cls, frameId, loaderId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h - - class FrameAttachedEvent(BaseEvent): js_name = 'Page.frameAttached' - hashable = ['frameId', 'parentFrameId'] + hashable = ['parentFrameId', 'frameId'] is_hashable = True def __init__(self, @@ -1120,7 +1093,7 @@ def __init__(self, self.stack = stack @classmethod - def build_hash(cls, frameId, parentFrameId): + def build_hash(cls, parentFrameId, frameId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -1129,18 +1102,18 @@ def build_hash(cls, frameId, parentFrameId): return h -class FrameNavigatedEvent(BaseEvent): +class FrameClearedScheduledNavigationEvent(BaseEvent): - js_name = 'Page.frameNavigated' + js_name = 'Page.frameClearedScheduledNavigation' hashable = ['frameId'] is_hashable = True def __init__(self, - frame: Union['Frame', dict], + frameId: Union['FrameId', dict], ): - if isinstance(frame, dict): - frame = Frame(**frame) - self.frame = frame + if isinstance(frameId, dict): + frameId = FrameId(**frameId) + self.frameId = frameId @classmethod def build_hash(cls, frameId): @@ -1175,18 +1148,18 @@ def build_hash(cls, frameId): return h -class FrameStartedLoadingEvent(BaseEvent): +class FrameNavigatedEvent(BaseEvent): - js_name = 'Page.frameStartedLoading' + js_name = 'Page.frameNavigated' hashable = ['frameId'] is_hashable = True def __init__(self, - frameId: Union['FrameId', dict], + frame: Union['Frame', dict], ): - if isinstance(frameId, dict): - frameId = FrameId(**frameId) - self.frameId = frameId + if isinstance(frame, dict): + frame = Frame(**frame) + self.frame = frame @classmethod def build_hash(cls, frameId): @@ -1198,18 +1171,44 @@ def build_hash(cls, frameId): return h -class FrameStoppedLoadingEvent(BaseEvent): +class FrameResizedEvent(BaseEvent): - js_name = 'Page.frameStoppedLoading' + js_name = 'Page.frameResized' + hashable = [] + is_hashable = False + + def __init__(self): + pass + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + +class FrameScheduledNavigationEvent(BaseEvent): + + js_name = 'Page.frameScheduledNavigation' hashable = ['frameId'] is_hashable = True def __init__(self, frameId: Union['FrameId', dict], + delay: Union['float', dict], + reason: Union['str', dict], + url: Union['str', dict], ): if isinstance(frameId, dict): frameId = FrameId(**frameId) self.frameId = frameId + if isinstance(delay, dict): + delay = float(**delay) + self.delay = delay + if isinstance(reason, dict): + reason = str(**reason) + self.reason = reason + if isinstance(url, dict): + url = str(**url) + self.url = url @classmethod def build_hash(cls, frameId): @@ -1221,30 +1220,18 @@ def build_hash(cls, frameId): return h -class FrameScheduledNavigationEvent(BaseEvent): +class FrameStartedLoadingEvent(BaseEvent): - js_name = 'Page.frameScheduledNavigation' + js_name = 'Page.frameStartedLoading' hashable = ['frameId'] is_hashable = True def __init__(self, frameId: Union['FrameId', dict], - delay: Union['float', dict], - reason: Union['str', dict], - url: Union['str', dict], ): if isinstance(frameId, dict): frameId = FrameId(**frameId) self.frameId = frameId - if isinstance(delay, dict): - delay = float(**delay) - self.delay = delay - if isinstance(reason, dict): - reason = str(**reason) - self.reason = reason - if isinstance(url, dict): - url = str(**url) - self.url = url @classmethod def build_hash(cls, frameId): @@ -1256,9 +1243,9 @@ def build_hash(cls, frameId): return h -class FrameClearedScheduledNavigationEvent(BaseEvent): +class FrameStoppedLoadingEvent(BaseEvent): - js_name = 'Page.frameClearedScheduledNavigation' + js_name = 'Page.frameStoppedLoading' hashable = ['frameId'] is_hashable = True @@ -1279,9 +1266,23 @@ def build_hash(cls, frameId): return h -class FrameResizedEvent(BaseEvent): +class InterstitialHiddenEvent(BaseEvent): - js_name = 'Page.frameResized' + js_name = 'Page.interstitialHidden' + hashable = [] + is_hashable = False + + def __init__(self): + pass + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + +class InterstitialShownEvent(BaseEvent): + + js_name = 'Page.interstitialShown' hashable = [] is_hashable = False @@ -1293,6 +1294,28 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') +class JavascriptDialogClosedEvent(BaseEvent): + + js_name = 'Page.javascriptDialogClosed' + hashable = [] + is_hashable = False + + def __init__(self, + result: Union['bool', dict], + userInput: Union['str', dict], + ): + if isinstance(result, dict): + result = bool(**result) + self.result = result + if isinstance(userInput, dict): + userInput = str(**userInput) + self.userInput = userInput + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + class JavascriptDialogOpeningEvent(BaseEvent): js_name = 'Page.javascriptDialogOpening' @@ -1323,22 +1346,53 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class JavascriptDialogClosedEvent(BaseEvent): +class LifecycleEventEvent(BaseEvent): - js_name = 'Page.javascriptDialogClosed' + js_name = 'Page.lifecycleEvent' + hashable = ['loaderId', 'frameId'] + is_hashable = True + + def __init__(self, + frameId: Union['FrameId', dict], + loaderId: Union['Network.LoaderId', dict], + name: Union['str', dict], + timestamp: Union['Network.MonotonicTime', dict], + ): + if isinstance(frameId, dict): + frameId = FrameId(**frameId) + self.frameId = frameId + if isinstance(loaderId, dict): + loaderId = Network.LoaderId(**loaderId) + self.loaderId = loaderId + if isinstance(name, dict): + name = str(**name) + self.name = name + if isinstance(timestamp, dict): + timestamp = Network.MonotonicTime(**timestamp) + self.timestamp = timestamp + + @classmethod + def build_hash(cls, loaderId, frameId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class LoadEventFiredEvent(BaseEvent): + + js_name = 'Page.loadEventFired' hashable = [] is_hashable = False def __init__(self, - result: Union['bool', dict], - userInput: Union['str', dict], + timestamp: Union['Network.MonotonicTime', dict], ): - if isinstance(result, dict): - result = bool(**result) - self.result = result - if isinstance(userInput, dict): - userInput = str(**userInput) - self.userInput = userInput + if isinstance(timestamp, dict): + timestamp = Network.MonotonicTime(**timestamp) + self.timestamp = timestamp @classmethod def build_hash(cls): @@ -1394,34 +1448,6 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class InterstitialShownEvent(BaseEvent): - - js_name = 'Page.interstitialShown' - hashable = [] - is_hashable = False - - def __init__(self): - pass - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class InterstitialHiddenEvent(BaseEvent): - - js_name = 'Page.interstitialHidden' - hashable = [] - is_hashable = False - - def __init__(self): - pass - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - class WindowOpenEvent(BaseEvent): js_name = 'Page.windowOpen' diff --git a/chromewhip/protocol/performance.py b/chromewhip/protocol/performance.py index f318b6f..f8d1e70 100644 --- a/chromewhip/protocol/performance.py +++ b/chromewhip/protocol/performance.py @@ -28,21 +28,21 @@ class Performance(PayloadMixin): """ """ @classmethod - def enable(cls): - """Enable collecting and reporting metrics. + def disable(cls): + """Disable collecting and reporting metrics. """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("disable", { }), None ) @classmethod - def disable(cls): - """Disable collecting and reporting metrics. + def enable(cls): + """Enable collecting and reporting metrics. """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("enable", { }), None ) diff --git a/chromewhip/protocol/profiler.py b/chromewhip/protocol/profiler.py index ec98e9c..2bd353a 100644 --- a/chromewhip/protocol/profiler.py +++ b/chromewhip/protocol/profiler.py @@ -138,25 +138,41 @@ class Profiler(PayloadMixin): """ """ @classmethod - def enable(cls): + def disable(cls): """ """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("disable", { }), None ) @classmethod - def disable(cls): + def enable(cls): """ """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("enable", { }), None ) + @classmethod + def getBestEffortCoverage(cls): + """Collect coverage data for the current isolate. The coverage data may be incomplete due to +garbage collection. + """ + return ( + cls.build_send_payload("getBestEffortCoverage", { + }), + cls.convert_payload({ + "result": { + "class": [ScriptCoverage], + "optional": False + }, + }) + ) + @classmethod def setSamplingInterval(cls, interval: Union['int'], @@ -182,27 +198,14 @@ def start(cls): None ) - @classmethod - def stop(cls): - """ - """ - return ( - cls.build_send_payload("stop", { - }), - cls.convert_payload({ - "profile": { - "class": Profile, - "optional": False - }, - }) - ) - @classmethod def startPreciseCoverage(cls, callCount: Optional['bool'] = None, detailed: Optional['bool'] = None, ): - """Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code coverage may be incomplete. Enabling prevents running optimized code and resets execution counters. + """Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code +coverage may be incomplete. Enabling prevents running optimized code and resets execution +counters. :param callCount: Collect accurate call counts beyond simple 'covered' or 'not covered'. :type callCount: bool :param detailed: Collect block-based coverage. @@ -217,63 +220,65 @@ def startPreciseCoverage(cls, ) @classmethod - def stopPreciseCoverage(cls): - """Disable precise code coverage. Disabling releases unnecessary execution count records and allows executing optimized code. + def startTypeProfile(cls): + """Enable type profile. """ return ( - cls.build_send_payload("stopPreciseCoverage", { + cls.build_send_payload("startTypeProfile", { }), None ) @classmethod - def takePreciseCoverage(cls): - """Collect coverage data for the current isolate, and resets execution counters. Precise code coverage needs to have started. + def stop(cls): + """ """ return ( - cls.build_send_payload("takePreciseCoverage", { + cls.build_send_payload("stop", { }), cls.convert_payload({ - "result": { - "class": [ScriptCoverage], + "profile": { + "class": Profile, "optional": False }, }) ) @classmethod - def getBestEffortCoverage(cls): - """Collect coverage data for the current isolate. The coverage data may be incomplete due to garbage collection. + def stopPreciseCoverage(cls): + """Disable precise code coverage. Disabling releases unnecessary execution count records and allows +executing optimized code. """ return ( - cls.build_send_payload("getBestEffortCoverage", { + cls.build_send_payload("stopPreciseCoverage", { }), - cls.convert_payload({ - "result": { - "class": [ScriptCoverage], - "optional": False - }, - }) + None ) @classmethod - def startTypeProfile(cls): - """Enable type profile. + def stopTypeProfile(cls): + """Disable type profile. Disabling releases type profile data collected so far. """ return ( - cls.build_send_payload("startTypeProfile", { + cls.build_send_payload("stopTypeProfile", { }), None ) @classmethod - def stopTypeProfile(cls): - """Disable type profile. Disabling releases type profile data collected so far. + def takePreciseCoverage(cls): + """Collect coverage data for the current isolate, and resets execution counters. Precise code +coverage needs to have started. """ return ( - cls.build_send_payload("stopTypeProfile", { + cls.build_send_payload("takePreciseCoverage", { }), - None + cls.convert_payload({ + "result": { + "class": [ScriptCoverage], + "optional": False + }, + }) ) @classmethod @@ -293,15 +298,16 @@ def takeTypeProfile(cls): -class ConsoleProfileStartedEvent(BaseEvent): +class ConsoleProfileFinishedEvent(BaseEvent): - js_name = 'Profiler.consoleProfileStarted' + js_name = 'Profiler.consoleProfileFinished' hashable = ['id'] is_hashable = True def __init__(self, id: Union['str', dict], location: Union['Debugger.Location', dict], + profile: Union['Profile', dict], title: Union['str', dict, None] = None, ): if isinstance(id, dict): @@ -310,6 +316,9 @@ def __init__(self, if isinstance(location, dict): location = Debugger.Location(**location) self.location = location + if isinstance(profile, dict): + profile = Profile(**profile) + self.profile = profile if isinstance(title, dict): title = str(**title) self.title = title @@ -324,16 +333,15 @@ def build_hash(cls, id): return h -class ConsoleProfileFinishedEvent(BaseEvent): +class ConsoleProfileStartedEvent(BaseEvent): - js_name = 'Profiler.consoleProfileFinished' + js_name = 'Profiler.consoleProfileStarted' hashable = ['id'] is_hashable = True def __init__(self, id: Union['str', dict], location: Union['Debugger.Location', dict], - profile: Union['Profile', dict], title: Union['str', dict, None] = None, ): if isinstance(id, dict): @@ -342,9 +350,6 @@ def __init__(self, if isinstance(location, dict): location = Debugger.Location(**location) self.location = location - if isinstance(profile, dict): - profile = Profile(**profile) - self.profile = profile if isinstance(title, dict): title = str(**title) self.title = title diff --git a/chromewhip/protocol/runtime.py b/chromewhip/protocol/runtime.py index b3e914a..76fd7a4 100644 --- a/chromewhip/protocol/runtime.py +++ b/chromewhip/protocol/runtime.py @@ -149,7 +149,7 @@ def __init__(self, self.value = value -# CallArgument: Represents function call argument. Either remote object id objectId, primitive value, unserializable primitive value or neither of (for undefined) them should be specified. +# CallArgument: Represents function call argument. Either remote object id `objectId`, primitive `value`,unserializable primitive value or neither of (for undefined) them should be specified. class CallArgument(ChromeTypeBase): def __init__(self, value: Optional['Any'] = None, @@ -180,7 +180,7 @@ def __init__(self, self.auxData = auxData -# ExceptionDetails: Detailed information about exception (or error) that was thrown during script compilation or execution. +# ExceptionDetails: Detailed information about exception (or error) that was thrown during script compilation orexecution. class ExceptionDetails(ChromeTypeBase): def __init__(self, exceptionId: Union['int'], @@ -231,74 +231,36 @@ def __init__(self, callFrames: Union['[CallFrame]'], description: Optional['str'] = None, parent: Optional['StackTrace'] = None, - promiseCreationFrame: Optional['CallFrame'] = None, + parentId: Optional['StackTraceId'] = None, ): self.description = description self.callFrames = callFrames self.parent = parent - self.promiseCreationFrame = promiseCreationFrame + self.parentId = parentId -class Runtime(PayloadMixin): - """ Runtime domain exposes JavaScript runtime by means of remote evaluation and mirror objects. Evaluation results are returned as mirror object that expose object type, string representation and unique identifier that can be used for further object reference. Original objects are maintained in memory unless they are either explicitly released or are released along with the other objects in their object group. - """ - @classmethod - def evaluate(cls, - expression: Union['str'], - objectGroup: Optional['str'] = None, - includeCommandLineAPI: Optional['bool'] = None, - silent: Optional['bool'] = None, - contextId: Optional['ExecutionContextId'] = None, - returnByValue: Optional['bool'] = None, - generatePreview: Optional['bool'] = None, - userGesture: Optional['bool'] = None, - awaitPromise: Optional['bool'] = None, +# UniqueDebuggerId: Unique identifier of current debugger. +UniqueDebuggerId = str + +# StackTraceId: If `debuggerId` is set stack trace comes from another debugger and can be resolved there. Thisallows to track cross-debugger calls. See `Runtime.StackTrace` and `Debugger.paused` for usages. +class StackTraceId(ChromeTypeBase): + def __init__(self, + id: Union['str'], + debuggerId: Optional['UniqueDebuggerId'] = None, ): - """Evaluates expression on global object. - :param expression: Expression to evaluate. - :type expression: str - :param objectGroup: Symbolic group name that can be used to release multiple objects. - :type objectGroup: str - :param includeCommandLineAPI: Determines whether Command Line API should be available during the evaluation. - :type includeCommandLineAPI: bool - :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides setPauseOnException state. - :type silent: bool - :param contextId: Specifies in which execution context to perform evaluation. If the parameter is omitted the evaluation will be performed in the context of the inspected page. - :type contextId: ExecutionContextId - :param returnByValue: Whether the result is expected to be a JSON object that should be sent by value. - :type returnByValue: bool - :param generatePreview: Whether preview should be generated for the result. - :type generatePreview: bool - :param userGesture: Whether execution should be treated as initiated by user in the UI. - :type userGesture: bool - :param awaitPromise: Whether execution should await for resulting value and return once awaited promise is resolved. - :type awaitPromise: bool - """ - return ( - cls.build_send_payload("evaluate", { - "expression": expression, - "objectGroup": objectGroup, - "includeCommandLineAPI": includeCommandLineAPI, - "silent": silent, - "contextId": contextId, - "returnByValue": returnByValue, - "generatePreview": generatePreview, - "userGesture": userGesture, - "awaitPromise": awaitPromise, - }), - cls.convert_payload({ - "result": { - "class": RemoteObject, - "optional": False - }, - "exceptionDetails": { - "class": ExceptionDetails, - "optional": True - }, - }) - ) + self.id = id + self.debuggerId = debuggerId + + +class Runtime(PayloadMixin): + """ Runtime domain exposes JavaScript runtime by means of remote evaluation and mirror objects. +Evaluation results are returned as mirror object that expose object type, string representation +and unique identifier that can be used for further object reference. Original objects are +maintained in memory unless they are either explicitly released or are released along with the +other objects in their object group. + """ @classmethod def awaitPromise(cls, promiseObjectId: Union['RemoteObjectId'], @@ -344,14 +306,18 @@ def callFunctionOn(cls, executionContextId: Optional['ExecutionContextId'] = None, objectGroup: Optional['str'] = None, ): - """Calls function with given declaration on the given object. Object group of the result is inherited from the target object. + """Calls function with given declaration on the given object. Object group of the result is +inherited from the target object. :param functionDeclaration: Declaration of the function to call. :type functionDeclaration: str - :param objectId: Identifier of the object to call function on. Either objectId or executionContextId should be specified. + :param objectId: Identifier of the object to call function on. Either objectId or executionContextId should +be specified. :type objectId: RemoteObjectId - :param arguments: Call arguments. All call arguments must belong to the same JavaScript world as the target object. + :param arguments: Call arguments. All call arguments must belong to the same JavaScript world as the target +object. :type arguments: [CallArgument] - :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides setPauseOnException state. + :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause +execution. Overrides `setPauseOnException` state. :type silent: bool :param returnByValue: Whether the result is expected to be a JSON object which should be sent by value. :type returnByValue: bool @@ -359,11 +325,14 @@ def callFunctionOn(cls, :type generatePreview: bool :param userGesture: Whether execution should be treated as initiated by user in the UI. :type userGesture: bool - :param awaitPromise: Whether execution should await for resulting value and return once awaited promise is resolved. + :param awaitPromise: Whether execution should `await` for resulting value and return once awaited promise is +resolved. :type awaitPromise: bool - :param executionContextId: Specifies execution context which global object will be used to call function on. Either executionContextId or objectId should be specified. + :param executionContextId: Specifies execution context which global object will be used to call function on. Either +executionContextId or objectId should be specified. :type executionContextId: ExecutionContextId - :param objectGroup: Symbolic group name that can be used to release multiple objects. If objectGroup is not specified and objectId is, objectGroup will be inherited from object. + :param objectGroup: Symbolic group name that can be used to release multiple objects. If objectGroup is not +specified and objectId is, objectGroup will be inherited from object. :type objectGroup: str """ return ( @@ -391,6 +360,134 @@ def callFunctionOn(cls, }) ) + @classmethod + def compileScript(cls, + expression: Union['str'], + sourceURL: Union['str'], + persistScript: Union['bool'], + executionContextId: Optional['ExecutionContextId'] = None, + ): + """Compiles expression. + :param expression: Expression to compile. + :type expression: str + :param sourceURL: Source url to be set for the script. + :type sourceURL: str + :param persistScript: Specifies whether the compiled script should be persisted. + :type persistScript: bool + :param executionContextId: Specifies in which execution context to perform script run. If the parameter is omitted the +evaluation will be performed in the context of the inspected page. + :type executionContextId: ExecutionContextId + """ + return ( + cls.build_send_payload("compileScript", { + "expression": expression, + "sourceURL": sourceURL, + "persistScript": persistScript, + "executionContextId": executionContextId, + }), + cls.convert_payload({ + "scriptId": { + "class": ScriptId, + "optional": True + }, + "exceptionDetails": { + "class": ExceptionDetails, + "optional": True + }, + }) + ) + + @classmethod + def disable(cls): + """Disables reporting of execution contexts creation. + """ + return ( + cls.build_send_payload("disable", { + }), + None + ) + + @classmethod + def discardConsoleEntries(cls): + """Discards collected exceptions and console API calls. + """ + return ( + cls.build_send_payload("discardConsoleEntries", { + }), + None + ) + + @classmethod + def enable(cls): + """Enables reporting of execution contexts creation by means of `executionContextCreated` event. +When the reporting gets enabled the event will be sent immediately for each existing execution +context. + """ + return ( + cls.build_send_payload("enable", { + }), + None + ) + + @classmethod + def evaluate(cls, + expression: Union['str'], + objectGroup: Optional['str'] = None, + includeCommandLineAPI: Optional['bool'] = None, + silent: Optional['bool'] = None, + contextId: Optional['ExecutionContextId'] = None, + returnByValue: Optional['bool'] = None, + generatePreview: Optional['bool'] = None, + userGesture: Optional['bool'] = None, + awaitPromise: Optional['bool'] = None, + ): + """Evaluates expression on global object. + :param expression: Expression to evaluate. + :type expression: str + :param objectGroup: Symbolic group name that can be used to release multiple objects. + :type objectGroup: str + :param includeCommandLineAPI: Determines whether Command Line API should be available during the evaluation. + :type includeCommandLineAPI: bool + :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause +execution. Overrides `setPauseOnException` state. + :type silent: bool + :param contextId: Specifies in which execution context to perform evaluation. If the parameter is omitted the +evaluation will be performed in the context of the inspected page. + :type contextId: ExecutionContextId + :param returnByValue: Whether the result is expected to be a JSON object that should be sent by value. + :type returnByValue: bool + :param generatePreview: Whether preview should be generated for the result. + :type generatePreview: bool + :param userGesture: Whether execution should be treated as initiated by user in the UI. + :type userGesture: bool + :param awaitPromise: Whether execution should `await` for resulting value and return once awaited promise is +resolved. + :type awaitPromise: bool + """ + return ( + cls.build_send_payload("evaluate", { + "expression": expression, + "objectGroup": objectGroup, + "includeCommandLineAPI": includeCommandLineAPI, + "silent": silent, + "contextId": contextId, + "returnByValue": returnByValue, + "generatePreview": generatePreview, + "userGesture": userGesture, + "awaitPromise": awaitPromise, + }), + cls.convert_payload({ + "result": { + "class": RemoteObject, + "optional": False + }, + "exceptionDetails": { + "class": ExceptionDetails, + "optional": True + }, + }) + ) + @classmethod def getProperties(cls, objectId: Union['RemoteObjectId'], @@ -398,12 +495,15 @@ def getProperties(cls, accessorPropertiesOnly: Optional['bool'] = None, generatePreview: Optional['bool'] = None, ): - """Returns properties of a given object. Object group of the result is inherited from the target object. + """Returns properties of a given object. Object group of the result is inherited from the target +object. :param objectId: Identifier of the object to return properties for. :type objectId: RemoteObjectId - :param ownProperties: If true, returns properties belonging only to the element itself, not to its prototype chain. + :param ownProperties: If true, returns properties belonging only to the element itself, not to its prototype +chain. :type ownProperties: bool - :param accessorPropertiesOnly: If true, returns accessor properties (with getter/setter) only; internal properties are not returned either. + :param accessorPropertiesOnly: If true, returns accessor properties (with getter/setter) only; internal properties are not +returned either. :type accessorPropertiesOnly: bool :param generatePreview: Whether preview should be generated for the results. :type generatePreview: bool @@ -431,6 +531,46 @@ def getProperties(cls, }) ) + @classmethod + def globalLexicalScopeNames(cls, + executionContextId: Optional['ExecutionContextId'] = None, + ): + """Returns all let, const and class variables from global scope. + :param executionContextId: Specifies in which execution context to lookup global scope variables. + :type executionContextId: ExecutionContextId + """ + return ( + cls.build_send_payload("globalLexicalScopeNames", { + "executionContextId": executionContextId, + }), + cls.convert_payload({ + "names": { + "class": [], + "optional": False + }, + }) + ) + + @classmethod + def queryObjects(cls, + prototypeObjectId: Union['RemoteObjectId'], + ): + """ + :param prototypeObjectId: Identifier of the prototype to return objects for. + :type prototypeObjectId: RemoteObjectId + """ + return ( + cls.build_send_payload("queryObjects", { + "prototypeObjectId": prototypeObjectId, + }), + cls.convert_payload({ + "objects": { + "class": RemoteObject, + "optional": False + }, + }) + ) + @classmethod def releaseObject(cls, objectId: Union['RemoteObjectId'], @@ -471,87 +611,6 @@ def runIfWaitingForDebugger(cls): None ) - @classmethod - def enable(cls): - """Enables reporting of execution contexts creation by means of executionContextCreated event. When the reporting gets enabled the event will be sent immediately for each existing execution context. - """ - return ( - cls.build_send_payload("enable", { - }), - None - ) - - @classmethod - def disable(cls): - """Disables reporting of execution contexts creation. - """ - return ( - cls.build_send_payload("disable", { - }), - None - ) - - @classmethod - def discardConsoleEntries(cls): - """Discards collected exceptions and console API calls. - """ - return ( - cls.build_send_payload("discardConsoleEntries", { - }), - None - ) - - @classmethod - def setCustomObjectFormatterEnabled(cls, - enabled: Union['bool'], - ): - """ - :param enabled: - :type enabled: bool - """ - return ( - cls.build_send_payload("setCustomObjectFormatterEnabled", { - "enabled": enabled, - }), - None - ) - - @classmethod - def compileScript(cls, - expression: Union['str'], - sourceURL: Union['str'], - persistScript: Union['bool'], - executionContextId: Optional['ExecutionContextId'] = None, - ): - """Compiles expression. - :param expression: Expression to compile. - :type expression: str - :param sourceURL: Source url to be set for the script. - :type sourceURL: str - :param persistScript: Specifies whether the compiled script should be persisted. - :type persistScript: bool - :param executionContextId: Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page. - :type executionContextId: ExecutionContextId - """ - return ( - cls.build_send_payload("compileScript", { - "expression": expression, - "sourceURL": sourceURL, - "persistScript": persistScript, - "executionContextId": executionContextId, - }), - cls.convert_payload({ - "scriptId": { - "class": ScriptId, - "optional": True - }, - "exceptionDetails": { - "class": ExceptionDetails, - "optional": True - }, - }) - ) - @classmethod def runScript(cls, scriptId: Union['ScriptId'], @@ -566,11 +625,13 @@ def runScript(cls, """Runs script with given id in a given context. :param scriptId: Id of the script to run. :type scriptId: ScriptId - :param executionContextId: Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page. + :param executionContextId: Specifies in which execution context to perform script run. If the parameter is omitted the +evaluation will be performed in the context of the inspected page. :type executionContextId: ExecutionContextId :param objectGroup: Symbolic group name that can be used to release multiple objects. :type objectGroup: str - :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause execution. Overrides setPauseOnException state. + :param silent: In silent mode exceptions thrown during evaluation are not reported and do not pause +execution. Overrides `setPauseOnException` state. :type silent: bool :param includeCommandLineAPI: Determines whether Command Line API should be available during the evaluation. :type includeCommandLineAPI: bool @@ -578,7 +639,8 @@ def runScript(cls, :type returnByValue: bool :param generatePreview: Whether preview should be generated for the result. :type generatePreview: bool - :param awaitPromise: Whether execution should await for resulting value and return once awaited promise is resolved. + :param awaitPromise: Whether execution should `await` for resulting value and return once awaited promise is +resolved. :type awaitPromise: bool """ return ( @@ -605,62 +667,57 @@ def runScript(cls, ) @classmethod - def queryObjects(cls, - prototypeObjectId: Union['RemoteObjectId'], - ): - """ - :param prototypeObjectId: Identifier of the prototype to return objects for. - :type prototypeObjectId: RemoteObjectId + def setCustomObjectFormatterEnabled(cls, + enabled: Union['bool'], + ): """ - return ( - cls.build_send_payload("queryObjects", { - "prototypeObjectId": prototypeObjectId, - }), - cls.convert_payload({ - "objects": { - "class": RemoteObject, - "optional": False - }, - }) - ) - - @classmethod - def globalLexicalScopeNames(cls, - executionContextId: Optional['ExecutionContextId'] = None, - ): - """Returns all let, const and class variables from global scope. - :param executionContextId: Specifies in which execution context to lookup global scope variables. - :type executionContextId: ExecutionContextId + :param enabled: + :type enabled: bool """ return ( - cls.build_send_payload("globalLexicalScopeNames", { - "executionContextId": executionContextId, + cls.build_send_payload("setCustomObjectFormatterEnabled", { + "enabled": enabled, }), - cls.convert_payload({ - "names": { - "class": [], - "optional": False - }, - }) + None ) -class ExecutionContextCreatedEvent(BaseEvent): +class ConsoleAPICalledEvent(BaseEvent): - js_name = 'Runtime.executionContextCreated' - hashable = ['contextId'] + js_name = 'Runtime.consoleAPICalled' + hashable = ['executionContextId'] is_hashable = True def __init__(self, - context: Union['ExecutionContextDescription', dict], + type: Union['str', dict], + args: Union['[RemoteObject]', dict], + executionContextId: Union['ExecutionContextId', dict], + timestamp: Union['Timestamp', dict], + stackTrace: Union['StackTrace', dict, None] = None, + context: Union['str', dict, None] = None, ): + if isinstance(type, dict): + type = str(**type) + self.type = type + if isinstance(args, dict): + args = [RemoteObject](**args) + self.args = args + if isinstance(executionContextId, dict): + executionContextId = ExecutionContextId(**executionContextId) + self.executionContextId = executionContextId + if isinstance(timestamp, dict): + timestamp = Timestamp(**timestamp) + self.timestamp = timestamp + if isinstance(stackTrace, dict): + stackTrace = StackTrace(**stackTrace) + self.stackTrace = stackTrace if isinstance(context, dict): - context = ExecutionContextDescription(**context) + context = str(**context) self.context = context @classmethod - def build_hash(cls, contextId): + def build_hash(cls, executionContextId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -669,21 +726,25 @@ def build_hash(cls, contextId): return h -class ExecutionContextDestroyedEvent(BaseEvent): +class ExceptionRevokedEvent(BaseEvent): - js_name = 'Runtime.executionContextDestroyed' - hashable = ['executionContextId'] + js_name = 'Runtime.exceptionRevoked' + hashable = ['exceptionId'] is_hashable = True def __init__(self, - executionContextId: Union['ExecutionContextId', dict], + reason: Union['str', dict], + exceptionId: Union['int', dict], ): - if isinstance(executionContextId, dict): - executionContextId = ExecutionContextId(**executionContextId) - self.executionContextId = executionContextId + if isinstance(reason, dict): + reason = str(**reason) + self.reason = reason + if isinstance(exceptionId, dict): + exceptionId = int(**exceptionId) + self.exceptionId = exceptionId @classmethod - def build_hash(cls, executionContextId): + def build_hash(cls, exceptionId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -692,20 +753,6 @@ def build_hash(cls, executionContextId): return h -class ExecutionContextsClearedEvent(BaseEvent): - - js_name = 'Runtime.executionContextsCleared' - hashable = [] - is_hashable = False - - def __init__(self): - pass - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - class ExceptionThrownEvent(BaseEvent): js_name = 'Runtime.exceptionThrown' @@ -728,25 +775,21 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class ExceptionRevokedEvent(BaseEvent): +class ExecutionContextCreatedEvent(BaseEvent): - js_name = 'Runtime.exceptionRevoked' - hashable = ['exceptionId'] + js_name = 'Runtime.executionContextCreated' + hashable = ['contextId'] is_hashable = True def __init__(self, - reason: Union['str', dict], - exceptionId: Union['int', dict], + context: Union['ExecutionContextDescription', dict], ): - if isinstance(reason, dict): - reason = str(**reason) - self.reason = reason - if isinstance(exceptionId, dict): - exceptionId = int(**exceptionId) - self.exceptionId = exceptionId + if isinstance(context, dict): + context = ExecutionContextDescription(**context) + self.context = context @classmethod - def build_hash(cls, exceptionId): + def build_hash(cls, contextId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -755,38 +798,18 @@ def build_hash(cls, exceptionId): return h -class ConsoleAPICalledEvent(BaseEvent): +class ExecutionContextDestroyedEvent(BaseEvent): - js_name = 'Runtime.consoleAPICalled' + js_name = 'Runtime.executionContextDestroyed' hashable = ['executionContextId'] is_hashable = True def __init__(self, - type: Union['str', dict], - args: Union['[RemoteObject]', dict], executionContextId: Union['ExecutionContextId', dict], - timestamp: Union['Timestamp', dict], - stackTrace: Union['StackTrace', dict, None] = None, - context: Union['str', dict, None] = None, ): - if isinstance(type, dict): - type = str(**type) - self.type = type - if isinstance(args, dict): - args = [RemoteObject](**args) - self.args = args if isinstance(executionContextId, dict): executionContextId = ExecutionContextId(**executionContextId) self.executionContextId = executionContextId - if isinstance(timestamp, dict): - timestamp = Timestamp(**timestamp) - self.timestamp = timestamp - if isinstance(stackTrace, dict): - stackTrace = StackTrace(**stackTrace) - self.stackTrace = stackTrace - if isinstance(context, dict): - context = str(**context) - self.context = context @classmethod def build_hash(cls, executionContextId): @@ -798,6 +821,20 @@ def build_hash(cls, executionContextId): return h +class ExecutionContextsClearedEvent(BaseEvent): + + js_name = 'Runtime.executionContextsCleared' + hashable = [] + is_hashable = False + + def __init__(self): + pass + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + class InspectRequestedEvent(BaseEvent): js_name = 'Runtime.inspectRequested' diff --git a/chromewhip/protocol/schema.py b/chromewhip/protocol/schema.py index 5c72dc6..a298438 100644 --- a/chromewhip/protocol/schema.py +++ b/chromewhip/protocol/schema.py @@ -25,7 +25,7 @@ def __init__(self, class Schema(PayloadMixin): - """ Provides information about the protocol schema. + """ This domain is deprecated. """ @classmethod def getDomains(cls): diff --git a/chromewhip/protocol/security.py b/chromewhip/protocol/security.py index 9d72a20..fc6199e 100644 --- a/chromewhip/protocol/security.py +++ b/chromewhip/protocol/security.py @@ -16,7 +16,7 @@ # CertificateId: An internal certificate ID value. CertificateId = int -# MixedContentType: A description of mixed content (HTTP resources on HTTPS pages), as defined by https://www.w3.org/TR/mixed-content/#categories +# MixedContentType: A description of mixed content (HTTP resources on HTTPS pages), as defined byhttps://www.w3.org/TR/mixed-content/#categories MixedContentType = str # SecurityState: The security level of a page or resource. @@ -26,6 +26,7 @@ class SecurityStateExplanation(ChromeTypeBase): def __init__(self, securityState: Union['SecurityState'], + title: Union['str'], summary: Union['str'], description: Union['str'], mixedContentType: Union['MixedContentType'], @@ -33,6 +34,7 @@ def __init__(self, ): self.securityState = securityState + self.title = title self.summary = summary self.description = description self.mixedContentType = mixedContentType @@ -60,12 +62,22 @@ def __init__(self, self.displayedInsecureContentStyle = displayedInsecureContentStyle -# CertificateErrorAction: The action to take when a certificate error occurs. continue will continue processing the request and cancel will cancel the request. +# CertificateErrorAction: The action to take when a certificate error occurs. continue will continue processing therequest and cancel will cancel the request. CertificateErrorAction = str class Security(PayloadMixin): """ Security """ + @classmethod + def disable(cls): + """Disables tracking security state changes. + """ + return ( + cls.build_send_payload("disable", { + }), + None + ) + @classmethod def enable(cls): """Enables tracking security state changes. @@ -77,11 +89,16 @@ def enable(cls): ) @classmethod - def disable(cls): - """Disables tracking security state changes. + def setIgnoreCertificateErrors(cls, + ignore: Union['bool'], + ): + """Enable/disable whether all certificate errors should be ignored. + :param ignore: If true, all certificate errors will be ignored. + :type ignore: bool """ return ( - cls.build_send_payload("disable", { + cls.build_send_payload("setIgnoreCertificateErrors", { + "ignore": ignore, }), None ) @@ -109,7 +126,8 @@ def handleCertificateError(cls, def setOverrideCertificateErrors(cls, override: Union['bool'], ): - """Enable/disable overriding certificate errors. If enabled, all certificate error events need to be handled by the DevTools client and should be answered with handleCertificateError commands. + """Enable/disable overriding certificate errors. If enabled, all certificate error events need to +be handled by the DevTools client and should be answered with handleCertificateError commands. :param override: If true, certificate errors will be overridden. :type override: bool """ @@ -122,6 +140,37 @@ def setOverrideCertificateErrors(cls, +class CertificateErrorEvent(BaseEvent): + + js_name = 'Security.certificateError' + hashable = ['eventId'] + is_hashable = True + + def __init__(self, + eventId: Union['int', dict], + errorType: Union['str', dict], + requestURL: Union['str', dict], + ): + if isinstance(eventId, dict): + eventId = int(**eventId) + self.eventId = eventId + if isinstance(errorType, dict): + errorType = str(**errorType) + self.errorType = errorType + if isinstance(requestURL, dict): + requestURL = str(**requestURL) + self.requestURL = requestURL + + @classmethod + def build_hash(cls, eventId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + class SecurityStateChangedEvent(BaseEvent): js_name = 'Security.securityStateChanged' @@ -154,34 +203,3 @@ def __init__(self, @classmethod def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') - - -class CertificateErrorEvent(BaseEvent): - - js_name = 'Security.certificateError' - hashable = ['eventId'] - is_hashable = True - - def __init__(self, - eventId: Union['int', dict], - errorType: Union['str', dict], - requestURL: Union['str', dict], - ): - if isinstance(eventId, dict): - eventId = int(**eventId) - self.eventId = eventId - if isinstance(errorType, dict): - errorType = str(**errorType) - self.errorType = errorType - if isinstance(requestURL, dict): - requestURL = str(**requestURL) - self.requestURL = requestURL - - @classmethod - def build_hash(cls, eventId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h diff --git a/chromewhip/protocol/serviceworker.py b/chromewhip/protocol/serviceworker.py index c03097a..2aa2ca8 100644 --- a/chromewhip/protocol/serviceworker.py +++ b/chromewhip/protocol/serviceworker.py @@ -80,11 +80,24 @@ class ServiceWorker(PayloadMixin): """ """ @classmethod - def enable(cls): + def deliverPushMessage(cls, + origin: Union['str'], + registrationId: Union['str'], + data: Union['str'], + ): """ + :param origin: + :type origin: str + :param registrationId: + :type registrationId: str + :param data: + :type data: str """ return ( - cls.build_send_payload("enable", { + cls.build_send_payload("deliverPushMessage", { + "origin": origin, + "registrationId": registrationId, + "data": data, }), None ) @@ -100,46 +113,68 @@ def disable(cls): ) @classmethod - def unregister(cls, - scopeURL: Union['str'], - ): + def dispatchSyncEvent(cls, + origin: Union['str'], + registrationId: Union['str'], + tag: Union['str'], + lastChance: Union['bool'], + ): """ - :param scopeURL: - :type scopeURL: str + :param origin: + :type origin: str + :param registrationId: + :type registrationId: str + :param tag: + :type tag: str + :param lastChance: + :type lastChance: bool """ return ( - cls.build_send_payload("unregister", { - "scopeURL": scopeURL, + cls.build_send_payload("dispatchSyncEvent", { + "origin": origin, + "registrationId": registrationId, + "tag": tag, + "lastChance": lastChance, }), None ) @classmethod - def updateRegistration(cls, - scopeURL: Union['str'], - ): + def enable(cls): """ - :param scopeURL: - :type scopeURL: str """ return ( - cls.build_send_payload("updateRegistration", { - "scopeURL": scopeURL, + cls.build_send_payload("enable", { }), None ) @classmethod - def startWorker(cls, - scopeURL: Union['str'], - ): + def inspectWorker(cls, + versionId: Union['str'], + ): """ - :param scopeURL: - :type scopeURL: str + :param versionId: + :type versionId: str """ return ( - cls.build_send_payload("startWorker", { - "scopeURL": scopeURL, + cls.build_send_payload("inspectWorker", { + "versionId": versionId, + }), + None + ) + + @classmethod + def setForceUpdateOnPageLoad(cls, + forceUpdateOnPageLoad: Union['bool'], + ): + """ + :param forceUpdateOnPageLoad: + :type forceUpdateOnPageLoad: bool + """ + return ( + cls.build_send_payload("setForceUpdateOnPageLoad", { + "forceUpdateOnPageLoad": forceUpdateOnPageLoad, }), None ) @@ -160,16 +195,16 @@ def skipWaiting(cls, ) @classmethod - def stopWorker(cls, - versionId: Union['str'], - ): + def startWorker(cls, + scopeURL: Union['str'], + ): """ - :param versionId: - :type versionId: str + :param scopeURL: + :type scopeURL: str """ return ( - cls.build_send_payload("stopWorker", { - "versionId": versionId, + cls.build_send_payload("startWorker", { + "scopeURL": scopeURL, }), None ) @@ -185,86 +220,69 @@ def stopAllWorkers(cls): ) @classmethod - def inspectWorker(cls, - versionId: Union['str'], - ): + def stopWorker(cls, + versionId: Union['str'], + ): """ :param versionId: :type versionId: str """ return ( - cls.build_send_payload("inspectWorker", { + cls.build_send_payload("stopWorker", { "versionId": versionId, }), None ) @classmethod - def setForceUpdateOnPageLoad(cls, - forceUpdateOnPageLoad: Union['bool'], - ): + def unregister(cls, + scopeURL: Union['str'], + ): """ - :param forceUpdateOnPageLoad: - :type forceUpdateOnPageLoad: bool + :param scopeURL: + :type scopeURL: str """ return ( - cls.build_send_payload("setForceUpdateOnPageLoad", { - "forceUpdateOnPageLoad": forceUpdateOnPageLoad, + cls.build_send_payload("unregister", { + "scopeURL": scopeURL, }), None ) @classmethod - def deliverPushMessage(cls, - origin: Union['str'], - registrationId: Union['str'], - data: Union['str'], + def updateRegistration(cls, + scopeURL: Union['str'], ): """ - :param origin: - :type origin: str - :param registrationId: - :type registrationId: str - :param data: - :type data: str + :param scopeURL: + :type scopeURL: str """ return ( - cls.build_send_payload("deliverPushMessage", { - "origin": origin, - "registrationId": registrationId, - "data": data, + cls.build_send_payload("updateRegistration", { + "scopeURL": scopeURL, }), None ) - @classmethod - def dispatchSyncEvent(cls, - origin: Union['str'], - registrationId: Union['str'], - tag: Union['str'], - lastChance: Union['bool'], - ): - """ - :param origin: - :type origin: str - :param registrationId: - :type registrationId: str - :param tag: - :type tag: str - :param lastChance: - :type lastChance: bool - """ - return ( - cls.build_send_payload("dispatchSyncEvent", { - "origin": origin, - "registrationId": registrationId, - "tag": tag, - "lastChance": lastChance, - }), - None - ) +class WorkerErrorReportedEvent(BaseEvent): + + js_name = 'Serviceworker.workerErrorReported' + hashable = [] + is_hashable = False + + def __init__(self, + errorMessage: Union['ServiceWorkerErrorMessage', dict], + ): + if isinstance(errorMessage, dict): + errorMessage = ServiceWorkerErrorMessage(**errorMessage) + self.errorMessage = errorMessage + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + class WorkerRegistrationUpdatedEvent(BaseEvent): @@ -300,21 +318,3 @@ def __init__(self, @classmethod def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') - - -class WorkerErrorReportedEvent(BaseEvent): - - js_name = 'Serviceworker.workerErrorReported' - hashable = [] - is_hashable = False - - def __init__(self, - errorMessage: Union['ServiceWorkerErrorMessage', dict], - ): - if isinstance(errorMessage, dict): - errorMessage = ServiceWorkerErrorMessage(**errorMessage) - self.errorMessage = errorMessage - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') diff --git a/chromewhip/protocol/storage.py b/chromewhip/protocol/storage.py index d36af23..f9bc8d4 100644 --- a/chromewhip/protocol/storage.py +++ b/chromewhip/protocol/storage.py @@ -93,30 +93,30 @@ def trackCacheStorageForOrigin(cls, ) @classmethod - def untrackCacheStorageForOrigin(cls, - origin: Union['str'], - ): - """Unregisters origin from receiving notifications for cache storage. + def trackIndexedDBForOrigin(cls, + origin: Union['str'], + ): + """Registers origin to be notified when an update occurs to its IndexedDB. :param origin: Security origin. :type origin: str """ return ( - cls.build_send_payload("untrackCacheStorageForOrigin", { + cls.build_send_payload("trackIndexedDBForOrigin", { "origin": origin, }), None ) @classmethod - def trackIndexedDBForOrigin(cls, - origin: Union['str'], - ): - """Registers origin to be notified when an update occurs to its IndexedDB. + def untrackCacheStorageForOrigin(cls, + origin: Union['str'], + ): + """Unregisters origin from receiving notifications for cache storage. :param origin: Security origin. :type origin: str """ return ( - cls.build_send_payload("trackIndexedDBForOrigin", { + cls.build_send_payload("untrackCacheStorageForOrigin", { "origin": origin, }), None @@ -139,24 +139,6 @@ def untrackIndexedDBForOrigin(cls, -class CacheStorageListUpdatedEvent(BaseEvent): - - js_name = 'Storage.cacheStorageListUpdated' - hashable = [] - is_hashable = False - - def __init__(self, - origin: Union['str', dict], - ): - if isinstance(origin, dict): - origin = str(**origin) - self.origin = origin - - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - class CacheStorageContentUpdatedEvent(BaseEvent): js_name = 'Storage.cacheStorageContentUpdated' @@ -179,9 +161,9 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class IndexedDBListUpdatedEvent(BaseEvent): +class CacheStorageListUpdatedEvent(BaseEvent): - js_name = 'Storage.indexedDBListUpdated' + js_name = 'Storage.cacheStorageListUpdated' hashable = [] is_hashable = False @@ -221,3 +203,21 @@ def __init__(self, @classmethod def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') + + +class IndexedDBListUpdatedEvent(BaseEvent): + + js_name = 'Storage.indexedDBListUpdated' + hashable = [] + is_hashable = False + + def __init__(self, + origin: Union['str', dict], + ): + if isinstance(origin, dict): + origin = str(**origin) + self.origin = origin + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') diff --git a/chromewhip/protocol/target.py b/chromewhip/protocol/target.py index de51bbc..89b62b8 100644 --- a/chromewhip/protocol/target.py +++ b/chromewhip/protocol/target.py @@ -56,127 +56,40 @@ class Target(PayloadMixin): """ Supports additional targets discovery and allows to attach to them. """ @classmethod - def setDiscoverTargets(cls, - discover: Union['bool'], - ): - """Controls whether to discover available targets and notify via targetCreated/targetInfoChanged/targetDestroyed events. - :param discover: Whether to discover available targets. - :type discover: bool - """ - return ( - cls.build_send_payload("setDiscoverTargets", { - "discover": discover, - }), - None - ) - - @classmethod - def setAutoAttach(cls, - autoAttach: Union['bool'], - waitForDebuggerOnStart: Union['bool'], - ): - """Controls whether to automatically attach to new targets which are considered to be related to this one. When turned on, attaches to all existing related targets as well. When turned off, automatically detaches from all currently attached targets. - :param autoAttach: Whether to auto-attach to related targets. - :type autoAttach: bool - :param waitForDebuggerOnStart: Whether to pause new targets when attaching to them. Use Runtime.runIfWaitingForDebugger to run paused targets. - :type waitForDebuggerOnStart: bool - """ - return ( - cls.build_send_payload("setAutoAttach", { - "autoAttach": autoAttach, - "waitForDebuggerOnStart": waitForDebuggerOnStart, - }), - None - ) - - @classmethod - def setAttachToFrames(cls, - value: Union['bool'], - ): - """ - :param value: Whether to attach to frames. - :type value: bool - """ - return ( - cls.build_send_payload("setAttachToFrames", { - "value": value, - }), - None - ) - - @classmethod - def setRemoteLocations(cls, - locations: Union['[RemoteLocation]'], - ): - """Enables target discovery for the specified locations, when setDiscoverTargets was set to true. - :param locations: List of remote locations. - :type locations: [RemoteLocation] - """ - return ( - cls.build_send_payload("setRemoteLocations", { - "locations": locations, - }), - None - ) - - @classmethod - def sendMessageToTarget(cls, - message: Union['str'], - sessionId: Optional['SessionID'] = None, - targetId: Optional['TargetID'] = None, - ): - """Sends protocol message over session with given id. - :param message: - :type message: str - :param sessionId: Identifier of the session. - :type sessionId: SessionID - :param targetId: Deprecated. + def activateTarget(cls, + targetId: Union['TargetID'], + ): + """Activates (focuses) the target. + :param targetId: :type targetId: TargetID """ return ( - cls.build_send_payload("sendMessageToTarget", { - "message": message, - "sessionId": sessionId, + cls.build_send_payload("activateTarget", { "targetId": targetId, }), None ) @classmethod - def getTargetInfo(cls, - targetId: Union['TargetID'], - ): - """Returns information about a target. + def attachToTarget(cls, + targetId: Union['TargetID'], + ): + """Attaches to the target with given id. :param targetId: :type targetId: TargetID """ return ( - cls.build_send_payload("getTargetInfo", { + cls.build_send_payload("attachToTarget", { "targetId": targetId, }), cls.convert_payload({ - "targetInfo": { - "class": TargetInfo, + "sessionId": { + "class": SessionID, "optional": False }, }) ) - @classmethod - def activateTarget(cls, - targetId: Union['TargetID'], - ): - """Activates (focuses) the target. - :param targetId: - :type targetId: TargetID - """ - return ( - cls.build_send_payload("activateTarget", { - "targetId": targetId, - }), - None - ) - @classmethod def closeTarget(cls, targetId: Union['TargetID'], @@ -198,20 +111,53 @@ def closeTarget(cls, ) @classmethod - def attachToTarget(cls, - targetId: Union['TargetID'], - ): - """Attaches to the target with given id. - :param targetId: - :type targetId: TargetID + def createBrowserContext(cls): + """Creates a new empty BrowserContext. Similar to an incognito profile but you can have more than +one. """ return ( - cls.build_send_payload("attachToTarget", { - "targetId": targetId, + cls.build_send_payload("createBrowserContext", { }), cls.convert_payload({ - "sessionId": { - "class": SessionID, + "browserContextId": { + "class": BrowserContextID, + "optional": False + }, + }) + ) + + @classmethod + def createTarget(cls, + url: Union['str'], + width: Optional['int'] = None, + height: Optional['int'] = None, + browserContextId: Optional['BrowserContextID'] = None, + enableBeginFrameControl: Optional['bool'] = None, + ): + """Creates a new page. + :param url: The initial URL the page will be navigated to. + :type url: str + :param width: Frame width in DIP (headless chrome only). + :type width: int + :param height: Frame height in DIP (headless chrome only). + :type height: int + :param browserContextId: The browser context to create the page in (headless chrome only). + :type browserContextId: BrowserContextID + :param enableBeginFrameControl: Whether BeginFrames for this target will be controlled via DevTools (headless chrome only, +not supported on MacOS yet, false by default). + :type enableBeginFrameControl: bool + """ + return ( + cls.build_send_payload("createTarget", { + "url": url, + "width": width, + "height": height, + "browserContextId": browserContextId, + "enableBeginFrameControl": enableBeginFrameControl, + }), + cls.convert_payload({ + "targetId": { + "class": TargetID, "optional": False }, }) @@ -236,21 +182,6 @@ def detachFromTarget(cls, None ) - @classmethod - def createBrowserContext(cls): - """Creates a new empty BrowserContext. Similar to an incognito profile but you can have more than one. - """ - return ( - cls.build_send_payload("createBrowserContext", { - }), - cls.convert_payload({ - "browserContextId": { - "class": BrowserContextID, - "optional": False - }, - }) - ) - @classmethod def disposeBrowserContext(cls, browserContextId: Union['BrowserContextID'], @@ -272,36 +203,20 @@ def disposeBrowserContext(cls, ) @classmethod - def createTarget(cls, - url: Union['str'], - width: Optional['int'] = None, - height: Optional['int'] = None, - browserContextId: Optional['BrowserContextID'] = None, - enableBeginFrameControl: Optional['bool'] = None, - ): - """Creates a new page. - :param url: The initial URL the page will be navigated to. - :type url: str - :param width: Frame width in DIP (headless chrome only). - :type width: int - :param height: Frame height in DIP (headless chrome only). - :type height: int - :param browserContextId: The browser context to create the page in (headless chrome only). - :type browserContextId: BrowserContextID - :param enableBeginFrameControl: Whether BeginFrames for this target will be controlled via DevTools (headless chrome only, not supported on MacOS yet, false by default). - :type enableBeginFrameControl: bool + def getTargetInfo(cls, + targetId: Union['TargetID'], + ): + """Returns information about a target. + :param targetId: + :type targetId: TargetID """ return ( - cls.build_send_payload("createTarget", { - "url": url, - "width": width, - "height": height, - "browserContextId": browserContextId, - "enableBeginFrameControl": enableBeginFrameControl, + cls.build_send_payload("getTargetInfo", { + "targetId": targetId, }), cls.convert_payload({ - "targetId": { - "class": TargetID, + "targetInfo": { + "class": TargetInfo, "optional": False }, }) @@ -322,65 +237,98 @@ def getTargets(cls): }) ) - - -class TargetCreatedEvent(BaseEvent): - - js_name = 'Target.targetCreated' - hashable = [] - is_hashable = False - - def __init__(self, - targetInfo: Union['TargetInfo', dict], - ): - if isinstance(targetInfo, dict): - targetInfo = TargetInfo(**targetInfo) - self.targetInfo = targetInfo - @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class TargetInfoChangedEvent(BaseEvent): - - js_name = 'Target.targetInfoChanged' - hashable = [] - is_hashable = False - - def __init__(self, - targetInfo: Union['TargetInfo', dict], - ): - if isinstance(targetInfo, dict): - targetInfo = TargetInfo(**targetInfo) - self.targetInfo = targetInfo + def sendMessageToTarget(cls, + message: Union['str'], + sessionId: Optional['SessionID'] = None, + targetId: Optional['TargetID'] = None, + ): + """Sends protocol message over session with given id. + :param message: + :type message: str + :param sessionId: Identifier of the session. + :type sessionId: SessionID + :param targetId: Deprecated. + :type targetId: TargetID + """ + return ( + cls.build_send_payload("sendMessageToTarget", { + "message": message, + "sessionId": sessionId, + "targetId": targetId, + }), + None + ) @classmethod - def build_hash(cls): - raise ValueError('Unable to build hash for non-hashable type') - - -class TargetDestroyedEvent(BaseEvent): + def setAttachToFrames(cls, + value: Union['bool'], + ): + """ + :param value: Whether to attach to frames. + :type value: bool + """ + return ( + cls.build_send_payload("setAttachToFrames", { + "value": value, + }), + None + ) - js_name = 'Target.targetDestroyed' - hashable = ['targetId'] - is_hashable = True + @classmethod + def setAutoAttach(cls, + autoAttach: Union['bool'], + waitForDebuggerOnStart: Union['bool'], + ): + """Controls whether to automatically attach to new targets which are considered to be related to +this one. When turned on, attaches to all existing related targets as well. When turned off, +automatically detaches from all currently attached targets. + :param autoAttach: Whether to auto-attach to related targets. + :type autoAttach: bool + :param waitForDebuggerOnStart: Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger` +to run paused targets. + :type waitForDebuggerOnStart: bool + """ + return ( + cls.build_send_payload("setAutoAttach", { + "autoAttach": autoAttach, + "waitForDebuggerOnStart": waitForDebuggerOnStart, + }), + None + ) - def __init__(self, - targetId: Union['TargetID', dict], - ): - if isinstance(targetId, dict): - targetId = TargetID(**targetId) - self.targetId = targetId + @classmethod + def setDiscoverTargets(cls, + discover: Union['bool'], + ): + """Controls whether to discover available targets and notify via +`targetCreated/targetInfoChanged/targetDestroyed` events. + :param discover: Whether to discover available targets. + :type discover: bool + """ + return ( + cls.build_send_payload("setDiscoverTargets", { + "discover": discover, + }), + None + ) @classmethod - def build_hash(cls, targetId): - kwargs = locals() - kwargs.pop('cls') - serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) - h = '{}:{}'.format(cls.js_name, serialized_id_params) - log.debug('generated hash = %s' % h) - return h + def setRemoteLocations(cls, + locations: Union['[RemoteLocation]'], + ): + """Enables target discovery for the specified locations, when `setDiscoverTargets` was set to +`true`. + :param locations: List of remote locations. + :type locations: [RemoteLocation] + """ + return ( + cls.build_send_payload("setRemoteLocations", { + "locations": locations, + }), + None + ) + class AttachedToTargetEvent(BaseEvent): @@ -417,7 +365,7 @@ def build_hash(cls, sessionId): class DetachedFromTargetEvent(BaseEvent): js_name = 'Target.detachedFromTarget' - hashable = ['sessionId', 'targetId'] + hashable = ['targetId', 'sessionId'] is_hashable = True def __init__(self, @@ -432,7 +380,7 @@ def __init__(self, self.targetId = targetId @classmethod - def build_hash(cls, sessionId, targetId): + def build_hash(cls, targetId, sessionId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) @@ -444,7 +392,7 @@ def build_hash(cls, sessionId, targetId): class ReceivedMessageFromTargetEvent(BaseEvent): js_name = 'Target.receivedMessageFromTarget' - hashable = ['sessionId', 'targetId'] + hashable = ['targetId', 'sessionId'] is_hashable = True def __init__(self, @@ -463,10 +411,69 @@ def __init__(self, self.targetId = targetId @classmethod - def build_hash(cls, sessionId, targetId): + def build_hash(cls, targetId, sessionId): + kwargs = locals() + kwargs.pop('cls') + serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) + h = '{}:{}'.format(cls.js_name, serialized_id_params) + log.debug('generated hash = %s' % h) + return h + + +class TargetCreatedEvent(BaseEvent): + + js_name = 'Target.targetCreated' + hashable = [] + is_hashable = False + + def __init__(self, + targetInfo: Union['TargetInfo', dict], + ): + if isinstance(targetInfo, dict): + targetInfo = TargetInfo(**targetInfo) + self.targetInfo = targetInfo + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') + + +class TargetDestroyedEvent(BaseEvent): + + js_name = 'Target.targetDestroyed' + hashable = ['targetId'] + is_hashable = True + + def __init__(self, + targetId: Union['TargetID', dict], + ): + if isinstance(targetId, dict): + targetId = TargetID(**targetId) + self.targetId = targetId + + @classmethod + def build_hash(cls, targetId): kwargs = locals() kwargs.pop('cls') serialized_id_params = ','.join(['='.join([p, str(v)]) for p, v in kwargs.items()]) h = '{}:{}'.format(cls.js_name, serialized_id_params) log.debug('generated hash = %s' % h) return h + + +class TargetInfoChangedEvent(BaseEvent): + + js_name = 'Target.targetInfoChanged' + hashable = [] + is_hashable = False + + def __init__(self, + targetInfo: Union['TargetInfo', dict], + ): + if isinstance(targetInfo, dict): + targetInfo = TargetInfo(**targetInfo) + self.targetInfo = targetInfo + + @classmethod + def build_hash(cls): + raise ValueError('Unable to build hash for non-hashable type') diff --git a/chromewhip/protocol/tracing.py b/chromewhip/protocol/tracing.py index f86bf5e..904f7ba 100644 --- a/chromewhip/protocol/tracing.py +++ b/chromewhip/protocol/tracing.py @@ -40,40 +40,12 @@ def __init__(self, self.memoryDumpConfig = memoryDumpConfig +# StreamCompression: Compression type to use for traces returned via streams. +StreamCompression = str + class Tracing(PayloadMixin): """ """ - @classmethod - def start(cls, - categories: Optional['str'] = None, - options: Optional['str'] = None, - bufferUsageReportingInterval: Optional['float'] = None, - transferMode: Optional['str'] = None, - traceConfig: Optional['TraceConfig'] = None, - ): - """Start trace events collection. - :param categories: Category/tag filter - :type categories: str - :param options: Tracing options - :type options: str - :param bufferUsageReportingInterval: If set, the agent will issue bufferUsage events at this interval, specified in milliseconds - :type bufferUsageReportingInterval: float - :param transferMode: Whether to report trace events as series of dataCollected events or to save trace to a stream (defaults to ReportEvents). - :type transferMode: str - :param traceConfig: - :type traceConfig: TraceConfig - """ - return ( - cls.build_send_payload("start", { - "categories": categories, - "options": options, - "bufferUsageReportingInterval": bufferUsageReportingInterval, - "transferMode": transferMode, - "traceConfig": traceConfig, - }), - None - ) - @classmethod def end(cls): """Stop trace events collection. @@ -99,6 +71,21 @@ def getCategories(cls): }) ) + @classmethod + def recordClockSyncMarker(cls, + syncId: Union['str'], + ): + """Record a clock sync marker in the trace. + :param syncId: The ID of this clock sync marker + :type syncId: str + """ + return ( + cls.build_send_payload("recordClockSyncMarker", { + "syncId": syncId, + }), + None + ) + @classmethod def requestMemoryDump(cls): """Request a global memory dump. @@ -119,33 +106,63 @@ def requestMemoryDump(cls): ) @classmethod - def recordClockSyncMarker(cls, - syncId: Union['str'], - ): - """Record a clock sync marker in the trace. - :param syncId: The ID of this clock sync marker - :type syncId: str + def start(cls, + categories: Optional['str'] = None, + options: Optional['str'] = None, + bufferUsageReportingInterval: Optional['float'] = None, + transferMode: Optional['str'] = None, + streamCompression: Optional['StreamCompression'] = None, + traceConfig: Optional['TraceConfig'] = None, + ): + """Start trace events collection. + :param categories: Category/tag filter + :type categories: str + :param options: Tracing options + :type options: str + :param bufferUsageReportingInterval: If set, the agent will issue bufferUsage events at this interval, specified in milliseconds + :type bufferUsageReportingInterval: float + :param transferMode: Whether to report trace events as series of dataCollected events or to save trace to a +stream (defaults to `ReportEvents`). + :type transferMode: str + :param streamCompression: Compression format to use. This only applies when using `ReturnAsStream` +transfer mode (defaults to `none`) + :type streamCompression: StreamCompression + :param traceConfig: + :type traceConfig: TraceConfig """ return ( - cls.build_send_payload("recordClockSyncMarker", { - "syncId": syncId, + cls.build_send_payload("start", { + "categories": categories, + "options": options, + "bufferUsageReportingInterval": bufferUsageReportingInterval, + "transferMode": transferMode, + "streamCompression": streamCompression, + "traceConfig": traceConfig, }), None ) -class DataCollectedEvent(BaseEvent): +class BufferUsageEvent(BaseEvent): - js_name = 'Tracing.dataCollected' + js_name = 'Tracing.bufferUsage' hashable = [] is_hashable = False def __init__(self, - value: Union['[]', dict], + percentFull: Union['float', dict, None] = None, + eventCount: Union['float', dict, None] = None, + value: Union['float', dict, None] = None, ): + if isinstance(percentFull, dict): + percentFull = float(**percentFull) + self.percentFull = percentFull + if isinstance(eventCount, dict): + eventCount = float(**eventCount) + self.eventCount = eventCount if isinstance(value, dict): - value = [](**value) + value = float(**value) self.value = value @classmethod @@ -153,44 +170,40 @@ def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class TracingCompleteEvent(BaseEvent): +class DataCollectedEvent(BaseEvent): - js_name = 'Tracing.tracingComplete' + js_name = 'Tracing.dataCollected' hashable = [] is_hashable = False def __init__(self, - stream: Union['IO.StreamHandle', dict, None] = None, + value: Union['[]', dict], ): - if isinstance(stream, dict): - stream = IO.StreamHandle(**stream) - self.stream = stream + if isinstance(value, dict): + value = [](**value) + self.value = value @classmethod def build_hash(cls): raise ValueError('Unable to build hash for non-hashable type') -class BufferUsageEvent(BaseEvent): +class TracingCompleteEvent(BaseEvent): - js_name = 'Tracing.bufferUsage' + js_name = 'Tracing.tracingComplete' hashable = [] is_hashable = False def __init__(self, - percentFull: Union['float', dict, None] = None, - eventCount: Union['float', dict, None] = None, - value: Union['float', dict, None] = None, + stream: Union['IO.StreamHandle', dict, None] = None, + streamCompression: Union['StreamCompression', dict, None] = None, ): - if isinstance(percentFull, dict): - percentFull = float(**percentFull) - self.percentFull = percentFull - if isinstance(eventCount, dict): - eventCount = float(**eventCount) - self.eventCount = eventCount - if isinstance(value, dict): - value = float(**value) - self.value = value + if isinstance(stream, dict): + stream = IO.StreamHandle(**stream) + self.stream = stream + if isinstance(streamCompression, dict): + streamCompression = StreamCompression(**streamCompression) + self.streamCompression = streamCompression @classmethod def build_hash(cls): diff --git a/data/browser_protocol.json b/data/browser_protocol.json index 48d0691..b5e5193 100644 --- a/data/browser_protocol.json +++ b/data/browser_protocol.json @@ -1,595 +1,783 @@ { "version": { "major": "1", - "minor": "2" + "minor": "3" }, "domains": [ { - "domain": "Inspector", + "domain": "Accessibility", "experimental": true, - "types": [], - "commands": [ + "dependencies": [ + "DOM" + ], + "types": [ { - "name": "enable", - "description": "Enables inspector domain notifications." + "id": "AXNodeId", + "description": "Unique accessibility node identifier.", + "type": "string" }, { - "name": "disable", - "description": "Disables inspector domain notifications." - } - ], - "events": [ - { - "name": "detached", - "description": "Fired when remote debugging connection is about to be terminated. Contains detach reason.", - "parameters": [ - { - "name": "reason", - "type": "string", - "description": "The reason why connection has been terminated." - } + "id": "AXValueType", + "description": "Enum of possible property types.", + "type": "string", + "enum": [ + "boolean", + "tristate", + "booleanOrUndefined", + "idref", + "idrefList", + "integer", + "node", + "nodeList", + "number", + "string", + "computedString", + "token", + "tokenList", + "domRelation", + "role", + "internalRole", + "valueUndefined" ] }, { - "name": "targetCrashed", - "description": "Fired when debugging target has crashed" - } - ] - }, - { - "domain": "Memory", - "experimental": true, - "types": [ + "id": "AXValueSourceType", + "description": "Enum of possible property sources.", + "type": "string", + "enum": [ + "attribute", + "implicit", + "style", + "contents", + "placeholder", + "relatedElement" + ] + }, { - "id": "PressureLevel", + "id": "AXValueNativeSourceType", + "description": "Enum of possible native property sources (as a subtype of a particular AXValueSourceType).", "type": "string", "enum": [ - "moderate", - "critical" - ], - "description": "Memory pressure level." - } - ], - "commands": [ + "figcaption", + "label", + "labelfor", + "labelwrapped", + "legend", + "tablecaption", + "title", + "other" + ] + }, { - "name": "getDOMCounters", - "returns": [ + "id": "AXValueSource", + "description": "A single source for a computed AX property.", + "type": "object", + "properties": [ { - "name": "documents", - "type": "integer" + "name": "type", + "description": "What type of source this is.", + "$ref": "AXValueSourceType" }, { - "name": "nodes", - "type": "integer" + "name": "value", + "description": "The value of this property source.", + "optional": true, + "$ref": "AXValue" }, { - "name": "jsEventListeners", - "type": "integer" + "name": "attribute", + "description": "The name of the relevant attribute, if any.", + "optional": true, + "type": "string" + }, + { + "name": "attributeValue", + "description": "The value of the relevant attribute, if any.", + "optional": true, + "$ref": "AXValue" + }, + { + "name": "superseded", + "description": "Whether this source is superseded by a higher priority source.", + "optional": true, + "type": "boolean" + }, + { + "name": "nativeSource", + "description": "The native markup source for this value, e.g. a