# 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."""
    #: The unique request id.
    request_id: typing.Optional[network.RequestId] = None
    url: typing.Optional[str] = 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_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 PerformanceIssueType(enum.Enum):
    DOCUMENT_COOKIE = "DocumentCookie"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> PerformanceIssueType:
        return cls(json)


@dataclass
class PerformanceIssueDetails:
    """Details for a performance issue."""
    performance_issue_type: PerformanceIssueType
    source_code_location: typing.Optional[SourceCodeLocation] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["performanceIssueType"] = self.performance_issue_type.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) -> PerformanceIssueDetails:
        return cls(
            performance_issue_type=PerformanceIssueType.from_json(
                json["performanceIssueType"]
            ),
            source_code_location=SourceCodeLocation.from_json(
                json["sourceCodeLocation"]
            )
            if json.get("sourceCodeLocation", 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(  # NOQA
                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 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_INVALID_TTL_FIELD = "WriteErrorInvalidTTLField"
    WRITE_ERROR_NAVIGATION_REQUEST = "WriteErrorNavigationRequest"
    WRITE_ERROR_NO_MATCH_FIELD = "WriteErrorNoMatchField"
    WRITE_ERROR_NON_INTEGER_TTL_FIELD = "WriteErrorNonIntegerTTLField"
    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)


class ConnectionAllowlistError(enum.Enum):
    INVALID_HEADER = "InvalidHeader"
    MORE_THAN_ONE_LIST = "MoreThanOneList"
    ITEM_NOT_INNER_LIST = "ItemNotInnerList"
    INVALID_ALLOWLIST_ITEM_TYPE = "InvalidAllowlistItemType"
    REPORTING_ENDPOINT_NOT_TOKEN = "ReportingEndpointNotToken"
    INVALID_URL_PATTERN = "InvalidUrlPattern"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> ConnectionAllowlistError:
        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"]),
        )


@dataclass
class ConnectionAllowlistIssueDetails:
    error: ConnectionAllowlistError
    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) -> ConnectionAllowlistIssueDetails:
        return cls(
            error=ConnectionAllowlistError.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_ERROR = (
        "FormAriaLabelledByToNonExistingIdError"
    )
    FORM_INPUT_ASSIGNED_AUTOCOMPLETE_VALUE_TO_ID_OR_NAME_ATTRIBUTE_ERROR = (
        "FormInputAssignedAutocompleteValueToIdOrNameAttributeError"
    )
    FORM_LABEL_HAS_NEITHER_FOR_NOR_NESTED_INPUT_ERROR = (
        "FormLabelHasNeitherForNorNestedInputError"
    )
    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"
    NAVIGATION_ENTRY_MARKED_SKIPPABLE = "NavigationEntryMarkedSkippable"
    AUTOFILL_AND_MANUAL_TEXT_POLICY_CONTROLLED_FEATURES_INFO = (
        "AutofillAndManualTextPolicyControlledFeaturesInfo"
    )
    AUTOFILL_POLICY_CONTROLLED_FEATURE_INFO = (
        "AutofillPolicyControlledFeatureInfo"
    )
    MANUAL_TEXT_POLICY_CONTROLLED_FEATURE_INFO = (
        "ManualTextPolicyControlledFeatureInfo"
    )
    FORM_MODEL_CONTEXT_PARAMETER_MISSING_TITLE_AND_DESCRIPTION = (
        "FormModelContextParameterMissingTitleAndDescription"
    )

    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(  # NOQA
                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"
    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"
    NOT_SIGNED_IN_WITH_IDP = "NotSignedInWithIdp"
    MISSING_TRANSIENT_USER_ACTIVATION = "MissingTransientUserActivation"
    REPLACED_BY_ACTIVE_MODE = "ReplacedByActiveMode"
    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(  # NOQA
                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 PermissionElementIssueType(enum.Enum):
    INVALID_TYPE = "InvalidType"
    FENCED_FRAME_DISALLOWED = "FencedFrameDisallowed"
    CSP_FRAME_ANCESTORS_MISSING = "CspFrameAncestorsMissing"
    PERMISSIONS_POLICY_BLOCKED = "PermissionsPolicyBlocked"
    PADDING_RIGHT_UNSUPPORTED = "PaddingRightUnsupported"
    PADDING_BOTTOM_UNSUPPORTED = "PaddingBottomUnsupported"
    INSET_BOX_SHADOW_UNSUPPORTED = "InsetBoxShadowUnsupported"
    REQUEST_IN_PROGRESS = "RequestInProgress"
    UNTRUSTED_EVENT = "UntrustedEvent"
    REGISTRATION_FAILED = "RegistrationFailed"
    TYPE_NOT_SUPPORTED = "TypeNotSupported"
    INVALID_TYPE_ACTIVATION = "InvalidTypeActivation"
    SECURITY_CHECKS_FAILED = "SecurityChecksFailed"
    ACTIVATION_DISABLED = "ActivationDisabled"
    GEOLOCATION_DEPRECATED = "GeolocationDeprecated"
    INVALID_DISPLAY_STYLE = "InvalidDisplayStyle"
    NON_OPAQUE_COLOR = "NonOpaqueColor"
    LOW_CONTRAST = "LowContrast"
    FONT_SIZE_TOO_SMALL = "FontSizeTooSmall"
    FONT_SIZE_TOO_LARGE = "FontSizeTooLarge"
    INVALID_SIZE_VALUE = "InvalidSizeValue"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> PermissionElementIssueType:
        return cls(json)


@dataclass
class PermissionElementIssueDetails:
    """This issue warns about improper usage of the <permission> element."""
    issue_type: PermissionElementIssueType
    #: The value of the type attribute.
    type_: typing.Optional[str] = None
    #: The node ID of the <permission> element.
    node_id: typing.Optional[dom.BackendNodeId] = None
    #: True if the issue is a warning, false if it is an error.
    is_warning: typing.Optional[bool] = None
    #: Fields for message construction:
    #: Used for messages that reference a specific permission name
    permission_name: typing.Optional[str] = None
    #: Used for messages about occlusion
    occluder_node_info: typing.Optional[str] = None
    #: Used for messages about occluder's parent
    occluder_parent_node_info: typing.Optional[str] = None
    #: Used for messages about activation disabled reason
    disable_reason: typing.Optional[str] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["issueType"] = self.issue_type.to_json()
        if self.type_ is not None:
            json["type"] = self.type_
        if self.node_id is not None:
            json["nodeId"] = self.node_id.to_json()
        if self.is_warning is not None:
            json["isWarning"] = self.is_warning
        if self.permission_name is not None:
            json["permissionName"] = self.permission_name
        if self.occluder_node_info is not None:
            json["occluderNodeInfo"] = self.occluder_node_info
        if self.occluder_parent_node_info is not None:
            json["occluderParentNodeInfo"] = self.occluder_parent_node_info
        if self.disable_reason is not None:
            json["disableReason"] = self.disable_reason
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> PermissionElementIssueDetails:
        return cls(
            issue_type=PermissionElementIssueType.from_json(json["issueType"]),
            type_=str(json["type"])
            if json.get("type", None) is not None
            else None,
            node_id=dom.BackendNodeId.from_json(json["nodeId"])
            if json.get("nodeId", None) is not None
            else None,
            is_warning=bool(json["isWarning"])
            if json.get("isWarning", None) is not None
            else None,
            permission_name=str(json["permissionName"])
            if json.get("permissionName", None) is not None
            else None,
            occluder_node_info=str(json["occluderNodeInfo"])
            if json.get("occluderNodeInfo", None) is not None
            else None,
            occluder_parent_node_info=str(json["occluderParentNodeInfo"])
            if json.get("occluderParentNodeInfo", None) is not None
            else None,
            disable_reason=str(json["disableReason"])
            if json.get("disableReason", None) is not None
            else None,
        )


@dataclass
class SelectivePermissionsInterventionIssueDetails:
    """
    The issue warns about blocked calls to privacy sensitive APIs
    via the Selective Permissions Intervention.
    """
    #: Which API was intervened on.
    api_name: str
    #: Why the ad script using the API is considered an ad.
    ad_ancestry: network.AdAncestry
    #: The stack trace at the time of the intervention.
    stack_trace: typing.Optional[runtime.StackTrace] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["apiName"] = self.api_name
        json["adAncestry"] = self.ad_ancestry.to_json()
        if self.stack_trace is not None:
            json["stackTrace"] = self.stack_trace.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> SelectivePermissionsInterventionIssueDetails:
        return cls(
            api_name=str(json["apiName"]),
            ad_ancestry=network.AdAncestry.from_json(json["adAncestry"]),
            stack_trace=runtime.StackTrace.from_json(json["stackTrace"])
            if json.get("stackTrace", 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"
    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"
    CONNECTION_ALLOWLIST_ISSUE = "ConnectionAllowlistIssue"
    USER_REIDENTIFICATION_ISSUE = "UserReidentificationIssue"
    PERMISSION_ELEMENT_ISSUE = "PermissionElementIssue"
    PERFORMANCE_ISSUE = "PerformanceIssue"
    SELECTIVE_PERMISSIONS_INTERVENTION_ISSUE = (
        "SelectivePermissionsInterventionIssue"
    )

    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
    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
    connection_allowlist_issue_details: typing.Optional[
        ConnectionAllowlistIssueDetails
    ] = None
    user_reidentification_issue_details: typing.Optional[
        UserReidentificationIssueDetails
    ] = None
    permission_element_issue_details: typing.Optional[
        PermissionElementIssueDetails
    ] = None
    performance_issue_details: typing.Optional[PerformanceIssueDetails] = None
    selective_permissions_intervention_issue_details: typing.Optional[
        SelectivePermissionsInterventionIssueDetails
    ] = 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.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.connection_allowlist_issue_details is not None:
            json["connectionAllowlistIssueDetails"] = (
                self.connection_allowlist_issue_details.to_json()
            )
        if self.user_reidentification_issue_details is not None:
            json["userReidentificationIssueDetails"] = (
                self.user_reidentification_issue_details.to_json()
            )
        if self.permission_element_issue_details is not None:
            json["permissionElementIssueDetails"] = (
                self.permission_element_issue_details.to_json()
            )
        if self.performance_issue_details is not None:
            json["performanceIssueDetails"] = (
                self.performance_issue_details.to_json()
            )
        if self.selective_permissions_intervention_issue_details is not None:
            json["selectivePermissionsInterventionIssueDetails"] = (
                self.selective_permissions_intervention_issue_details.to_json()
            )
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> InspectorIssueDetails:
        def get_detail(key, detail_cls):
            val = json.get(key)
            return detail_cls.from_json(val) if val is not None else None

        return cls(
            cookie_issue_details=get_detail(
                "cookieIssueDetails", CookieIssueDetails
            ),
            mixed_content_issue_details=get_detail(
                "mixedContentIssueDetails", MixedContentIssueDetails
            ),
            blocked_by_response_issue_details=get_detail(
                "blockedByResponseIssueDetails", BlockedByResponseIssueDetails
            ),
            heavy_ad_issue_details=get_detail(
                "heavyAdIssueDetails", HeavyAdIssueDetails
            ),
            content_security_policy_issue_details=get_detail(
                "contentSecurityPolicyIssueDetails",
                ContentSecurityPolicyIssueDetails,
            ),
            shared_array_buffer_issue_details=get_detail(
                "sharedArrayBufferIssueDetails", SharedArrayBufferIssueDetails
            ),
            cors_issue_details=get_detail(
                "corsIssueDetails", CorsIssueDetails
            ),
            attribution_reporting_issue_details=get_detail(
                "attributionReportingIssueDetails",
                AttributionReportingIssueDetails,
            ),
            quirks_mode_issue_details=get_detail(
                "quirksModeIssueDetails", QuirksModeIssueDetails
            ),
            partitioning_blob_url_issue_details=get_detail(
                "partitioningBlobURLIssueDetails",
                PartitioningBlobURLIssueDetails,
            ),
            navigator_user_agent_issue_details=get_detail(
                "navigatorUserAgentIssueDetails",
                NavigatorUserAgentIssueDetails,
            ),
            generic_issue_details=get_detail(
                "genericIssueDetails", GenericIssueDetails
            ),
            deprecation_issue_details=get_detail(
                "deprecationIssueDetails", DeprecationIssueDetails
            ),
            client_hint_issue_details=get_detail(
                "clientHintIssueDetails", ClientHintIssueDetails
            ),
            federated_auth_request_issue_details=get_detail(
                "federatedAuthRequestIssueDetails",
                FederatedAuthRequestIssueDetails,
            ),
            bounce_tracking_issue_details=get_detail(
                "bounceTrackingIssueDetails", BounceTrackingIssueDetails
            ),
            cookie_deprecation_metadata_issue_details=get_detail(
                "cookieDeprecationMetadataIssueDetails",
                CookieDeprecationMetadataIssueDetails,
            ),
            stylesheet_loading_issue_details=get_detail(
                "stylesheetLoadingIssueDetails", StylesheetLoadingIssueDetails
            ),
            property_rule_issue_details=get_detail(
                "propertyRuleIssueDetails", PropertyRuleIssueDetails
            ),
            federated_auth_user_info_request_issue_details=get_detail(
                "federatedAuthUserInfoRequestIssueDetails",
                FederatedAuthUserInfoRequestIssueDetails,
            ),
            shared_dictionary_issue_details=get_detail(
                "sharedDictionaryIssueDetails", SharedDictionaryIssueDetails
            ),
            element_accessibility_issue_details=get_detail(
                "elementAccessibilityIssueDetails",
                ElementAccessibilityIssueDetails,
            ),
            sri_message_signature_issue_details=get_detail(
                "sriMessageSignatureIssueDetails",
                SRIMessageSignatureIssueDetails,
            ),
            unencoded_digest_issue_details=get_detail(
                "unencodedDigestIssueDetails", UnencodedDigestIssueDetails
            ),
            connection_allowlist_issue_details=get_detail(
                "connectionAllowlistIssueDetails",
                ConnectionAllowlistIssueDetails,
            ),
            user_reidentification_issue_details=get_detail(
                "userReidentificationIssueDetails",
                UserReidentificationIssueDetails,
            ),
            permission_element_issue_details=get_detail(
                "permissionElementIssueDetails", PermissionElementIssueDetails
            ),
            performance_issue_details=get_detail(
                "performanceIssueDetails", PerformanceIssueDetails
            ),
            selective_permissions_intervention_issue_details=get_detail(
                "selectivePermissionsInterventionIssueDetails",
                SelectivePermissionsInterventionIssueDetails,
            ),
        )


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  # NOQA


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  # NOQA


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.
    """
    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"]))
