Hide navigation sidebar
Hide table of contents sidebar
Back to top
Toggle table of contents sidebar

# Source code for nodriver.cdp.audits

    # 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: Audits (experimental)

    from __future__ import annotations
    import enum
    import typing
    from dataclasses import dataclass
    from .util import event_class, T_JSON_DICT

    from . import dom
    from . import network
    from . import page
    from . import runtime

    @dataclass
    class AffectedCookie:
        '''
        Information about a cookie that is affected by an inspector issue.
        '''
        #: The following three properties uniquely identify a cookie
        name: str

        path: str

        domain: str

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['name'] = self.name
            json['path'] = self.path
            json['domain'] = self.domain
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> AffectedCookie:
            return cls(
                name=str(json['name']),
                path=str(json['path']),
                domain=str(json['domain']),
            )

    @dataclass
    class AffectedRequest:
        '''
        Information about a request that is affected by an inspector issue.
        '''
        url: str

        #: The unique request id.
        request_id: typing.Optional[network.RequestId] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['url'] = self.url
            if self.request_id is not None:
                json['requestId'] = self.request_id.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> AffectedRequest:
            return cls(
                url=str(json['url']),
                request_id=network.RequestId.from_json(json['requestId']) if json.get('requestId', None) is not None else None,
            )

    @dataclass
    class AffectedFrame:
        '''
        Information about the frame affected by an inspector issue.
        '''
        frame_id: page.FrameId

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['frameId'] = self.frame_id.to_json()
            return json

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

    class CookieExclusionReason(enum.Enum):
        EXCLUDE_SAME_SITE_UNSPECIFIED_TREATED_AS_LAX = "ExcludeSameSiteUnspecifiedTreatedAsLax"
        EXCLUDE_SAME_SITE_NONE_INSECURE = "ExcludeSameSiteNoneInsecure"
        EXCLUDE_SAME_SITE_LAX = "ExcludeSameSiteLax"
        EXCLUDE_SAME_SITE_STRICT = "ExcludeSameSiteStrict"
        EXCLUDE_INVALID_SAME_PARTY = "ExcludeInvalidSameParty"
        EXCLUDE_SAME_PARTY_CROSS_PARTY_CONTEXT = "ExcludeSamePartyCrossPartyContext"
        EXCLUDE_DOMAIN_NON_ASCII = "ExcludeDomainNonASCII"
        EXCLUDE_THIRD_PARTY_COOKIE_BLOCKED_IN_FIRST_PARTY_SET = "ExcludeThirdPartyCookieBlockedInFirstPartySet"
        EXCLUDE_THIRD_PARTY_PHASEOUT = "ExcludeThirdPartyPhaseout"
        EXCLUDE_PORT_MISMATCH = "ExcludePortMismatch"
        EXCLUDE_SCHEME_MISMATCH = "ExcludeSchemeMismatch"

        def to_json(self) -> str:
            return self.value

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

    class CookieWarningReason(enum.Enum):
        WARN_SAME_SITE_UNSPECIFIED_CROSS_SITE_CONTEXT = "WarnSameSiteUnspecifiedCrossSiteContext"
        WARN_SAME_SITE_NONE_INSECURE = "WarnSameSiteNoneInsecure"
        WARN_SAME_SITE_UNSPECIFIED_LAX_ALLOW_UNSAFE = "WarnSameSiteUnspecifiedLaxAllowUnsafe"
        WARN_SAME_SITE_STRICT_LAX_DOWNGRADE_STRICT = "WarnSameSiteStrictLaxDowngradeStrict"
        WARN_SAME_SITE_STRICT_CROSS_DOWNGRADE_STRICT = "WarnSameSiteStrictCrossDowngradeStrict"
        WARN_SAME_SITE_STRICT_CROSS_DOWNGRADE_LAX = "WarnSameSiteStrictCrossDowngradeLax"
        WARN_SAME_SITE_LAX_CROSS_DOWNGRADE_STRICT = "WarnSameSiteLaxCrossDowngradeStrict"
        WARN_SAME_SITE_LAX_CROSS_DOWNGRADE_LAX = "WarnSameSiteLaxCrossDowngradeLax"
        WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE = "WarnAttributeValueExceedsMaxSize"
        WARN_DOMAIN_NON_ASCII = "WarnDomainNonASCII"
        WARN_THIRD_PARTY_PHASEOUT = "WarnThirdPartyPhaseout"
        WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION = "WarnCrossSiteRedirectDowngradeChangesInclusion"
        WARN_DEPRECATION_TRIAL_METADATA = "WarnDeprecationTrialMetadata"
        WARN_THIRD_PARTY_COOKIE_HEURISTIC = "WarnThirdPartyCookieHeuristic"

        def to_json(self) -> str:
            return self.value

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

    class CookieOperation(enum.Enum):
        SET_COOKIE = "SetCookie"
        READ_COOKIE = "ReadCookie"

        def to_json(self) -> str:
            return self.value

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

    class InsightType(enum.Enum):
        '''
        Represents the category of insight that a cookie issue falls under.
        '''
        GIT_HUB_RESOURCE = "GitHubResource"
        GRACE_PERIOD = "GracePeriod"
        HEURISTICS = "Heuristics"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class CookieIssueInsight:
        '''
        Information about the suggested solution to a cookie issue.
        '''
        type_: InsightType

        #: Link to table entry in third-party cookie migration readiness list.
        table_entry_url: typing.Optional[str] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['type'] = self.type_.to_json()
            if self.table_entry_url is not None:
                json['tableEntryUrl'] = self.table_entry_url
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> CookieIssueInsight:
            return cls(
                type_=InsightType.from_json(json['type']),
                table_entry_url=str(json['tableEntryUrl']) if json.get('tableEntryUrl', None) is not None else None,
            )

    @dataclass
    class CookieIssueDetails:
        '''
        This information is currently necessary, as the front-end has a difficult
        time finding a specific cookie. With this, we can convey specific error
        information without the cookie.
        '''
        cookie_warning_reasons: typing.List[CookieWarningReason]

        cookie_exclusion_reasons: typing.List[CookieExclusionReason]

        #: Optionally identifies the site-for-cookies and the cookie url, which
        #: may be used by the front-end as additional context.
        operation: CookieOperation

        #: If AffectedCookie is not set then rawCookieLine contains the raw
        #: Set-Cookie header string. This hints at a problem where the
        #: cookie line is syntactically or semantically malformed in a way
        #: that no valid cookie could be created.
        cookie: typing.Optional[AffectedCookie] = None

        raw_cookie_line: typing.Optional[str] = None

        site_for_cookies: typing.Optional[str] = None

        cookie_url: typing.Optional[str] = None

        request: typing.Optional[AffectedRequest] = None

        #: The recommended solution to the issue.
        insight: typing.Optional[CookieIssueInsight] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['cookieWarningReasons'] = [i.to_json() for i in self.cookie_warning_reasons]
            json['cookieExclusionReasons'] = [i.to_json() for i in self.cookie_exclusion_reasons]
            json['operation'] = self.operation.to_json()
            if self.cookie is not None:
                json['cookie'] = self.cookie.to_json()
            if self.raw_cookie_line is not None:
                json['rawCookieLine'] = self.raw_cookie_line
            if self.site_for_cookies is not None:
                json['siteForCookies'] = self.site_for_cookies
            if self.cookie_url is not None:
                json['cookieUrl'] = self.cookie_url
            if self.request is not None:
                json['request'] = self.request.to_json()
            if self.insight is not None:
                json['insight'] = self.insight.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> CookieIssueDetails:
            return cls(
                cookie_warning_reasons=[CookieWarningReason.from_json(i) for i in json['cookieWarningReasons']],
                cookie_exclusion_reasons=[CookieExclusionReason.from_json(i) for i in json['cookieExclusionReasons']],
                operation=CookieOperation.from_json(json['operation']),
                cookie=AffectedCookie.from_json(json['cookie']) if json.get('cookie', None) is not None else None,
                raw_cookie_line=str(json['rawCookieLine']) if json.get('rawCookieLine', None) is not None else None,
                site_for_cookies=str(json['siteForCookies']) if json.get('siteForCookies', None) is not None else None,
                cookie_url=str(json['cookieUrl']) if json.get('cookieUrl', None) is not None else None,
                request=AffectedRequest.from_json(json['request']) if json.get('request', None) is not None else None,
                insight=CookieIssueInsight.from_json(json['insight']) if json.get('insight', None) is not None else None,
            )

    class MixedContentResolutionStatus(enum.Enum):
        MIXED_CONTENT_BLOCKED = "MixedContentBlocked"
        MIXED_CONTENT_AUTOMATICALLY_UPGRADED = "MixedContentAutomaticallyUpgraded"
        MIXED_CONTENT_WARNING = "MixedContentWarning"

        def to_json(self) -> str:
            return self.value

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

    class MixedContentResourceType(enum.Enum):
        ATTRIBUTION_SRC = "AttributionSrc"
        AUDIO = "Audio"
        BEACON = "Beacon"
        CSP_REPORT = "CSPReport"
        DOWNLOAD = "Download"
        EVENT_SOURCE = "EventSource"
        FAVICON = "Favicon"
        FONT = "Font"
        FORM = "Form"
        FRAME = "Frame"
        IMAGE = "Image"
        IMPORT = "Import"
        JSON = "JSON"
        MANIFEST = "Manifest"
        PING = "Ping"
        PLUGIN_DATA = "PluginData"
        PLUGIN_RESOURCE = "PluginResource"
        PREFETCH = "Prefetch"
        RESOURCE = "Resource"
        SCRIPT = "Script"
        SERVICE_WORKER = "ServiceWorker"
        SHARED_WORKER = "SharedWorker"
        SPECULATION_RULES = "SpeculationRules"
        STYLESHEET = "Stylesheet"
        TRACK = "Track"
        VIDEO = "Video"
        WORKER = "Worker"
        XML_HTTP_REQUEST = "XMLHttpRequest"
        XSLT = "XSLT"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class MixedContentIssueDetails:
        #: The way the mixed content issue is being resolved.
        resolution_status: MixedContentResolutionStatus

        #: The unsafe http url causing the mixed content issue.
        insecure_url: str

        #: The url responsible for the call to an unsafe url.
        main_resource_url: str

        #: The type of resource causing the mixed content issue (css, js, iframe,
        #: form,...). Marked as optional because it is mapped to from
        #: blink::mojom::RequestContextType, which will be replaced
        #: by network::mojom::RequestDestination
        resource_type: typing.Optional[MixedContentResourceType] = None

        #: The mixed content request.
        #: Does not always exist (e.g. for unsafe form submission urls).
        request: typing.Optional[AffectedRequest] = None

        #: Optional because not every mixed content issue is necessarily linked to a frame.
        frame: typing.Optional[AffectedFrame] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['resolutionStatus'] = self.resolution_status.to_json()
            json['insecureURL'] = self.insecure_url
            json['mainResourceURL'] = self.main_resource_url
            if self.resource_type is not None:
                json['resourceType'] = self.resource_type.to_json()
            if self.request is not None:
                json['request'] = self.request.to_json()
            if self.frame is not None:
                json['frame'] = self.frame.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> MixedContentIssueDetails:
            return cls(
                resolution_status=MixedContentResolutionStatus.from_json(json['resolutionStatus']),
                insecure_url=str(json['insecureURL']),
                main_resource_url=str(json['mainResourceURL']),
                resource_type=MixedContentResourceType.from_json(json['resourceType']) if json.get('resourceType', None) is not None else None,
                request=AffectedRequest.from_json(json['request']) if json.get('request', None) is not None else None,
                frame=AffectedFrame.from_json(json['frame']) if json.get('frame', None) is not None else None,
            )

    class BlockedByResponseReason(enum.Enum):
        '''
        Enum indicating the reason a response has been blocked. These reasons are
        refinements of the net error BLOCKED_BY_RESPONSE.
        '''
        COEP_FRAME_RESOURCE_NEEDS_COEP_HEADER = "CoepFrameResourceNeedsCoepHeader"
        COOP_SANDBOXED_I_FRAME_CANNOT_NAVIGATE_TO_COOP_PAGE = "CoopSandboxedIFrameCannotNavigateToCoopPage"
        CORP_NOT_SAME_ORIGIN = "CorpNotSameOrigin"
        CORP_NOT_SAME_ORIGIN_AFTER_DEFAULTED_TO_SAME_ORIGIN_BY_COEP = "CorpNotSameOriginAfterDefaultedToSameOriginByCoep"
        CORP_NOT_SAME_ORIGIN_AFTER_DEFAULTED_TO_SAME_ORIGIN_BY_DIP = "CorpNotSameOriginAfterDefaultedToSameOriginByDip"
        CORP_NOT_SAME_ORIGIN_AFTER_DEFAULTED_TO_SAME_ORIGIN_BY_COEP_AND_DIP = "CorpNotSameOriginAfterDefaultedToSameOriginByCoepAndDip"
        CORP_NOT_SAME_SITE = "CorpNotSameSite"
        SRI_MESSAGE_SIGNATURE_MISMATCH = "SRIMessageSignatureMismatch"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class BlockedByResponseIssueDetails:
        '''
        Details for a request that has been blocked with the BLOCKED_BY_RESPONSE
        code. Currently only used for COEP/COOP, but may be extended to include
        some CSP errors in the future.
        '''
        request: AffectedRequest

        reason: BlockedByResponseReason

        parent_frame: typing.Optional[AffectedFrame] = None

        blocked_frame: typing.Optional[AffectedFrame] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['request'] = self.request.to_json()
            json['reason'] = self.reason.to_json()
            if self.parent_frame is not None:
                json['parentFrame'] = self.parent_frame.to_json()
            if self.blocked_frame is not None:
                json['blockedFrame'] = self.blocked_frame.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> BlockedByResponseIssueDetails:
            return cls(
                request=AffectedRequest.from_json(json['request']),
                reason=BlockedByResponseReason.from_json(json['reason']),
                parent_frame=AffectedFrame.from_json(json['parentFrame']) if json.get('parentFrame', None) is not None else None,
                blocked_frame=AffectedFrame.from_json(json['blockedFrame']) if json.get('blockedFrame', None) is not None else None,
            )

    class HeavyAdResolutionStatus(enum.Enum):
        HEAVY_AD_BLOCKED = "HeavyAdBlocked"
        HEAVY_AD_WARNING = "HeavyAdWarning"

        def to_json(self) -> str:
            return self.value

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

    class HeavyAdReason(enum.Enum):
        NETWORK_TOTAL_LIMIT = "NetworkTotalLimit"
        CPU_TOTAL_LIMIT = "CpuTotalLimit"
        CPU_PEAK_LIMIT = "CpuPeakLimit"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class HeavyAdIssueDetails:
        #: The resolution status, either blocking the content or warning.
        resolution: HeavyAdResolutionStatus

        #: The reason the ad was blocked, total network or cpu or peak cpu.
        reason: HeavyAdReason

        #: The frame that was blocked.
        frame: AffectedFrame

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['resolution'] = self.resolution.to_json()
            json['reason'] = self.reason.to_json()
            json['frame'] = self.frame.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> HeavyAdIssueDetails:
            return cls(
                resolution=HeavyAdResolutionStatus.from_json(json['resolution']),
                reason=HeavyAdReason.from_json(json['reason']),
                frame=AffectedFrame.from_json(json['frame']),
            )

    class ContentSecurityPolicyViolationType(enum.Enum):
        K_INLINE_VIOLATION = "kInlineViolation"
        K_EVAL_VIOLATION = "kEvalViolation"
        K_URL_VIOLATION = "kURLViolation"
        K_SRI_VIOLATION = "kSRIViolation"
        K_TRUSTED_TYPES_SINK_VIOLATION = "kTrustedTypesSinkViolation"
        K_TRUSTED_TYPES_POLICY_VIOLATION = "kTrustedTypesPolicyViolation"
        K_WASM_EVAL_VIOLATION = "kWasmEvalViolation"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class SourceCodeLocation:
        url: str

        line_number: int

        column_number: int

        script_id: typing.Optional[runtime.ScriptId] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['url'] = self.url
            json['lineNumber'] = self.line_number
            json['columnNumber'] = self.column_number
            if self.script_id is not None:
                json['scriptId'] = self.script_id.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> SourceCodeLocation:
            return cls(
                url=str(json['url']),
                line_number=int(json['lineNumber']),
                column_number=int(json['columnNumber']),
                script_id=runtime.ScriptId.from_json(json['scriptId']) if json.get('scriptId', None) is not None else None,
            )

    @dataclass
    class ContentSecurityPolicyIssueDetails:
        #: Specific directive that is violated, causing the CSP issue.
        violated_directive: str

        is_report_only: bool

        content_security_policy_violation_type: ContentSecurityPolicyViolationType

        #: The url not included in allowed sources.
        blocked_url: typing.Optional[str] = None

        frame_ancestor: typing.Optional[AffectedFrame] = None

        source_code_location: typing.Optional[SourceCodeLocation] = None

        violating_node_id: typing.Optional[dom.BackendNodeId] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['violatedDirective'] = self.violated_directive
            json['isReportOnly'] = self.is_report_only
            json['contentSecurityPolicyViolationType'] = self.content_security_policy_violation_type.to_json()
            if self.blocked_url is not None:
                json['blockedURL'] = self.blocked_url
            if self.frame_ancestor is not None:
                json['frameAncestor'] = self.frame_ancestor.to_json()
            if self.source_code_location is not None:
                json['sourceCodeLocation'] = self.source_code_location.to_json()
            if self.violating_node_id is not None:
                json['violatingNodeId'] = self.violating_node_id.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> ContentSecurityPolicyIssueDetails:
            return cls(
                violated_directive=str(json['violatedDirective']),
                is_report_only=bool(json['isReportOnly']),
                content_security_policy_violation_type=ContentSecurityPolicyViolationType.from_json(json['contentSecurityPolicyViolationType']),
                blocked_url=str(json['blockedURL']) if json.get('blockedURL', None) is not None else None,
                frame_ancestor=AffectedFrame.from_json(json['frameAncestor']) if json.get('frameAncestor', None) is not None else None,
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']) if json.get('sourceCodeLocation', None) is not None else None,
                violating_node_id=dom.BackendNodeId.from_json(json['violatingNodeId']) if json.get('violatingNodeId', None) is not None else None,
            )

    class SharedArrayBufferIssueType(enum.Enum):
        TRANSFER_ISSUE = "TransferIssue"
        CREATION_ISSUE = "CreationIssue"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class SharedArrayBufferIssueDetails:
        '''
        Details for a issue arising from an SAB being instantiated in, or
        transferred to a context that is not cross-origin isolated.
        '''
        source_code_location: SourceCodeLocation

        is_warning: bool

        type_: SharedArrayBufferIssueType

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['sourceCodeLocation'] = self.source_code_location.to_json()
            json['isWarning'] = self.is_warning
            json['type'] = self.type_.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> SharedArrayBufferIssueDetails:
            return cls(
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
                is_warning=bool(json['isWarning']),
                type_=SharedArrayBufferIssueType.from_json(json['type']),
            )

    @dataclass
    class LowTextContrastIssueDetails:
        violating_node_id: dom.BackendNodeId

        violating_node_selector: str

        contrast_ratio: float

        threshold_aa: float

        threshold_aaa: float

        font_size: str

        font_weight: str

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['violatingNodeId'] = self.violating_node_id.to_json()
            json['violatingNodeSelector'] = self.violating_node_selector
            json['contrastRatio'] = self.contrast_ratio
            json['thresholdAA'] = self.threshold_aa
            json['thresholdAAA'] = self.threshold_aaa
            json['fontSize'] = self.font_size
            json['fontWeight'] = self.font_weight
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> LowTextContrastIssueDetails:
            return cls(
                violating_node_id=dom.BackendNodeId.from_json(json['violatingNodeId']),
                violating_node_selector=str(json['violatingNodeSelector']),
                contrast_ratio=float(json['contrastRatio']),
                threshold_aa=float(json['thresholdAA']),
                threshold_aaa=float(json['thresholdAAA']),
                font_size=str(json['fontSize']),
                font_weight=str(json['fontWeight']),
            )

    @dataclass
    class CorsIssueDetails:
        '''
        Details for a CORS related issue, e.g. a warning or error related to
        CORS RFC1918 enforcement.
        '''
        cors_error_status: network.CorsErrorStatus

        is_warning: bool

        request: AffectedRequest

        location: typing.Optional[SourceCodeLocation] = None

        initiator_origin: typing.Optional[str] = None

        resource_ip_address_space: typing.Optional[network.IPAddressSpace] = None

        client_security_state: typing.Optional[network.ClientSecurityState] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['corsErrorStatus'] = self.cors_error_status.to_json()
            json['isWarning'] = self.is_warning
            json['request'] = self.request.to_json()
            if self.location is not None:
                json['location'] = self.location.to_json()
            if self.initiator_origin is not None:
                json['initiatorOrigin'] = self.initiator_origin
            if self.resource_ip_address_space is not None:
                json['resourceIPAddressSpace'] = self.resource_ip_address_space.to_json()
            if self.client_security_state is not None:
                json['clientSecurityState'] = self.client_security_state.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> CorsIssueDetails:
            return cls(
                cors_error_status=network.CorsErrorStatus.from_json(json['corsErrorStatus']),
                is_warning=bool(json['isWarning']),
                request=AffectedRequest.from_json(json['request']),
                location=SourceCodeLocation.from_json(json['location']) if json.get('location', None) is not None else None,
                initiator_origin=str(json['initiatorOrigin']) if json.get('initiatorOrigin', None) is not None else None,
                resource_ip_address_space=network.IPAddressSpace.from_json(json['resourceIPAddressSpace']) if json.get('resourceIPAddressSpace', None) is not None else None,
                client_security_state=network.ClientSecurityState.from_json(json['clientSecurityState']) if json.get('clientSecurityState', None) is not None else None,
            )

    class AttributionReportingIssueType(enum.Enum):
        PERMISSION_POLICY_DISABLED = "PermissionPolicyDisabled"
        UNTRUSTWORTHY_REPORTING_ORIGIN = "UntrustworthyReportingOrigin"
        INSECURE_CONTEXT = "InsecureContext"
        INVALID_HEADER = "InvalidHeader"
        INVALID_REGISTER_TRIGGER_HEADER = "InvalidRegisterTriggerHeader"
        SOURCE_AND_TRIGGER_HEADERS = "SourceAndTriggerHeaders"
        SOURCE_IGNORED = "SourceIgnored"
        TRIGGER_IGNORED = "TriggerIgnored"
        OS_SOURCE_IGNORED = "OsSourceIgnored"
        OS_TRIGGER_IGNORED = "OsTriggerIgnored"
        INVALID_REGISTER_OS_SOURCE_HEADER = "InvalidRegisterOsSourceHeader"
        INVALID_REGISTER_OS_TRIGGER_HEADER = "InvalidRegisterOsTriggerHeader"
        WEB_AND_OS_HEADERS = "WebAndOsHeaders"
        NO_WEB_OR_OS_SUPPORT = "NoWebOrOsSupport"
        NAVIGATION_REGISTRATION_WITHOUT_TRANSIENT_USER_ACTIVATION = "NavigationRegistrationWithoutTransientUserActivation"
        INVALID_INFO_HEADER = "InvalidInfoHeader"
        NO_REGISTER_SOURCE_HEADER = "NoRegisterSourceHeader"
        NO_REGISTER_TRIGGER_HEADER = "NoRegisterTriggerHeader"
        NO_REGISTER_OS_SOURCE_HEADER = "NoRegisterOsSourceHeader"
        NO_REGISTER_OS_TRIGGER_HEADER = "NoRegisterOsTriggerHeader"
        NAVIGATION_REGISTRATION_UNIQUE_SCOPE_ALREADY_SET = "NavigationRegistrationUniqueScopeAlreadySet"

        def to_json(self) -> str:
            return self.value

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

    class SharedDictionaryError(enum.Enum):
        USE_ERROR_CROSS_ORIGIN_NO_CORS_REQUEST = "UseErrorCrossOriginNoCorsRequest"
        USE_ERROR_DICTIONARY_LOAD_FAILURE = "UseErrorDictionaryLoadFailure"
        USE_ERROR_MATCHING_DICTIONARY_NOT_USED = "UseErrorMatchingDictionaryNotUsed"
        USE_ERROR_UNEXPECTED_CONTENT_DICTIONARY_HEADER = "UseErrorUnexpectedContentDictionaryHeader"
        WRITE_ERROR_COSS_ORIGIN_NO_CORS_REQUEST = "WriteErrorCossOriginNoCorsRequest"
        WRITE_ERROR_DISALLOWED_BY_SETTINGS = "WriteErrorDisallowedBySettings"
        WRITE_ERROR_EXPIRED_RESPONSE = "WriteErrorExpiredResponse"
        WRITE_ERROR_FEATURE_DISABLED = "WriteErrorFeatureDisabled"
        WRITE_ERROR_INSUFFICIENT_RESOURCES = "WriteErrorInsufficientResources"
        WRITE_ERROR_INVALID_MATCH_FIELD = "WriteErrorInvalidMatchField"
        WRITE_ERROR_INVALID_STRUCTURED_HEADER = "WriteErrorInvalidStructuredHeader"
        WRITE_ERROR_NAVIGATION_REQUEST = "WriteErrorNavigationRequest"
        WRITE_ERROR_NO_MATCH_FIELD = "WriteErrorNoMatchField"
        WRITE_ERROR_NON_LIST_MATCH_DEST_FIELD = "WriteErrorNonListMatchDestField"
        WRITE_ERROR_NON_SECURE_CONTEXT = "WriteErrorNonSecureContext"
        WRITE_ERROR_NON_STRING_ID_FIELD = "WriteErrorNonStringIdField"
        WRITE_ERROR_NON_STRING_IN_MATCH_DEST_LIST = "WriteErrorNonStringInMatchDestList"
        WRITE_ERROR_NON_STRING_MATCH_FIELD = "WriteErrorNonStringMatchField"
        WRITE_ERROR_NON_TOKEN_TYPE_FIELD = "WriteErrorNonTokenTypeField"
        WRITE_ERROR_REQUEST_ABORTED = "WriteErrorRequestAborted"
        WRITE_ERROR_SHUTTING_DOWN = "WriteErrorShuttingDown"
        WRITE_ERROR_TOO_LONG_ID_FIELD = "WriteErrorTooLongIdField"
        WRITE_ERROR_UNSUPPORTED_TYPE = "WriteErrorUnsupportedType"

        def to_json(self) -> str:
            return self.value

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

    class SRIMessageSignatureError(enum.Enum):
        MISSING_SIGNATURE_HEADER = "MissingSignatureHeader"
        MISSING_SIGNATURE_INPUT_HEADER = "MissingSignatureInputHeader"
        INVALID_SIGNATURE_HEADER = "InvalidSignatureHeader"
        INVALID_SIGNATURE_INPUT_HEADER = "InvalidSignatureInputHeader"
        SIGNATURE_HEADER_VALUE_IS_NOT_BYTE_SEQUENCE = "SignatureHeaderValueIsNotByteSequence"
        SIGNATURE_HEADER_VALUE_IS_PARAMETERIZED = "SignatureHeaderValueIsParameterized"
        SIGNATURE_HEADER_VALUE_IS_INCORRECT_LENGTH = "SignatureHeaderValueIsIncorrectLength"
        SIGNATURE_INPUT_HEADER_MISSING_LABEL = "SignatureInputHeaderMissingLabel"
        SIGNATURE_INPUT_HEADER_VALUE_NOT_INNER_LIST = "SignatureInputHeaderValueNotInnerList"
        SIGNATURE_INPUT_HEADER_VALUE_MISSING_COMPONENTS = "SignatureInputHeaderValueMissingComponents"
        SIGNATURE_INPUT_HEADER_INVALID_COMPONENT_TYPE = "SignatureInputHeaderInvalidComponentType"
        SIGNATURE_INPUT_HEADER_INVALID_COMPONENT_NAME = "SignatureInputHeaderInvalidComponentName"
        SIGNATURE_INPUT_HEADER_INVALID_HEADER_COMPONENT_PARAMETER = "SignatureInputHeaderInvalidHeaderComponentParameter"
        SIGNATURE_INPUT_HEADER_INVALID_DERIVED_COMPONENT_PARAMETER = "SignatureInputHeaderInvalidDerivedComponentParameter"
        SIGNATURE_INPUT_HEADER_KEY_ID_LENGTH = "SignatureInputHeaderKeyIdLength"
        SIGNATURE_INPUT_HEADER_INVALID_PARAMETER = "SignatureInputHeaderInvalidParameter"
        SIGNATURE_INPUT_HEADER_MISSING_REQUIRED_PARAMETERS = "SignatureInputHeaderMissingRequiredParameters"
        VALIDATION_FAILED_SIGNATURE_EXPIRED = "ValidationFailedSignatureExpired"
        VALIDATION_FAILED_INVALID_LENGTH = "ValidationFailedInvalidLength"
        VALIDATION_FAILED_SIGNATURE_MISMATCH = "ValidationFailedSignatureMismatch"
        VALIDATION_FAILED_INTEGRITY_MISMATCH = "ValidationFailedIntegrityMismatch"

        def to_json(self) -> str:
            return self.value

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

    class UnencodedDigestError(enum.Enum):
        MALFORMED_DICTIONARY = "MalformedDictionary"
        UNKNOWN_ALGORITHM = "UnknownAlgorithm"
        INCORRECT_DIGEST_TYPE = "IncorrectDigestType"
        INCORRECT_DIGEST_LENGTH = "IncorrectDigestLength"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class AttributionReportingIssueDetails:
        '''
        Details for issues around "Attribution Reporting API" usage.
        Explainer: https://github.com/WICG/attribution-reporting-api
        '''
        violation_type: AttributionReportingIssueType

        request: typing.Optional[AffectedRequest] = None

        violating_node_id: typing.Optional[dom.BackendNodeId] = None

        invalid_parameter: typing.Optional[str] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['violationType'] = self.violation_type.to_json()
            if self.request is not None:
                json['request'] = self.request.to_json()
            if self.violating_node_id is not None:
                json['violatingNodeId'] = self.violating_node_id.to_json()
            if self.invalid_parameter is not None:
                json['invalidParameter'] = self.invalid_parameter
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> AttributionReportingIssueDetails:
            return cls(
                violation_type=AttributionReportingIssueType.from_json(json['violationType']),
                request=AffectedRequest.from_json(json['request']) if json.get('request', None) is not None else None,
                violating_node_id=dom.BackendNodeId.from_json(json['violatingNodeId']) if json.get('violatingNodeId', None) is not None else None,
                invalid_parameter=str(json['invalidParameter']) if json.get('invalidParameter', None) is not None else None,
            )

    @dataclass
    class QuirksModeIssueDetails:
        '''
        Details for issues about documents in Quirks Mode
        or Limited Quirks Mode that affects page layouting.
        '''
        #: If false, it means the document's mode is "quirks"
        #: instead of "limited-quirks".
        is_limited_quirks_mode: bool

        document_node_id: dom.BackendNodeId

        url: str

        frame_id: page.FrameId

        loader_id: network.LoaderId

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['isLimitedQuirksMode'] = self.is_limited_quirks_mode
            json['documentNodeId'] = self.document_node_id.to_json()
            json['url'] = self.url
            json['frameId'] = self.frame_id.to_json()
            json['loaderId'] = self.loader_id.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> QuirksModeIssueDetails:
            return cls(
                is_limited_quirks_mode=bool(json['isLimitedQuirksMode']),
                document_node_id=dom.BackendNodeId.from_json(json['documentNodeId']),
                url=str(json['url']),
                frame_id=page.FrameId.from_json(json['frameId']),
                loader_id=network.LoaderId.from_json(json['loaderId']),
            )

    @dataclass
    class NavigatorUserAgentIssueDetails:
        url: str

        location: typing.Optional[SourceCodeLocation] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['url'] = self.url
            if self.location is not None:
                json['location'] = self.location.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> NavigatorUserAgentIssueDetails:
            return cls(
                url=str(json['url']),
                location=SourceCodeLocation.from_json(json['location']) if json.get('location', None) is not None else None,
            )

    @dataclass
    class SharedDictionaryIssueDetails:
        shared_dictionary_error: SharedDictionaryError

        request: AffectedRequest

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['sharedDictionaryError'] = self.shared_dictionary_error.to_json()
            json['request'] = self.request.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> SharedDictionaryIssueDetails:
            return cls(
                shared_dictionary_error=SharedDictionaryError.from_json(json['sharedDictionaryError']),
                request=AffectedRequest.from_json(json['request']),
            )

    @dataclass
    class SRIMessageSignatureIssueDetails:
        error: SRIMessageSignatureError

        signature_base: str

        integrity_assertions: typing.List[str]

        request: AffectedRequest

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['error'] = self.error.to_json()
            json['signatureBase'] = self.signature_base
            json['integrityAssertions'] = [i for i in self.integrity_assertions]
            json['request'] = self.request.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> SRIMessageSignatureIssueDetails:
            return cls(
                error=SRIMessageSignatureError.from_json(json['error']),
                signature_base=str(json['signatureBase']),
                integrity_assertions=[str(i) for i in json['integrityAssertions']],
                request=AffectedRequest.from_json(json['request']),
            )

    @dataclass
    class UnencodedDigestIssueDetails:
        error: UnencodedDigestError

        request: AffectedRequest

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['error'] = self.error.to_json()
            json['request'] = self.request.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> UnencodedDigestIssueDetails:
            return cls(
                error=UnencodedDigestError.from_json(json['error']),
                request=AffectedRequest.from_json(json['request']),
            )

    class GenericIssueErrorType(enum.Enum):
        FORM_LABEL_FOR_NAME_ERROR = "FormLabelForNameError"
        FORM_DUPLICATE_ID_FOR_INPUT_ERROR = "FormDuplicateIdForInputError"
        FORM_INPUT_WITH_NO_LABEL_ERROR = "FormInputWithNoLabelError"
        FORM_AUTOCOMPLETE_ATTRIBUTE_EMPTY_ERROR = "FormAutocompleteAttributeEmptyError"
        FORM_EMPTY_ID_AND_NAME_ATTRIBUTES_FOR_INPUT_ERROR = "FormEmptyIdAndNameAttributesForInputError"
        FORM_ARIA_LABELLED_BY_TO_NON_EXISTING_ID = "FormAriaLabelledByToNonExistingId"
        FORM_INPUT_ASSIGNED_AUTOCOMPLETE_VALUE_TO_ID_OR_NAME_ATTRIBUTE_ERROR = "FormInputAssignedAutocompleteValueToIdOrNameAttributeError"
        FORM_LABEL_HAS_NEITHER_FOR_NOR_NESTED_INPUT = "FormLabelHasNeitherForNorNestedInput"
        FORM_LABEL_FOR_MATCHES_NON_EXISTING_ID_ERROR = "FormLabelForMatchesNonExistingIdError"
        FORM_INPUT_HAS_WRONG_BUT_WELL_INTENDED_AUTOCOMPLETE_VALUE_ERROR = "FormInputHasWrongButWellIntendedAutocompleteValueError"
        RESPONSE_WAS_BLOCKED_BY_ORB = "ResponseWasBlockedByORB"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class GenericIssueDetails:
        '''
        Depending on the concrete errorType, different properties are set.
        '''
        #: Issues with the same errorType are aggregated in the frontend.
        error_type: GenericIssueErrorType

        frame_id: typing.Optional[page.FrameId] = None

        violating_node_id: typing.Optional[dom.BackendNodeId] = None

        violating_node_attribute: typing.Optional[str] = None

        request: typing.Optional[AffectedRequest] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['errorType'] = self.error_type.to_json()
            if self.frame_id is not None:
                json['frameId'] = self.frame_id.to_json()
            if self.violating_node_id is not None:
                json['violatingNodeId'] = self.violating_node_id.to_json()
            if self.violating_node_attribute is not None:
                json['violatingNodeAttribute'] = self.violating_node_attribute
            if self.request is not None:
                json['request'] = self.request.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> GenericIssueDetails:
            return cls(
                error_type=GenericIssueErrorType.from_json(json['errorType']),
                frame_id=page.FrameId.from_json(json['frameId']) if json.get('frameId', None) is not None else None,
                violating_node_id=dom.BackendNodeId.from_json(json['violatingNodeId']) if json.get('violatingNodeId', None) is not None else None,
                violating_node_attribute=str(json['violatingNodeAttribute']) if json.get('violatingNodeAttribute', None) is not None else None,
                request=AffectedRequest.from_json(json['request']) if json.get('request', None) is not None else None,
            )

    @dataclass
    class DeprecationIssueDetails:
        '''
        This issue tracks information needed to print a deprecation message.
        https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/third_party/blink/renderer/core/frame/deprecation/README.md
        '''
        source_code_location: SourceCodeLocation

        #: One of the deprecation names from third_party/blink/renderer/core/frame/deprecation/deprecation.json5
        type_: str

        affected_frame: typing.Optional[AffectedFrame] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['sourceCodeLocation'] = self.source_code_location.to_json()
            json['type'] = self.type_
            if self.affected_frame is not None:
                json['affectedFrame'] = self.affected_frame.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> DeprecationIssueDetails:
            return cls(
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
                type_=str(json['type']),
                affected_frame=AffectedFrame.from_json(json['affectedFrame']) if json.get('affectedFrame', None) is not None else None,
            )

    @dataclass
    class BounceTrackingIssueDetails:
        '''
        This issue warns about sites in the redirect chain of a finished navigation
        that may be flagged as trackers and have their state cleared if they don't
        receive a user interaction. Note that in this context 'site' means eTLD+1.
        For example, if the URL ``https://example.test:80/bounce`` was in the
        redirect chain, the site reported would be ``example.test``.
        '''
        tracking_sites: typing.List[str]

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['trackingSites'] = [i for i in self.tracking_sites]
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> BounceTrackingIssueDetails:
            return cls(
                tracking_sites=[str(i) for i in json['trackingSites']],
            )

    @dataclass
    class CookieDeprecationMetadataIssueDetails:
        '''
        This issue warns about third-party sites that are accessing cookies on the
        current page, and have been permitted due to having a global metadata grant.
        Note that in this context 'site' means eTLD+1. For example, if the URL
        ``https://example.test:80/web_page`` was accessing cookies, the site reported
        would be ``example.test``.
        '''
        allowed_sites: typing.List[str]

        opt_out_percentage: float

        is_opt_out_top_level: bool

        operation: CookieOperation

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['allowedSites'] = [i for i in self.allowed_sites]
            json['optOutPercentage'] = self.opt_out_percentage
            json['isOptOutTopLevel'] = self.is_opt_out_top_level
            json['operation'] = self.operation.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> CookieDeprecationMetadataIssueDetails:
            return cls(
                allowed_sites=[str(i) for i in json['allowedSites']],
                opt_out_percentage=float(json['optOutPercentage']),
                is_opt_out_top_level=bool(json['isOptOutTopLevel']),
                operation=CookieOperation.from_json(json['operation']),
            )

    class ClientHintIssueReason(enum.Enum):
        META_TAG_ALLOW_LIST_INVALID_ORIGIN = "MetaTagAllowListInvalidOrigin"
        META_TAG_MODIFIED_HTML = "MetaTagModifiedHTML"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class FederatedAuthRequestIssueDetails:
        federated_auth_request_issue_reason: FederatedAuthRequestIssueReason

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['federatedAuthRequestIssueReason'] = self.federated_auth_request_issue_reason.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> FederatedAuthRequestIssueDetails:
            return cls(
                federated_auth_request_issue_reason=FederatedAuthRequestIssueReason.from_json(json['federatedAuthRequestIssueReason']),
            )

    class FederatedAuthRequestIssueReason(enum.Enum):
        '''
        Represents the failure reason when a federated authentication reason fails.
        Should be updated alongside RequestIdTokenStatus in
        third_party/blink/public/mojom/devtools/inspector_issue.mojom to include
        all cases except for success.
        '''
        SHOULD_EMBARGO = "ShouldEmbargo"
        TOO_MANY_REQUESTS = "TooManyRequests"
        WELL_KNOWN_HTTP_NOT_FOUND = "WellKnownHttpNotFound"
        WELL_KNOWN_NO_RESPONSE = "WellKnownNoResponse"
        WELL_KNOWN_INVALID_RESPONSE = "WellKnownInvalidResponse"
        WELL_KNOWN_LIST_EMPTY = "WellKnownListEmpty"
        WELL_KNOWN_INVALID_CONTENT_TYPE = "WellKnownInvalidContentType"
        CONFIG_NOT_IN_WELL_KNOWN = "ConfigNotInWellKnown"
        WELL_KNOWN_TOO_BIG = "WellKnownTooBig"
        CONFIG_HTTP_NOT_FOUND = "ConfigHttpNotFound"
        CONFIG_NO_RESPONSE = "ConfigNoResponse"
        CONFIG_INVALID_RESPONSE = "ConfigInvalidResponse"
        CONFIG_INVALID_CONTENT_TYPE = "ConfigInvalidContentType"
        CLIENT_METADATA_HTTP_NOT_FOUND = "ClientMetadataHttpNotFound"
        CLIENT_METADATA_NO_RESPONSE = "ClientMetadataNoResponse"
        CLIENT_METADATA_INVALID_RESPONSE = "ClientMetadataInvalidResponse"
        CLIENT_METADATA_INVALID_CONTENT_TYPE = "ClientMetadataInvalidContentType"
        IDP_NOT_POTENTIALLY_TRUSTWORTHY = "IdpNotPotentiallyTrustworthy"
        DISABLED_IN_SETTINGS = "DisabledInSettings"
        DISABLED_IN_FLAGS = "DisabledInFlags"
        ERROR_FETCHING_SIGNIN = "ErrorFetchingSignin"
        INVALID_SIGNIN_RESPONSE = "InvalidSigninResponse"
        ACCOUNTS_HTTP_NOT_FOUND = "AccountsHttpNotFound"
        ACCOUNTS_NO_RESPONSE = "AccountsNoResponse"
        ACCOUNTS_INVALID_RESPONSE = "AccountsInvalidResponse"
        ACCOUNTS_LIST_EMPTY = "AccountsListEmpty"
        ACCOUNTS_INVALID_CONTENT_TYPE = "AccountsInvalidContentType"
        ID_TOKEN_HTTP_NOT_FOUND = "IdTokenHttpNotFound"
        ID_TOKEN_NO_RESPONSE = "IdTokenNoResponse"
        ID_TOKEN_INVALID_RESPONSE = "IdTokenInvalidResponse"
        ID_TOKEN_IDP_ERROR_RESPONSE = "IdTokenIdpErrorResponse"
        ID_TOKEN_CROSS_SITE_IDP_ERROR_RESPONSE = "IdTokenCrossSiteIdpErrorResponse"
        ID_TOKEN_INVALID_REQUEST = "IdTokenInvalidRequest"
        ID_TOKEN_INVALID_CONTENT_TYPE = "IdTokenInvalidContentType"
        ERROR_ID_TOKEN = "ErrorIdToken"
        CANCELED = "Canceled"
        RP_PAGE_NOT_VISIBLE = "RpPageNotVisible"
        SILENT_MEDIATION_FAILURE = "SilentMediationFailure"
        THIRD_PARTY_COOKIES_BLOCKED = "ThirdPartyCookiesBlocked"
        NOT_SIGNED_IN_WITH_IDP = "NotSignedInWithIdp"
        MISSING_TRANSIENT_USER_ACTIVATION = "MissingTransientUserActivation"
        REPLACED_BY_ACTIVE_MODE = "ReplacedByActiveMode"
        INVALID_FIELDS_SPECIFIED = "InvalidFieldsSpecified"
        RELYING_PARTY_ORIGIN_IS_OPAQUE = "RelyingPartyOriginIsOpaque"
        TYPE_NOT_MATCHING = "TypeNotMatching"
        UI_DISMISSED_NO_EMBARGO = "UiDismissedNoEmbargo"
        CORS_ERROR = "CorsError"
        SUPPRESSED_BY_SEGMENTATION_PLATFORM = "SuppressedBySegmentationPlatform"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class FederatedAuthUserInfoRequestIssueDetails:
        federated_auth_user_info_request_issue_reason: FederatedAuthUserInfoRequestIssueReason

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['federatedAuthUserInfoRequestIssueReason'] = self.federated_auth_user_info_request_issue_reason.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> FederatedAuthUserInfoRequestIssueDetails:
            return cls(
                federated_auth_user_info_request_issue_reason=FederatedAuthUserInfoRequestIssueReason.from_json(json['federatedAuthUserInfoRequestIssueReason']),
            )

    class FederatedAuthUserInfoRequestIssueReason(enum.Enum):
        '''
        Represents the failure reason when a getUserInfo() call fails.
        Should be updated alongside FederatedAuthUserInfoRequestResult in
        third_party/blink/public/mojom/devtools/inspector_issue.mojom.
        '''
        NOT_SAME_ORIGIN = "NotSameOrigin"
        NOT_IFRAME = "NotIframe"
        NOT_POTENTIALLY_TRUSTWORTHY = "NotPotentiallyTrustworthy"
        NO_API_PERMISSION = "NoApiPermission"
        NOT_SIGNED_IN_WITH_IDP = "NotSignedInWithIdp"
        NO_ACCOUNT_SHARING_PERMISSION = "NoAccountSharingPermission"
        INVALID_CONFIG_OR_WELL_KNOWN = "InvalidConfigOrWellKnown"
        INVALID_ACCOUNTS_RESPONSE = "InvalidAccountsResponse"
        NO_RETURNING_USER_FROM_FETCHED_ACCOUNTS = "NoReturningUserFromFetchedAccounts"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class ClientHintIssueDetails:
        '''
        This issue tracks client hints related issues. It's used to deprecate old
        features, encourage the use of new ones, and provide general guidance.
        '''
        source_code_location: SourceCodeLocation

        client_hint_issue_reason: ClientHintIssueReason

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['sourceCodeLocation'] = self.source_code_location.to_json()
            json['clientHintIssueReason'] = self.client_hint_issue_reason.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> ClientHintIssueDetails:
            return cls(
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
                client_hint_issue_reason=ClientHintIssueReason.from_json(json['clientHintIssueReason']),
            )

    @dataclass
    class FailedRequestInfo:
        #: The URL that failed to load.
        url: str

        #: The failure message for the failed request.
        failure_message: str

        request_id: typing.Optional[network.RequestId] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['url'] = self.url
            json['failureMessage'] = self.failure_message
            if self.request_id is not None:
                json['requestId'] = self.request_id.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> FailedRequestInfo:
            return cls(
                url=str(json['url']),
                failure_message=str(json['failureMessage']),
                request_id=network.RequestId.from_json(json['requestId']) if json.get('requestId', None) is not None else None,
            )

    class PartitioningBlobURLInfo(enum.Enum):
        BLOCKED_CROSS_PARTITION_FETCHING = "BlockedCrossPartitionFetching"
        ENFORCE_NOOPENER_FOR_NAVIGATION = "EnforceNoopenerForNavigation"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class PartitioningBlobURLIssueDetails:
        #: The BlobURL that failed to load.
        url: str

        #: Additional information about the Partitioning Blob URL issue.
        partitioning_blob_url_info: PartitioningBlobURLInfo

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['url'] = self.url
            json['partitioningBlobURLInfo'] = self.partitioning_blob_url_info.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> PartitioningBlobURLIssueDetails:
            return cls(
                url=str(json['url']),
                partitioning_blob_url_info=PartitioningBlobURLInfo.from_json(json['partitioningBlobURLInfo']),
            )

    class ElementAccessibilityIssueReason(enum.Enum):
        DISALLOWED_SELECT_CHILD = "DisallowedSelectChild"
        DISALLOWED_OPT_GROUP_CHILD = "DisallowedOptGroupChild"
        NON_PHRASING_CONTENT_OPTION_CHILD = "NonPhrasingContentOptionChild"
        INTERACTIVE_CONTENT_OPTION_CHILD = "InteractiveContentOptionChild"
        INTERACTIVE_CONTENT_LEGEND_CHILD = "InteractiveContentLegendChild"
        INTERACTIVE_CONTENT_SUMMARY_DESCENDANT = "InteractiveContentSummaryDescendant"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class ElementAccessibilityIssueDetails:
        '''
        This issue warns about errors in the select or summary element content model.
        '''
        node_id: dom.BackendNodeId

        element_accessibility_issue_reason: ElementAccessibilityIssueReason

        has_disallowed_attributes: bool

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['nodeId'] = self.node_id.to_json()
            json['elementAccessibilityIssueReason'] = self.element_accessibility_issue_reason.to_json()
            json['hasDisallowedAttributes'] = self.has_disallowed_attributes
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> ElementAccessibilityIssueDetails:
            return cls(
                node_id=dom.BackendNodeId.from_json(json['nodeId']),
                element_accessibility_issue_reason=ElementAccessibilityIssueReason.from_json(json['elementAccessibilityIssueReason']),
                has_disallowed_attributes=bool(json['hasDisallowedAttributes']),
            )

    class StyleSheetLoadingIssueReason(enum.Enum):
        LATE_IMPORT_RULE = "LateImportRule"
        REQUEST_FAILED = "RequestFailed"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class StylesheetLoadingIssueDetails:
        '''
        This issue warns when a referenced stylesheet couldn't be loaded.
        '''
        #: Source code position that referenced the failing stylesheet.
        source_code_location: SourceCodeLocation

        #: Reason why the stylesheet couldn't be loaded.
        style_sheet_loading_issue_reason: StyleSheetLoadingIssueReason

        #: Contains additional info when the failure was due to a request.
        failed_request_info: typing.Optional[FailedRequestInfo] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['sourceCodeLocation'] = self.source_code_location.to_json()
            json['styleSheetLoadingIssueReason'] = self.style_sheet_loading_issue_reason.to_json()
            if self.failed_request_info is not None:
                json['failedRequestInfo'] = self.failed_request_info.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> StylesheetLoadingIssueDetails:
            return cls(
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
                style_sheet_loading_issue_reason=StyleSheetLoadingIssueReason.from_json(json['styleSheetLoadingIssueReason']),
                failed_request_info=FailedRequestInfo.from_json(json['failedRequestInfo']) if json.get('failedRequestInfo', None) is not None else None,
            )

    class PropertyRuleIssueReason(enum.Enum):
        INVALID_SYNTAX = "InvalidSyntax"
        INVALID_INITIAL_VALUE = "InvalidInitialValue"
        INVALID_INHERITS = "InvalidInherits"
        INVALID_NAME = "InvalidName"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class PropertyRuleIssueDetails:
        '''
        This issue warns about errors in property rules that lead to property
        registrations being ignored.
        '''
        #: Source code position of the property rule.
        source_code_location: SourceCodeLocation

        #: Reason why the property rule was discarded.
        property_rule_issue_reason: PropertyRuleIssueReason

        #: The value of the property rule property that failed to parse
        property_value: typing.Optional[str] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['sourceCodeLocation'] = self.source_code_location.to_json()
            json['propertyRuleIssueReason'] = self.property_rule_issue_reason.to_json()
            if self.property_value is not None:
                json['propertyValue'] = self.property_value
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> PropertyRuleIssueDetails:
            return cls(
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
                property_rule_issue_reason=PropertyRuleIssueReason.from_json(json['propertyRuleIssueReason']),
                property_value=str(json['propertyValue']) if json.get('propertyValue', None) is not None else None,
            )

    class UserReidentificationIssueType(enum.Enum):
        BLOCKED_FRAME_NAVIGATION = "BlockedFrameNavigation"
        BLOCKED_SUBRESOURCE = "BlockedSubresource"
        NOISED_CANVAS_READBACK = "NoisedCanvasReadback"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class UserReidentificationIssueDetails:
        '''
        This issue warns about uses of APIs that may be considered misuse to
        re-identify users.
        '''
        type_: UserReidentificationIssueType

        #: Applies to BlockedFrameNavigation and BlockedSubresource issue types.
        request: typing.Optional[AffectedRequest] = None

        #: Applies to NoisedCanvasReadback issue type.
        source_code_location: typing.Optional[SourceCodeLocation] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['type'] = self.type_.to_json()
            if self.request is not None:
                json['request'] = self.request.to_json()
            if self.source_code_location is not None:
                json['sourceCodeLocation'] = self.source_code_location.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> UserReidentificationIssueDetails:
            return cls(
                type_=UserReidentificationIssueType.from_json(json['type']),
                request=AffectedRequest.from_json(json['request']) if json.get('request', None) is not None else None,
                source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']) if json.get('sourceCodeLocation', None) is not None else None,
            )

    class InspectorIssueCode(enum.Enum):
        '''
        A unique identifier for the type of issue. Each type may use one of the
        optional fields in InspectorIssueDetails to convey more specific
        information about the kind of issue.
        '''
        COOKIE_ISSUE = "CookieIssue"
        MIXED_CONTENT_ISSUE = "MixedContentIssue"
        BLOCKED_BY_RESPONSE_ISSUE = "BlockedByResponseIssue"
        HEAVY_AD_ISSUE = "HeavyAdIssue"
        CONTENT_SECURITY_POLICY_ISSUE = "ContentSecurityPolicyIssue"
        SHARED_ARRAY_BUFFER_ISSUE = "SharedArrayBufferIssue"
        LOW_TEXT_CONTRAST_ISSUE = "LowTextContrastIssue"
        CORS_ISSUE = "CorsIssue"
        ATTRIBUTION_REPORTING_ISSUE = "AttributionReportingIssue"
        QUIRKS_MODE_ISSUE = "QuirksModeIssue"
        PARTITIONING_BLOB_URL_ISSUE = "PartitioningBlobURLIssue"
        NAVIGATOR_USER_AGENT_ISSUE = "NavigatorUserAgentIssue"
        GENERIC_ISSUE = "GenericIssue"
        DEPRECATION_ISSUE = "DeprecationIssue"
        CLIENT_HINT_ISSUE = "ClientHintIssue"
        FEDERATED_AUTH_REQUEST_ISSUE = "FederatedAuthRequestIssue"
        BOUNCE_TRACKING_ISSUE = "BounceTrackingIssue"
        COOKIE_DEPRECATION_METADATA_ISSUE = "CookieDeprecationMetadataIssue"
        STYLESHEET_LOADING_ISSUE = "StylesheetLoadingIssue"
        FEDERATED_AUTH_USER_INFO_REQUEST_ISSUE = "FederatedAuthUserInfoRequestIssue"
        PROPERTY_RULE_ISSUE = "PropertyRuleIssue"
        SHARED_DICTIONARY_ISSUE = "SharedDictionaryIssue"
        ELEMENT_ACCESSIBILITY_ISSUE = "ElementAccessibilityIssue"
        SRI_MESSAGE_SIGNATURE_ISSUE = "SRIMessageSignatureIssue"
        UNENCODED_DIGEST_ISSUE = "UnencodedDigestIssue"
        USER_REIDENTIFICATION_ISSUE = "UserReidentificationIssue"

        def to_json(self) -> str:
            return self.value

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

    @dataclass
    class InspectorIssueDetails:
        '''
        This struct holds a list of optional fields with additional information
        specific to the kind of issue. When adding a new issue code, please also
        add a new optional field to this type.
        '''
        cookie_issue_details: typing.Optional[CookieIssueDetails] = None

        mixed_content_issue_details: typing.Optional[MixedContentIssueDetails] = None

        blocked_by_response_issue_details: typing.Optional[BlockedByResponseIssueDetails] = None

        heavy_ad_issue_details: typing.Optional[HeavyAdIssueDetails] = None

        content_security_policy_issue_details: typing.Optional[ContentSecurityPolicyIssueDetails] = None

        shared_array_buffer_issue_details: typing.Optional[SharedArrayBufferIssueDetails] = None

        low_text_contrast_issue_details: typing.Optional[LowTextContrastIssueDetails] = None

        cors_issue_details: typing.Optional[CorsIssueDetails] = None

        attribution_reporting_issue_details: typing.Optional[AttributionReportingIssueDetails] = None

        quirks_mode_issue_details: typing.Optional[QuirksModeIssueDetails] = None

        partitioning_blob_url_issue_details: typing.Optional[PartitioningBlobURLIssueDetails] = None

        navigator_user_agent_issue_details: typing.Optional[NavigatorUserAgentIssueDetails] = None

        generic_issue_details: typing.Optional[GenericIssueDetails] = None

        deprecation_issue_details: typing.Optional[DeprecationIssueDetails] = None

        client_hint_issue_details: typing.Optional[ClientHintIssueDetails] = None

        federated_auth_request_issue_details: typing.Optional[FederatedAuthRequestIssueDetails] = None

        bounce_tracking_issue_details: typing.Optional[BounceTrackingIssueDetails] = None

        cookie_deprecation_metadata_issue_details: typing.Optional[CookieDeprecationMetadataIssueDetails] = None

        stylesheet_loading_issue_details: typing.Optional[StylesheetLoadingIssueDetails] = None

        property_rule_issue_details: typing.Optional[PropertyRuleIssueDetails] = None

        federated_auth_user_info_request_issue_details: typing.Optional[FederatedAuthUserInfoRequestIssueDetails] = None

        shared_dictionary_issue_details: typing.Optional[SharedDictionaryIssueDetails] = None

        element_accessibility_issue_details: typing.Optional[ElementAccessibilityIssueDetails] = None

        sri_message_signature_issue_details: typing.Optional[SRIMessageSignatureIssueDetails] = None

        unencoded_digest_issue_details: typing.Optional[UnencodedDigestIssueDetails] = None

        user_reidentification_issue_details: typing.Optional[UserReidentificationIssueDetails] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            if self.cookie_issue_details is not None:
                json['cookieIssueDetails'] = self.cookie_issue_details.to_json()
            if self.mixed_content_issue_details is not None:
                json['mixedContentIssueDetails'] = self.mixed_content_issue_details.to_json()
            if self.blocked_by_response_issue_details is not None:
                json['blockedByResponseIssueDetails'] = self.blocked_by_response_issue_details.to_json()
            if self.heavy_ad_issue_details is not None:
                json['heavyAdIssueDetails'] = self.heavy_ad_issue_details.to_json()
            if self.content_security_policy_issue_details is not None:
                json['contentSecurityPolicyIssueDetails'] = self.content_security_policy_issue_details.to_json()
            if self.shared_array_buffer_issue_details is not None:
                json['sharedArrayBufferIssueDetails'] = self.shared_array_buffer_issue_details.to_json()
            if self.low_text_contrast_issue_details is not None:
                json['lowTextContrastIssueDetails'] = self.low_text_contrast_issue_details.to_json()
            if self.cors_issue_details is not None:
                json['corsIssueDetails'] = self.cors_issue_details.to_json()
            if self.attribution_reporting_issue_details is not None:
                json['attributionReportingIssueDetails'] = self.attribution_reporting_issue_details.to_json()
            if self.quirks_mode_issue_details is not None:
                json['quirksModeIssueDetails'] = self.quirks_mode_issue_details.to_json()
            if self.partitioning_blob_url_issue_details is not None:
                json['partitioningBlobURLIssueDetails'] = self.partitioning_blob_url_issue_details.to_json()
            if self.navigator_user_agent_issue_details is not None:
                json['navigatorUserAgentIssueDetails'] = self.navigator_user_agent_issue_details.to_json()
            if self.generic_issue_details is not None:
                json['genericIssueDetails'] = self.generic_issue_details.to_json()
            if self.deprecation_issue_details is not None:
                json['deprecationIssueDetails'] = self.deprecation_issue_details.to_json()
            if self.client_hint_issue_details is not None:
                json['clientHintIssueDetails'] = self.client_hint_issue_details.to_json()
            if self.federated_auth_request_issue_details is not None:
                json['federatedAuthRequestIssueDetails'] = self.federated_auth_request_issue_details.to_json()
            if self.bounce_tracking_issue_details is not None:
                json['bounceTrackingIssueDetails'] = self.bounce_tracking_issue_details.to_json()
            if self.cookie_deprecation_metadata_issue_details is not None:
                json['cookieDeprecationMetadataIssueDetails'] = self.cookie_deprecation_metadata_issue_details.to_json()
            if self.stylesheet_loading_issue_details is not None:
                json['stylesheetLoadingIssueDetails'] = self.stylesheet_loading_issue_details.to_json()
            if self.property_rule_issue_details is not None:
                json['propertyRuleIssueDetails'] = self.property_rule_issue_details.to_json()
            if self.federated_auth_user_info_request_issue_details is not None:
                json['federatedAuthUserInfoRequestIssueDetails'] = self.federated_auth_user_info_request_issue_details.to_json()
            if self.shared_dictionary_issue_details is not None:
                json['sharedDictionaryIssueDetails'] = self.shared_dictionary_issue_details.to_json()
            if self.element_accessibility_issue_details is not None:
                json['elementAccessibilityIssueDetails'] = self.element_accessibility_issue_details.to_json()
            if self.sri_message_signature_issue_details is not None:
                json['sriMessageSignatureIssueDetails'] = self.sri_message_signature_issue_details.to_json()
            if self.unencoded_digest_issue_details is not None:
                json['unencodedDigestIssueDetails'] = self.unencoded_digest_issue_details.to_json()
            if self.user_reidentification_issue_details is not None:
                json['userReidentificationIssueDetails'] = self.user_reidentification_issue_details.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> InspectorIssueDetails:
            return cls(
                cookie_issue_details=CookieIssueDetails.from_json(json['cookieIssueDetails']) if json.get('cookieIssueDetails', None) is not None else None,
                mixed_content_issue_details=MixedContentIssueDetails.from_json(json['mixedContentIssueDetails']) if json.get('mixedContentIssueDetails', None) is not None else None,
                blocked_by_response_issue_details=BlockedByResponseIssueDetails.from_json(json['blockedByResponseIssueDetails']) if json.get('blockedByResponseIssueDetails', None) is not None else None,
                heavy_ad_issue_details=HeavyAdIssueDetails.from_json(json['heavyAdIssueDetails']) if json.get('heavyAdIssueDetails', None) is not None else None,
                content_security_policy_issue_details=ContentSecurityPolicyIssueDetails.from_json(json['contentSecurityPolicyIssueDetails']) if json.get('contentSecurityPolicyIssueDetails', None) is not None else None,
                shared_array_buffer_issue_details=SharedArrayBufferIssueDetails.from_json(json['sharedArrayBufferIssueDetails']) if json.get('sharedArrayBufferIssueDetails', None) is not None else None,
                low_text_contrast_issue_details=LowTextContrastIssueDetails.from_json(json['lowTextContrastIssueDetails']) if json.get('lowTextContrastIssueDetails', None) is not None else None,
                cors_issue_details=CorsIssueDetails.from_json(json['corsIssueDetails']) if json.get('corsIssueDetails', None) is not None else None,
                attribution_reporting_issue_details=AttributionReportingIssueDetails.from_json(json['attributionReportingIssueDetails']) if json.get('attributionReportingIssueDetails', None) is not None else None,
                quirks_mode_issue_details=QuirksModeIssueDetails.from_json(json['quirksModeIssueDetails']) if json.get('quirksModeIssueDetails', None) is not None else None,
                partitioning_blob_url_issue_details=PartitioningBlobURLIssueDetails.from_json(json['partitioningBlobURLIssueDetails']) if json.get('partitioningBlobURLIssueDetails', None) is not None else None,
                navigator_user_agent_issue_details=NavigatorUserAgentIssueDetails.from_json(json['navigatorUserAgentIssueDetails']) if json.get('navigatorUserAgentIssueDetails', None) is not None else None,
                generic_issue_details=GenericIssueDetails.from_json(json['genericIssueDetails']) if json.get('genericIssueDetails', None) is not None else None,
                deprecation_issue_details=DeprecationIssueDetails.from_json(json['deprecationIssueDetails']) if json.get('deprecationIssueDetails', None) is not None else None,
                client_hint_issue_details=ClientHintIssueDetails.from_json(json['clientHintIssueDetails']) if json.get('clientHintIssueDetails', None) is not None else None,
                federated_auth_request_issue_details=FederatedAuthRequestIssueDetails.from_json(json['federatedAuthRequestIssueDetails']) if json.get('federatedAuthRequestIssueDetails', None) is not None else None,
                bounce_tracking_issue_details=BounceTrackingIssueDetails.from_json(json['bounceTrackingIssueDetails']) if json.get('bounceTrackingIssueDetails', None) is not None else None,
                cookie_deprecation_metadata_issue_details=CookieDeprecationMetadataIssueDetails.from_json(json['cookieDeprecationMetadataIssueDetails']) if json.get('cookieDeprecationMetadataIssueDetails', None) is not None else None,
                stylesheet_loading_issue_details=StylesheetLoadingIssueDetails.from_json(json['stylesheetLoadingIssueDetails']) if json.get('stylesheetLoadingIssueDetails', None) is not None else None,
                property_rule_issue_details=PropertyRuleIssueDetails.from_json(json['propertyRuleIssueDetails']) if json.get('propertyRuleIssueDetails', None) is not None else None,
                federated_auth_user_info_request_issue_details=FederatedAuthUserInfoRequestIssueDetails.from_json(json['federatedAuthUserInfoRequestIssueDetails']) if json.get('federatedAuthUserInfoRequestIssueDetails', None) is not None else None,
                shared_dictionary_issue_details=SharedDictionaryIssueDetails.from_json(json['sharedDictionaryIssueDetails']) if json.get('sharedDictionaryIssueDetails', None) is not None else None,
                element_accessibility_issue_details=ElementAccessibilityIssueDetails.from_json(json['elementAccessibilityIssueDetails']) if json.get('elementAccessibilityIssueDetails', None) is not None else None,
                sri_message_signature_issue_details=SRIMessageSignatureIssueDetails.from_json(json['sriMessageSignatureIssueDetails']) if json.get('sriMessageSignatureIssueDetails', None) is not None else None,
                unencoded_digest_issue_details=UnencodedDigestIssueDetails.from_json(json['unencodedDigestIssueDetails']) if json.get('unencodedDigestIssueDetails', None) is not None else None,
                user_reidentification_issue_details=UserReidentificationIssueDetails.from_json(json['userReidentificationIssueDetails']) if json.get('userReidentificationIssueDetails', None) is not None else None,
            )

    class IssueId(str):
        '''
        A unique id for a DevTools inspector issue. Allows other entities (e.g.
        exceptions, CDP message, console messages, etc.) to reference an issue.
        '''
        def to_json(self) -> str:
            return self

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

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

    @dataclass
    class InspectorIssue:
        '''
        An inspector issue reported from the back-end.
        '''
        code: InspectorIssueCode

        details: InspectorIssueDetails

        #: A unique id for this issue. May be omitted if no other entity (e.g.
        #: exception, CDP message, etc.) is referencing this issue.
        issue_id: typing.Optional[IssueId] = None

        def to_json(self) -> T_JSON_DICT:
            json: T_JSON_DICT = dict()
            json['code'] = self.code.to_json()
            json['details'] = self.details.to_json()
            if self.issue_id is not None:
                json['issueId'] = self.issue_id.to_json()
            return json

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> InspectorIssue:
            return cls(
                code=InspectorIssueCode.from_json(json['code']),
                details=InspectorIssueDetails.from_json(json['details']),
                issue_id=IssueId.from_json(json['issueId']) if json.get('issueId', None) is not None else None,
            )

    def get_encoded_response(
            request_id: network.RequestId,
            encoding: str,
            quality: typing.Optional[float] = None,
            size_only: typing.Optional[bool] = None
        ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[typing.Optional[str], int, int]]:
        '''
        Returns the response body and size if it were re-encoded with the specified settings. Only
        applies to images.

        :param request_id: Identifier of the network request to get content for.
        :param encoding: The encoding to use.
        :param quality: *(Optional)* The quality of the encoding (0-1). (defaults to 1)
        :param size_only: *(Optional)* Whether to only return the size information (defaults to false).
        :returns: A tuple with the following items:

            0. **body** - *(Optional)* The encoded body as a base64 string. Omitted if sizeOnly is true. (Encoded as a base64 string when passed over JSON)
            1. **originalSize** - Size before re-encoding.
            2. **encodedSize** - Size after re-encoding.
        '''
        params: T_JSON_DICT = dict()
        params['requestId'] = request_id.to_json()
        params['encoding'] = encoding
        if quality is not None:
            params['quality'] = quality
        if size_only is not None:
            params['sizeOnly'] = size_only
        cmd_dict: T_JSON_DICT = {
            'method': 'Audits.getEncodedResponse',
            'params': params,
        }
        json = yield cmd_dict
        return (
            str(json['body']) if json.get('body', None) is not None else None,
            int(json['originalSize']),
            int(json['encodedSize'])
        )

    def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
        '''
        Disables issues domain, prevents further issues from being reported to the client.
        '''
        cmd_dict: T_JSON_DICT = {
            'method': 'Audits.disable',
        }
        json = yield cmd_dict

    def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
        '''
        Enables issues domain, sends the issues collected so far to the client by means of the
        ``issueAdded`` event.
        '''
        cmd_dict: T_JSON_DICT = {
            'method': 'Audits.enable',
        }
        json = yield cmd_dict

    def check_contrast(
            report_aaa: typing.Optional[bool] = None
        ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
        '''
        Runs the contrast check for the target page. Found issues are reported
        using Audits.issueAdded event.

        :param report_aaa: *(Optional)* Whether to report WCAG AAA level issues. Default is false.
        '''
        params: T_JSON_DICT = dict()
        if report_aaa is not None:
            params['reportAAA'] = report_aaa
        cmd_dict: T_JSON_DICT = {
            'method': 'Audits.checkContrast',
            'params': params,
        }
        json = yield cmd_dict

    def check_forms_issues() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[GenericIssueDetails]]:
        '''
        Runs the form issues check for the target page. Found issues are reported
        using Audits.issueAdded event.

        :returns:
        '''
        cmd_dict: T_JSON_DICT = {
            'method': 'Audits.checkFormsIssues',
        }
        json = yield cmd_dict
        return [GenericIssueDetails.from_json(i) for i in json['formIssues']]

    @event_class('Audits.issueAdded')
    @dataclass
    class IssueAdded:
        issue: InspectorIssue

        @classmethod
        def from_json(cls, json: T_JSON_DICT) -> IssueAdded:
            return cls(
                issue=InspectorIssue.from_json(json['issue'])
            )