diff --git a/.github/workflows/infra.yml b/.github/workflows/infra.yml index 40f281c7d680c..505baa8011567 100644 --- a/.github/workflows/infra.yml +++ b/.github/workflows/infra.yml @@ -5,10 +5,7 @@ on: branches: - main - release-* - pull_request: - branches: - - main - - release-* + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge env: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 diff --git a/.github/workflows/tests_bidi.yml b/.github/workflows/tests_bidi.yml index acd796fb03d4b..9e7c95af883e6 100644 --- a/.github/workflows/tests_bidi.yml +++ b/.github/workflows/tests_bidi.yml @@ -7,13 +7,7 @@ on: description: Playwright SHA / ref to test. Use 'refs/pull/PULL_REQUEST_ID/head' to test a PR. Defaults to the current branch. required: false default: '' - pull_request: - branches: - - main - paths: - - .github/workflows/tests_bidi.yml - - packages/playwright-core/src/server/bidi/** - - tests/bidi/** + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge schedule: # Run every day at midnight - cron: '0 0 * * *' diff --git a/.github/workflows/tests_components.yml b/.github/workflows/tests_components.yml index 585796c280070..d6225bf7370f7 100644 --- a/.github/workflows/tests_components.yml +++ b/.github/workflows/tests_components.yml @@ -5,19 +5,7 @@ on: branches: - main - release-* - pull_request: - paths-ignore: - - 'browser_patches/**' - - 'docs/**' - - 'packages/extension/**' - - 'packages/playwright-core/src/server/bidi/**' - - 'packages/playwright-core/src/tools/**' - - 'tests/bidi/**' - - 'tests/extension/**' - - 'tests/mcp/**' - branches: - - main - - release-* + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge env: FORCE_COLOR: 1 diff --git a/.github/workflows/tests_extension.yml b/.github/workflows/tests_extension.yml index 3a7b806c5aa2e..1aa7ba74e16a1 100644 --- a/.github/workflows/tests_extension.yml +++ b/.github/workflows/tests_extension.yml @@ -12,17 +12,7 @@ on: - 'packages/extension/**' - 'tests/extension/**' - '.github/workflows/tests_extension.yml' - pull_request: - branches: - - main - - release-* - paths: - - 'packages/playwright-core/src/tools/**' - - '!packages/playwright-core/src/tools/dashboard/**' - - '!packages/playwright-core/src/tools/trace/**' - - 'packages/extension/**' - - 'tests/extension/**' - - '.github/workflows/tests_extension.yml' + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} diff --git a/.github/workflows/tests_mcp.yml b/.github/workflows/tests_mcp.yml index 3e1c7e7cbb5cb..44d3a181050a5 100644 --- a/.github/workflows/tests_mcp.yml +++ b/.github/workflows/tests_mcp.yml @@ -5,17 +5,7 @@ on: branches: - main - release-* - pull_request: - paths-ignore: - - 'browser_patches/**' - - 'docs/**' - - 'packages/extension/**' - - 'packages/playwright-core/src/server/bidi/**' - - 'tests/bidi/**' - - 'tests/extension/**' - branches: - - main - - release-* + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge concurrency: # For pull requests, cancel all currently-running jobs for this workflow diff --git a/.github/workflows/tests_others.yml b/.github/workflows/tests_others.yml index 8444c353fdb66..318b21933ddac 100644 --- a/.github/workflows/tests_others.yml +++ b/.github/workflows/tests_others.yml @@ -5,16 +5,7 @@ on: branches: - main - release-* - pull_request: - paths-ignore: - - 'browser_patches/**' - - 'docs/**' - - 'packages/playwright-core/src/server/bidi/**' - - 'tests/bidi/**' - types: [ labeled ] - branches: - - main - - release-* + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge env: FORCE_COLOR: 1 diff --git a/.github/workflows/tests_primary.yml b/.github/workflows/tests_primary.yml index 1fbba4dc5b64a..56b859c88bade 100644 --- a/.github/workflows/tests_primary.yml +++ b/.github/workflows/tests_primary.yml @@ -5,19 +5,7 @@ on: branches: - main - release-* - pull_request: - paths-ignore: - - 'browser_patches/**' - - 'docs/**' - - 'packages/extension/**' - - 'packages/playwright-core/src/server/bidi/**' - - 'packages/playwright-core/src/tools/**' - - 'tests/bidi/**' - - 'tests/extension/**' - - 'tests/mcp/**' - branches: - - main - - release-* + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge concurrency: # For pull requests, cancel all currently-running jobs for this workflow diff --git a/.github/workflows/tests_secondary.yml b/.github/workflows/tests_secondary.yml index 70b7ec55ed15c..7be9ea82d7ee8 100644 --- a/.github/workflows/tests_secondary.yml +++ b/.github/workflows/tests_secondary.yml @@ -5,11 +5,7 @@ on: branches: - main - release-* - pull_request: - types: [ labeled ] - branches: - - main - - release-* + # pull_request trigger disabled to avoid CI churn during wk_wv iteration - restore before merge env: # Force terminal colors. @see https://www.npmjs.com/package/colors diff --git a/.github/workflows/tests_webview_simulator.yml b/.github/workflows/tests_webview_simulator.yml new file mode 100644 index 0000000000000..95fc7d351d710 --- /dev/null +++ b/.github/workflows/tests_webview_simulator.yml @@ -0,0 +1,249 @@ +name: "tests WebView (iOS Simulator)" + +on: + workflow_dispatch: + pull_request: + paths: + - 'packages/playwright-core/src/server/webkit/webview/**' + - 'tests/webview/**' + - '.github/workflows/tests_webview_simulator.yml' + branches: + - main + - release-* + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + FORCE_COLOR: 1 + ELECTRON_SKIP_BINARY_DOWNLOAD: 1 + # Loud protocol logging so we can post-mortem any handshake failure. + # wvBrowser.ts wires helper.debugProtocolLogger() as protocolLogger, identical + # to wkBrowser.ts — so pw:protocol emits SEND ► / ◀ RECV for every wire frame. + DEBUG: pw:protocol,pw:browser* + +jobs: + test_webview_simulator: + name: "WebView on iOS Simulator" + runs-on: macos-15 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Runner environment + run: | + echo "::group::OS / Xcode" + sw_vers + uname -a + xcode-select -p + xcodebuild -version + echo "::endgroup::" + echo "::group::Available iOS runtimes" + xcrun simctl list runtimes + echo "::endgroup::" + echo "::group::Available device types" + xcrun simctl list devicetypes | grep -i 'iPhone\|iPad' | head -40 + echo "::endgroup::" + echo "::group::Network config" + cat /etc/hosts + ifconfig lo0 + echo "::endgroup::" + + - name: Ensure ::1 localhost in /etc/hosts + run: | + if grep -qE '^::1[[:space:]]+localhost' /etc/hosts; then + echo "::1 localhost already present" + else + echo "::1 localhost" | sudo tee -a /etc/hosts + echo "Added ::1 localhost" + fi + echo "--- /etc/hosts after ---" + cat /etc/hosts + + - name: npm ci + run: | + echo "::group::npm ci" + npm ci + echo "::endgroup::" + + - name: npm run build + run: | + echo "::group::npm run build" + npm run build + echo "::endgroup::" + + - name: Install ios-webkit-debug-proxy + run: | + echo "::group::brew install ios-webkit-debug-proxy" + brew install ios-webkit-debug-proxy + which ios_webkit_debug_proxy + ios_webkit_debug_proxy --help 2>&1 | head -40 || true + echo "::endgroup::" + + - name: Boot iOS Simulator + uses: futureware-tech/simulator-action@v5 + with: + # Per wiki/Devices-macos-15.md only iPhone 16/17 series ship pre-installed; iPhone 15 isn't. + model: 'iPhone 16' + os_version: '18.6' + wait_for_boot: true + boot_timeout_seconds: 300 + + - name: Simulator state after boot + run: | + echo "::group::Booted devices" + xcrun simctl list devices booted + echo "::endgroup::" + echo "::group::Simulator processes" + pgrep -lf Simulator || true + pgrep -lf launchd_sim || true + echo "::endgroup::" + + - name: Launch Mobile Safari + run: | + echo "::group::Launching Mobile Safari" + xcrun simctl launch booted com.apple.mobilesafari "about:blank" + sleep 2 + echo "::endgroup::" + echo "::group::Mobile Safari process" + pgrep -lf MobileSafari || true + echo "::endgroup::" + + - name: Locate simulator webinspectord socket + run: | + echo "::group::Locating com.apple.webinspectord_sim.socket" + # On modern macOS, ios_webkit_debug_proxy can no longer auto-discover the simulator; + # we have to point -s at the launchd-owned unix socket. + for i in $(seq 1 15); do + SOCK=$(lsof -aUc launchd_sim 2>/dev/null | awk '/com\.apple\.webinspectord_sim\.socket/{print $NF; exit}') + [[ -n "$SOCK" ]] && break + echo "attempt $i: socket not found yet" + sleep 1 + done + if [[ -z "$SOCK" ]]; then + echo "Failed to locate webinspectord_sim.socket" + echo "--- launchd_sim file table ---" + lsof -aUc launchd_sim 2>/dev/null || true + exit 1 + fi + echo "socket: $SOCK" + echo "SIM_WI_SOCKET=unix:$SOCK" >> $GITHUB_ENV + echo "::endgroup::" + + - name: Start ios-webkit-debug-proxy + run: | + echo "::group::Starting proxy (SIM_WI_SOCKET=$SIM_WI_SOCKET)" + ios_webkit_debug_proxy -F -d -s "$SIM_WI_SOCKET" -c "null:9221,:9222-9322" > "$RUNNER_TEMP/iwdp.log" 2>&1 & + PID=$! + echo "IWDP_PID=$PID" >> $GITHUB_ENV + echo "proxy pid=$PID" + sleep 3 + if ! kill -0 "$PID" 2>/dev/null; then + echo "Proxy died immediately. Log:" + cat "$RUNNER_TEMP/iwdp.log" + exit 1 + fi + echo "::endgroup::" + echo "::group::Listening ports" + lsof -nP -iTCP -sTCP:LISTEN | grep -E "9221|9222|ios_webkit" || true + echo "::endgroup::" + + - name: Discover WebSocket endpoint + run: | + echo "::group::Device list (port 9221)" + for i in $(seq 1 15); do + if curl -sf http://localhost:9221/json > /tmp/devices.json; then + jq . /tmp/devices.json + [[ "$(jq 'length' /tmp/devices.json)" -gt 0 ]] && break + fi + echo "attempt $i: no devices yet" + sleep 1 + done + echo "::endgroup::" + + echo "::group::Tab list (port 9222)" + for i in $(seq 1 30); do + if curl -sf http://localhost:9222/json > /tmp/tabs.json && [[ "$(jq 'length' /tmp/tabs.json)" -gt 0 ]]; then + jq . /tmp/tabs.json + break + fi + echo "attempt $i: no tabs yet" + sleep 1 + done + if [[ ! -s /tmp/tabs.json ]] || [[ "$(jq 'length' /tmp/tabs.json)" == "0" ]]; then + echo "Failed to discover any tab" + echo "--- proxy log ---" + cat "$RUNNER_TEMP/iwdp.log" + exit 1 + fi + echo "::endgroup::" + + WS=$(jq -r '.[0].webSocketDebuggerUrl' /tmp/tabs.json) + TITLE=$(jq -r '.[0].title' /tmp/tabs.json) + URL=$(jq -r '.[0].url' /tmp/tabs.json) + echo "discovered tab title=$TITLE url=$URL" + echo "discovered ws endpoint=$WS" + if [[ -z "$WS" || "$WS" == "null" ]]; then + echo "No webSocketDebuggerUrl" + exit 1 + fi + echo "PW_WEBVIEW_CDP_ENDPOINT=$WS" >> $GITHUB_ENV + + - name: Pre-flight WebSocket reachability + run: | + echo "::group::Pre-flight" + echo "PW_WEBVIEW_CDP_ENDPOINT=$PW_WEBVIEW_CDP_ENDPOINT" + # Strip ws:// and split host:port from the URL for a basic TCP check + HOSTPORT=$(echo "$PW_WEBVIEW_CDP_ENDPOINT" | sed -E 's|^ws://||' | cut -d/ -f1) + echo "checking TCP reachability of $HOSTPORT" + nc -zv ${HOSTPORT/:/ } || true + echo "::endgroup::" + + - name: Run WebView tests + run: | + echo "::group::Test run (DEBUG=$DEBUG)" + # Mirror protocol logs to file via DEBUG_FILE (read by packages/utils/debugLogger.ts). + npx playwright test --config tests/webview/playwright.config.ts + echo "::endgroup::" + env: + DEBUG_FILE: ${{ github.workspace }}/playwright-debug.log + + - name: Protocol log tail + if: always() + run: | + if [[ -s "${{ github.workspace }}/playwright-debug.log" ]]; then + SIZE=$(wc -c < "${{ github.workspace }}/playwright-debug.log") + echo "::group::pw:protocol log (size=$SIZE bytes, tailing last 400KB)" + tail -c 400000 "${{ github.workspace }}/playwright-debug.log" + echo "::endgroup::" + else + echo "::warning::No protocol log produced — DEBUG=$DEBUG may not have matched any namespace" + fi + + - name: Proxy log + if: always() + run: | + echo "::group::ios-webkit-debug-proxy log" + cat "$RUNNER_TEMP/iwdp.log" || true + echo "::endgroup::" + + - name: Stop proxy + if: always() + run: | + [[ -n "$IWDP_PID" ]] && kill "$IWDP_PID" 2>/dev/null || true + # Simulator shutdown is owned by futureware-tech/simulator-action's post step. + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: webview-simulator-logs + path: | + ${{ runner.temp }}/iwdp.log + ${{ github.workspace }}/playwright-debug.log + ${{ github.workspace }}/test-results/** + if-no-files-found: ignore diff --git a/packages/injected/src/injectedScript.ts b/packages/injected/src/injectedScript.ts index e7b476fd1c6d9..22b118974a324 100644 --- a/packages/injected/src/injectedScript.ts +++ b/packages/injected/src/injectedScript.ts @@ -1112,8 +1112,9 @@ export class InjectedScript { return; // Playwright only issues trusted events, so allow any custom events originating from - // the page or content scripts. - if (!event.isTrusted) + // the page or content scripts. The WebView backend cannot produce trusted events, so + // it marks synthetic events with __pwTrustedSynthetic to opt back into interception. + if (!event.isTrusted && !(event as any).__pwTrustedSynthetic) return; // Determine the event point. Note that Firefox does not always have window.TouchEvent. diff --git a/packages/playwright-core/src/client/browserType.ts b/packages/playwright-core/src/client/browserType.ts index 5cbc931d710fc..2261e5c5ea3a9 100644 --- a/packages/playwright-core/src/client/browserType.ts +++ b/packages/playwright-core/src/client/browserType.ts @@ -150,8 +150,8 @@ export class BrowserType extends ChannelOwner imple } async _connectOverCDP(endpointURL: string, params: api.ConnectOverCDPOptions = {}): Promise { - if (this.name() !== 'chromium') - throw new Error('Connecting over CDP is only supported in Chromium.'); + if (this.name() !== 'chromium' && this.name() !== 'webkit') + throw new Error('Connecting over CDP is only supported in Chromium and WebKit.'); const headers = params.headers ? headersObjectToArray(params.headers) : undefined; const result = await this._channel.connectOverCDP({ endpointURL, diff --git a/packages/playwright-core/src/server/webkit/DEPS.list b/packages/playwright-core/src/server/webkit/DEPS.list new file mode 100644 index 0000000000000..46643d0e0aa01 --- /dev/null +++ b/packages/playwright-core/src/server/webkit/DEPS.list @@ -0,0 +1,10 @@ +[*] +@isomorphic/** +@utils/** +../ +../registry/ +node_modules/jpeg-js +node_modules/pngjs + +[webkit.ts] +./webview/wvBrowser.ts diff --git a/packages/playwright-core/src/server/webkit/webkit.ts b/packages/playwright-core/src/server/webkit/webkit.ts index 40dce2b2aaf87..d5f8eb1ce477b 100644 --- a/packages/playwright-core/src/server/webkit/webkit.ts +++ b/packages/playwright-core/src/server/webkit/webkit.ts @@ -20,11 +20,14 @@ import path from 'path'; import { wrapInASCIIBox } from '@utils/ascii'; import { spawnAsync } from '@utils/spawnAsync'; import { kBrowserCloseMessageId } from './wkConnection'; +import { Browser } from '../browser'; import { BrowserType, kNoXServerRunningError } from '../browserType'; -import { WKBrowser } from '../webkit/wkBrowser'; +import { WKBrowser } from './wkBrowser'; +import { connectOverRDP } from './webview/wvBrowser'; import type { BrowserOptions } from '../browser'; import type { SdkObject } from '../instrumentation'; +import type { Progress } from '../progress'; import type { ConnectionTransport } from '../transport'; import type * as types from '../types'; @@ -37,6 +40,10 @@ export class WebKit extends BrowserType { return WKBrowser.connect(this.attribution.playwright, transport, options); } + override async connectOverCDP(progress: Progress, endpointURL: string, options: { slowMo?: number, headers?: types.HeadersArray, isLocal?: boolean, noDefaults?: boolean }): Promise { + return connectOverRDP(progress, this, endpointURL, options); + } + override amendEnvironment(env: NodeJS.ProcessEnv, userDataDir: string, isPersistent: boolean, options: types.LaunchOptions): NodeJS.ProcessEnv { return { ...env, diff --git a/packages/playwright-core/src/server/webkit/webview/protocol.d.ts b/packages/playwright-core/src/server/webkit/webview/protocol.d.ts new file mode 100644 index 0000000000000..0b4b959e034ce --- /dev/null +++ b/packages/playwright-core/src/server/webkit/webview/protocol.d.ts @@ -0,0 +1,8452 @@ +// This is generated from /utils/protocol-types-generator/index.js +type binary = string; +export namespace Protocol { + /** + * Domain for tracking/modifying Web Animations, as well as CSS (declarative) animations and transitions. + */ + export namespace Animation { + /** + * Unique Web Animation identifier. + */ + export type AnimationId = string; + export type AnimationState = "ready"|"delayed"|"active"|"canceled"|"done"; + export type PlaybackDirection = "normal"|"reverse"|"alternate"|"alternate-reverse"; + export type FillMode = "none"|"forwards"|"backwards"|"both"|"auto"; + export interface Animation { + animationId: AnimationId; + /** + * Equal to `Animation.prototype.get id`. + */ + name?: string; + /** + * Equal to the corresponding `animation-name` CSS property. Should not be provided if `transitionProperty` is also provided. + */ + cssAnimationName?: string; + /** + * Equal to the corresponding `transition-property` CSS property. Should not be provided if `animationName` is also provided. + */ + cssTransitionProperty?: string; + /** + * Backtrace that was captured when this `WebAnimation` was created. + */ + stackTrace?: Console.StackTrace; + } + export interface Effect { + startDelay?: number; + endDelay?: number; + /** + * Number of iterations in the animation. Infinity is represented as -1. + */ + iterationCount?: number; + /** + * Index of which iteration to start at. + */ + iterationStart?: number; + /** + * Total time of each iteration, measured in milliseconds. + */ + iterationDuration?: number; + /** + * CSS timing function of the overall animation. + */ + timingFunction?: string; + playbackDirection?: PlaybackDirection; + fillMode?: FillMode; + keyframes?: Keyframe[]; + } + export interface Keyframe { + /** + * Decimal percentage [0,1] representing where this keyframe is in the entire duration of the animation. + */ + offset: number; + /** + * CSS timing function for how the `style` is applied. + */ + easing?: string; + /** + * CSS style declaration of the CSS properties that will be animated. + */ + style?: string; + } + export interface TrackingUpdate { + trackingAnimationId: AnimationId; + animationState: AnimationState; + nodeId?: DOM.NodeId; + /** + * Equal to the corresponding `animation-name` CSS property. Should not be provided if `transitionProperty` is also provided. + */ + animationName?: string; + /** + * Equal to the corresponding `transition-property` CSS property. Should not be provided if `animationName` is also provided. + */ + transitionProperty?: string; + } + + /** + * Dispatched whenever a `WebAnimation` is created. + */ + export type animationCreatedPayload = { + animation: Animation; + } + /** + * Dispatched whenever `Animation.prototype.set id` is called. + */ + export type nameChangedPayload = { + animationId: AnimationId; + /** + * Equal to `Animation.prototype.get id`. + */ + name?: string; + } + /** + * Dispatched whenever the effect of any animation is changed in any way. + */ + export type effectChangedPayload = { + animationId: AnimationId; + } + /** + * Dispatched whenever the target of any effect of any animation is changed in any way. + */ + export type targetChangedPayload = { + animationId: AnimationId; + } + /** + * Dispatched whenever a `WebAnimation` is destroyed. + */ + export type animationDestroyedPayload = { + animationId: AnimationId; + } + /** + * Dispatched after `startTracking` command. + */ + export type trackingStartPayload = { + timestamp: number; + } + /** + * Fired for each phase of Web Animation. + */ + export type trackingUpdatePayload = { + timestamp: number; + event: TrackingUpdate; + } + /** + * Dispatched after `stopTracking` command. + */ + export type trackingCompletePayload = { + timestamp: number; + } + + /** + * Enables Canvas domain events. + */ + export type enableParameters = { + } + export type enableReturnValue = { + } + /** + * Disables Canvas domain events. + */ + export type disableParameters = { + } + export type disableReturnValue = { + } + /** + * Gets the `Effect` for the animation with the given `AnimationId`. + */ + export type requestEffectParameters = { + animationId: AnimationId; + } + export type requestEffectReturnValue = { + /** + * This is omitted when there is no effect. + */ + effect?: Effect; + } + /** + * Gets the `DOM.NodeId` for the target of the effect of the animation with the given `AnimationId`. + */ + export type requestEffectTargetParameters = { + animationId: AnimationId; + } + export type requestEffectTargetReturnValue = { + effectTarget: DOM.Styleable; + } + /** + * Resolves JavaScript `WebAnimation` object for given `AnimationId`. + */ + export type resolveAnimationParameters = { + animationId: AnimationId; + /** + * Symbolic group name that can be used to release multiple objects. + */ + objectGroup?: string; + } + export type resolveAnimationReturnValue = { + object: Runtime.RemoteObject; + } + /** + * Start tracking animations. This will produce a `trackingStart` event. + */ + export type startTrackingParameters = { + } + export type startTrackingReturnValue = { + } + /** + * Stop tracking animations. This will produce a `trackingComplete` event. + */ + export type stopTrackingParameters = { + } + export type stopTrackingReturnValue = { + } + } + + export namespace Audit { + + + /** + * Creates the `WebInspectorAudit` object that is passed to run. Must call teardown before calling setup more than once. + */ + export type setupParameters = { + /** + * Specifies in which isolated context to run the test. Each content script lives in an isolated context and this parameter may be used to specify one of those contexts. If the parameter is omitted or 0 the evaluation will be performed in the context of the inspected page. + */ + contextId?: Runtime.ExecutionContextId; + } + export type setupReturnValue = { + } + /** + * Parses and evaluates the given test string and sends back the result. Returned values are saved to the "audit" object group. Call setup before and teardown after if the `WebInspectorAudit` object should be passed into the test. + */ + export type runParameters = { + /** + * Test string to parse and evaluate. + */ + test: string; + /** + * Specifies in which isolated context to run the test. Each content script lives in an isolated context and this parameter may be used to specify one of those contexts. If the parameter is omitted or 0 the evaluation will be performed in the context of the inspected page. + */ + contextId?: Runtime.ExecutionContextId; + } + export type runReturnValue = { + /** + * Evaluation result. + */ + result: Runtime.RemoteObject; + /** + * True if the result was thrown during the evaluation. + */ + wasThrown?: boolean; + } + /** + * Destroys the `WebInspectorAudit` object that is passed to run. Must call setup before calling teardown. + */ + export type teardownParameters = { + } + export type teardownReturnValue = { + } + } + + /** + * The Browser domain contains commands and events related to getting information about the browser + */ + export namespace Browser { + /** + * Unique extension identifier. + */ + export type ExtensionId = string; + /** + * Information about an extension. + */ + export interface Extension { + /** + * Extension identifier. + */ + extensionId: ExtensionId; + /** + * The display name for the extension. + */ + name: string; + } + + export type extensionsEnabledPayload = { + /** + * Information about the enabled extensions. + */ + extensions: Extension[]; + } + export type extensionsDisabledPayload = { + /** + * Disabled extension identifiers. + */ + extensionIds: ExtensionId[]; + } + + /** + * Enables Browser domain events. + */ + export type enableParameters = { + } + export type enableReturnValue = { + } + /** + * Disables Browser domain events. + */ + export type disableParameters = { + } + export type disableReturnValue = { + } + } + + /** + * Canvas domain allows tracking of canvases that have an associated graphics context. Tracks canvases in the DOM and CSS canvases created with -webkit-canvas. + */ + export namespace Canvas { + /** + * Unique canvas identifier. + */ + export type CanvasId = string; + /** + * Unique shader program identifier. + */ + export type ProgramId = string; + export type ColorSpace = "srgb"|"srgb-linear"|"display-p3"|"display-p3-linear"; + /** + * The type of rendering context backing the canvas element. + */ + export type ContextType = "canvas-2d"|"offscreen-canvas-2d"|"bitmaprenderer"|"offscreen-bitmaprenderer"|"webgl"|"offscreen-webgl"|"webgl2"|"offscreen-webgl2"; + export type ProgramType = "compute"|"render"; + export type ShaderType = "compute"|"fragment"|"vertex"; + /** + * Drawing surface attributes. + */ + export interface ContextAttributes { + /** + * WebGL, WebGL2, ImageBitmapRenderingContext + */ + alpha?: boolean; + /** + * 2D + */ + colorSpace?: ColorSpace; + /** + * 2D + */ + desynchronized?: boolean; + /** + * 2D + */ + willReadFrequently?: boolean; + /** + * WebGL, WebGL2 + */ + depth?: boolean; + /** + * WebGL, WebGL2 + */ + stencil?: boolean; + /** + * WebGL, WebGL2 + */ + antialias?: boolean; + /** + * WebGL, WebGL2 + */ + premultipliedAlpha?: boolean; + /** + * WebGL, WebGL2 + */ + preserveDrawingBuffer?: boolean; + /** + * WebGL, WebGL2 + */ + failIfMajorPerformanceCaveat?: boolean; + /** + * WebGL, WebGL2 + */ + powerPreference?: string; + } + /** + * Information about a canvas for which a rendering context has been created. + */ + export interface Canvas { + /** + * Canvas identifier. + */ + canvasId: CanvasId; + /** + * The type of rendering context backing the canvas. + */ + contextType: ContextType; + /** + * Width of the canvas in pixels. + */ + width: number; + /** + * Height of the canvas in pixels. + */ + height: number; + /** + * The corresponding DOM node id. + */ + nodeId?: DOM.NodeId; + /** + * The CSS canvas identifier, for canvases created with document.getCSSCanvasContext. + */ + cssCanvasName?: string; + /** + * Context attributes for rendering contexts. + */ + contextAttributes?: ContextAttributes; + /** + * Memory usage of the canvas in bytes. + */ + memoryCost?: number; + /** + * Backtrace that was captured when this canvas context was created. + */ + stackTrace?: Console.StackTrace; + } + /** + * Information about a WebGL/WebGL2 shader program. + */ + export interface ShaderProgram { + programId: ProgramId; + programType: ProgramType; + canvasId: CanvasId; + } + + export type canvasAddedPayload = { + /** + * Canvas object. + */ + canvas: Canvas; + } + export type canvasRemovedPayload = { + /** + * Removed canvas identifier. + */ + canvasId: CanvasId; + } + export type canvasSizeChangedPayload = { + /** + * Identifier of canvas that changed. + */ + canvasId: CanvasId; + /** + * Width of the canvas in pixels. + */ + width: number; + /** + * Height of the canvas in pixels. + */ + height: number; + } + export type canvasMemoryChangedPayload = { + /** + * Identifier of canvas that changed. + */ + canvasId: CanvasId; + /** + * New memory cost value for the canvas in bytes. + */ + memoryCost: number; + } + export type extensionEnabledPayload = { + canvasId: CanvasId; + /** + * Name of the extension that was enabled. + */ + extension: string; + } + export type clientNodesChangedPayload = { + /** + * Identifier of canvas that changed. + */ + canvasId: CanvasId; + } + export type recordingStartedPayload = { + canvasId: CanvasId; + initiator: Recording.Initiator; + } + export type recordingProgressPayload = { + canvasId: CanvasId; + frames: Recording.Frame[]; + /** + * Total memory size in bytes of all data recorded since the recording began. + */ + bufferUsed: number; + } + export type recordingFinishedPayload = { + canvasId: CanvasId; + recording?: Recording.Recording; + } + export type programCreatedPayload = { + shaderProgram: ShaderProgram; + } + export type programDeletedPayload = { + programId: ProgramId; + } + + /** + * Enables Canvas domain events. + */ + export type enableParameters = { + } + export type enableReturnValue = { + } + /** + * Disables Canvas domain events. + */ + export type disableParameters = { + } + export type disableReturnValue = { + } + /** + * Gets the NodeId for the canvas node with the given CanvasId. + */ + export type requestNodeParameters = { + /** + * Canvas identifier. + */ + canvasId: CanvasId; + } + export type requestNodeReturnValue = { + /** + * Node identifier for given canvas. + */ + nodeId: DOM.NodeId; + } + /** + * Gets the data for the canvas node with the given CanvasId. + */ + export type requestContentParameters = { + /** + * Canvas identifier. + */ + canvasId: CanvasId; + } + export type requestContentReturnValue = { + /** + * Base64-encoded data of the canvas' contents. + */ + content: string; + } + /** + * Gets all -webkit-canvas nodes or active HTMLCanvasElement for a WebGPUDevice. + */ + export type requestClientNodesParameters = { + canvasId: CanvasId; + } + export type requestClientNodesReturnValue = { + clientNodeIds: DOM.NodeId[]; + } + /** + * Resolves JavaScript canvas/device context object for given canvasId. + */ + export type resolveContextParameters = { + /** + * Canvas identifier. + */ + canvasId: CanvasId; + /** + * Symbolic group name that can be used to release multiple objects. + */ + objectGroup?: string; + } + export type resolveContextReturnValue = { + /** + * JavaScript object wrapper for given canvas context. + */ + object: Runtime.RemoteObject; + } + /** + * Tells the backend to record `count` frames whenever a new context is created. + */ + export type setRecordingAutoCaptureFrameCountParameters = { + /** + * Number of frames to record (0 means don't record anything). + */ + count: number; + } + export type setRecordingAutoCaptureFrameCountReturnValue = { + } + /** + * Record the next frame, or up to the given number of bytes of data, for the given canvas. + */ + export type startRecordingParameters = { + canvasId: CanvasId; + /** + * Number of frames to record (unlimited when not specified). + */ + frameCount?: number; + /** + * Memory limit of recorded data (100MB when not specified). + */ + memoryLimit?: number; + } + export type startRecordingReturnValue = { + } + /** + * Stop recording the given canvas. + */ + export type stopRecordingParameters = { + canvasId: CanvasId; + } + export type stopRecordingReturnValue = { + } + /** + * Requests the source of the shader of the given type from the program with the given id. + */ + export type requestShaderSourceParameters = { + programId: ProgramId; + shaderType: ShaderType; + } + export type requestShaderSourceReturnValue = { + source: string; + } + /** + * Compiles and links the shader with identifier and type with the given source code. + */ + export type updateShaderParameters = { + programId: ProgramId; + shaderType: ShaderType; + source: string; + } + export type updateShaderReturnValue = { + } + /** + * Enable/disable the visibility of the given shader program. + */ + export type setShaderProgramDisabledParameters = { + programId: ProgramId; + disabled: boolean; + } + export type setShaderProgramDisabledReturnValue = { + } + /** + * Enable/disable highlighting of the given shader program. + */ + export type setShaderProgramHighlightedParameters = { + programId: ProgramId; + highlighted: boolean; + } + export type setShaderProgramHighlightedReturnValue = { + } + } + + /** + * Console domain defines methods and events for interaction with the JavaScript console. Console collects messages created by means of the JavaScript Console API. One needs to enable this domain using enable command in order to start receiving the console messages. Browser collects messages issued while console domain is not enabled as well and reports them using messageAdded notification upon enabling. + */ + export namespace Console { + /** + * Channels for different types of log messages. + */ + export type ChannelSource = "xml"|"javascript"|"network"|"console-api"|"storage"|"rendering"|"css"|"accessibility"|"security"|"content-blocker"|"media"|"mediasource"|"webrtc"|"itp-debug"|"private-click-measurement"|"payment-request"|"other"; + /** + * Level of logging. + */ + export type ChannelLevel = "off"|"basic"|"verbose"; + /** + * The reason the console is being cleared. + */ + export type ClearReason = "console-api"|"frontend"|"main-frame-navigation"; + /** + * Logging channel. + */ + export interface Channel { + source: ChannelSource; + level: ChannelLevel; + } + /** + * Console message. + */ + export interface ConsoleMessage { + source: ChannelSource; + /** + * Message severity. + */ + level: "log"|"info"|"warning"|"error"|"debug"; + /** + * Message text. + */ + text: string; + /** + * Console message type. + */ + type?: "log"|"dir"|"dirxml"|"table"|"trace"|"clear"|"startGroup"|"startGroupCollapsed"|"endGroup"|"assert"|"timing"|"profile"|"profileEnd"|"image"; + /** + * URL of the message origin. + */ + url?: string; + /** + * Line number in the resource that generated this message. + */ + line?: number; + /** + * Column number on the line in the resource that generated this message. + */ + column?: number; + /** + * Repeat count for repeated messages. + */ + repeatCount?: number; + /** + * Message parameters in case of the formatted message. + */ + parameters?: Runtime.RemoteObject[]; + /** + * JavaScript stack trace for assertions and error messages. + */ + stackTrace?: StackTrace; + /** + * Identifier of the network request associated with this message. + */ + networkRequestId?: Network.RequestId; + /** + * Time when this message was added. Currently only used when an expensive operation happens to make sure that the frontend can account for it. + */ + timestamp?: number; + } + /** + * Stack entry for console errors and assertions. + */ + export interface CallFrame { + /** + * JavaScript function name. + */ + functionName: string; + /** + * JavaScript script name or url. + */ + url: string; + /** + * Script identifier. + */ + scriptId: Debugger.ScriptId; + /** + * JavaScript script line number. + */ + lineNumber: number; + /** + * JavaScript script column number. + */ + columnNumber: number; + } + /** + * Call frames for async function calls, console assertions, and error messages. + */ + export interface StackTrace { + callFrames: CallFrame[]; + /** + * Whether the first item in callFrames is the native function that scheduled the asynchronous operation (e.g. setTimeout). + */ + topCallFrameIsBoundary?: boolean; + /** + * Whether one or more frames have been truncated from the bottom of the stack. + */ + truncated?: boolean; + /** + * Parent StackTrace. + */ + parentStackTrace?: StackTrace; + } + + /** + * Issued when new console message is added. + */ + export type messageAddedPayload = { + /** + * Console message that has been added. + */ + message: ConsoleMessage; + } + /** + * Issued when subsequent message(s) are equal to the previous one(s). + */ + export type messageRepeatCountUpdatedPayload = { + /** + * New repeat count value. + */ + count: number; + /** + * Timestamp of the latest message. + */ + timestamp?: number; + } + /** + * Issued when console is cleared. This happens either upon clearMessages command or after page navigation. + */ + export type messagesClearedPayload = { + /** + * The reason the console is being cleared. + */ + reason: ClearReason; + } + /** + * Issued from console.takeHeapSnapshot. + */ + export type heapSnapshotPayload = { + timestamp: number; + /** + * Snapshot at the end of tracking. + */ + snapshotData: Heap.HeapSnapshotData; + /** + * Optional title provided to console.takeHeapSnapshot. + */ + title?: string; + } + + /** + * Enables console domain, sends the messages collected so far to the client by means of the messageAdded notification. + */ + export type enableParameters = { + } + export type enableReturnValue = { + } + /** + * Disables console domain, prevents further console messages from being reported to the client. + */ + export type disableParameters = { + } + export type disableReturnValue = { + } + /** + * Clears console messages collected in the browser. + */ + export type clearMessagesParameters = { + } + export type clearMessagesReturnValue = { + } + /** + * Control whether calling console.clear() has an effect in Web Inspector. Defaults to true. + */ + export type setConsoleClearAPIEnabledParameters = { + enable: boolean; + } + export type setConsoleClearAPIEnabledReturnValue = { + } + /** + * List of the different message sources that are non-default logging channels. + */ + export type getLoggingChannelsParameters = { + } + export type getLoggingChannelsReturnValue = { + /** + * Logging channels. + */ + channels: Channel[]; + } + /** + * Modify the level of a channel. + */ + export type setLoggingChannelLevelParameters = { + /** + * Logging channel to modify. + */ + source: ChannelSource; + /** + * New level. + */ + level: ChannelLevel; + } + export type setLoggingChannelLevelReturnValue = { + } + } + + /** + * CPUProfiler domain exposes cpu usage tracking. + */ + export namespace CPUProfiler { + /** + * CPU usage for an individual thread. + */ + export interface ThreadInfo { + /** + * Some thread identification information. + */ + name: string; + /** + * CPU usage for this thread. This should not exceed 100% for an individual thread. + */ + usage: number; + /** + * Type of thread. There should be a single main thread. + */ + type?: "main"|"webkit"; + /** + * A thread may be associated with a target, such as a Worker, in the process. + */ + targetId?: string; + } + export interface Event { + timestamp: number; + /** + * Percent of total cpu usage. If there are multiple cores the usage may be greater than 100%. + */ + usage: number; + /** + * Per-thread CPU usage information. Does not include the main thread. + */ + threads?: ThreadInfo[]; + } + + /** + * Tracking started. + */ + export type trackingStartPayload = { + timestamp: number; + } + /** + * Periodic tracking updates with event data. + */ + export type trackingUpdatePayload = { + event: Event; + } + /** + * Tracking stopped. + */ + export type trackingCompletePayload = { + timestamp: number; + } + + /** + * Start tracking cpu usage. + */ + export type startTrackingParameters = { + } + export type startTrackingReturnValue = { + } + /** + * Stop tracking cpu usage. This will produce a `trackingComplete` event. + */ + export type stopTrackingParameters = { + } + export type stopTrackingReturnValue = { + } + } + + /** + * This domain exposes CSS read/write operations. All CSS objects, like stylesheets, rules, and styles, have an associated id used in subsequent operations on the related object. Each object type has a specific id structure, and those are not interchangeable between objects of different kinds. CSS objects can be loaded using the get*ForNode() calls (which accept a DOM node id). Alternatively, a client can discover all the existing stylesheets with the getAllStyleSheets() method and subsequently load the required stylesheet contents using the getStyleSheet[Text]() methods. + */ + export namespace CSS { + export type StyleSheetId = string; + /** + * This object identifies a CSS style in a unique way. + */ + export interface CSSStyleId { + /** + * Enclosing stylesheet identifier. + */ + styleSheetId: StyleSheetId; + /** + * The style ordinal within the stylesheet. + */ + ordinal: number; + } + /** + * Stylesheet type: "user" for user stylesheets, "user-agent" for user-agent stylesheets, "inspector" for stylesheets created by the inspector (i.e. those holding the "via inspector" rules), "regular" for regular stylesheets. + */ + export type StyleSheetOrigin = "user"|"user-agent"|"author"|"inspector"; + /** + * This object identifies a CSS rule in a unique way. + */ + export interface CSSRuleId { + /** + * Enclosing stylesheet identifier. + */ + styleSheetId: StyleSheetId; + /** + * The rule ordinal within the stylesheet. + */ + ordinal: number; + } + /** + * Pseudo-style identifier (see enum PseudoId in RenderStyleConstants.h). + */ + export type PseudoId = "first-line"|"first-letter"|"grammar-error"|"highlight"|"marker"|"before"|"after"|"selection"|"backdrop"|"spelling-error"|"target-text"|"checkmark"|"picker-icon"|"slider-fill"|"slider-thumb"|"slider-track"|"view-transition"|"view-transition-group"|"view-transition-image-pair"|"view-transition-old"|"view-transition-new"|"-webkit-scrollbar"|"-webkit-resizer"|"-webkit-scrollbar-thumb"|"-webkit-scrollbar-button"|"-webkit-scrollbar-track"|"-webkit-scrollbar-track-piece"|"-webkit-scrollbar-corner"; + /** + * Pseudo-style identifier (see enum PseudoId in RenderStyleConstants.h). + */ + export type ForceablePseudoClass = "active"|"focus"|"focus-visible"|"focus-within"|"hover"|"target"|"visited"; + /** + * CSS rule collection for a single pseudo style. + */ + export interface PseudoIdMatches { + pseudoId: PseudoId; + /** + * Matches of CSS rules applicable to the pseudo style. + */ + matches: RuleMatch[]; + } + /** + * CSS rule collection for a single pseudo style. + */ + export interface InheritedStyleEntry { + /** + * The ancestor node's inline style, if any, in the style inheritance chain. + */ + inlineStyle?: CSSStyle; + /** + * Matches of CSS rules matching the ancestor node in the style inheritance chain. + */ + matchedCSSRules: RuleMatch[]; + } + /** + * Match data for a CSS rule. + */ + export interface RuleMatch { + /** + * CSS rule in the match. + */ + rule: CSSRule; + /** + * Matching selector indices in the rule's selectorList selectors (0-based). + */ + matchingSelectors: number[]; + } + /** + * CSS selector. + */ + export interface CSSSelector { + /** + * Canonicalized selector text. + */ + text: string; + /** + * Specificity (a, b, c) tuple. Included if the selector is sent in response to CSS.getMatchedStylesForNode which provides a context element. + */ + specificity?: number[]; + /** + * Whether or not the specificity can be dynamic. Included if the selector is sent in response to CSS.getMatchedStylesForNode which provides a context element. + */ + dynamic?: boolean; + } + /** + * Selector list data. + */ + export interface SelectorList { + /** + * Selectors in the list. + */ + selectors: CSSSelector[]; + /** + * Rule selector text. + */ + text: string; + /** + * Rule selector range in the underlying resource (if available). + */ + range?: SourceRange; + } + /** + * CSS style information for a DOM style attribute. + */ + export interface CSSStyleAttribute { + /** + * DOM attribute name (e.g. "width"). + */ + name: string; + /** + * CSS style generated by the respective DOM attribute. + */ + style: CSSStyle; + } + /** + * CSS stylesheet meta-information. + */ + export interface CSSStyleSheetHeader { + /** + * The stylesheet identifier. + */ + styleSheetId: StyleSheetId; + /** + * Owner frame identifier. + */ + frameId: Network.FrameId; + /** + * Stylesheet resource URL. + */ + sourceURL: string; + /** + * Stylesheet origin. + */ + origin: StyleSheetOrigin; + /** + * Stylesheet title. + */ + title: string; + /** + * Denotes whether the stylesheet is disabled. + */ + disabled: boolean; + /** + * Whether this stylesheet is a