Skip to content

Commit d0b2b3f

Browse files
author
Rahim Abdi
committed
WebDriver: Add support for GetAccessibilityPropertiesForElement, GetAccessibilityPropertiesForAccessibilityNode commands
https://bugs.webkit.org/show_bug.cgi?id=299508 rdar://161303091 Reviewed by NOBODY (OOPS!). This patch implements two new WebDriver automation commands used to support more robust WPT accessibility testing: - GetAccessibilityPropertiesForElement - GetAccessibilityPropertiesForAccessibilityNode For this initial implementation, test_driver.get_accessibility_properties...() will return an accessibility property bag containing the following computed properties: - accessibilityNodeId - role - label - checked ("true", "false", or "mixed"; omitted if the node does not support a checked state) - pressed ("true", "false", or "mixed"; omitted if the node is not a toggle button) - children (array of serialized AXIDs) - parent (serialized AXID; omitted if the node has no parent) As these new WebDriver commands are test-only interfaces, there's been in-depth discussion around how to treat computed AX properties when a property is missing and supported, or present & unsupported; see WICG/aom#203 Some additional resources: - WebDriver PR for the new commands: w3c/webdriver#1960 - ARIA PR for the initial set of computed accessibility properties, and treatment of undefined/missing/unsupported values: w3c/aria#2800 At a high level, the WebDriver client (i.e., Web Platform Tests' testdriver.js) initiates these new commands which is then dispatched to the UI Process (WebAutomationSession). The WebAutomationSession then parses the payload and extracts the protocol-specific element or accessibility node, after which it identifies the target (WebPageProxy) which invokes an asynchronous IPC message to the corresponding Web Process. Note that GetAccessibilityPropertiesForElement uses the same DOM node/frame-based approach as many other WebDriver commands however, GetAccessibilityPropertiesForAccessibilityNode does not require frame-based process routing (it retrieves computed accessibility properties using the page's axObjectCache, rather than a specific frame tied to a DOM node); thus, GetAccessibilityPropertiesForAccessibilityNode has a different message signature. Since AXIDs are only unique within a single Web Process, accessibility nodes in cross-process (site-isolated) iframes are not yet supported; a FIXME tracks this. The WebProcess returns the computed accessibility properties to the UIProcess as a typed "ComputedAccessibilityProperties" struct (Source/WebKit/Shared/Automation), using AXIDs and an AccessibilityTriState enum rather than strings; the UIProcess converts these to strings when building the protocol object. Note that to fully support these new WebDriver commands, corresponding WebDriver HTTP endpoints must be implemented in Webdriver for Safari (safaridriver): - session/{session_id}/element/{elId}/accessibilityproperties: Returns accessibility properties for DOM element {elId} - session/{session_id}/accessibility/<accessibility node id>/properties/{accessibility node id}: Returns accessibility properties for accessibility node {accessibility node id} Due to the existence of two AccessibilityProperties protocol object definitions, documentation for each has been updated: - Source/WebKit/UIProcess/Automation/Automation.json — specification conformance and interoperability testing - Source/JavaScriptCore/inspector/protocol/DOM.json — Web Inspector DOM element inspection As an unrelated small fix, the return type for GetComputedLabel (WebAutomationSessionProxy IPC message) incorrectly names the first string parameter as "role" instead of "label" so this patch also corrects the tuple to return (label, errorType). * LayoutTests/resources/testdriver-vendor.js: (window.test_driver_internal.get_accessibility_properties_for_element): (window.test_driver_internal.get_accessibility_properties_for_accessibility_node): * Source/JavaScriptCore/inspector/protocol/DOM.json * Source/WebKit/CMakeLists.txt: * Source/WebKit/DerivedSources-input.xcfilelist: * Source/WebKit/DerivedSources.make: * Source/WebKit/Shared/Automation/ComputedAccessibilityProperties.h: Added. * Source/WebKit/Shared/Automation/ComputedAccessibilityProperties.serialization.in: Added. * Source/WebKit/UIProcess/Automation/Automation.json: * Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp: (WebKit::stringForAccessibilityNodeID): (WebKit::stringForAccessibilityTriState): (WebKit::makeAccessibilityPropertiesCompletionHandler): (WebKit::WebAutomationSession::getAccessibilityPropertiesForElement): (WebKit::WebAutomationSession::getAccessibilityPropertiesForAccessibilityNode): * Source/WebKit/UIProcess/Automation/WebAutomationSession.h: * Source/WebKit/UIProcess/WebPageProxy.cpp: * Source/WebKit/WebKit.xcodeproj/project.pbxproj: * Source/WebKit/WebProcess/Automation/WebAutomationSessionProxy.cpp: (WebKit::WebAutomationSessionProxy::getAccessibilityObjectForAXNode): (WebKit::toAccessibilityTriState): (WebKit::getComputedAccessibilityProperties): (WebKit::WebAutomationSessionProxy::getAccessibilityPropertiesForElement): (WebKit::WebAutomationSessionProxy::getAccessibilityPropertiesForAccessibilityNode): * Source/WebKit/WebProcess/Automation/WebAutomationSessionProxy.h: * Source/WebKit/WebProcess/Automation/WebAutomationSessionProxy.messages.in:
1 parent e64c8f4 commit d0b2b3f

16 files changed

Lines changed: 364 additions & 4 deletions

‎LayoutTests/resources/testdriver-vendor.js‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,32 @@ window.test_driver_internal.get_computed_role = async function (element, context
810810
return context.internals.getComputedRole(element);
811811
}
812812

813+
/**
814+
*
815+
* @param {Element} element
816+
* @returns {Promise<Object>}
817+
*/
818+
window.test_driver_internal.get_accessibility_properties_for_element = async function (element, context=null) {
819+
if (!element)
820+
return {};
821+
context = context ?? window;
822+
823+
return context.internals.getAccessibilityPropertiesForElement(element);
824+
}
825+
826+
/**
827+
*
828+
* @param {string} accessibilityNodeId
829+
* @returns {Promise<Object>}
830+
*/
831+
window.test_driver_internal.get_accessibility_properties_for_accessibility_node = async function (accessibilityNodeId, context=null) {
832+
if (!accessibilityNodeId)
833+
return {};
834+
context = context ?? window;
835+
836+
return context.internals.getAccessibilityPropertiesForAccessibilityNode(accessibilityNodeId);
837+
}
838+
813839
/**
814840
*
815841
* @param {string} origin

‎Source/JavaScriptCore/inspector/protocol/DOM.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
},
102102
{
103103
"id": "AccessibilityProperties",
104-
"description": "A structure holding accessibility properties.",
104+
"description": "A structure holding accessibility properties, either forwarded to the DOM Element from its backing Accessibility Node, and/or some local properties (e.g., ignored) that may clarify other characteristics, such as why a backing Accessibility Node is not available for this DOM Element.",
105105
"type": "object",
106106
"properties": [
107107
{ "name": "activeDescendantNodeId", "$ref": "NodeId", "optional": true, "description": "<code>DOMNode</code> id of the accessibility object referenced by aria-activedescendant." },

‎Source/WebCore/accessibility/AXObjectCache.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ enum class AXStreamOptions : uint16_t;
111111
enum class AXProperty : uint16_t;
112112
enum class LiveRegionStatus: uint8_t;
113113

114-
115114
struct AXTreeData {
116115
String liveTree;
117116
String isolatedTree;

‎Source/WebKit/CMakeLists.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ set(WebKit_SERIALIZATION_IN_FILES
606606

607607
Shared/Authentication/AuthenticationChallengeDisposition.serialization.in
608608

609+
Shared/Automation/ComputedAccessibilityProperties.serialization.in
610+
609611
Shared/Databases/IndexedDB/WebIDBResult.serialization.in
610612

611613
Shared/Extensions/WebExtensionActionClickBehavior.serialization.in

‎Source/WebKit/DerivedSources-input.xcfilelist‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ $(PROJECT_DIR)/Shared/ApplePay/ApplePayPaymentSetupFeatures.serialization.in
249249
$(PROJECT_DIR)/Shared/ApplePay/PaymentSetupConfiguration.serialization.in
250250
$(PROJECT_DIR)/Shared/ApplePay/WebPaymentCoordinatorProxy.messages.in
251251
$(PROJECT_DIR)/Shared/Authentication/AuthenticationChallengeDisposition.serialization.in
252+
$(PROJECT_DIR)/Shared/Automation/ComputedAccessibilityProperties.serialization.in
252253
$(PROJECT_DIR)/Shared/AuxiliaryProcess.messages.in
253254
$(PROJECT_DIR)/Shared/AuxiliaryProcessCreationParameters.serialization.in
254255
$(PROJECT_DIR)/Shared/BackgroundFetchChange.serialization.in

‎Source/WebKit/DerivedSources.make‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ SERIALIZATION_DESCRIPTION_FILES = \
705705
Shared/AlternativeTextClient.serialization.in \
706706
Shared/AppPrivacyReportTestingData.serialization.in \
707707
Shared/Authentication/AuthenticationChallengeDisposition.serialization.in \
708+
Shared/Automation/ComputedAccessibilityProperties.serialization.in \
708709
Shared/BackgroundFetchChange.serialization.in \
709710
Shared/BackgroundFetchState.serialization.in \
710711
Shared/CacheModel.serialization.in \
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (C) 2026 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#pragma once
27+
28+
#include <WebCore/AXID.h>
29+
#include <optional>
30+
#include <wtf/Vector.h>
31+
#include <wtf/text/WTFString.h>
32+
33+
namespace WebKit {
34+
35+
// The value of a tristate ARIA property such as aria-checked or aria-pressed.
36+
enum class AccessibilityTriState : uint8_t {
37+
False,
38+
True,
39+
Mixed,
40+
};
41+
42+
// Computed accessibility properties sent from the WebProcess to the UIProcess for WebDriver.
43+
// When this is updated, ComputedAccessibilityProperties.serialization.in must be updated as well.
44+
struct ComputedAccessibilityProperties {
45+
WebCore::AXID accessibilityNodeID;
46+
String role;
47+
String label;
48+
std::optional<AccessibilityTriState> checked;
49+
std::optional<AccessibilityTriState> pressed;
50+
std::optional<WebCore::AXID> parentAccessibilityNodeID;
51+
Vector<WebCore::AXID> childAccessibilityNodeIDs;
52+
};
53+
54+
} // namespace WebKit
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (C) 2026 Apple Inc. All rights reserved.
2+
#
3+
# Redistribution and use in source and binary forms, with or without
4+
# modification, are permitted provided that the following conditions
5+
# are met:
6+
# 1. Redistributions of source code must retain the above copyright
7+
# notice, this list of conditions and the following disclaimer.
8+
# 2. Redistributions in binary form must reproduce the above copyright
9+
# notice, this list of conditions and the following disclaimer in the
10+
# documentation and/or other materials provided with the distribution.
11+
#
12+
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15+
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22+
23+
header: "ComputedAccessibilityProperties.h"
24+
enum class WebKit::AccessibilityTriState : uint8_t {
25+
False,
26+
True,
27+
Mixed,
28+
};
29+
30+
header: "ComputedAccessibilityProperties.h"
31+
struct WebKit::ComputedAccessibilityProperties {
32+
WebCore::AXID accessibilityNodeID;
33+
String role;
34+
String label;
35+
std::optional<WebKit::AccessibilityTriState> checked;
36+
std::optional<WebKit::AccessibilityTriState> pressed;
37+
std::optional<WebCore::AXID> parentAccessibilityNodeID;
38+
Vector<WebCore::AXID> childAccessibilityNodeIDs;
39+
};

‎Source/WebKit/UIProcess/Automation/Automation.json‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22
"domain": "Automation",
33
"description": "Automation domain exposes commands for automating user interactions with the browser.",
44
"types": [
5+
{
6+
"id": "AccessibilityProperties",
7+
"type": "object",
8+
"description": "Snapshot of a DOM node's computed accessibility properties used in WebDriver contexts.",
9+
"properties": [
10+
{ "name": "accessibilityNodeId", "type": "string", "description": "The handle of the accessibility node." },
11+
{ "name": "role", "type": "string", "description": "The computed role." },
12+
{ "name": "label", "type": "string", "description": "The computed label." },
13+
{ "name": "checked", "type": "string", "optional": true, "description": "The checked state (\"true\", \"false\", or \"mixed\"). Omitted if the node does not support a checked state." },
14+
{ "name": "pressed", "type": "string", "optional": true, "description": "The pressed state (\"true\", \"false\", or \"mixed\"). Omitted if the node is not a toggle button." },
15+
{ "name": "parent", "type": "string", "optional": true, "description": "The handle of the parent accessibility node. Omitted if the node has no parent." },
16+
{ "name": "children", "type": "array", "items": { "type": "string" }, "description": "The handles of the unignored child accessibility nodes." }
17+
]
18+
},
519
{
620
"id": "Point",
721
"type": "object",
@@ -736,6 +750,31 @@
736750
],
737751
"async": true
738752
},
753+
{
754+
"name": "getAccessibilityPropertiesForElement",
755+
"description": "Get computed accessibility properties for a DOM element.",
756+
"parameters": [
757+
{ "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
758+
{ "name": "frameHandle", "$ref": "FrameHandle", "optional": true, "description": "The handle for the frame that contains the element. The main frame is used if this parameter is empty string or excluded." },
759+
{ "name": "nodeHandle", "$ref": "NodeHandle", "description": "The handle of the element to get the accessibility properties for." }
760+
],
761+
"returns": [
762+
{ "name": "properties", "$ref": "AccessibilityProperties" }
763+
],
764+
"async": true
765+
},
766+
{
767+
"name": "getAccessibilityPropertiesForAccessibilityNode",
768+
"description": "Get computed accessibility properties for an accessibility node from WebKit's accessibility tree.",
769+
"parameters": [
770+
{ "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." },
771+
{ "name": "accessibilityNodeHandle", "type": "string", "description": "The handle of the accessibility node to get the accessibility properties for." }
772+
],
773+
"returns": [
774+
{ "name": "properties", "$ref": "AccessibilityProperties" }
775+
],
776+
"async": true
777+
},
739778
{
740779
"name": "selectOptionElement",
741780
"description": "Selects the given option element. In case of container with multiple options enabled, the element selectedness is toggled.",

‎Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "APIOpenPanelParameters.h"
3434
#include "APIString.h"
3535
#include "AutomationProtocolObjects.h"
36+
#include "ComputedAccessibilityProperties.h"
3637
#include "CoordinateSystem.h"
3738
#include "InspectorPassthroughChannel.h"
3839
#include "PageLoadState.h"
@@ -1783,6 +1784,83 @@ void WebAutomationSession::getComputedLabel(const Inspector::Protocol::Automatio
17831784
page->sendWithAsyncReplyToProcessContainingFrameWithoutDestinationIdentifier(frameID, Messages::WebAutomationSessionProxy::GetComputedLabel(page->webPageIDInProcessForFrame(frameID), frameID, nodeHandle), WTF::move(completionHandler));
17841785
}
17851786

1787+
static String stringForAccessibilityNodeID(WebCore::AXID accessibilityNodeID)
1788+
{
1789+
return String::number(accessibilityNodeID.toUInt64());
1790+
}
1791+
1792+
static String stringForAccessibilityTriState(AccessibilityTriState state)
1793+
{
1794+
switch (state) {
1795+
case AccessibilityTriState::True:
1796+
return "true"_s;
1797+
case AccessibilityTriState::False:
1798+
return "false"_s;
1799+
case AccessibilityTriState::Mixed:
1800+
return "mixed"_s;
1801+
}
1802+
ASSERT_NOT_REACHED();
1803+
return "false"_s;
1804+
}
1805+
1806+
static WTF::CompletionHandler<void(std::optional<String>, std::optional<ComputedAccessibilityProperties>)> makeAccessibilityPropertiesCompletionHandler(Inspector::CommandCallback<Ref<Inspector::Protocol::Automation::AccessibilityProperties>>&& callback)
1807+
{
1808+
return [callback = WTF::move(callback)](std::optional<String>&& optionalError, std::optional<ComputedAccessibilityProperties>&& properties) mutable {
1809+
ASYNC_FAIL_WITH_PREDEFINED_ERROR_IF_SET(optionalError);
1810+
ASYNC_FAIL_WITH_PREDEFINED_ERROR_IF(!properties, InternalError);
1811+
1812+
auto children = JSON::ArrayOf<String>::create();
1813+
for (auto childAccessibilityNodeID : properties->childAccessibilityNodeIDs)
1814+
children->addItem(stringForAccessibilityNodeID(childAccessibilityNodeID));
1815+
1816+
auto axProperties = Inspector::Protocol::Automation::AccessibilityProperties::create()
1817+
.setAccessibilityNodeId(stringForAccessibilityNodeID(properties->accessibilityNodeID))
1818+
.setRole(WTF::move(properties->role))
1819+
.setLabel(WTF::move(properties->label))
1820+
.setChildren(WTF::move(children))
1821+
.release();
1822+
1823+
if (properties->checked)
1824+
axProperties->setChecked(stringForAccessibilityTriState(*properties->checked));
1825+
if (properties->pressed)
1826+
axProperties->setPressed(stringForAccessibilityTriState(*properties->pressed));
1827+
if (properties->parentAccessibilityNodeID)
1828+
axProperties->setParent(stringForAccessibilityNodeID(*properties->parentAccessibilityNodeID));
1829+
1830+
callback({ WTF::move(axProperties) });
1831+
};
1832+
}
1833+
1834+
void WebAutomationSession::getAccessibilityPropertiesForElement(const Inspector::Protocol::Automation::BrowsingContextHandle& browsingContextHandle, const Inspector::Protocol::Automation::FrameHandle& frameHandle, const Inspector::Protocol::Automation::NodeHandle& nodeHandle, Inspector::CommandCallback<Ref<Inspector::Protocol::Automation::AccessibilityProperties>>&& callback)
1835+
{
1836+
auto page = webPageProxyForHandle(browsingContextHandle);
1837+
ASYNC_FAIL_WITH_PREDEFINED_ERROR_IF(!page, WindowNotFound);
1838+
1839+
bool frameNotFound = false;
1840+
auto frameID = webFrameIDForHandle(frameHandle, frameNotFound);
1841+
ASYNC_FAIL_WITH_PREDEFINED_ERROR_IF(frameNotFound, FrameNotFound);
1842+
1843+
page->sendWithAsyncReplyToProcessContainingFrameWithoutDestinationIdentifier(
1844+
frameID,
1845+
Messages::WebAutomationSessionProxy::GetAccessibilityPropertiesForElement(page->webPageIDInProcessForFrame(frameID), frameID, nodeHandle),
1846+
Messages::WebAutomationSessionProxy::GetAccessibilityPropertiesForElement::Reply {
1847+
makeAccessibilityPropertiesCompletionHandler(WTF::move(callback))
1848+
});
1849+
}
1850+
1851+
void WebAutomationSession::getAccessibilityPropertiesForAccessibilityNode(const Inspector::Protocol::Automation::BrowsingContextHandle& browsingContextHandle, const String& accessibilityNodeHandle, Inspector::CommandCallback<Ref<Inspector::Protocol::Automation::AccessibilityProperties>>&& callback)
1852+
{
1853+
RefPtr page = webPageProxyForHandle(browsingContextHandle);
1854+
ASYNC_FAIL_WITH_PREDEFINED_ERROR_IF(!page, WindowNotFound);
1855+
1856+
// FIXME: Accessibility node handles are AXIDs, which are only unique within a single web process, and this
1857+
// always looks them up in the main frame's process. Encode the frame in the handle and route to the process
1858+
// containing that frame so that nodes in cross-process (site-isolated) iframes work.
1859+
protect(page->legacyMainFrameProcess())->sendWithAsyncReply(
1860+
Messages::WebAutomationSessionProxy::GetAccessibilityPropertiesForAccessibilityNode(page->webPageIDInMainFrameProcess(), accessibilityNodeHandle),
1861+
makeAccessibilityPropertiesCompletionHandler(WTF::move(callback)));
1862+
}
1863+
17861864
void WebAutomationSession::selectOptionElement(const Inspector::Protocol::Automation::BrowsingContextHandle& browsingContextHandle, const Inspector::Protocol::Automation::FrameHandle& frameHandle, const Inspector::Protocol::Automation::NodeHandle& nodeHandle, CommandCallback<void>&& callback)
17871865
{
17881866
auto page = webPageProxyForHandle(browsingContextHandle);

0 commit comments

Comments
 (0)