You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1277 lines
47 KiB
Python

# 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
from .util import event_class, T_JSON_DICT
from dataclasses import dataclass
import enum
import typing
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):
json = dict()
json['name'] = self.name
json['path'] = self.path
json['domain'] = self.domain
return json
@classmethod
def from_json(cls, json):
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: network.RequestId
url: typing.Optional[str] = None
def to_json(self):
json = dict()
json['requestId'] = self.request_id.to_json()
if self.url is not None:
json['url'] = self.url
return json
@classmethod
def from_json(cls, json):
return cls(
request_id=network.RequestId.from_json(json['requestId']),
url=str(json['url']) if 'url' in json else None,
)
@dataclass
class AffectedFrame:
'''
Information about the frame affected by an inspector issue.
'''
frame_id: page.FrameId
def to_json(self):
json = dict()
json['frameId'] = self.frame_id.to_json()
return json
@classmethod
def from_json(cls, json):
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"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
return cls(json)
class CookieOperation(enum.Enum):
SET_COOKIE = "SetCookie"
READ_COOKIE = "ReadCookie"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
return cls(json)
@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
def to_json(self):
json = 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()
return json
@classmethod
def from_json(cls, json):
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 'cookie' in json else None,
raw_cookie_line=str(json['rawCookieLine']) if 'rawCookieLine' in json else None,
site_for_cookies=str(json['siteForCookies']) if 'siteForCookies' in json else None,
cookie_url=str(json['cookieUrl']) if 'cookieUrl' in json else None,
request=AffectedRequest.from_json(json['request']) if 'request' in json else None,
)
class MixedContentResolutionStatus(enum.Enum):
MIXED_CONTENT_BLOCKED = "MixedContentBlocked"
MIXED_CONTENT_AUTOMATICALLY_UPGRADED = "MixedContentAutomaticallyUpgraded"
MIXED_CONTENT_WARNING = "MixedContentWarning"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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"
MANIFEST = "Manifest"
PING = "Ping"
PLUGIN_DATA = "PluginData"
PLUGIN_RESOURCE = "PluginResource"
PREFETCH = "Prefetch"
RESOURCE = "Resource"
SCRIPT = "Script"
SERVICE_WORKER = "ServiceWorker"
SHARED_WORKER = "SharedWorker"
STYLESHEET = "Stylesheet"
TRACK = "Track"
VIDEO = "Video"
WORKER = "Worker"
XML_HTTP_REQUEST = "XMLHttpRequest"
XSLT = "XSLT"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
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 'resourceType' in json else None,
request=AffectedRequest.from_json(json['request']) if 'request' in json else None,
frame=AffectedFrame.from_json(json['frame']) if 'frame' in json 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_SITE = "CorpNotSameSite"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
return cls(
request=AffectedRequest.from_json(json['request']),
reason=BlockedByResponseReason.from_json(json['reason']),
parent_frame=AffectedFrame.from_json(json['parentFrame']) if 'parentFrame' in json else None,
blocked_frame=AffectedFrame.from_json(json['blockedFrame']) if 'blockedFrame' in json else None,
)
class HeavyAdResolutionStatus(enum.Enum):
HEAVY_AD_BLOCKED = "HeavyAdBlocked"
HEAVY_AD_WARNING = "HeavyAdWarning"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
return cls(json)
class HeavyAdReason(enum.Enum):
NETWORK_TOTAL_LIMIT = "NetworkTotalLimit"
CPU_TOTAL_LIMIT = "CpuTotalLimit"
CPU_PEAK_LIMIT = "CpuPeakLimit"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
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_TRUSTED_TYPES_SINK_VIOLATION = "kTrustedTypesSinkViolation"
K_TRUSTED_TYPES_POLICY_VIOLATION = "kTrustedTypesPolicyViolation"
K_WASM_EVAL_VIOLATION = "kWasmEvalViolation"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
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 'scriptId' in json 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):
json = 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):
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 'blockedURL' in json else None,
frame_ancestor=AffectedFrame.from_json(json['frameAncestor']) if 'frameAncestor' in json else None,
source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']) if 'sourceCodeLocation' in json else None,
violating_node_id=dom.BackendNodeId.from_json(json['violatingNodeId']) if 'violatingNodeId' in json else None,
)
class SharedArrayBufferIssueType(enum.Enum):
TRANSFER_ISSUE = "TransferIssue"
CREATION_ISSUE = "CreationIssue"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
return cls(
source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
is_warning=bool(json['isWarning']),
type_=SharedArrayBufferIssueType.from_json(json['type']),
)
class TwaQualityEnforcementViolationType(enum.Enum):
K_HTTP_ERROR = "kHttpError"
K_UNAVAILABLE_OFFLINE = "kUnavailableOffline"
K_DIGITAL_ASSET_LINKS = "kDigitalAssetLinks"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
return cls(json)
@dataclass
class TrustedWebActivityIssueDetails:
#: The url that triggers the violation.
url: str
violation_type: TwaQualityEnforcementViolationType
http_status_code: typing.Optional[int] = None
#: The package name of the Trusted Web Activity client app. This field is
#: only used when violation type is kDigitalAssetLinks.
package_name: typing.Optional[str] = None
#: The signature of the Trusted Web Activity client app. This field is only
#: used when violation type is kDigitalAssetLinks.
signature: typing.Optional[str] = None
def to_json(self):
json = dict()
json['url'] = self.url
json['violationType'] = self.violation_type.to_json()
if self.http_status_code is not None:
json['httpStatusCode'] = self.http_status_code
if self.package_name is not None:
json['packageName'] = self.package_name
if self.signature is not None:
json['signature'] = self.signature
return json
@classmethod
def from_json(cls, json):
return cls(
url=str(json['url']),
violation_type=TwaQualityEnforcementViolationType.from_json(json['violationType']),
http_status_code=int(json['httpStatusCode']) if 'httpStatusCode' in json else None,
package_name=str(json['packageName']) if 'packageName' in json else None,
signature=str(json['signature']) if 'signature' in json else None,
)
@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):
json = 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):
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):
json = 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):
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 'location' in json else None,
initiator_origin=str(json['initiatorOrigin']) if 'initiatorOrigin' in json else None,
resource_ip_address_space=network.IPAddressSpace.from_json(json['resourceIPAddressSpace']) if 'resourceIPAddressSpace' in json else None,
client_security_state=network.ClientSecurityState.from_json(json['clientSecurityState']) if 'clientSecurityState' in json else None,
)
class AttributionReportingIssueType(enum.Enum):
PERMISSION_POLICY_DISABLED = "PermissionPolicyDisabled"
PERMISSION_POLICY_NOT_DELEGATED = "PermissionPolicyNotDelegated"
UNTRUSTWORTHY_REPORTING_ORIGIN = "UntrustworthyReportingOrigin"
INSECURE_CONTEXT = "InsecureContext"
INVALID_HEADER = "InvalidHeader"
INVALID_REGISTER_TRIGGER_HEADER = "InvalidRegisterTriggerHeader"
INVALID_ELIGIBLE_HEADER = "InvalidEligibleHeader"
TOO_MANY_CONCURRENT_REQUESTS = "TooManyConcurrentRequests"
SOURCE_AND_TRIGGER_HEADERS = "SourceAndTriggerHeaders"
SOURCE_IGNORED = "SourceIgnored"
TRIGGER_IGNORED = "TriggerIgnored"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
return cls(
violation_type=AttributionReportingIssueType.from_json(json['violationType']),
request=AffectedRequest.from_json(json['request']) if 'request' in json else None,
violating_node_id=dom.BackendNodeId.from_json(json['violatingNodeId']) if 'violatingNodeId' in json else None,
invalid_parameter=str(json['invalidParameter']) if 'invalidParameter' in json 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):
json = 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):
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):
json = 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):
return cls(
url=str(json['url']),
location=SourceCodeLocation.from_json(json['location']) if 'location' in json else None,
)
class GenericIssueErrorType(enum.Enum):
CROSS_ORIGIN_PORTAL_POST_MESSAGE_ERROR = "CrossOriginPortalPostMessageError"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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
def to_json(self):
json = dict()
json['errorType'] = self.error_type.to_json()
if self.frame_id is not None:
json['frameId'] = self.frame_id.to_json()
return json
@classmethod
def from_json(cls, json):
return cls(
error_type=GenericIssueErrorType.from_json(json['errorType']),
frame_id=page.FrameId.from_json(json['frameId']) if 'frameId' in json else None,
)
class DeprecationIssueType(enum.Enum):
AUTHORIZATION_COVERED_BY_WILDCARD = "AuthorizationCoveredByWildcard"
CAN_REQUEST_URLHTTP_CONTAINING_NEWLINE = "CanRequestURLHTTPContainingNewline"
CHROME_LOAD_TIMES_CONNECTION_INFO = "ChromeLoadTimesConnectionInfo"
CHROME_LOAD_TIMES_FIRST_PAINT_AFTER_LOAD_TIME = "ChromeLoadTimesFirstPaintAfterLoadTime"
CHROME_LOAD_TIMES_WAS_ALTERNATE_PROTOCOL_AVAILABLE = "ChromeLoadTimesWasAlternateProtocolAvailable"
COOKIE_WITH_TRUNCATING_CHAR = "CookieWithTruncatingChar"
CROSS_ORIGIN_ACCESS_BASED_ON_DOCUMENT_DOMAIN = "CrossOriginAccessBasedOnDocumentDomain"
CROSS_ORIGIN_WINDOW_ALERT = "CrossOriginWindowAlert"
CROSS_ORIGIN_WINDOW_CONFIRM = "CrossOriginWindowConfirm"
CSS_SELECTOR_INTERNAL_MEDIA_CONTROLS_OVERLAY_CAST_BUTTON = "CSSSelectorInternalMediaControlsOverlayCastButton"
DEPRECATION_EXAMPLE = "DeprecationExample"
DOCUMENT_DOMAIN_SETTING_WITHOUT_ORIGIN_AGENT_CLUSTER_HEADER = "DocumentDomainSettingWithoutOriginAgentClusterHeader"
EVENT_PATH = "EventPath"
EXPECT_CT_HEADER = "ExpectCTHeader"
GEOLOCATION_INSECURE_ORIGIN = "GeolocationInsecureOrigin"
GEOLOCATION_INSECURE_ORIGIN_DEPRECATED_NOT_REMOVED = "GeolocationInsecureOriginDeprecatedNotRemoved"
GET_USER_MEDIA_INSECURE_ORIGIN = "GetUserMediaInsecureOrigin"
HOST_CANDIDATE_ATTRIBUTE_GETTER = "HostCandidateAttributeGetter"
IDENTITY_IN_CAN_MAKE_PAYMENT_EVENT = "IdentityInCanMakePaymentEvent"
INSECURE_PRIVATE_NETWORK_SUBRESOURCE_REQUEST = "InsecurePrivateNetworkSubresourceRequest"
LEGACY_CONSTRAINT_GOOG_I_PV6 = "LegacyConstraintGoogIPv6"
LOCAL_CSS_FILE_EXTENSION_REJECTED = "LocalCSSFileExtensionRejected"
MEDIA_SOURCE_ABORT_REMOVE = "MediaSourceAbortRemove"
MEDIA_SOURCE_DURATION_TRUNCATING_BUFFERED = "MediaSourceDurationTruncatingBuffered"
NAVIGATE_EVENT_RESTORE_SCROLL = "NavigateEventRestoreScroll"
NAVIGATE_EVENT_TRANSITION_WHILE = "NavigateEventTransitionWhile"
NO_SYSEX_WEB_MIDI_WITHOUT_PERMISSION = "NoSysexWebMIDIWithoutPermission"
NOTIFICATION_INSECURE_ORIGIN = "NotificationInsecureOrigin"
NOTIFICATION_PERMISSION_REQUESTED_IFRAME = "NotificationPermissionRequestedIframe"
OBSOLETE_WEB_RTC_CIPHER_SUITE = "ObsoleteWebRtcCipherSuite"
OPEN_WEB_DATABASE_INSECURE_CONTEXT = "OpenWebDatabaseInsecureContext"
OVERFLOW_VISIBLE_ON_REPLACED_ELEMENT = "OverflowVisibleOnReplacedElement"
PERSISTENT_QUOTA_TYPE = "PersistentQuotaType"
PICTURE_SOURCE_SRC = "PictureSourceSrc"
PREFIXED_CANCEL_ANIMATION_FRAME = "PrefixedCancelAnimationFrame"
PREFIXED_REQUEST_ANIMATION_FRAME = "PrefixedRequestAnimationFrame"
PREFIXED_STORAGE_INFO = "PrefixedStorageInfo"
PREFIXED_VIDEO_DISPLAYING_FULLSCREEN = "PrefixedVideoDisplayingFullscreen"
PREFIXED_VIDEO_ENTER_FULL_SCREEN = "PrefixedVideoEnterFullScreen"
PREFIXED_VIDEO_EXIT_FULL_SCREEN = "PrefixedVideoExitFullScreen"
PREFIXED_VIDEO_SUPPORTS_FULLSCREEN = "PrefixedVideoSupportsFullscreen"
RANGE_EXPAND = "RangeExpand"
REQUESTED_SUBRESOURCE_WITH_EMBEDDED_CREDENTIALS = "RequestedSubresourceWithEmbeddedCredentials"
RTC_CONSTRAINT_ENABLE_DTLS_SRTP_FALSE = "RTCConstraintEnableDtlsSrtpFalse"
RTC_CONSTRAINT_ENABLE_DTLS_SRTP_TRUE = "RTCConstraintEnableDtlsSrtpTrue"
RTC_PEER_CONNECTION_COMPLEX_PLAN_B_SDP_USING_DEFAULT_SDP_SEMANTICS = "RTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics"
RTC_PEER_CONNECTION_SDP_SEMANTICS_PLAN_B = "RTCPeerConnectionSdpSemanticsPlanB"
RTCP_MUX_POLICY_NEGOTIATE = "RtcpMuxPolicyNegotiate"
SHARED_ARRAY_BUFFER_CONSTRUCTED_WITHOUT_ISOLATION = "SharedArrayBufferConstructedWithoutIsolation"
TEXT_TO_SPEECH_DISALLOWED_BY_AUTOPLAY = "TextToSpeech_DisallowedByAutoplay"
V8_SHARED_ARRAY_BUFFER_CONSTRUCTED_IN_EXTENSION_WITHOUT_ISOLATION = "V8SharedArrayBufferConstructedInExtensionWithoutIsolation"
XHRJSON_ENCODING_DETECTION = "XHRJSONEncodingDetection"
XML_HTTP_REQUEST_SYNCHRONOUS_IN_NON_WORKER_OUTSIDE_BEFORE_UNLOAD = "XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload"
XR_SUPPORTS_SESSION = "XRSupportsSession"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
return cls(json)
@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
type_: DeprecationIssueType
affected_frame: typing.Optional[AffectedFrame] = None
def to_json(self):
json = dict()
json['sourceCodeLocation'] = self.source_code_location.to_json()
json['type'] = self.type_.to_json()
if self.affected_frame is not None:
json['affectedFrame'] = self.affected_frame.to_json()
return json
@classmethod
def from_json(cls, json):
return cls(
source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
type_=DeprecationIssueType.from_json(json['type']),
affected_frame=AffectedFrame.from_json(json['affectedFrame']) if 'affectedFrame' in json else None,
)
class ClientHintIssueReason(enum.Enum):
META_TAG_ALLOW_LIST_INVALID_ORIGIN = "MetaTagAllowListInvalidOrigin"
META_TAG_MODIFIED_HTML = "MetaTagModifiedHTML"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
return cls(json)
@dataclass
class FederatedAuthRequestIssueDetails:
federated_auth_request_issue_reason: FederatedAuthRequestIssueReason
def to_json(self):
json = dict()
json['federatedAuthRequestIssueReason'] = self.federated_auth_request_issue_reason.to_json()
return json
@classmethod
def from_json(cls, json):
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"
MANIFEST_LIST_HTTP_NOT_FOUND = "ManifestListHttpNotFound"
MANIFEST_LIST_NO_RESPONSE = "ManifestListNoResponse"
MANIFEST_LIST_INVALID_RESPONSE = "ManifestListInvalidResponse"
MANIFEST_NOT_IN_MANIFEST_LIST = "ManifestNotInManifestList"
MANIFEST_LIST_TOO_BIG = "ManifestListTooBig"
MANIFEST_HTTP_NOT_FOUND = "ManifestHttpNotFound"
MANIFEST_NO_RESPONSE = "ManifestNoResponse"
MANIFEST_INVALID_RESPONSE = "ManifestInvalidResponse"
CLIENT_METADATA_HTTP_NOT_FOUND = "ClientMetadataHttpNotFound"
CLIENT_METADATA_NO_RESPONSE = "ClientMetadataNoResponse"
CLIENT_METADATA_INVALID_RESPONSE = "ClientMetadataInvalidResponse"
DISABLED_IN_SETTINGS = "DisabledInSettings"
ERROR_FETCHING_SIGNIN = "ErrorFetchingSignin"
INVALID_SIGNIN_RESPONSE = "InvalidSigninResponse"
ACCOUNTS_HTTP_NOT_FOUND = "AccountsHttpNotFound"
ACCOUNTS_NO_RESPONSE = "AccountsNoResponse"
ACCOUNTS_INVALID_RESPONSE = "AccountsInvalidResponse"
ID_TOKEN_HTTP_NOT_FOUND = "IdTokenHttpNotFound"
ID_TOKEN_NO_RESPONSE = "IdTokenNoResponse"
ID_TOKEN_INVALID_RESPONSE = "IdTokenInvalidResponse"
ID_TOKEN_INVALID_REQUEST = "IdTokenInvalidRequest"
ERROR_ID_TOKEN = "ErrorIdToken"
CANCELED = "Canceled"
RP_PAGE_NOT_VISIBLE = "RpPageNotVisible"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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):
json = 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):
return cls(
source_code_location=SourceCodeLocation.from_json(json['sourceCodeLocation']),
client_hint_issue_reason=ClientHintIssueReason.from_json(json['clientHintIssueReason']),
)
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"
TRUSTED_WEB_ACTIVITY_ISSUE = "TrustedWebActivityIssue"
LOW_TEXT_CONTRAST_ISSUE = "LowTextContrastIssue"
CORS_ISSUE = "CorsIssue"
ATTRIBUTION_REPORTING_ISSUE = "AttributionReportingIssue"
QUIRKS_MODE_ISSUE = "QuirksModeIssue"
NAVIGATOR_USER_AGENT_ISSUE = "NavigatorUserAgentIssue"
GENERIC_ISSUE = "GenericIssue"
DEPRECATION_ISSUE = "DeprecationIssue"
CLIENT_HINT_ISSUE = "ClientHintIssue"
FEDERATED_AUTH_REQUEST_ISSUE = "FederatedAuthRequestIssue"
def to_json(self):
return self.value
@classmethod
def from_json(cls, json):
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
twa_quality_enforcement_details: typing.Optional[TrustedWebActivityIssueDetails] = 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
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
def to_json(self):
json = 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.twa_quality_enforcement_details is not None:
json['twaQualityEnforcementDetails'] = self.twa_quality_enforcement_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.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()
return json
@classmethod
def from_json(cls, json):
return cls(
cookie_issue_details=CookieIssueDetails.from_json(json['cookieIssueDetails']) if 'cookieIssueDetails' in json else None,
mixed_content_issue_details=MixedContentIssueDetails.from_json(json['mixedContentIssueDetails']) if 'mixedContentIssueDetails' in json else None,
blocked_by_response_issue_details=BlockedByResponseIssueDetails.from_json(json['blockedByResponseIssueDetails']) if 'blockedByResponseIssueDetails' in json else None,
heavy_ad_issue_details=HeavyAdIssueDetails.from_json(json['heavyAdIssueDetails']) if 'heavyAdIssueDetails' in json else None,
content_security_policy_issue_details=ContentSecurityPolicyIssueDetails.from_json(json['contentSecurityPolicyIssueDetails']) if 'contentSecurityPolicyIssueDetails' in json else None,
shared_array_buffer_issue_details=SharedArrayBufferIssueDetails.from_json(json['sharedArrayBufferIssueDetails']) if 'sharedArrayBufferIssueDetails' in json else None,
twa_quality_enforcement_details=TrustedWebActivityIssueDetails.from_json(json['twaQualityEnforcementDetails']) if 'twaQualityEnforcementDetails' in json else None,
low_text_contrast_issue_details=LowTextContrastIssueDetails.from_json(json['lowTextContrastIssueDetails']) if 'lowTextContrastIssueDetails' in json else None,
cors_issue_details=CorsIssueDetails.from_json(json['corsIssueDetails']) if 'corsIssueDetails' in json else None,
attribution_reporting_issue_details=AttributionReportingIssueDetails.from_json(json['attributionReportingIssueDetails']) if 'attributionReportingIssueDetails' in json else None,
quirks_mode_issue_details=QuirksModeIssueDetails.from_json(json['quirksModeIssueDetails']) if 'quirksModeIssueDetails' in json else None,
navigator_user_agent_issue_details=NavigatorUserAgentIssueDetails.from_json(json['navigatorUserAgentIssueDetails']) if 'navigatorUserAgentIssueDetails' in json else None,
generic_issue_details=GenericIssueDetails.from_json(json['genericIssueDetails']) if 'genericIssueDetails' in json else None,
deprecation_issue_details=DeprecationIssueDetails.from_json(json['deprecationIssueDetails']) if 'deprecationIssueDetails' in json else None,
client_hint_issue_details=ClientHintIssueDetails.from_json(json['clientHintIssueDetails']) if 'clientHintIssueDetails' in json else None,
federated_auth_request_issue_details=FederatedAuthRequestIssueDetails.from_json(json['federatedAuthRequestIssueDetails']) if 'federatedAuthRequestIssueDetails' in json 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):
json = 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):
return cls(
code=InspectorIssueCode.from_json(json['code']),
details=InspectorIssueDetails.from_json(json['details']),
issue_id=IssueId.from_json(json['issueId']) if 'issueId' in json 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.
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 'body' in json 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
@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'])
)