# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# CDP domain: Page
from __future__ import annotations
from .util import event_class, T_JSON_DICT
from dataclasses import dataclass
import enum
import typing
from . import debugger
from . import dom
from . import emulation
from . import io
from . import network
from . import runtime


class FrameId(str):
    '''
    Unique frame identifier.
    '''
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> FrameId:
        return cls(json)

    def __repr__(self):
        return 'FrameId({})'.format(super().__repr__())


class AdFrameType(enum.Enum):
    '''
    Indicates whether a frame has been identified as an ad.
    '''
    NONE = "none"
    CHILD = "child"
    ROOT = "root"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class AdFrameExplanation(enum.Enum):
    PARENT_IS_AD = "ParentIsAd"
    CREATED_BY_AD_SCRIPT = "CreatedByAdScript"
    MATCHED_BLOCKING_RULE = "MatchedBlockingRule"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class AdFrameStatus:
    '''
    Indicates whether a frame has been identified as an ad and why.
    '''
    ad_frame_type: AdFrameType

    explanations: typing.Optional[typing.List[AdFrameExplanation]] = None

    def to_json(self):
        json = dict()
        json['adFrameType'] = self.ad_frame_type.to_json()
        if self.explanations is not None:
            json['explanations'] = [i.to_json() for i in self.explanations]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            ad_frame_type=AdFrameType.from_json(json['adFrameType']),
            explanations=[AdFrameExplanation.from_json(i) for i in json['explanations']] if 'explanations' in json else None,
        )


class SecureContextType(enum.Enum):
    '''
    Indicates whether the frame is a secure context and why it is the case.
    '''
    SECURE = "Secure"
    SECURE_LOCALHOST = "SecureLocalhost"
    INSECURE_SCHEME = "InsecureScheme"
    INSECURE_ANCESTOR = "InsecureAncestor"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class CrossOriginIsolatedContextType(enum.Enum):
    '''
    Indicates whether the frame is cross-origin isolated and why it is the case.
    '''
    ISOLATED = "Isolated"
    NOT_ISOLATED = "NotIsolated"
    NOT_ISOLATED_FEATURE_DISABLED = "NotIsolatedFeatureDisabled"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class GatedAPIFeatures(enum.Enum):
    SHARED_ARRAY_BUFFERS = "SharedArrayBuffers"
    SHARED_ARRAY_BUFFERS_TRANSFER_ALLOWED = "SharedArrayBuffersTransferAllowed"
    PERFORMANCE_MEASURE_MEMORY = "PerformanceMeasureMemory"
    PERFORMANCE_PROFILE = "PerformanceProfile"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class PermissionsPolicyFeature(enum.Enum):
    '''
    All Permissions Policy features. This enum should match the one defined
    in third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5.
    '''
    ACCELEROMETER = "accelerometer"
    AMBIENT_LIGHT_SENSOR = "ambient-light-sensor"
    ATTRIBUTION_REPORTING = "attribution-reporting"
    AUTOPLAY = "autoplay"
    BROWSING_TOPICS = "browsing-topics"
    CAMERA = "camera"
    CH_DPR = "ch-dpr"
    CH_DEVICE_MEMORY = "ch-device-memory"
    CH_DOWNLINK = "ch-downlink"
    CH_ECT = "ch-ect"
    CH_PARTITIONED_COOKIES = "ch-partitioned-cookies"
    CH_PREFERS_COLOR_SCHEME = "ch-prefers-color-scheme"
    CH_RTT = "ch-rtt"
    CH_SAVE_DATA = "ch-save-data"
    CH_UA = "ch-ua"
    CH_UA_ARCH = "ch-ua-arch"
    CH_UA_BITNESS = "ch-ua-bitness"
    CH_UA_PLATFORM = "ch-ua-platform"
    CH_UA_MODEL = "ch-ua-model"
    CH_UA_MOBILE = "ch-ua-mobile"
    CH_UA_FULL = "ch-ua-full"
    CH_UA_FULL_VERSION = "ch-ua-full-version"
    CH_UA_FULL_VERSION_LIST = "ch-ua-full-version-list"
    CH_UA_PLATFORM_VERSION = "ch-ua-platform-version"
    CH_UA_REDUCED = "ch-ua-reduced"
    CH_UA_WOW64 = "ch-ua-wow64"
    CH_VIEWPORT_HEIGHT = "ch-viewport-height"
    CH_VIEWPORT_WIDTH = "ch-viewport-width"
    CH_WIDTH = "ch-width"
    CLIPBOARD_READ = "clipboard-read"
    CLIPBOARD_WRITE = "clipboard-write"
    CROSS_ORIGIN_ISOLATED = "cross-origin-isolated"
    DIRECT_SOCKETS = "direct-sockets"
    DISPLAY_CAPTURE = "display-capture"
    DOCUMENT_DOMAIN = "document-domain"
    ENCRYPTED_MEDIA = "encrypted-media"
    EXECUTION_WHILE_OUT_OF_VIEWPORT = "execution-while-out-of-viewport"
    EXECUTION_WHILE_NOT_RENDERED = "execution-while-not-rendered"
    FOCUS_WITHOUT_USER_ACTIVATION = "focus-without-user-activation"
    FULLSCREEN = "fullscreen"
    FROBULATE = "frobulate"
    GAMEPAD = "gamepad"
    GEOLOCATION = "geolocation"
    GYROSCOPE = "gyroscope"
    HID = "hid"
    IDLE_DETECTION = "idle-detection"
    INTEREST_COHORT = "interest-cohort"
    JOIN_AD_INTEREST_GROUP = "join-ad-interest-group"
    KEYBOARD_MAP = "keyboard-map"
    MAGNETOMETER = "magnetometer"
    MICROPHONE = "microphone"
    MIDI = "midi"
    OTP_CREDENTIALS = "otp-credentials"
    PAYMENT = "payment"
    PICTURE_IN_PICTURE = "picture-in-picture"
    PUBLICKEY_CREDENTIALS_GET = "publickey-credentials-get"
    RUN_AD_AUCTION = "run-ad-auction"
    SCREEN_WAKE_LOCK = "screen-wake-lock"
    SERIAL = "serial"
    SHARED_AUTOFILL = "shared-autofill"
    STORAGE_ACCESS_API = "storage-access-api"
    SYNC_XHR = "sync-xhr"
    TRUST_TOKEN_REDEMPTION = "trust-token-redemption"
    USB = "usb"
    VERTICAL_SCROLL = "vertical-scroll"
    WEB_SHARE = "web-share"
    WINDOW_PLACEMENT = "window-placement"
    XR_SPATIAL_TRACKING = "xr-spatial-tracking"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class PermissionsPolicyBlockReason(enum.Enum):
    '''
    Reason for a permissions policy feature to be disabled.
    '''
    HEADER = "Header"
    IFRAME_ATTRIBUTE = "IframeAttribute"
    IN_FENCED_FRAME_TREE = "InFencedFrameTree"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class PermissionsPolicyBlockLocator:
    frame_id: FrameId

    block_reason: PermissionsPolicyBlockReason

    def to_json(self):
        json = dict()
        json['frameId'] = self.frame_id.to_json()
        json['blockReason'] = self.block_reason.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            block_reason=PermissionsPolicyBlockReason.from_json(json['blockReason']),
        )


@dataclass
class PermissionsPolicyFeatureState:
    feature: PermissionsPolicyFeature

    allowed: bool

    locator: typing.Optional[PermissionsPolicyBlockLocator] = None

    def to_json(self):
        json = dict()
        json['feature'] = self.feature.to_json()
        json['allowed'] = self.allowed
        if self.locator is not None:
            json['locator'] = self.locator.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            feature=PermissionsPolicyFeature.from_json(json['feature']),
            allowed=bool(json['allowed']),
            locator=PermissionsPolicyBlockLocator.from_json(json['locator']) if 'locator' in json else None,
        )


class OriginTrialTokenStatus(enum.Enum):
    '''
    Origin Trial(https://www.chromium.org/blink/origin-trials) support.
    Status for an Origin Trial token.
    '''
    SUCCESS = "Success"
    NOT_SUPPORTED = "NotSupported"
    INSECURE = "Insecure"
    EXPIRED = "Expired"
    WRONG_ORIGIN = "WrongOrigin"
    INVALID_SIGNATURE = "InvalidSignature"
    MALFORMED = "Malformed"
    WRONG_VERSION = "WrongVersion"
    FEATURE_DISABLED = "FeatureDisabled"
    TOKEN_DISABLED = "TokenDisabled"
    FEATURE_DISABLED_FOR_USER = "FeatureDisabledForUser"
    UNKNOWN_TRIAL = "UnknownTrial"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class OriginTrialStatus(enum.Enum):
    '''
    Status for an Origin Trial.
    '''
    ENABLED = "Enabled"
    VALID_TOKEN_NOT_PROVIDED = "ValidTokenNotProvided"
    OS_NOT_SUPPORTED = "OSNotSupported"
    TRIAL_NOT_ALLOWED = "TrialNotAllowed"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class OriginTrialUsageRestriction(enum.Enum):
    NONE = "None"
    SUBSET = "Subset"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class OriginTrialToken:
    origin: str

    match_sub_domains: bool

    trial_name: str

    expiry_time: network.TimeSinceEpoch

    is_third_party: bool

    usage_restriction: OriginTrialUsageRestriction

    def to_json(self):
        json = dict()
        json['origin'] = self.origin
        json['matchSubDomains'] = self.match_sub_domains
        json['trialName'] = self.trial_name
        json['expiryTime'] = self.expiry_time.to_json()
        json['isThirdParty'] = self.is_third_party
        json['usageRestriction'] = self.usage_restriction.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            origin=str(json['origin']),
            match_sub_domains=bool(json['matchSubDomains']),
            trial_name=str(json['trialName']),
            expiry_time=network.TimeSinceEpoch.from_json(json['expiryTime']),
            is_third_party=bool(json['isThirdParty']),
            usage_restriction=OriginTrialUsageRestriction.from_json(json['usageRestriction']),
        )


@dataclass
class OriginTrialTokenWithStatus:
    raw_token_text: str

    status: OriginTrialTokenStatus

    #: ``parsedToken`` is present only when the token is extractable and
    #: parsable.
    parsed_token: typing.Optional[OriginTrialToken] = None

    def to_json(self):
        json = dict()
        json['rawTokenText'] = self.raw_token_text
        json['status'] = self.status.to_json()
        if self.parsed_token is not None:
            json['parsedToken'] = self.parsed_token.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            raw_token_text=str(json['rawTokenText']),
            status=OriginTrialTokenStatus.from_json(json['status']),
            parsed_token=OriginTrialToken.from_json(json['parsedToken']) if 'parsedToken' in json else None,
        )


@dataclass
class OriginTrial:
    trial_name: str

    status: OriginTrialStatus

    tokens_with_status: typing.List[OriginTrialTokenWithStatus]

    def to_json(self):
        json = dict()
        json['trialName'] = self.trial_name
        json['status'] = self.status.to_json()
        json['tokensWithStatus'] = [i.to_json() for i in self.tokens_with_status]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            trial_name=str(json['trialName']),
            status=OriginTrialStatus.from_json(json['status']),
            tokens_with_status=[OriginTrialTokenWithStatus.from_json(i) for i in json['tokensWithStatus']],
        )


@dataclass
class Frame:
    '''
    Information about the Frame on the page.
    '''
    #: Frame unique identifier.
    id_: FrameId

    #: Identifier of the loader associated with this frame.
    loader_id: network.LoaderId

    #: Frame document's URL without fragment.
    url: str

    #: Frame document's registered domain, taking the public suffixes list into account.
    #: Extracted from the Frame's url.
    #: Example URLs: http://www.google.com/file.html -> "google.com"
    #:               http://a.b.co.uk/file.html      -> "b.co.uk"
    domain_and_registry: str

    #: Frame document's security origin.
    security_origin: str

    #: Frame document's mimeType as determined by the browser.
    mime_type: str

    #: Indicates whether the main document is a secure context and explains why that is the case.
    secure_context_type: SecureContextType

    #: Indicates whether this is a cross origin isolated context.
    cross_origin_isolated_context_type: CrossOriginIsolatedContextType

    #: Indicated which gated APIs / features are available.
    gated_api_features: typing.List[GatedAPIFeatures]

    #: Parent frame identifier.
    parent_id: typing.Optional[FrameId] = None

    #: Frame's name as specified in the tag.
    name: typing.Optional[str] = None

    #: Frame document's URL fragment including the '#'.
    url_fragment: typing.Optional[str] = None

    #: If the frame failed to load, this contains the URL that could not be loaded. Note that unlike url above, this URL may contain a fragment.
    unreachable_url: typing.Optional[str] = None

    #: Indicates whether this frame was tagged as an ad and why.
    ad_frame_status: typing.Optional[AdFrameStatus] = None

    def to_json(self):
        json = dict()
        json['id'] = self.id_.to_json()
        json['loaderId'] = self.loader_id.to_json()
        json['url'] = self.url
        json['domainAndRegistry'] = self.domain_and_registry
        json['securityOrigin'] = self.security_origin
        json['mimeType'] = self.mime_type
        json['secureContextType'] = self.secure_context_type.to_json()
        json['crossOriginIsolatedContextType'] = self.cross_origin_isolated_context_type.to_json()
        json['gatedAPIFeatures'] = [i.to_json() for i in self.gated_api_features]
        if self.parent_id is not None:
            json['parentId'] = self.parent_id.to_json()
        if self.name is not None:
            json['name'] = self.name
        if self.url_fragment is not None:
            json['urlFragment'] = self.url_fragment
        if self.unreachable_url is not None:
            json['unreachableUrl'] = self.unreachable_url
        if self.ad_frame_status is not None:
            json['adFrameStatus'] = self.ad_frame_status.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            id_=FrameId.from_json(json['id']),
            loader_id=network.LoaderId.from_json(json['loaderId']),
            url=str(json['url']),
            domain_and_registry=str(json['domainAndRegistry']),
            security_origin=str(json['securityOrigin']),
            mime_type=str(json['mimeType']),
            secure_context_type=SecureContextType.from_json(json['secureContextType']),
            cross_origin_isolated_context_type=CrossOriginIsolatedContextType.from_json(json['crossOriginIsolatedContextType']),
            gated_api_features=[GatedAPIFeatures.from_json(i) for i in json['gatedAPIFeatures']],
            parent_id=FrameId.from_json(json['parentId']) if 'parentId' in json else None,
            name=str(json['name']) if 'name' in json else None,
            url_fragment=str(json['urlFragment']) if 'urlFragment' in json else None,
            unreachable_url=str(json['unreachableUrl']) if 'unreachableUrl' in json else None,
            ad_frame_status=AdFrameStatus.from_json(json['adFrameStatus']) if 'adFrameStatus' in json else None,
        )


@dataclass
class FrameResource:
    '''
    Information about the Resource on the page.
    '''
    #: Resource URL.
    url: str

    #: Type of this resource.
    type_: network.ResourceType

    #: Resource mimeType as determined by the browser.
    mime_type: str

    #: last-modified timestamp as reported by server.
    last_modified: typing.Optional[network.TimeSinceEpoch] = None

    #: Resource content size.
    content_size: typing.Optional[float] = None

    #: True if the resource failed to load.
    failed: typing.Optional[bool] = None

    #: True if the resource was canceled during loading.
    canceled: typing.Optional[bool] = None

    def to_json(self):
        json = dict()
        json['url'] = self.url
        json['type'] = self.type_.to_json()
        json['mimeType'] = self.mime_type
        if self.last_modified is not None:
            json['lastModified'] = self.last_modified.to_json()
        if self.content_size is not None:
            json['contentSize'] = self.content_size
        if self.failed is not None:
            json['failed'] = self.failed
        if self.canceled is not None:
            json['canceled'] = self.canceled
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            url=str(json['url']),
            type_=network.ResourceType.from_json(json['type']),
            mime_type=str(json['mimeType']),
            last_modified=network.TimeSinceEpoch.from_json(json['lastModified']) if 'lastModified' in json else None,
            content_size=float(json['contentSize']) if 'contentSize' in json else None,
            failed=bool(json['failed']) if 'failed' in json else None,
            canceled=bool(json['canceled']) if 'canceled' in json else None,
        )


@dataclass
class FrameResourceTree:
    '''
    Information about the Frame hierarchy along with their cached resources.
    '''
    #: Frame information for this tree item.
    frame: Frame

    #: Information about frame resources.
    resources: typing.List[FrameResource]

    #: Child frames.
    child_frames: typing.Optional[typing.List[FrameResourceTree]] = None

    def to_json(self):
        json = dict()
        json['frame'] = self.frame.to_json()
        json['resources'] = [i.to_json() for i in self.resources]
        if self.child_frames is not None:
            json['childFrames'] = [i.to_json() for i in self.child_frames]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            frame=Frame.from_json(json['frame']),
            resources=[FrameResource.from_json(i) for i in json['resources']],
            child_frames=[FrameResourceTree.from_json(i) for i in json['childFrames']] if 'childFrames' in json else None,
        )


@dataclass
class FrameTree:
    '''
    Information about the Frame hierarchy.
    '''
    #: Frame information for this tree item.
    frame: Frame

    #: Child frames.
    child_frames: typing.Optional[typing.List[FrameTree]] = None

    def to_json(self):
        json = dict()
        json['frame'] = self.frame.to_json()
        if self.child_frames is not None:
            json['childFrames'] = [i.to_json() for i in self.child_frames]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            frame=Frame.from_json(json['frame']),
            child_frames=[FrameTree.from_json(i) for i in json['childFrames']] if 'childFrames' in json else None,
        )


class ScriptIdentifier(str):
    '''
    Unique script identifier.
    '''
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> ScriptIdentifier:
        return cls(json)

    def __repr__(self):
        return 'ScriptIdentifier({})'.format(super().__repr__())


class TransitionType(enum.Enum):
    '''
    Transition type.
    '''
    LINK = "link"
    TYPED = "typed"
    ADDRESS_BAR = "address_bar"
    AUTO_BOOKMARK = "auto_bookmark"
    AUTO_SUBFRAME = "auto_subframe"
    MANUAL_SUBFRAME = "manual_subframe"
    GENERATED = "generated"
    AUTO_TOPLEVEL = "auto_toplevel"
    FORM_SUBMIT = "form_submit"
    RELOAD = "reload"
    KEYWORD = "keyword"
    KEYWORD_GENERATED = "keyword_generated"
    OTHER = "other"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class NavigationEntry:
    '''
    Navigation history entry.
    '''
    #: Unique id of the navigation history entry.
    id_: int

    #: URL of the navigation history entry.
    url: str

    #: URL that the user typed in the url bar.
    user_typed_url: str

    #: Title of the navigation history entry.
    title: str

    #: Transition type.
    transition_type: TransitionType

    def to_json(self):
        json = dict()
        json['id'] = self.id_
        json['url'] = self.url
        json['userTypedURL'] = self.user_typed_url
        json['title'] = self.title
        json['transitionType'] = self.transition_type.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            id_=int(json['id']),
            url=str(json['url']),
            user_typed_url=str(json['userTypedURL']),
            title=str(json['title']),
            transition_type=TransitionType.from_json(json['transitionType']),
        )


@dataclass
class ScreencastFrameMetadata:
    '''
    Screencast frame metadata.
    '''
    #: Top offset in DIP.
    offset_top: float

    #: Page scale factor.
    page_scale_factor: float

    #: Device screen width in DIP.
    device_width: float

    #: Device screen height in DIP.
    device_height: float

    #: Position of horizontal scroll in CSS pixels.
    scroll_offset_x: float

    #: Position of vertical scroll in CSS pixels.
    scroll_offset_y: float

    #: Frame swap timestamp.
    timestamp: typing.Optional[network.TimeSinceEpoch] = None

    def to_json(self):
        json = dict()
        json['offsetTop'] = self.offset_top
        json['pageScaleFactor'] = self.page_scale_factor
        json['deviceWidth'] = self.device_width
        json['deviceHeight'] = self.device_height
        json['scrollOffsetX'] = self.scroll_offset_x
        json['scrollOffsetY'] = self.scroll_offset_y
        if self.timestamp is not None:
            json['timestamp'] = self.timestamp.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            offset_top=float(json['offsetTop']),
            page_scale_factor=float(json['pageScaleFactor']),
            device_width=float(json['deviceWidth']),
            device_height=float(json['deviceHeight']),
            scroll_offset_x=float(json['scrollOffsetX']),
            scroll_offset_y=float(json['scrollOffsetY']),
            timestamp=network.TimeSinceEpoch.from_json(json['timestamp']) if 'timestamp' in json else None,
        )


class DialogType(enum.Enum):
    '''
    Javascript dialog type.
    '''
    ALERT = "alert"
    CONFIRM = "confirm"
    PROMPT = "prompt"
    BEFOREUNLOAD = "beforeunload"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class AppManifestError:
    '''
    Error while paring app manifest.
    '''
    #: Error message.
    message: str

    #: If criticial, this is a non-recoverable parse error.
    critical: int

    #: Error line.
    line: int

    #: Error column.
    column: int

    def to_json(self):
        json = dict()
        json['message'] = self.message
        json['critical'] = self.critical
        json['line'] = self.line
        json['column'] = self.column
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            message=str(json['message']),
            critical=int(json['critical']),
            line=int(json['line']),
            column=int(json['column']),
        )


@dataclass
class AppManifestParsedProperties:
    '''
    Parsed app manifest properties.
    '''
    #: Computed scope value
    scope: str

    def to_json(self):
        json = dict()
        json['scope'] = self.scope
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            scope=str(json['scope']),
        )


@dataclass
class LayoutViewport:
    '''
    Layout viewport position and dimensions.
    '''
    #: Horizontal offset relative to the document (CSS pixels).
    page_x: int

    #: Vertical offset relative to the document (CSS pixels).
    page_y: int

    #: Width (CSS pixels), excludes scrollbar if present.
    client_width: int

    #: Height (CSS pixels), excludes scrollbar if present.
    client_height: int

    def to_json(self):
        json = dict()
        json['pageX'] = self.page_x
        json['pageY'] = self.page_y
        json['clientWidth'] = self.client_width
        json['clientHeight'] = self.client_height
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            page_x=int(json['pageX']),
            page_y=int(json['pageY']),
            client_width=int(json['clientWidth']),
            client_height=int(json['clientHeight']),
        )


@dataclass
class VisualViewport:
    '''
    Visual viewport position, dimensions, and scale.
    '''
    #: Horizontal offset relative to the layout viewport (CSS pixels).
    offset_x: float

    #: Vertical offset relative to the layout viewport (CSS pixels).
    offset_y: float

    #: Horizontal offset relative to the document (CSS pixels).
    page_x: float

    #: Vertical offset relative to the document (CSS pixels).
    page_y: float

    #: Width (CSS pixels), excludes scrollbar if present.
    client_width: float

    #: Height (CSS pixels), excludes scrollbar if present.
    client_height: float

    #: Scale relative to the ideal viewport (size at width=device-width).
    scale: float

    #: Page zoom factor (CSS to device independent pixels ratio).
    zoom: typing.Optional[float] = None

    def to_json(self):
        json = dict()
        json['offsetX'] = self.offset_x
        json['offsetY'] = self.offset_y
        json['pageX'] = self.page_x
        json['pageY'] = self.page_y
        json['clientWidth'] = self.client_width
        json['clientHeight'] = self.client_height
        json['scale'] = self.scale
        if self.zoom is not None:
            json['zoom'] = self.zoom
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            offset_x=float(json['offsetX']),
            offset_y=float(json['offsetY']),
            page_x=float(json['pageX']),
            page_y=float(json['pageY']),
            client_width=float(json['clientWidth']),
            client_height=float(json['clientHeight']),
            scale=float(json['scale']),
            zoom=float(json['zoom']) if 'zoom' in json else None,
        )


@dataclass
class Viewport:
    '''
    Viewport for capturing screenshot.
    '''
    #: X offset in device independent pixels (dip).
    x: float

    #: Y offset in device independent pixels (dip).
    y: float

    #: Rectangle width in device independent pixels (dip).
    width: float

    #: Rectangle height in device independent pixels (dip).
    height: float

    #: Page scale factor.
    scale: float

    def to_json(self):
        json = dict()
        json['x'] = self.x
        json['y'] = self.y
        json['width'] = self.width
        json['height'] = self.height
        json['scale'] = self.scale
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            x=float(json['x']),
            y=float(json['y']),
            width=float(json['width']),
            height=float(json['height']),
            scale=float(json['scale']),
        )


@dataclass
class FontFamilies:
    '''
    Generic font families collection.
    '''
    #: The standard font-family.
    standard: typing.Optional[str] = None

    #: The fixed font-family.
    fixed: typing.Optional[str] = None

    #: The serif font-family.
    serif: typing.Optional[str] = None

    #: The sansSerif font-family.
    sans_serif: typing.Optional[str] = None

    #: The cursive font-family.
    cursive: typing.Optional[str] = None

    #: The fantasy font-family.
    fantasy: typing.Optional[str] = None

    def to_json(self):
        json = dict()
        if self.standard is not None:
            json['standard'] = self.standard
        if self.fixed is not None:
            json['fixed'] = self.fixed
        if self.serif is not None:
            json['serif'] = self.serif
        if self.sans_serif is not None:
            json['sansSerif'] = self.sans_serif
        if self.cursive is not None:
            json['cursive'] = self.cursive
        if self.fantasy is not None:
            json['fantasy'] = self.fantasy
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            standard=str(json['standard']) if 'standard' in json else None,
            fixed=str(json['fixed']) if 'fixed' in json else None,
            serif=str(json['serif']) if 'serif' in json else None,
            sans_serif=str(json['sansSerif']) if 'sansSerif' in json else None,
            cursive=str(json['cursive']) if 'cursive' in json else None,
            fantasy=str(json['fantasy']) if 'fantasy' in json else None,
        )


@dataclass
class ScriptFontFamilies:
    '''
    Font families collection for a script.
    '''
    #: Name of the script which these font families are defined for.
    script: str

    #: Generic font families collection for the script.
    font_families: FontFamilies

    def to_json(self):
        json = dict()
        json['script'] = self.script
        json['fontFamilies'] = self.font_families.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            script=str(json['script']),
            font_families=FontFamilies.from_json(json['fontFamilies']),
        )


@dataclass
class FontSizes:
    '''
    Default font sizes.
    '''
    #: Default standard font size.
    standard: typing.Optional[int] = None

    #: Default fixed font size.
    fixed: typing.Optional[int] = None

    def to_json(self):
        json = dict()
        if self.standard is not None:
            json['standard'] = self.standard
        if self.fixed is not None:
            json['fixed'] = self.fixed
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            standard=int(json['standard']) if 'standard' in json else None,
            fixed=int(json['fixed']) if 'fixed' in json else None,
        )


class ClientNavigationReason(enum.Enum):
    FORM_SUBMISSION_GET = "formSubmissionGet"
    FORM_SUBMISSION_POST = "formSubmissionPost"
    HTTP_HEADER_REFRESH = "httpHeaderRefresh"
    SCRIPT_INITIATED = "scriptInitiated"
    META_TAG_REFRESH = "metaTagRefresh"
    PAGE_BLOCK_INTERSTITIAL = "pageBlockInterstitial"
    RELOAD = "reload"
    ANCHOR_CLICK = "anchorClick"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class ClientNavigationDisposition(enum.Enum):
    CURRENT_TAB = "currentTab"
    NEW_TAB = "newTab"
    NEW_WINDOW = "newWindow"
    DOWNLOAD = "download"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class InstallabilityErrorArgument:
    #: Argument name (e.g. name:'minimum-icon-size-in-pixels').
    name: str

    #: Argument value (e.g. value:'64').
    value: str

    def to_json(self):
        json = dict()
        json['name'] = self.name
        json['value'] = self.value
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            name=str(json['name']),
            value=str(json['value']),
        )


@dataclass
class InstallabilityError:
    '''
    The installability error
    '''
    #: The error id (e.g. 'manifest-missing-suitable-icon').
    error_id: str

    #: The list of error arguments (e.g. {name:'minimum-icon-size-in-pixels', value:'64'}).
    error_arguments: typing.List[InstallabilityErrorArgument]

    def to_json(self):
        json = dict()
        json['errorId'] = self.error_id
        json['errorArguments'] = [i.to_json() for i in self.error_arguments]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            error_id=str(json['errorId']),
            error_arguments=[InstallabilityErrorArgument.from_json(i) for i in json['errorArguments']],
        )


class ReferrerPolicy(enum.Enum):
    '''
    The referring-policy used for the navigation.
    '''
    NO_REFERRER = "noReferrer"
    NO_REFERRER_WHEN_DOWNGRADE = "noReferrerWhenDowngrade"
    ORIGIN = "origin"
    ORIGIN_WHEN_CROSS_ORIGIN = "originWhenCrossOrigin"
    SAME_ORIGIN = "sameOrigin"
    STRICT_ORIGIN = "strictOrigin"
    STRICT_ORIGIN_WHEN_CROSS_ORIGIN = "strictOriginWhenCrossOrigin"
    UNSAFE_URL = "unsafeUrl"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class CompilationCacheParams:
    '''
    Per-script compilation cache parameters for ``Page.produceCompilationCache``
    '''
    #: The URL of the script to produce a compilation cache entry for.
    url: str

    #: A hint to the backend whether eager compilation is recommended.
    #: (the actual compilation mode used is upon backend discretion).
    eager: typing.Optional[bool] = None

    def to_json(self):
        json = dict()
        json['url'] = self.url
        if self.eager is not None:
            json['eager'] = self.eager
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            url=str(json['url']),
            eager=bool(json['eager']) if 'eager' in json else None,
        )


class NavigationType(enum.Enum):
    '''
    The type of a frameNavigated event.
    '''
    NAVIGATION = "Navigation"
    BACK_FORWARD_CACHE_RESTORE = "BackForwardCacheRestore"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class BackForwardCacheNotRestoredReason(enum.Enum):
    '''
    List of not restored reasons for back-forward cache.
    '''
    NOT_PRIMARY_MAIN_FRAME = "NotPrimaryMainFrame"
    BACK_FORWARD_CACHE_DISABLED = "BackForwardCacheDisabled"
    RELATED_ACTIVE_CONTENTS_EXIST = "RelatedActiveContentsExist"
    HTTP_STATUS_NOT_OK = "HTTPStatusNotOK"
    SCHEME_NOT_HTTP_OR_HTTPS = "SchemeNotHTTPOrHTTPS"
    LOADING = "Loading"
    WAS_GRANTED_MEDIA_ACCESS = "WasGrantedMediaAccess"
    DISABLE_FOR_RENDER_FRAME_HOST_CALLED = "DisableForRenderFrameHostCalled"
    DOMAIN_NOT_ALLOWED = "DomainNotAllowed"
    HTTP_METHOD_NOT_GET = "HTTPMethodNotGET"
    SUBFRAME_IS_NAVIGATING = "SubframeIsNavigating"
    TIMEOUT = "Timeout"
    CACHE_LIMIT = "CacheLimit"
    JAVA_SCRIPT_EXECUTION = "JavaScriptExecution"
    RENDERER_PROCESS_KILLED = "RendererProcessKilled"
    RENDERER_PROCESS_CRASHED = "RendererProcessCrashed"
    GRANTED_MEDIA_STREAM_ACCESS = "GrantedMediaStreamAccess"
    SCHEDULER_TRACKED_FEATURE_USED = "SchedulerTrackedFeatureUsed"
    CONFLICTING_BROWSING_INSTANCE = "ConflictingBrowsingInstance"
    CACHE_FLUSHED = "CacheFlushed"
    SERVICE_WORKER_VERSION_ACTIVATION = "ServiceWorkerVersionActivation"
    SESSION_RESTORED = "SessionRestored"
    SERVICE_WORKER_POST_MESSAGE = "ServiceWorkerPostMessage"
    ENTERED_BACK_FORWARD_CACHE_BEFORE_SERVICE_WORKER_HOST_ADDED = "EnteredBackForwardCacheBeforeServiceWorkerHostAdded"
    RENDER_FRAME_HOST_REUSED_SAME_SITE = "RenderFrameHostReused_SameSite"
    RENDER_FRAME_HOST_REUSED_CROSS_SITE = "RenderFrameHostReused_CrossSite"
    SERVICE_WORKER_CLAIM = "ServiceWorkerClaim"
    IGNORE_EVENT_AND_EVICT = "IgnoreEventAndEvict"
    HAVE_INNER_CONTENTS = "HaveInnerContents"
    TIMEOUT_PUTTING_IN_CACHE = "TimeoutPuttingInCache"
    BACK_FORWARD_CACHE_DISABLED_BY_LOW_MEMORY = "BackForwardCacheDisabledByLowMemory"
    BACK_FORWARD_CACHE_DISABLED_BY_COMMAND_LINE = "BackForwardCacheDisabledByCommandLine"
    NETWORK_REQUEST_DATAPIPE_DRAINED_AS_BYTES_CONSUMER = "NetworkRequestDatapipeDrainedAsBytesConsumer"
    NETWORK_REQUEST_REDIRECTED = "NetworkRequestRedirected"
    NETWORK_REQUEST_TIMEOUT = "NetworkRequestTimeout"
    NETWORK_EXCEEDS_BUFFER_LIMIT = "NetworkExceedsBufferLimit"
    NAVIGATION_CANCELLED_WHILE_RESTORING = "NavigationCancelledWhileRestoring"
    NOT_MOST_RECENT_NAVIGATION_ENTRY = "NotMostRecentNavigationEntry"
    BACK_FORWARD_CACHE_DISABLED_FOR_PRERENDER = "BackForwardCacheDisabledForPrerender"
    USER_AGENT_OVERRIDE_DIFFERS = "UserAgentOverrideDiffers"
    FOREGROUND_CACHE_LIMIT = "ForegroundCacheLimit"
    BROWSING_INSTANCE_NOT_SWAPPED = "BrowsingInstanceNotSwapped"
    BACK_FORWARD_CACHE_DISABLED_FOR_DELEGATE = "BackForwardCacheDisabledForDelegate"
    OPT_IN_UNLOAD_HEADER_NOT_PRESENT = "OptInUnloadHeaderNotPresent"
    UNLOAD_HANDLER_EXISTS_IN_MAIN_FRAME = "UnloadHandlerExistsInMainFrame"
    UNLOAD_HANDLER_EXISTS_IN_SUB_FRAME = "UnloadHandlerExistsInSubFrame"
    SERVICE_WORKER_UNREGISTRATION = "ServiceWorkerUnregistration"
    CACHE_CONTROL_NO_STORE = "CacheControlNoStore"
    CACHE_CONTROL_NO_STORE_COOKIE_MODIFIED = "CacheControlNoStoreCookieModified"
    CACHE_CONTROL_NO_STORE_HTTP_ONLY_COOKIE_MODIFIED = "CacheControlNoStoreHTTPOnlyCookieModified"
    NO_RESPONSE_HEAD = "NoResponseHead"
    UNKNOWN = "Unknown"
    ACTIVATION_NAVIGATIONS_DISALLOWED_FOR_BUG1234857 = "ActivationNavigationsDisallowedForBug1234857"
    ERROR_DOCUMENT = "ErrorDocument"
    FENCED_FRAMES_EMBEDDER = "FencedFramesEmbedder"
    WEB_SOCKET = "WebSocket"
    WEB_TRANSPORT = "WebTransport"
    WEB_RTC = "WebRTC"
    MAIN_RESOURCE_HAS_CACHE_CONTROL_NO_STORE = "MainResourceHasCacheControlNoStore"
    MAIN_RESOURCE_HAS_CACHE_CONTROL_NO_CACHE = "MainResourceHasCacheControlNoCache"
    SUBRESOURCE_HAS_CACHE_CONTROL_NO_STORE = "SubresourceHasCacheControlNoStore"
    SUBRESOURCE_HAS_CACHE_CONTROL_NO_CACHE = "SubresourceHasCacheControlNoCache"
    CONTAINS_PLUGINS = "ContainsPlugins"
    DOCUMENT_LOADED = "DocumentLoaded"
    DEDICATED_WORKER_OR_WORKLET = "DedicatedWorkerOrWorklet"
    OUTSTANDING_NETWORK_REQUEST_OTHERS = "OutstandingNetworkRequestOthers"
    OUTSTANDING_INDEXED_DB_TRANSACTION = "OutstandingIndexedDBTransaction"
    REQUESTED_NOTIFICATIONS_PERMISSION = "RequestedNotificationsPermission"
    REQUESTED_MIDI_PERMISSION = "RequestedMIDIPermission"
    REQUESTED_AUDIO_CAPTURE_PERMISSION = "RequestedAudioCapturePermission"
    REQUESTED_VIDEO_CAPTURE_PERMISSION = "RequestedVideoCapturePermission"
    REQUESTED_BACK_FORWARD_CACHE_BLOCKED_SENSORS = "RequestedBackForwardCacheBlockedSensors"
    REQUESTED_BACKGROUND_WORK_PERMISSION = "RequestedBackgroundWorkPermission"
    BROADCAST_CHANNEL = "BroadcastChannel"
    INDEXED_DB_CONNECTION = "IndexedDBConnection"
    WEB_XR = "WebXR"
    SHARED_WORKER = "SharedWorker"
    WEB_LOCKS = "WebLocks"
    WEB_HID = "WebHID"
    WEB_SHARE = "WebShare"
    REQUESTED_STORAGE_ACCESS_GRANT = "RequestedStorageAccessGrant"
    WEB_NFC = "WebNfc"
    OUTSTANDING_NETWORK_REQUEST_FETCH = "OutstandingNetworkRequestFetch"
    OUTSTANDING_NETWORK_REQUEST_XHR = "OutstandingNetworkRequestXHR"
    APP_BANNER = "AppBanner"
    PRINTING = "Printing"
    WEB_DATABASE = "WebDatabase"
    PICTURE_IN_PICTURE = "PictureInPicture"
    PORTAL = "Portal"
    SPEECH_RECOGNIZER = "SpeechRecognizer"
    IDLE_MANAGER = "IdleManager"
    PAYMENT_MANAGER = "PaymentManager"
    SPEECH_SYNTHESIS = "SpeechSynthesis"
    KEYBOARD_LOCK = "KeyboardLock"
    WEB_OTP_SERVICE = "WebOTPService"
    OUTSTANDING_NETWORK_REQUEST_DIRECT_SOCKET = "OutstandingNetworkRequestDirectSocket"
    INJECTED_JAVASCRIPT = "InjectedJavascript"
    INJECTED_STYLE_SHEET = "InjectedStyleSheet"
    DUMMY = "Dummy"
    CONTENT_SECURITY_HANDLER = "ContentSecurityHandler"
    CONTENT_WEB_AUTHENTICATION_API = "ContentWebAuthenticationAPI"
    CONTENT_FILE_CHOOSER = "ContentFileChooser"
    CONTENT_SERIAL = "ContentSerial"
    CONTENT_FILE_SYSTEM_ACCESS = "ContentFileSystemAccess"
    CONTENT_MEDIA_DEVICES_DISPATCHER_HOST = "ContentMediaDevicesDispatcherHost"
    CONTENT_WEB_BLUETOOTH = "ContentWebBluetooth"
    CONTENT_WEB_USB = "ContentWebUSB"
    CONTENT_MEDIA_SESSION = "ContentMediaSession"
    CONTENT_MEDIA_SESSION_SERVICE = "ContentMediaSessionService"
    CONTENT_SCREEN_READER = "ContentScreenReader"
    EMBEDDER_POPUP_BLOCKER_TAB_HELPER = "EmbedderPopupBlockerTabHelper"
    EMBEDDER_SAFE_BROWSING_TRIGGERED_POPUP_BLOCKER = "EmbedderSafeBrowsingTriggeredPopupBlocker"
    EMBEDDER_SAFE_BROWSING_THREAT_DETAILS = "EmbedderSafeBrowsingThreatDetails"
    EMBEDDER_APP_BANNER_MANAGER = "EmbedderAppBannerManager"
    EMBEDDER_DOM_DISTILLER_VIEWER_SOURCE = "EmbedderDomDistillerViewerSource"
    EMBEDDER_DOM_DISTILLER_SELF_DELETING_REQUEST_DELEGATE = "EmbedderDomDistillerSelfDeletingRequestDelegate"
    EMBEDDER_OOM_INTERVENTION_TAB_HELPER = "EmbedderOomInterventionTabHelper"
    EMBEDDER_OFFLINE_PAGE = "EmbedderOfflinePage"
    EMBEDDER_CHROME_PASSWORD_MANAGER_CLIENT_BIND_CREDENTIAL_MANAGER = "EmbedderChromePasswordManagerClientBindCredentialManager"
    EMBEDDER_PERMISSION_REQUEST_MANAGER = "EmbedderPermissionRequestManager"
    EMBEDDER_MODAL_DIALOG = "EmbedderModalDialog"
    EMBEDDER_EXTENSIONS = "EmbedderExtensions"
    EMBEDDER_EXTENSION_MESSAGING = "EmbedderExtensionMessaging"
    EMBEDDER_EXTENSION_MESSAGING_FOR_OPEN_PORT = "EmbedderExtensionMessagingForOpenPort"
    EMBEDDER_EXTENSION_SENT_MESSAGE_TO_CACHED_FRAME = "EmbedderExtensionSentMessageToCachedFrame"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class BackForwardCacheNotRestoredReasonType(enum.Enum):
    '''
    Types of not restored reasons for back-forward cache.
    '''
    SUPPORT_PENDING = "SupportPending"
    PAGE_SUPPORT_NEEDED = "PageSupportNeeded"
    CIRCUMSTANTIAL = "Circumstantial"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class BackForwardCacheNotRestoredExplanation:
    #: Type of the reason
    type_: BackForwardCacheNotRestoredReasonType

    #: Not restored reason
    reason: BackForwardCacheNotRestoredReason

    #: Context associated with the reason. The meaning of this context is
    #: dependent on the reason:
    #: - EmbedderExtensionSentMessageToCachedFrame: the extension ID.
    context: typing.Optional[str] = None

    def to_json(self):
        json = dict()
        json['type'] = self.type_.to_json()
        json['reason'] = self.reason.to_json()
        if self.context is not None:
            json['context'] = self.context
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            type_=BackForwardCacheNotRestoredReasonType.from_json(json['type']),
            reason=BackForwardCacheNotRestoredReason.from_json(json['reason']),
            context=str(json['context']) if 'context' in json else None,
        )


@dataclass
class BackForwardCacheNotRestoredExplanationTree:
    #: URL of each frame
    url: str

    #: Not restored reasons of each frame
    explanations: typing.List[BackForwardCacheNotRestoredExplanation]

    #: Array of children frame
    children: typing.List[BackForwardCacheNotRestoredExplanationTree]

    def to_json(self):
        json = dict()
        json['url'] = self.url
        json['explanations'] = [i.to_json() for i in self.explanations]
        json['children'] = [i.to_json() for i in self.children]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            url=str(json['url']),
            explanations=[BackForwardCacheNotRestoredExplanation.from_json(i) for i in json['explanations']],
            children=[BackForwardCacheNotRestoredExplanationTree.from_json(i) for i in json['children']],
        )


class PrerenderFinalStatus(enum.Enum):
    '''
    List of FinalStatus reasons for Prerender2.
    '''
    ACTIVATED = "Activated"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


def add_script_to_evaluate_on_load(
        script_source: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,ScriptIdentifier]:
    '''
    Deprecated, please use addScriptToEvaluateOnNewDocument instead.

    **EXPERIMENTAL**

    :param script_source:
    :returns: Identifier of the added script.
    '''
    params: T_JSON_DICT = dict()
    params['scriptSource'] = script_source
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.addScriptToEvaluateOnLoad',
        'params': params,
    }
    json = yield cmd_dict
    return ScriptIdentifier.from_json(json['identifier'])


def add_script_to_evaluate_on_new_document(
        source: str,
        world_name: typing.Optional[str] = None,
        include_command_line_api: typing.Optional[bool] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,ScriptIdentifier]:
    '''
    Evaluates given script in every frame upon creation (before loading frame's scripts).

    :param source:
    :param world_name: **(EXPERIMENTAL)** *(Optional)* If specified, creates an isolated world with the given name and evaluates given script in it. This world name will be used as the ExecutionContextDescription::name when the corresponding event is emitted.
    :param include_command_line_api: **(EXPERIMENTAL)** *(Optional)* Specifies whether command line API should be available to the script, defaults to false.
    :returns: Identifier of the added script.
    '''
    params: T_JSON_DICT = dict()
    params['source'] = source
    if world_name is not None:
        params['worldName'] = world_name
    if include_command_line_api is not None:
        params['includeCommandLineAPI'] = include_command_line_api
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.addScriptToEvaluateOnNewDocument',
        'params': params,
    }
    json = yield cmd_dict
    return ScriptIdentifier.from_json(json['identifier'])


def bring_to_front() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Brings page to front (activates tab).
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.bringToFront',
    }
    json = yield cmd_dict


def capture_screenshot(
        format_: typing.Optional[str] = None,
        quality: typing.Optional[int] = None,
        clip: typing.Optional[Viewport] = None,
        from_surface: typing.Optional[bool] = None,
        capture_beyond_viewport: typing.Optional[bool] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
    '''
    Capture page screenshot.

    :param format_: *(Optional)* Image compression format (defaults to png).
    :param quality: *(Optional)* Compression quality from range [0..100] (jpeg only).
    :param clip: *(Optional)* Capture the screenshot of a given region only.
    :param from_surface: **(EXPERIMENTAL)** *(Optional)* Capture the screenshot from the surface, rather than the view. Defaults to true.
    :param capture_beyond_viewport: **(EXPERIMENTAL)** *(Optional)* Capture the screenshot beyond the viewport. Defaults to false.
    :returns: Base64-encoded image data.
    '''
    params: T_JSON_DICT = dict()
    if format_ is not None:
        params['format'] = format_
    if quality is not None:
        params['quality'] = quality
    if clip is not None:
        params['clip'] = clip.to_json()
    if from_surface is not None:
        params['fromSurface'] = from_surface
    if capture_beyond_viewport is not None:
        params['captureBeyondViewport'] = capture_beyond_viewport
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.captureScreenshot',
        'params': params,
    }
    json = yield cmd_dict
    return str(json['data'])


def capture_snapshot(
        format_: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,str]:
    '''
    Returns a snapshot of the page as a string. For MHTML format, the serialization includes
    iframes, shadow DOM, external resources, and element-inline styles.

    **EXPERIMENTAL**

    :param format_: *(Optional)* Format (defaults to mhtml).
    :returns: Serialized page data.
    '''
    params: T_JSON_DICT = dict()
    if format_ is not None:
        params['format'] = format_
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.captureSnapshot',
        'params': params,
    }
    json = yield cmd_dict
    return str(json['data'])


def clear_device_metrics_override() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Clears the overridden device metrics.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.clearDeviceMetricsOverride',
    }
    json = yield cmd_dict


def clear_device_orientation_override() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Clears the overridden Device Orientation.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.clearDeviceOrientationOverride',
    }
    json = yield cmd_dict


def clear_geolocation_override() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Clears the overridden Geolocation Position and Error.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.clearGeolocationOverride',
    }
    json = yield cmd_dict


def create_isolated_world(
        frame_id: FrameId,
        world_name: typing.Optional[str] = None,
        grant_univeral_access: typing.Optional[bool] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,runtime.ExecutionContextId]:
    '''
    Creates an isolated world for the given frame.

    :param frame_id: Id of the frame in which the isolated world should be created.
    :param world_name: *(Optional)* An optional name which is reported in the Execution Context.
    :param grant_univeral_access: *(Optional)* Whether or not universal access should be granted to the isolated world. This is a powerful option, use with caution.
    :returns: Execution context of the isolated world.
    '''
    params: T_JSON_DICT = dict()
    params['frameId'] = frame_id.to_json()
    if world_name is not None:
        params['worldName'] = world_name
    if grant_univeral_access is not None:
        params['grantUniveralAccess'] = grant_univeral_access
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.createIsolatedWorld',
        'params': params,
    }
    json = yield cmd_dict
    return runtime.ExecutionContextId.from_json(json['executionContextId'])


def delete_cookie(
        cookie_name: str,
        url: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Deletes browser cookie with given name, domain and path.

    **EXPERIMENTAL**

    :param cookie_name: Name of the cookie to remove.
    :param url: URL to match cooke domain and path.
    '''
    params: T_JSON_DICT = dict()
    params['cookieName'] = cookie_name
    params['url'] = url
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.deleteCookie',
        'params': params,
    }
    json = yield cmd_dict


def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Disables page domain notifications.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.disable',
    }
    json = yield cmd_dict


def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Enables page domain notifications.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.enable',
    }
    json = yield cmd_dict


def get_app_manifest() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[str, typing.List[AppManifestError], typing.Optional[str], typing.Optional[AppManifestParsedProperties]]]:
    '''


    :returns: A tuple with the following items:

        0. **url** - Manifest location.
        1. **errors** - 
        2. **data** - *(Optional)* Manifest content.
        3. **parsed** - *(Optional)* Parsed manifest properties
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getAppManifest',
    }
    json = yield cmd_dict
    return (
        str(json['url']),
        [AppManifestError.from_json(i) for i in json['errors']],
        str(json['data']) if 'data' in json else None,
        AppManifestParsedProperties.from_json(json['parsed']) if 'parsed' in json else None
    )


def get_installability_errors() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[InstallabilityError]]:
    '''


    **EXPERIMENTAL**

    :returns: 
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getInstallabilityErrors',
    }
    json = yield cmd_dict
    return [InstallabilityError.from_json(i) for i in json['installabilityErrors']]


def get_manifest_icons() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Optional[str]]:
    '''


    **EXPERIMENTAL**

    :returns: 
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getManifestIcons',
    }
    json = yield cmd_dict
    return str(json['primaryIcon']) if 'primaryIcon' in json else None


def get_app_id() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[typing.Optional[str], typing.Optional[str]]]:
    '''
    Returns the unique (PWA) app id.
    Only returns values if the feature flag 'WebAppEnableManifestId' is enabled

    **EXPERIMENTAL**

    :returns: A tuple with the following items:

        0. **appId** - *(Optional)* App id, either from manifest's id attribute or computed from start_url
        1. **recommendedId** - *(Optional)* Recommendation for manifest's id attribute to match current id computed from start_url
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getAppId',
    }
    json = yield cmd_dict
    return (
        str(json['appId']) if 'appId' in json else None,
        str(json['recommendedId']) if 'recommendedId' in json else None
    )


def get_cookies() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[network.Cookie]]:
    '''
    Returns all browser cookies. Depending on the backend support, will return detailed cookie
    information in the ``cookies`` field.

    **EXPERIMENTAL**

    :returns: Array of cookie objects.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getCookies',
    }
    json = yield cmd_dict
    return [network.Cookie.from_json(i) for i in json['cookies']]


def get_frame_tree() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,FrameTree]:
    '''
    Returns present frame tree structure.

    :returns: Present frame tree structure.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getFrameTree',
    }
    json = yield cmd_dict
    return FrameTree.from_json(json['frameTree'])


def get_layout_metrics() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[LayoutViewport, VisualViewport, dom.Rect, LayoutViewport, VisualViewport, dom.Rect]]:
    '''
    Returns metrics relating to the layouting of the page, such as viewport bounds/scale.

    :returns: A tuple with the following items:

        0. **layoutViewport** - Deprecated metrics relating to the layout viewport. Is in device pixels. Use ``cssLayoutViewport`` instead.
        1. **visualViewport** - Deprecated metrics relating to the visual viewport. Is in device pixels. Use ``cssVisualViewport`` instead.
        2. **contentSize** - Deprecated size of scrollable area. Is in DP. Use ``cssContentSize`` instead.
        3. **cssLayoutViewport** - Metrics relating to the layout viewport in CSS pixels.
        4. **cssVisualViewport** - Metrics relating to the visual viewport in CSS pixels.
        5. **cssContentSize** - Size of scrollable area in CSS pixels.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getLayoutMetrics',
    }
    json = yield cmd_dict
    return (
        LayoutViewport.from_json(json['layoutViewport']),
        VisualViewport.from_json(json['visualViewport']),
        dom.Rect.from_json(json['contentSize']),
        LayoutViewport.from_json(json['cssLayoutViewport']),
        VisualViewport.from_json(json['cssVisualViewport']),
        dom.Rect.from_json(json['cssContentSize'])
    )


def get_navigation_history() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[int, typing.List[NavigationEntry]]]:
    '''
    Returns navigation history for the current page.

    :returns: A tuple with the following items:

        0. **currentIndex** - Index of the current navigation history entry.
        1. **entries** - Array of navigation history entries.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getNavigationHistory',
    }
    json = yield cmd_dict
    return (
        int(json['currentIndex']),
        [NavigationEntry.from_json(i) for i in json['entries']]
    )


def reset_navigation_history() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Resets navigation history for the current page.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.resetNavigationHistory',
    }
    json = yield cmd_dict


def get_resource_content(
        frame_id: FrameId,
        url: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[str, bool]]:
    '''
    Returns content of the given resource.

    **EXPERIMENTAL**

    :param frame_id: Frame id to get resource for.
    :param url: URL of the resource to get content for.
    :returns: A tuple with the following items:

        0. **content** - Resource content.
        1. **base64Encoded** - True, if content was served as base64.
    '''
    params: T_JSON_DICT = dict()
    params['frameId'] = frame_id.to_json()
    params['url'] = url
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getResourceContent',
        'params': params,
    }
    json = yield cmd_dict
    return (
        str(json['content']),
        bool(json['base64Encoded'])
    )


def get_resource_tree() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,FrameResourceTree]:
    '''
    Returns present frame / resource tree structure.

    **EXPERIMENTAL**

    :returns: Present frame / resource tree structure.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getResourceTree',
    }
    json = yield cmd_dict
    return FrameResourceTree.from_json(json['frameTree'])


def handle_java_script_dialog(
        accept: bool,
        prompt_text: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).

    :param accept: Whether to accept or dismiss the dialog.
    :param prompt_text: *(Optional)* The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog.
    '''
    params: T_JSON_DICT = dict()
    params['accept'] = accept
    if prompt_text is not None:
        params['promptText'] = prompt_text
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.handleJavaScriptDialog',
        'params': params,
    }
    json = yield cmd_dict


def navigate(
        url: str,
        referrer: typing.Optional[str] = None,
        transition_type: typing.Optional[TransitionType] = None,
        frame_id: typing.Optional[FrameId] = None,
        referrer_policy: typing.Optional[ReferrerPolicy] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[FrameId, typing.Optional[network.LoaderId], typing.Optional[str]]]:
    '''
    Navigates current page to the given URL.

    :param url: URL to navigate the page to.
    :param referrer: *(Optional)* Referrer URL.
    :param transition_type: *(Optional)* Intended transition type.
    :param frame_id: *(Optional)* Frame id to navigate, if not specified navigates the top frame.
    :param referrer_policy: **(EXPERIMENTAL)** *(Optional)* Referrer-policy used for the navigation.
    :returns: A tuple with the following items:

        0. **frameId** - Frame id that has navigated (or failed to navigate)
        1. **loaderId** - *(Optional)* Loader identifier.
        2. **errorText** - *(Optional)* User friendly error message, present if and only if navigation has failed.
    '''
    params: T_JSON_DICT = dict()
    params['url'] = url
    if referrer is not None:
        params['referrer'] = referrer
    if transition_type is not None:
        params['transitionType'] = transition_type.to_json()
    if frame_id is not None:
        params['frameId'] = frame_id.to_json()
    if referrer_policy is not None:
        params['referrerPolicy'] = referrer_policy.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.navigate',
        'params': params,
    }
    json = yield cmd_dict
    return (
        FrameId.from_json(json['frameId']),
        network.LoaderId.from_json(json['loaderId']) if 'loaderId' in json else None,
        str(json['errorText']) if 'errorText' in json else None
    )


def navigate_to_history_entry(
        entry_id: int
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Navigates current page to the given history entry.

    :param entry_id: Unique id of the entry to navigate to.
    '''
    params: T_JSON_DICT = dict()
    params['entryId'] = entry_id
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.navigateToHistoryEntry',
        'params': params,
    }
    json = yield cmd_dict


def print_to_pdf(
        landscape: typing.Optional[bool] = None,
        display_header_footer: typing.Optional[bool] = None,
        print_background: typing.Optional[bool] = None,
        scale: typing.Optional[float] = None,
        paper_width: typing.Optional[float] = None,
        paper_height: typing.Optional[float] = None,
        margin_top: typing.Optional[float] = None,
        margin_bottom: typing.Optional[float] = None,
        margin_left: typing.Optional[float] = None,
        margin_right: typing.Optional[float] = None,
        page_ranges: typing.Optional[str] = None,
        ignore_invalid_page_ranges: typing.Optional[bool] = None,
        header_template: typing.Optional[str] = None,
        footer_template: typing.Optional[str] = None,
        prefer_css_page_size: typing.Optional[bool] = None,
        transfer_mode: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[str, typing.Optional[io.StreamHandle]]]:
    '''
    Print page as PDF.

    :param landscape: *(Optional)* Paper orientation. Defaults to false.
    :param display_header_footer: *(Optional)* Display header and footer. Defaults to false.
    :param print_background: *(Optional)* Print background graphics. Defaults to false.
    :param scale: *(Optional)* Scale of the webpage rendering. Defaults to 1.
    :param paper_width: *(Optional)* Paper width in inches. Defaults to 8.5 inches.
    :param paper_height: *(Optional)* Paper height in inches. Defaults to 11 inches.
    :param margin_top: *(Optional)* Top margin in inches. Defaults to 1cm (~0.4 inches).
    :param margin_bottom: *(Optional)* Bottom margin in inches. Defaults to 1cm (~0.4 inches).
    :param margin_left: *(Optional)* Left margin in inches. Defaults to 1cm (~0.4 inches).
    :param margin_right: *(Optional)* Right margin in inches. Defaults to 1cm (~0.4 inches).
    :param page_ranges: *(Optional)* Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
    :param ignore_invalid_page_ranges: *(Optional)* Whether to silently ignore invalid but successfully parsed page ranges, such as '3-2'. Defaults to false.
    :param header_template: *(Optional)* 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, ````<span class=title></span>```` would generate span containing the title.
    :param footer_template: *(Optional)* HTML template for the print footer. Should use the same format as the ````headerTemplate````.
    :param prefer_css_page_size: *(Optional)* Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
    :param transfer_mode: **(EXPERIMENTAL)** *(Optional)* return as stream
    :returns: A tuple with the following items:

        0. **data** - Base64-encoded pdf data. Empty if `` returnAsStream` is specified.
        1. **stream** - *(Optional)* A handle of the stream that holds resulting PDF data.
    '''
    params: T_JSON_DICT = dict()
    if landscape is not None:
        params['landscape'] = landscape
    if display_header_footer is not None:
        params['displayHeaderFooter'] = display_header_footer
    if print_background is not None:
        params['printBackground'] = print_background
    if scale is not None:
        params['scale'] = scale
    if paper_width is not None:
        params['paperWidth'] = paper_width
    if paper_height is not None:
        params['paperHeight'] = paper_height
    if margin_top is not None:
        params['marginTop'] = margin_top
    if margin_bottom is not None:
        params['marginBottom'] = margin_bottom
    if margin_left is not None:
        params['marginLeft'] = margin_left
    if margin_right is not None:
        params['marginRight'] = margin_right
    if page_ranges is not None:
        params['pageRanges'] = page_ranges
    if ignore_invalid_page_ranges is not None:
        params['ignoreInvalidPageRanges'] = ignore_invalid_page_ranges
    if header_template is not None:
        params['headerTemplate'] = header_template
    if footer_template is not None:
        params['footerTemplate'] = footer_template
    if prefer_css_page_size is not None:
        params['preferCSSPageSize'] = prefer_css_page_size
    if transfer_mode is not None:
        params['transferMode'] = transfer_mode
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.printToPDF',
        'params': params,
    }
    json = yield cmd_dict
    return (
        str(json['data']),
        io.StreamHandle.from_json(json['stream']) if 'stream' in json else None
    )


def reload(
        ignore_cache: typing.Optional[bool] = None,
        script_to_evaluate_on_load: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Reloads given page optionally ignoring the cache.

    :param ignore_cache: *(Optional)* If true, browser cache is ignored (as if the user pressed Shift+refresh).
    :param script_to_evaluate_on_load: *(Optional)* If set, the script will be injected into all frames of the inspected page after reload. Argument will be ignored if reloading dataURL origin.
    '''
    params: T_JSON_DICT = dict()
    if ignore_cache is not None:
        params['ignoreCache'] = ignore_cache
    if script_to_evaluate_on_load is not None:
        params['scriptToEvaluateOnLoad'] = script_to_evaluate_on_load
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.reload',
        'params': params,
    }
    json = yield cmd_dict


def remove_script_to_evaluate_on_load(
        identifier: ScriptIdentifier
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Deprecated, please use removeScriptToEvaluateOnNewDocument instead.

    **EXPERIMENTAL**

    :param identifier:
    '''
    params: T_JSON_DICT = dict()
    params['identifier'] = identifier.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.removeScriptToEvaluateOnLoad',
        'params': params,
    }
    json = yield cmd_dict


def remove_script_to_evaluate_on_new_document(
        identifier: ScriptIdentifier
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Removes given script from the list.

    :param identifier:
    '''
    params: T_JSON_DICT = dict()
    params['identifier'] = identifier.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.removeScriptToEvaluateOnNewDocument',
        'params': params,
    }
    json = yield cmd_dict


def screencast_frame_ack(
        session_id: int
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Acknowledges that a screencast frame has been received by the frontend.

    **EXPERIMENTAL**

    :param session_id: Frame number.
    '''
    params: T_JSON_DICT = dict()
    params['sessionId'] = session_id
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.screencastFrameAck',
        'params': params,
    }
    json = yield cmd_dict


def search_in_resource(
        frame_id: FrameId,
        url: str,
        query: str,
        case_sensitive: typing.Optional[bool] = None,
        is_regex: typing.Optional[bool] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[debugger.SearchMatch]]:
    '''
    Searches for given string in resource content.

    **EXPERIMENTAL**

    :param frame_id: Frame id for resource to search in.
    :param url: URL of the resource to search in.
    :param query: String to search for.
    :param case_sensitive: *(Optional)* If true, search is case sensitive.
    :param is_regex: *(Optional)* If true, treats string parameter as regex.
    :returns: List of search matches.
    '''
    params: T_JSON_DICT = dict()
    params['frameId'] = frame_id.to_json()
    params['url'] = url
    params['query'] = query
    if case_sensitive is not None:
        params['caseSensitive'] = case_sensitive
    if is_regex is not None:
        params['isRegex'] = is_regex
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.searchInResource',
        'params': params,
    }
    json = yield cmd_dict
    return [debugger.SearchMatch.from_json(i) for i in json['result']]


def set_ad_blocking_enabled(
        enabled: bool
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Enable Chrome's experimental ad filter on all sites.

    **EXPERIMENTAL**

    :param enabled: Whether to block ads.
    '''
    params: T_JSON_DICT = dict()
    params['enabled'] = enabled
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setAdBlockingEnabled',
        'params': params,
    }
    json = yield cmd_dict


def set_bypass_csp(
        enabled: bool
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Enable page Content Security Policy by-passing.

    **EXPERIMENTAL**

    :param enabled: Whether to bypass page CSP.
    '''
    params: T_JSON_DICT = dict()
    params['enabled'] = enabled
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setBypassCSP',
        'params': params,
    }
    json = yield cmd_dict


def get_permissions_policy_state(
        frame_id: FrameId
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[PermissionsPolicyFeatureState]]:
    '''
    Get Permissions Policy state on given frame.

    **EXPERIMENTAL**

    :param frame_id:
    :returns: 
    '''
    params: T_JSON_DICT = dict()
    params['frameId'] = frame_id.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getPermissionsPolicyState',
        'params': params,
    }
    json = yield cmd_dict
    return [PermissionsPolicyFeatureState.from_json(i) for i in json['states']]


def get_origin_trials(
        frame_id: FrameId
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[OriginTrial]]:
    '''
    Get Origin Trials on given frame.

    **EXPERIMENTAL**

    :param frame_id:
    :returns: 
    '''
    params: T_JSON_DICT = dict()
    params['frameId'] = frame_id.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.getOriginTrials',
        'params': params,
    }
    json = yield cmd_dict
    return [OriginTrial.from_json(i) for i in json['originTrials']]


def set_device_metrics_override(
        width: int,
        height: int,
        device_scale_factor: float,
        mobile: bool,
        scale: typing.Optional[float] = None,
        screen_width: typing.Optional[int] = None,
        screen_height: typing.Optional[int] = None,
        position_x: typing.Optional[int] = None,
        position_y: typing.Optional[int] = None,
        dont_set_visible_size: typing.Optional[bool] = None,
        screen_orientation: typing.Optional[emulation.ScreenOrientation] = None,
        viewport: typing.Optional[Viewport] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,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).

    **EXPERIMENTAL**

    :param width: Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.
    :param height: Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.
    :param device_scale_factor: Overriding device scale factor value. 0 disables the override.
    :param mobile: Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more.
    :param scale: *(Optional)* Scale to apply to resulting view image.
    :param screen_width: *(Optional)* Overriding screen width value in pixels (minimum 0, maximum 10000000).
    :param screen_height: *(Optional)* Overriding screen height value in pixels (minimum 0, maximum 10000000).
    :param position_x: *(Optional)* Overriding view X position on screen in pixels (minimum 0, maximum 10000000).
    :param position_y: *(Optional)* Overriding view Y position on screen in pixels (minimum 0, maximum 10000000).
    :param dont_set_visible_size: *(Optional)* Do not set visible view size, rely upon explicit setVisibleSize call.
    :param screen_orientation: *(Optional)* Screen orientation override.
    :param viewport: *(Optional)* The viewport dimensions and scale. If not set, the override is cleared.
    '''
    params: T_JSON_DICT = dict()
    params['width'] = width
    params['height'] = height
    params['deviceScaleFactor'] = device_scale_factor
    params['mobile'] = mobile
    if scale is not None:
        params['scale'] = scale
    if screen_width is not None:
        params['screenWidth'] = screen_width
    if screen_height is not None:
        params['screenHeight'] = screen_height
    if position_x is not None:
        params['positionX'] = position_x
    if position_y is not None:
        params['positionY'] = position_y
    if dont_set_visible_size is not None:
        params['dontSetVisibleSize'] = dont_set_visible_size
    if screen_orientation is not None:
        params['screenOrientation'] = screen_orientation.to_json()
    if viewport is not None:
        params['viewport'] = viewport.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setDeviceMetricsOverride',
        'params': params,
    }
    json = yield cmd_dict


def set_device_orientation_override(
        alpha: float,
        beta: float,
        gamma: float
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Overrides the Device Orientation.

    **EXPERIMENTAL**

    :param alpha: Mock alpha
    :param beta: Mock beta
    :param gamma: Mock gamma
    '''
    params: T_JSON_DICT = dict()
    params['alpha'] = alpha
    params['beta'] = beta
    params['gamma'] = gamma
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setDeviceOrientationOverride',
        'params': params,
    }
    json = yield cmd_dict


def set_font_families(
        font_families: FontFamilies,
        for_scripts: typing.Optional[typing.List[ScriptFontFamilies]] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Set generic font families.

    **EXPERIMENTAL**

    :param font_families: Specifies font families to set. If a font family is not specified, it won't be changed.
    :param for_scripts: *(Optional)* Specifies font families to set for individual scripts.
    '''
    params: T_JSON_DICT = dict()
    params['fontFamilies'] = font_families.to_json()
    if for_scripts is not None:
        params['forScripts'] = [i.to_json() for i in for_scripts]
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setFontFamilies',
        'params': params,
    }
    json = yield cmd_dict


def set_font_sizes(
        font_sizes: FontSizes
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Set default font sizes.

    **EXPERIMENTAL**

    :param font_sizes: Specifies font sizes to set. If a font size is not specified, it won't be changed.
    '''
    params: T_JSON_DICT = dict()
    params['fontSizes'] = font_sizes.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setFontSizes',
        'params': params,
    }
    json = yield cmd_dict


def set_document_content(
        frame_id: FrameId,
        html: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Sets given markup as the document's HTML.

    :param frame_id: Frame id to set HTML for.
    :param html: HTML content to set.
    '''
    params: T_JSON_DICT = dict()
    params['frameId'] = frame_id.to_json()
    params['html'] = html
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setDocumentContent',
        'params': params,
    }
    json = yield cmd_dict


def set_download_behavior(
        behavior: str,
        download_path: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Set the behavior when downloading a file.

    **EXPERIMENTAL**

    :param behavior: Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny).
    :param download_path: *(Optional)* The default path to save downloaded files to. This is required if behavior is set to 'allow'
    '''
    params: T_JSON_DICT = dict()
    params['behavior'] = behavior
    if download_path is not None:
        params['downloadPath'] = download_path
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setDownloadBehavior',
        'params': params,
    }
    json = yield cmd_dict


def set_geolocation_override(
        latitude: typing.Optional[float] = None,
        longitude: typing.Optional[float] = None,
        accuracy: typing.Optional[float] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position
    unavailable.

    :param latitude: *(Optional)* Mock latitude
    :param longitude: *(Optional)* Mock longitude
    :param accuracy: *(Optional)* Mock accuracy
    '''
    params: T_JSON_DICT = dict()
    if latitude is not None:
        params['latitude'] = latitude
    if longitude is not None:
        params['longitude'] = longitude
    if accuracy is not None:
        params['accuracy'] = accuracy
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setGeolocationOverride',
        'params': params,
    }
    json = yield cmd_dict


def set_lifecycle_events_enabled(
        enabled: bool
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Controls whether page will emit lifecycle events.

    **EXPERIMENTAL**

    :param enabled: If true, starts emitting lifecycle events.
    '''
    params: T_JSON_DICT = dict()
    params['enabled'] = enabled
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setLifecycleEventsEnabled',
        'params': params,
    }
    json = yield cmd_dict


def set_touch_emulation_enabled(
        enabled: bool,
        configuration: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Toggles mouse event-based touch event emulation.

    **EXPERIMENTAL**

    :param enabled: Whether the touch event emulation should be enabled.
    :param configuration: *(Optional)* Touch/gesture events configuration. Default: current platform.
    '''
    params: T_JSON_DICT = dict()
    params['enabled'] = enabled
    if configuration is not None:
        params['configuration'] = configuration
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setTouchEmulationEnabled',
        'params': params,
    }
    json = yield cmd_dict


def start_screencast(
        format_: typing.Optional[str] = None,
        quality: typing.Optional[int] = None,
        max_width: typing.Optional[int] = None,
        max_height: typing.Optional[int] = None,
        every_nth_frame: typing.Optional[int] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Starts sending each frame using the ``screencastFrame`` event.

    **EXPERIMENTAL**

    :param format_: *(Optional)* Image compression format.
    :param quality: *(Optional)* Compression quality from range [0..100].
    :param max_width: *(Optional)* Maximum screenshot width.
    :param max_height: *(Optional)* Maximum screenshot height.
    :param every_nth_frame: *(Optional)* Send every n-th frame.
    '''
    params: T_JSON_DICT = dict()
    if format_ is not None:
        params['format'] = format_
    if quality is not None:
        params['quality'] = quality
    if max_width is not None:
        params['maxWidth'] = max_width
    if max_height is not None:
        params['maxHeight'] = max_height
    if every_nth_frame is not None:
        params['everyNthFrame'] = every_nth_frame
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.startScreencast',
        'params': params,
    }
    json = yield cmd_dict


def stop_loading() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Force the page stop all navigations and pending resource fetches.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.stopLoading',
    }
    json = yield cmd_dict


def crash() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Crashes renderer on the IO thread, generates minidumps.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.crash',
    }
    json = yield cmd_dict


def close() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Tries to close page, running its beforeunload hooks, if any.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.close',
    }
    json = yield cmd_dict


def set_web_lifecycle_state(
        state: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Tries to update the web lifecycle state of the page.
    It will transition the page to the given state according to:
    https://github.com/WICG/web-lifecycle/

    **EXPERIMENTAL**

    :param state: Target lifecycle state
    '''
    params: T_JSON_DICT = dict()
    params['state'] = state
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setWebLifecycleState',
        'params': params,
    }
    json = yield cmd_dict


def stop_screencast() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Stops sending each frame in the ``screencastFrame``.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.stopScreencast',
    }
    json = yield cmd_dict


def produce_compilation_cache(
        scripts: typing.List[CompilationCacheParams]
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Requests backend to produce compilation cache for the specified scripts.
    ``scripts`` are appeneded to the list of scripts for which the cache
    would be produced. The list may be reset during page navigation.
    When script with a matching URL is encountered, the cache is optionally
    produced upon backend discretion, based on internal heuristics.
    See also: ``Page.compilationCacheProduced``.

    **EXPERIMENTAL**

    :param scripts:
    '''
    params: T_JSON_DICT = dict()
    params['scripts'] = [i.to_json() for i in scripts]
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.produceCompilationCache',
        'params': params,
    }
    json = yield cmd_dict


def add_compilation_cache(
        url: str,
        data: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Seeds compilation cache for given url. Compilation cache does not survive
    cross-process navigation.

    **EXPERIMENTAL**

    :param url:
    :param data: Base64-encoded data
    '''
    params: T_JSON_DICT = dict()
    params['url'] = url
    params['data'] = data
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.addCompilationCache',
        'params': params,
    }
    json = yield cmd_dict


def clear_compilation_cache() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Clears seeded compilation cache.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.clearCompilationCache',
    }
    json = yield cmd_dict


def set_spc_transaction_mode(
        mode: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Sets the Secure Payment Confirmation transaction mode.
    https://w3c.github.io/secure-payment-confirmation/#sctn-automation-set-spc-transaction-mode

    **EXPERIMENTAL**

    :param mode:
    '''
    params: T_JSON_DICT = dict()
    params['mode'] = mode
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setSPCTransactionMode',
        'params': params,
    }
    json = yield cmd_dict


def generate_test_report(
        message: str,
        group: typing.Optional[str] = None
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Generates a report for testing.

    **EXPERIMENTAL**

    :param message: Message to be displayed in the report.
    :param group: *(Optional)* Specifies the endpoint group to deliver the report to.
    '''
    params: T_JSON_DICT = dict()
    params['message'] = message
    if group is not None:
        params['group'] = group
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.generateTestReport',
        'params': params,
    }
    json = yield cmd_dict


def wait_for_debugger() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Pauses page execution. Can be resumed using generic Runtime.runIfWaitingForDebugger.

    **EXPERIMENTAL**
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.waitForDebugger',
    }
    json = yield cmd_dict


def set_intercept_file_chooser_dialog(
        enabled: bool
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Intercept file chooser requests and transfer control to protocol clients.
    When file chooser interception is enabled, native file chooser dialog is not shown.
    Instead, a protocol event ``Page.fileChooserOpened`` is emitted.

    **EXPERIMENTAL**

    :param enabled:
    '''
    params: T_JSON_DICT = dict()
    params['enabled'] = enabled
    cmd_dict: T_JSON_DICT = {
        'method': 'Page.setInterceptFileChooserDialog',
        'params': params,
    }
    json = yield cmd_dict


@event_class('Page.domContentEventFired')
@dataclass
class DomContentEventFired:
    timestamp: network.MonotonicTime

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> DomContentEventFired:
        return cls(
            timestamp=network.MonotonicTime.from_json(json['timestamp'])
        )


@event_class('Page.fileChooserOpened')
@dataclass
class FileChooserOpened:
    '''
    Emitted only when ``page.interceptFileChooser`` is enabled.
    '''
    #: Id of the frame containing input node.
    frame_id: FrameId
    #: Input node id.
    backend_node_id: dom.BackendNodeId
    #: Input mode.
    mode: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FileChooserOpened:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            backend_node_id=dom.BackendNodeId.from_json(json['backendNodeId']),
            mode=str(json['mode'])
        )


@event_class('Page.frameAttached')
@dataclass
class FrameAttached:
    '''
    Fired when frame has been attached to its parent.
    '''
    #: Id of the frame that has been attached.
    frame_id: FrameId
    #: Parent frame identifier.
    parent_frame_id: FrameId
    #: JavaScript stack trace of when frame was attached, only set if frame initiated from script.
    stack: typing.Optional[runtime.StackTrace]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameAttached:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            parent_frame_id=FrameId.from_json(json['parentFrameId']),
            stack=runtime.StackTrace.from_json(json['stack']) if 'stack' in json else None
        )


@event_class('Page.frameClearedScheduledNavigation')
@dataclass
class FrameClearedScheduledNavigation:
    '''
    Fired when frame no longer has a scheduled navigation.
    '''
    #: Id of the frame that has cleared its scheduled navigation.
    frame_id: FrameId

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameClearedScheduledNavigation:
        return cls(
            frame_id=FrameId.from_json(json['frameId'])
        )


@event_class('Page.frameDetached')
@dataclass
class FrameDetached:
    '''
    Fired when frame has been detached from its parent.
    '''
    #: Id of the frame that has been detached.
    frame_id: FrameId
    reason: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameDetached:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            reason=str(json['reason'])
        )


@event_class('Page.frameNavigated')
@dataclass
class FrameNavigated:
    '''
    Fired once navigation of the frame has completed. Frame is now associated with the new loader.
    '''
    #: Frame object.
    frame: Frame
    type_: NavigationType

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameNavigated:
        return cls(
            frame=Frame.from_json(json['frame']),
            type_=NavigationType.from_json(json['type'])
        )


@event_class('Page.documentOpened')
@dataclass
class DocumentOpened:
    '''
    **EXPERIMENTAL**

    Fired when opening document to write to.
    '''
    #: Frame object.
    frame: Frame

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> DocumentOpened:
        return cls(
            frame=Frame.from_json(json['frame'])
        )


@event_class('Page.frameResized')
@dataclass
class FrameResized:
    '''
    **EXPERIMENTAL**


    '''


    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameResized:
        return cls(

        )


@event_class('Page.frameRequestedNavigation')
@dataclass
class FrameRequestedNavigation:
    '''
    **EXPERIMENTAL**

    Fired when a renderer-initiated navigation is requested.
    Navigation may still be cancelled after the event is issued.
    '''
    #: Id of the frame that is being navigated.
    frame_id: FrameId
    #: The reason for the navigation.
    reason: ClientNavigationReason
    #: The destination URL for the requested navigation.
    url: str
    #: The disposition for the navigation.
    disposition: ClientNavigationDisposition

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameRequestedNavigation:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            reason=ClientNavigationReason.from_json(json['reason']),
            url=str(json['url']),
            disposition=ClientNavigationDisposition.from_json(json['disposition'])
        )


@event_class('Page.frameScheduledNavigation')
@dataclass
class FrameScheduledNavigation:
    '''
    Fired when frame schedules a potential navigation.
    '''
    #: Id of the frame that has scheduled a navigation.
    frame_id: FrameId
    #: Delay (in seconds) until the navigation is scheduled to begin. The navigation is not
    #: guaranteed to start.
    delay: float
    #: The reason for the navigation.
    reason: ClientNavigationReason
    #: The destination URL for the scheduled navigation.
    url: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameScheduledNavigation:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            delay=float(json['delay']),
            reason=ClientNavigationReason.from_json(json['reason']),
            url=str(json['url'])
        )


@event_class('Page.frameStartedLoading')
@dataclass
class FrameStartedLoading:
    '''
    **EXPERIMENTAL**

    Fired when frame has started loading.
    '''
    #: Id of the frame that has started loading.
    frame_id: FrameId

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameStartedLoading:
        return cls(
            frame_id=FrameId.from_json(json['frameId'])
        )


@event_class('Page.frameStoppedLoading')
@dataclass
class FrameStoppedLoading:
    '''
    **EXPERIMENTAL**

    Fired when frame has stopped loading.
    '''
    #: Id of the frame that has stopped loading.
    frame_id: FrameId

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> FrameStoppedLoading:
        return cls(
            frame_id=FrameId.from_json(json['frameId'])
        )


@event_class('Page.downloadWillBegin')
@dataclass
class DownloadWillBegin:
    '''
    **EXPERIMENTAL**

    Fired when page is about to start a download.
    Deprecated. Use Browser.downloadWillBegin instead.
    '''
    #: Id of the frame that caused download to begin.
    frame_id: FrameId
    #: Global unique identifier of the download.
    guid: str
    #: URL of the resource being downloaded.
    url: str
    #: Suggested file name of the resource (the actual name of the file saved on disk may differ).
    suggested_filename: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> DownloadWillBegin:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            guid=str(json['guid']),
            url=str(json['url']),
            suggested_filename=str(json['suggestedFilename'])
        )


@event_class('Page.downloadProgress')
@dataclass
class DownloadProgress:
    '''
    **EXPERIMENTAL**

    Fired when download makes progress. Last call has ``done`` == true.
    Deprecated. Use Browser.downloadProgress instead.
    '''
    #: Global unique identifier of the download.
    guid: str
    #: Total expected bytes to download.
    total_bytes: float
    #: Total bytes received.
    received_bytes: float
    #: Download status.
    state: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> DownloadProgress:
        return cls(
            guid=str(json['guid']),
            total_bytes=float(json['totalBytes']),
            received_bytes=float(json['receivedBytes']),
            state=str(json['state'])
        )


@event_class('Page.interstitialHidden')
@dataclass
class InterstitialHidden:
    '''
    Fired when interstitial page was hidden
    '''


    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> InterstitialHidden:
        return cls(

        )


@event_class('Page.interstitialShown')
@dataclass
class InterstitialShown:
    '''
    Fired when interstitial page was shown
    '''


    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> InterstitialShown:
        return cls(

        )


@event_class('Page.javascriptDialogClosed')
@dataclass
class JavascriptDialogClosed:
    '''
    Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been
    closed.
    '''
    #: Whether dialog was confirmed.
    result: bool
    #: User input in case of prompt.
    user_input: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> JavascriptDialogClosed:
        return cls(
            result=bool(json['result']),
            user_input=str(json['userInput'])
        )


@event_class('Page.javascriptDialogOpening')
@dataclass
class JavascriptDialogOpening:
    '''
    Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to
    open.
    '''
    #: Frame url.
    url: str
    #: Message that will be displayed by the dialog.
    message: str
    #: Dialog type.
    type_: DialogType
    #: True iff browser is capable showing or acting on the given dialog. When browser has no
    #: dialog handler for given target, calling alert while Page domain is engaged will stall
    #: the page execution. Execution can be resumed via calling Page.handleJavaScriptDialog.
    has_browser_handler: bool
    #: Default dialog prompt.
    default_prompt: typing.Optional[str]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> JavascriptDialogOpening:
        return cls(
            url=str(json['url']),
            message=str(json['message']),
            type_=DialogType.from_json(json['type']),
            has_browser_handler=bool(json['hasBrowserHandler']),
            default_prompt=str(json['defaultPrompt']) if 'defaultPrompt' in json else None
        )


@event_class('Page.lifecycleEvent')
@dataclass
class LifecycleEvent:
    '''
    Fired for top level page lifecycle events such as navigation, load, paint, etc.
    '''
    #: Id of the frame.
    frame_id: FrameId
    #: Loader identifier. Empty string if the request is fetched from worker.
    loader_id: network.LoaderId
    name: str
    timestamp: network.MonotonicTime

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> LifecycleEvent:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            loader_id=network.LoaderId.from_json(json['loaderId']),
            name=str(json['name']),
            timestamp=network.MonotonicTime.from_json(json['timestamp'])
        )


@event_class('Page.backForwardCacheNotUsed')
@dataclass
class BackForwardCacheNotUsed:
    '''
    **EXPERIMENTAL**

    Fired for failed bfcache history navigations if BackForwardCache feature is enabled. Do
    not assume any ordering with the Page.frameNavigated event. This event is fired only for
    main-frame history navigation where the document changes (non-same-document navigations),
    when bfcache navigation fails.
    '''
    #: The loader id for the associated navgation.
    loader_id: network.LoaderId
    #: The frame id of the associated frame.
    frame_id: FrameId
    #: Array of reasons why the page could not be cached. This must not be empty.
    not_restored_explanations: typing.List[BackForwardCacheNotRestoredExplanation]
    #: Tree structure of reasons why the page could not be cached for each frame.
    not_restored_explanations_tree: typing.Optional[BackForwardCacheNotRestoredExplanationTree]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> BackForwardCacheNotUsed:
        return cls(
            loader_id=network.LoaderId.from_json(json['loaderId']),
            frame_id=FrameId.from_json(json['frameId']),
            not_restored_explanations=[BackForwardCacheNotRestoredExplanation.from_json(i) for i in json['notRestoredExplanations']],
            not_restored_explanations_tree=BackForwardCacheNotRestoredExplanationTree.from_json(json['notRestoredExplanationsTree']) if 'notRestoredExplanationsTree' in json else None
        )


@event_class('Page.prerenderAttemptCompleted')
@dataclass
class PrerenderAttemptCompleted:
    '''
    Fired when a prerender attempt is completed.
    '''
    #: The frame id of the frame initiating prerendering.
    initiating_frame_id: FrameId
    prerendering_url: str
    final_status: PrerenderFinalStatus

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> PrerenderAttemptCompleted:
        return cls(
            initiating_frame_id=FrameId.from_json(json['initiatingFrameId']),
            prerendering_url=str(json['prerenderingUrl']),
            final_status=PrerenderFinalStatus.from_json(json['finalStatus'])
        )


@event_class('Page.loadEventFired')
@dataclass
class LoadEventFired:
    timestamp: network.MonotonicTime

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> LoadEventFired:
        return cls(
            timestamp=network.MonotonicTime.from_json(json['timestamp'])
        )


@event_class('Page.navigatedWithinDocument')
@dataclass
class NavigatedWithinDocument:
    '''
    **EXPERIMENTAL**

    Fired when same-document navigation happens, e.g. due to history API usage or anchor navigation.
    '''
    #: Id of the frame.
    frame_id: FrameId
    #: Frame's new url.
    url: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> NavigatedWithinDocument:
        return cls(
            frame_id=FrameId.from_json(json['frameId']),
            url=str(json['url'])
        )


@event_class('Page.screencastFrame')
@dataclass
class ScreencastFrame:
    '''
    **EXPERIMENTAL**

    Compressed image data requested by the ``startScreencast``.
    '''
    #: Base64-encoded compressed image.
    data: str
    #: Screencast frame metadata.
    metadata: ScreencastFrameMetadata
    #: Frame number.
    session_id: int

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ScreencastFrame:
        return cls(
            data=str(json['data']),
            metadata=ScreencastFrameMetadata.from_json(json['metadata']),
            session_id=int(json['sessionId'])
        )


@event_class('Page.screencastVisibilityChanged')
@dataclass
class ScreencastVisibilityChanged:
    '''
    **EXPERIMENTAL**

    Fired when the page with currently enabled screencast was shown or hidden .
    '''
    #: True if the page is visible.
    visible: bool

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ScreencastVisibilityChanged:
        return cls(
            visible=bool(json['visible'])
        )


@event_class('Page.windowOpen')
@dataclass
class WindowOpen:
    '''
    Fired when a new window is going to be opened, via window.open(), link click, form submission,
    etc.
    '''
    #: The URL for the new window.
    url: str
    #: Window name.
    window_name: str
    #: An array of enabled window features.
    window_features: typing.List[str]
    #: Whether or not it was triggered by user gesture.
    user_gesture: bool

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> WindowOpen:
        return cls(
            url=str(json['url']),
            window_name=str(json['windowName']),
            window_features=[str(i) for i in json['windowFeatures']],
            user_gesture=bool(json['userGesture'])
        )


@event_class('Page.compilationCacheProduced')
@dataclass
class CompilationCacheProduced:
    '''
    **EXPERIMENTAL**

    Issued for every compilation cache generated. Is only available
    if Page.setGenerateCompilationCache is enabled.
    '''
    url: str
    #: Base64-encoded data
    data: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> CompilationCacheProduced:
        return cls(
            url=str(json['url']),
            data=str(json['data'])
        )
