WebDriver: add support for wheel actions
https://bugs.webkit.org/show_bug.cgi?id=217174
Reviewed by Brian Burg.
.:
Enable WEBDRIVER_WHEEL_INTERACTIONS for GTK and WPE ports.
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsWPE.cmake:
* Source/cmake/WebKitFeatures.cmake:
Source/WebDriver:
Handle wheel actions.
* Actions.h:
* Session.cpp:
(WebDriver::automationSourceType): Handle InputSource::Type::Wheel.
(WebDriver::Session::performActions): Handle Action::Type::Wheel.
* WebDriverService.cpp:
(WebDriver::processKeyAction): Assert if Action::Subtype::Scroll.
(WebDriver::processPointerMoveAction): Move this code to a helper to be used by both pointer move and scroll actions.
(WebDriver::processPointerAction): Use processPointerMoveAction().
(WebDriver::processWheelAction): Call processPointerMoveAction() and process the scroll delta too.
(WebDriver::processInputActionSequence): Handle InputSource::Type::Wheel.
Source/WebKit:
* UIProcess/Automation/Automation.json: Add scroll delta to action state.
* UIProcess/Automation/SimulatedInputDispatcher.cpp:
(WebKit::SimulatedInputSourceState::emptyStateForSourceType): Initialize scrollDelta for wheel actions.
(WebKit::SimulatedInputDispatcher::transitionInputSourceToState): Handle SimulatedInputSourceType::Wheel.
* UIProcess/Automation/SimulatedInputDispatcher.h:
* UIProcess/Automation/WebAutomationSession.cpp:
(WebKit::WebAutomationSession::WebAutomationSession): Add SimulatedInputSourceType::Wheel.
(WebKit::WebAutomationSession::terminate): Handle pending wheel events.
(WebKit::WebAutomationSession::willShowJavaScriptDialog): Ditto.
(WebKit::WebAutomationSession::wheelEventsFlushedForPage): Ditto.
(WebKit::WebAutomationSession::willClosePage): Ditto.
(WebKit::WebAutomationSession::isSimulatingUserInteraction const): Return true if there are pending wheel events too.
(WebKit::WebAutomationSession::simulateWheelInteraction): Handle the wheel action.
(WebKit::simulatedInputSourceTypeFromProtocolSourceType): Handle Inspector::Protocol::Automation::InputSourceType::Wheel.
(WebKit::WebAutomationSession::performInteractionSequence): Initialize the scroll delta for wheel action.
* UIProcess/Automation/WebAutomationSession.h:
* UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp:
(WebKit::WebAutomationSession::platformSimulateWheelInteraction): Synthesize a wheel event.
* UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp:
(WebKit::WebAutomationSession::platformSimulateWheelInteraction): Ditto.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::isProcessingWheelEvents const): Return whether page has pending wheel events.
(WebKit::WebPageProxy::didReceiveEvent): Notify automation that pending wheel events have been processed.
* UIProcess/WebPageProxy.h:
* config.h:
Tools:
Add webdriver-wheel-interactions option.
* Scripts/webkitperl/FeatureList.pm:
WebDriverTests:
Remove expectations for wheel actions test.
* TestExpectations.json:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@268793 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/ChangeLog b/ChangeLog
index 90c6d15..45c63ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2020-10-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ WebDriver: add support for wheel actions
+ https://bugs.webkit.org/show_bug.cgi?id=217174
+
+ Reviewed by Brian Burg.
+
+ Enable WEBDRIVER_WHEEL_INTERACTIONS for GTK and WPE ports.
+
+ * Source/cmake/OptionsGTK.cmake:
+ * Source/cmake/OptionsWPE.cmake:
+ * Source/cmake/WebKitFeatures.cmake:
+
2020-10-20 Michael Catanzaro <mcatanzaro@gnome.org>
[GTK] Move ENABLE_ASYNC_SCROLLING build option to right place in OptionsGTK.cmake
diff --git a/Source/WebDriver/Actions.h b/Source/WebDriver/Actions.h
index 671f4a2..3024f2d 100644
--- a/Source/WebDriver/Actions.h
+++ b/Source/WebDriver/Actions.h
@@ -33,7 +33,7 @@
enum class PointerType { Mouse, Pen, Touch };
struct InputSource {
- enum class Type { None, Key, Pointer };
+ enum class Type { None, Key, Pointer, Wheel };
Type type;
Optional<PointerType> pointerType;
@@ -51,8 +51,8 @@
};
struct Action {
- enum class Type { None, Key, Pointer };
- enum class Subtype { Pause, PointerUp, PointerDown, PointerMove, PointerCancel, KeyUp, KeyDown };
+ enum class Type { None, Key, Pointer, Wheel };
+ enum class Subtype { Pause, PointerUp, PointerDown, PointerMove, PointerCancel, KeyUp, KeyDown, Scroll };
Action(const String& id, Type type, Subtype subtype)
: id(id)
@@ -71,6 +71,8 @@
Optional<PointerOrigin> origin;
Optional<int64_t> x;
Optional<int64_t> y;
+ Optional<int64_t> deltaX;
+ Optional<int64_t> deltaY;
Optional<String> key;
};
diff --git a/Source/WebDriver/ChangeLog b/Source/WebDriver/ChangeLog
index 411d255..83b4cca 100644
--- a/Source/WebDriver/ChangeLog
+++ b/Source/WebDriver/ChangeLog
@@ -1,3 +1,23 @@
+2020-10-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ WebDriver: add support for wheel actions
+ https://bugs.webkit.org/show_bug.cgi?id=217174
+
+ Reviewed by Brian Burg.
+
+ Handle wheel actions.
+
+ * Actions.h:
+ * Session.cpp:
+ (WebDriver::automationSourceType): Handle InputSource::Type::Wheel.
+ (WebDriver::Session::performActions): Handle Action::Type::Wheel.
+ * WebDriverService.cpp:
+ (WebDriver::processKeyAction): Assert if Action::Subtype::Scroll.
+ (WebDriver::processPointerMoveAction): Move this code to a helper to be used by both pointer move and scroll actions.
+ (WebDriver::processPointerAction): Use processPointerMoveAction().
+ (WebDriver::processWheelAction): Call processPointerMoveAction() and process the scroll delta too.
+ (WebDriver::processInputActionSequence): Handle InputSource::Type::Wheel.
+
2020-10-20 Carlos Garcia Campos <cgarcia@igalia.com>
WebDriver: add support for right variations of virtual keys
diff --git a/Source/WebDriver/Session.cpp b/Source/WebDriver/Session.cpp
index 3335da5..fe1ccca 100644
--- a/Source/WebDriver/Session.cpp
+++ b/Source/WebDriver/Session.cpp
@@ -2619,6 +2619,8 @@
return "Mouse";
case InputSource::Type::Key:
return "Keyboard";
+ case InputSource::Type::Wheel:
+ return "Wheel";
}
RELEASE_ASSERT_NOT_REACHED();
}
@@ -2709,6 +2711,7 @@
break;
case Action::Subtype::KeyUp:
case Action::Subtype::KeyDown:
+ case Action::Subtype::Scroll:
ASSERT_NOT_REACHED();
}
if (currentState.pressedButton)
@@ -2743,6 +2746,7 @@
case Action::Subtype::PointerDown:
case Action::Subtype::PointerMove:
case Action::Subtype::PointerCancel:
+ case Action::Subtype::Scroll:
ASSERT_NOT_REACHED();
}
if (currentState.pressedKey)
@@ -2755,6 +2759,36 @@
state->setArray("pressedVirtualKeys"_s, WTFMove(virtualKeys));
}
break;
+ case Action::Type::Wheel:
+ switch (action.subtype) {
+ case Action::Subtype::Scroll: {
+ state->setString("origin"_s, automationOriginType(action.origin->type));
+ auto location = JSON::Object::create();
+ location->setInteger("x"_s, action.x.value());
+ location->setInteger("y"_s, action.y.value());
+ state->setObject("location"_s, WTFMove(location));
+
+ auto delta = JSON::Object::create();
+ delta->setInteger("width"_s, action.deltaX.value());
+ delta->setInteger("height"_s, action.deltaY.value());
+ state->setObject("delta"_s, WTFMove(delta));
+
+ if (action.origin->type == PointerOrigin::Type::Element)
+ state->setString("nodeHandle"_s, action.origin->elementID.value());
+ FALLTHROUGH;
+ }
+ case Action::Subtype::Pause:
+ if (action.duration)
+ state->setDouble("duration"_s, action.duration.value());
+ break;
+ case Action::Subtype::PointerUp:
+ case Action::Subtype::PointerDown:
+ case Action::Subtype::PointerMove:
+ case Action::Subtype::PointerCancel:
+ case Action::Subtype::KeyUp:
+ case Action::Subtype::KeyDown:
+ ASSERT_NOT_REACHED();
+ }
}
states->pushObject(WTFMove(state));
}
diff --git a/Source/WebDriver/WebDriverService.cpp b/Source/WebDriver/WebDriverService.cpp
index 29449f5..8b79aae 100644
--- a/Source/WebDriver/WebDriverService.cpp
+++ b/Source/WebDriver/WebDriverService.cpp
@@ -1909,6 +1909,7 @@
case Action::Subtype::PointerDown:
case Action::Subtype::PointerMove:
case Action::Subtype::PointerCancel:
+ case Action::Subtype::Scroll:
ASSERT_NOT_REACHED();
}
@@ -1931,6 +1932,60 @@
return MouseButton::None;
}
+static bool processPointerMoveAction(JSON::Object& actionItem, Action& action, Optional<String>& errorMessage)
+{
+ if (auto durationValue = actionItem.getValue("duration"_s)) {
+ auto duration = unsignedValue(*durationValue);
+ if (!duration) {
+ errorMessage = String("The parameter 'duration' is invalid in action");
+ return false;
+ }
+ action.duration = duration.value();
+ }
+
+ if (auto originValue = actionItem.getValue("origin"_s)) {
+ if (auto originObject = originValue->asObject()) {
+ auto elementID = originObject->getString(Session::webElementIdentifier());
+ if (!elementID) {
+ errorMessage = String("The parameter 'origin' is not a valid web element object in action");
+ return false;
+ }
+ action.origin = PointerOrigin { PointerOrigin::Type::Element, elementID };
+ } else {
+ auto origin = originValue->asString();
+ if (origin == "viewport")
+ action.origin = PointerOrigin { PointerOrigin::Type::Viewport, WTF::nullopt };
+ else if (origin == "pointer")
+ action.origin = PointerOrigin { PointerOrigin::Type::Pointer, WTF::nullopt };
+ else {
+ errorMessage = String("The parameter 'origin' is invalid in action");
+ return false;
+ }
+ }
+ } else
+ action.origin = PointerOrigin { PointerOrigin::Type::Viewport, WTF::nullopt };
+
+ if (auto xValue = actionItem.getValue("x"_s)) {
+ auto x = valueAsNumberInRange(*xValue, INT_MIN);
+ if (!x) {
+ errorMessage = String("The paramater 'x' is invalid for action");
+ return false;
+ }
+ action.x = x.value();
+ }
+
+ if (auto yValue = actionItem.getValue("y"_s)) {
+ auto y = valueAsNumberInRange(*yValue, INT_MIN);
+ if (!y) {
+ errorMessage = String("The paramater 'y' is invalid for action");
+ return false;
+ }
+ action.y = y.value();
+ }
+
+ return true;
+}
+
static Optional<Action> processPointerAction(const String& id, PointerParameters& parameters, JSON::Object& actionItem, Optional<String>& errorMessage)
{
Action::Subtype actionSubtype;
@@ -1973,61 +2028,69 @@
action.button = actionMouseButton(button.value());
break;
}
- case Action::Subtype::PointerMove: {
- if (auto durationValue = actionItem.getValue("duration"_s)) {
- auto duration = unsignedValue(*durationValue);
- if (!duration) {
- errorMessage = String("The parameter 'duration' is invalid in pointer move action");
- return WTF::nullopt;
- }
- action.duration = duration.value();
- }
-
- if (auto originValue = actionItem.getValue("origin"_s)) {
- if (auto originObject = originValue->asObject()) {
- auto elementID = originObject->getString(Session::webElementIdentifier());
- if (!elementID) {
- errorMessage = String("The parameter 'origin' is not a valid web element object in pointer move action");
- return WTF::nullopt;
- }
- action.origin = PointerOrigin { PointerOrigin::Type::Element, elementID };
- } else {
- auto origin = originValue->asString();
- if (origin == "viewport")
- action.origin = PointerOrigin { PointerOrigin::Type::Viewport, WTF::nullopt };
- else if (origin == "pointer")
- action.origin = PointerOrigin { PointerOrigin::Type::Pointer, WTF::nullopt };
- else {
- errorMessage = String("The parameter 'origin' is invalid in pointer move action");
- return WTF::nullopt;
- }
- }
- } else
- action.origin = PointerOrigin { PointerOrigin::Type::Viewport, WTF::nullopt };
-
- if (auto xValue = actionItem.getValue("x"_s)) {
- auto x = valueAsNumberInRange(*xValue, INT_MIN);
- if (!x) {
- errorMessage = String("The paramater 'x' is invalid for pointer move action");
- return WTF::nullopt;
- }
- action.x = x.value();
- }
-
- if (auto yValue = actionItem.getValue("y"_s)) {
- auto y = valueAsNumberInRange(*yValue, INT_MIN);
- if (!y) {
- errorMessage = String("The paramater 'y' is invalid for pointer move action");
- return WTF::nullopt;
- }
- action.y = y.value();
- }
+ case Action::Subtype::PointerMove:
+ if (!processPointerMoveAction(actionItem, action, errorMessage))
+ return WTF::nullopt;
break;
- }
case Action::Subtype::PointerCancel:
break;
case Action::Subtype::KeyUp:
case Action::Subtype::KeyDown:
+ case Action::Subtype::Scroll:
+ ASSERT_NOT_REACHED();
+ }
+
+ return action;
+}
+
+static Optional<Action> processWheelAction(const String& id, JSON::Object& actionItem, Optional<String>& errorMessage)
+{
+ Action::Subtype actionSubtype;
+ auto subtype = actionItem.getString("type"_s);
+ if (subtype == "pause")
+ actionSubtype = Action::Subtype::Pause;
+ else if (subtype == "scroll")
+ actionSubtype = Action::Subtype::Scroll;
+ else {
+ errorMessage = String("The parameter 'type' of wheel action is invalid");
+ return WTF::nullopt;
+ }
+
+ Action action(id, Action::Type::Wheel, actionSubtype);
+
+ switch (actionSubtype) {
+ case Action::Subtype::Pause:
+ if (!processPauseAction(actionItem, action, errorMessage))
+ return WTF::nullopt;
+ break;
+ case Action::Subtype::Scroll:
+ if (!processPointerMoveAction(actionItem, action, errorMessage))
+ return WTF::nullopt;
+
+ if (auto deltaXValue = actionItem.getValue("deltaX"_s)) {
+ auto deltaX = valueAsNumberInRange(*deltaXValue, INT_MIN);
+ if (!deltaX) {
+ errorMessage = String("The paramater 'deltaX' is invalid for action");
+ return WTF::nullopt;
+ }
+ action.deltaX = deltaX.value();
+ }
+
+ if (auto deltaYValue = actionItem.getValue("deltaY"_s)) {
+ auto deltaY = valueAsNumberInRange(*deltaYValue, INT_MIN);
+ if (!deltaY) {
+ errorMessage = String("The paramater 'deltaY' is invalid for action");
+ return WTF::nullopt;
+ }
+ action.deltaY = deltaY.value();
+ }
+ break;
+ case Action::Subtype::KeyUp:
+ case Action::Subtype::KeyDown:
+ case Action::Subtype::PointerUp:
+ case Action::Subtype::PointerDown:
+ case Action::Subtype::PointerMove:
+ case Action::Subtype::PointerCancel:
ASSERT_NOT_REACHED();
}
@@ -2080,6 +2143,8 @@
inputSourceType = InputSource::Type::Key;
else if (type == "pointer")
inputSourceType = InputSource::Type::Pointer;
+ else if (type == "wheel")
+ inputSourceType = InputSource::Type::Wheel;
else if (type == "none")
inputSourceType = InputSource::Type::None;
else {
@@ -2136,6 +2201,8 @@
action = processKeyAction(id, *actionItem, errorMessage);
else if (inputSourceType == InputSource::Type::Pointer)
action = processPointerAction(id, parameters.value(), *actionItem, errorMessage);
+ else if (inputSourceType == InputSource::Type::Wheel)
+ action = processWheelAction(id, *actionItem, errorMessage);
if (!action)
return WTF::nullopt;
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index f49b9dc..f05edcb 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,36 @@
+2020-10-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ WebDriver: add support for wheel actions
+ https://bugs.webkit.org/show_bug.cgi?id=217174
+
+ Reviewed by Brian Burg.
+
+ * UIProcess/Automation/Automation.json: Add scroll delta to action state.
+ * UIProcess/Automation/SimulatedInputDispatcher.cpp:
+ (WebKit::SimulatedInputSourceState::emptyStateForSourceType): Initialize scrollDelta for wheel actions.
+ (WebKit::SimulatedInputDispatcher::transitionInputSourceToState): Handle SimulatedInputSourceType::Wheel.
+ * UIProcess/Automation/SimulatedInputDispatcher.h:
+ * UIProcess/Automation/WebAutomationSession.cpp:
+ (WebKit::WebAutomationSession::WebAutomationSession): Add SimulatedInputSourceType::Wheel.
+ (WebKit::WebAutomationSession::terminate): Handle pending wheel events.
+ (WebKit::WebAutomationSession::willShowJavaScriptDialog): Ditto.
+ (WebKit::WebAutomationSession::wheelEventsFlushedForPage): Ditto.
+ (WebKit::WebAutomationSession::willClosePage): Ditto.
+ (WebKit::WebAutomationSession::isSimulatingUserInteraction const): Return true if there are pending wheel events too.
+ (WebKit::WebAutomationSession::simulateWheelInteraction): Handle the wheel action.
+ (WebKit::simulatedInputSourceTypeFromProtocolSourceType): Handle Inspector::Protocol::Automation::InputSourceType::Wheel.
+ (WebKit::WebAutomationSession::performInteractionSequence): Initialize the scroll delta for wheel action.
+ * UIProcess/Automation/WebAutomationSession.h:
+ * UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp:
+ (WebKit::WebAutomationSession::platformSimulateWheelInteraction): Synthesize a wheel event.
+ * UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp:
+ (WebKit::WebAutomationSession::platformSimulateWheelInteraction): Ditto.
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::isProcessingWheelEvents const): Return whether page has pending wheel events.
+ (WebKit::WebPageProxy::didReceiveEvent): Notify automation that pending wheel events have been processed.
+ * UIProcess/WebPageProxy.h:
+ * config.h:
+
2020-10-20 Peng Liu <peng.liu6@apple.com>
[Media in GPU Process] Some WebAudio layout tests generate strange noises
diff --git a/Source/WebKit/UIProcess/Automation/Automation.json b/Source/WebKit/UIProcess/Automation/Automation.json
index f9d08da..2e8b8e3 100644
--- a/Source/WebKit/UIProcess/Automation/Automation.json
+++ b/Source/WebKit/UIProcess/Automation/Automation.json
@@ -289,7 +289,8 @@
"Null",
"Mouse",
"Keyboard",
- "Touch"
+ "Touch",
+ "Wheel"
]
},
{
@@ -327,9 +328,10 @@
{ "name": "pressedCharKey", "type": "string", "optional": true, "description": "For 'keyboard' input sources, specifies a character key that has 'pressed' state. Unmentioned character keys are assumed to have a 'released' state." },
{ "name": "pressedVirtualKeys", "type": "array", "items": { "$ref": "VirtualKey" }, "optional": true, "description": "For 'keyboard' input sources, specifies virtual keys that have a 'pressed' state. Unmentioned virtual keys are assumed to have a 'released' state." },
{ "name": "pressedButton", "$ref": "MouseButton", "optional": true, "description": "For 'mouse' input sources, specifies which mouse button has a 'pressed' state. Unmentioned mouse buttons are assumed to have a 'released' state. For 'touch' input sources, passing MouseButton::Left denotes a touch-down state." },
- { "name": "origin", "$ref": "MouseMoveOrigin", "optional": true, "description": "For 'mouse' input sources, specifies the origin type of a mouse move transition. Defaults to 'Viewport' if omitted."},
+ { "name": "origin", "$ref": "MouseMoveOrigin", "optional": true, "description": "For 'mouse' or 'wheel' input sources, specifies the origin type of a mouse move transition. Defaults to 'Viewport' if omitted."},
{ "name": "nodeHandle", "$ref": "NodeHandle", "optional": true, "description": "The handle of the element to use as origin when origin type is 'Element'."},
- { "name": "location", "$ref": "Point", "optional": true, "description": "For 'mouse' or 'touch' input sources, specifies a location in view coordinates to which the input source should transition. Transitioning to this state may interpolate intemediate input source states to better simulate real user movements and gestures." },
+ { "name": "location", "$ref": "Point", "optional": true, "description": "For 'mouse', 'wheel' or 'touch' input sources, specifies a location in view coordinates to which the input source should transition. Transitioning to this state may interpolate intemediate input source states to better simulate real user movements and gestures." },
+ { "name": "delta", "$ref": "Size", "optional": true, "description": "For 'wheel' input sources, specifies a scroll delta."},
{ "name": "duration", "type": "integer", "optional": true, "description": "The minimum number of milliseconds that must elapse while the relevant input source transitions to this state." }
]
}
diff --git a/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.cpp b/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.cpp
index 74b8867..8b623c1 100644
--- a/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.cpp
+++ b/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.cpp
@@ -43,6 +43,9 @@
case SimulatedInputSourceType::Null:
case SimulatedInputSourceType::Keyboard:
break;
+ case SimulatedInputSourceType::Wheel:
+ result.scrollDelta = WebCore::IntSize();
+ FALLTHROUGH;
case SimulatedInputSourceType::Mouse:
case SimulatedInputSourceType::Touch:
result.location = WebCore::IntPoint();
@@ -380,6 +383,35 @@
eventDispatchFinished(WTF::nullopt);
#endif // !ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
break;
+ case SimulatedInputSourceType::Wheel:
+#if !ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ RELEASE_ASSERT_NOT_REACHED();
+#else
+ resolveLocation(a.location.valueOr(WebCore::IntPoint()), b.location, b.origin.valueOr(MouseMoveOrigin::Viewport), b.nodeHandle, [this, &a, &b, eventDispatchFinished = WTFMove(eventDispatchFinished)](Optional<WebCore::IntPoint> location, Optional<AutomationCommandError> error) mutable {
+ if (error) {
+ eventDispatchFinished(error);
+ return;
+ }
+
+ if (!location) {
+ eventDispatchFinished(AUTOMATION_COMMAND_ERROR_WITH_NAME(ElementNotInteractable));
+ return;
+ }
+
+ b.location = location;
+
+ if (!a.scrollDelta->isZero())
+ b.scrollDelta->contract(a.scrollDelta->width(), a.scrollDelta->height());
+
+ if (!b.scrollDelta->isZero()) {
+ LOG(Automation, "SimulatedInputDispatcher[%p]: simulating Wheel from (%d, %d) to (%d, %d) for transition to %d.%d", this, a.scrollDelta->width(), a.scrollDelta->height(), b.scrollDelta->width(), b.scrollDelta->height(), m_keyframeIndex, m_inputSourceStateIndex);
+ // FIXME: This does not interpolate mouse scrolls per the "perform a scroll" algorithm (ยง15.4.4 Wheel actions).
+ m_client.simulateWheelInteraction(m_page, b.location.value(), b.scrollDelta.value(), WTFMove(eventDispatchFinished));
+ } else
+ eventDispatchFinished(WTF::nullopt);
+ });
+#endif // !ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ break;
}
}
diff --git a/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.h b/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.h
index 86fd478..1bf2b28 100644
--- a/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.h
+++ b/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.h
@@ -29,6 +29,7 @@
#include <WebCore/FrameIdentifier.h>
#include <WebCore/IntPoint.h>
+#include <WebCore/IntSize.h>
#include <wtf/CompletionHandler.h>
#include <wtf/HashSet.h>
#include <wtf/Optional.h>
@@ -67,6 +68,7 @@
Keyboard,
Mouse,
Touch,
+ Wheel,
};
enum class TouchInteraction {
@@ -82,6 +84,7 @@
Optional<MouseMoveOrigin> origin;
Optional<String> nodeHandle;
Optional<WebCore::IntPoint> location;
+ Optional<WebCore::IntSize> scrollDelta;
Optional<Seconds> duration;
static SimulatedInputSourceState emptyStateForSourceType(SimulatedInputSourceType);
@@ -134,6 +137,9 @@
#if ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
virtual void simulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, WTF::Variant<VirtualKey, CharKey>&&, AutomationCompletionHandler&&) = 0;
#endif
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ virtual void simulateWheelInteraction(WebPageProxy&, const WebCore::IntPoint& locationInView, const WebCore::IntSize& delta, AutomationCompletionHandler&&) = 0;
+#endif
virtual void viewportInViewCenterPointOfElement(WebPageProxy&, Optional<WebCore::FrameIdentifier>, const String& nodeHandle, Function<void (Optional<WebCore::IntPoint>, Optional<AutomationCommandError>)>&&) = 0;
};
diff --git a/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp b/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp
index a8735f0..a30da43 100644
--- a/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp
+++ b/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp
@@ -92,6 +92,9 @@
#if ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
m_inputSources.add(SimulatedInputSource::create(SimulatedInputSourceType::Keyboard));
#endif
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ m_inputSources.add(SimulatedInputSource::create(SimulatedInputSourceType::Wheel));
+#endif
m_inputSources.add(SimulatedInputSource::create(SimulatedInputSourceType::Null));
#endif // ENABLE(WEBDRIVER_ACTIONS_API)
}
@@ -165,6 +168,13 @@
}
#endif // ENABLE(WEBDRIVER_MOUSE_INTERACTIONS)
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ for (auto& identifier : copyToVector(m_pendingWheelEventsFlushedCallbacksPerPage.keys())) {
+ auto callback = m_pendingWheelEventsFlushedCallbacksPerPage.take(identifier);
+ callback(AUTOMATION_COMMAND_ERROR_WITH_NAME(InternalError));
+ }
+#endif // ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+
#if ENABLE(REMOTE_INSPECTOR)
if (Inspector::FrontendChannel* channel = m_remoteChannel) {
m_remoteChannel = nullptr;
@@ -676,6 +686,15 @@
}
#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
});
+
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ if (!m_pendingWheelEventsFlushedCallbacksPerPage.isEmpty()) {
+ for (auto key : copyToVector(m_pendingWheelEventsFlushedCallbacksPerPage.keys())) {
+ auto callback = m_pendingWheelEventsFlushedCallbacksPerPage.take(key);
+ callback(WTF::nullopt);
+ }
+ }
+#endif // ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
}
void WebAutomationSession::didEnterFullScreenForPage(const WebPageProxy&)
@@ -816,6 +835,16 @@
#endif
}
+void WebAutomationSession::wheelEventsFlushedForPage(const WebPageProxy& page)
+{
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ if (auto callback = m_pendingWheelEventsFlushedCallbacksPerPage.take(page.identifier()))
+ callback(WTF::nullopt);
+#else
+ UNUSED_PARAM(page);
+#endif
+}
+
void WebAutomationSession::willClosePage(const WebPageProxy& page)
{
String handle = handleForWebPageProxy(page);
@@ -831,6 +860,10 @@
if (auto callback = m_pendingKeyboardEventsFlushedCallbacksPerPage.take(page.identifier()))
callback(AUTOMATION_COMMAND_ERROR_WITH_NAME(WindowNotFound));
#endif
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ if (auto callback = m_pendingWheelEventsFlushedCallbacksPerPage.take(page.identifier()))
+ callback(AUTOMATION_COMMAND_ERROR_WITH_NAME(WindowNotFound));
+#endif
#if ENABLE(WEBDRIVER_ACTIONS_API)
// Then tell the input dispatcher to cancel so timers are stopped, and let it go out of scope.
@@ -1525,6 +1558,10 @@
if (!m_pendingKeyboardEventsFlushedCallbacksPerPage.isEmpty())
return true;
#endif
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ if (!m_pendingWheelEventsFlushedCallbacksPerPage.isEmpty())
+ return true;
+#endif
#if ENABLE(WEBDRIVER_TOUCH_INTERACTIONS)
if (m_simulatingTouchInteraction)
return true;
@@ -1671,6 +1708,40 @@
// Otherwise, wait for keyboardEventsFlushedCallback to run when all events are handled.
}
#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
+
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+void WebAutomationSession::simulateWheelInteraction(WebPageProxy& page, const WebCore::IntPoint& locationInViewport, const WebCore::IntSize& delta, AutomationCompletionHandler&& completionHandler)
+{
+ page.getWindowFrameWithCallback([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler), page = makeRef(page), locationInViewport, delta](WebCore::FloatRect windowFrame) mutable {
+ auto clippedX = std::min(std::max(0.0f, static_cast<float>(locationInViewport.x())), windowFrame.size().width());
+ auto clippedY = std::min(std::max(0.0f, static_cast<float>(locationInViewport.y())), windowFrame.size().height());
+ if (clippedX != locationInViewport.x() || clippedY != locationInViewport.y()) {
+ completionHandler(AUTOMATION_COMMAND_ERROR_WITH_NAME(TargetOutOfBounds));
+ return;
+ }
+
+ // Bridge the flushed callback to our command's completion handler.
+ auto wheelEventsFlushedCallback = [completionHandler = WTFMove(completionHandler)](Optional<AutomationCommandError> error) mutable {
+ completionHandler(error);
+ };
+
+ auto& callbackInMap = m_pendingWheelEventsFlushedCallbacksPerPage.add(page->identifier(), nullptr).iterator->value;
+ if (callbackInMap)
+ callbackInMap(AUTOMATION_COMMAND_ERROR_WITH_NAME(Timeout));
+ callbackInMap = WTFMove(wheelEventsFlushedCallback);
+
+ platformSimulateWheelInteraction(page, locationInViewport, delta);
+
+ // If the event does not hit test anything in the window, then it may not have been delivered.
+ if (callbackInMap && !page->isProcessingWheelEvents()) {
+ auto callbackToCancel = m_pendingWheelEventsFlushedCallbacksPerPage.take(page->identifier());
+ callbackToCancel(WTF::nullopt);
+ }
+
+ // Otherwise, wait for wheelEventsFlushedCallback to run when all events are handled.
+ });
+}
+#endif
#endif // ENABLE(WEBDRIVER_ACTIONS_API)
#if ENABLE(WEBDRIVER_MOUSE_INTERACTIONS)
@@ -1854,6 +1925,8 @@
return SimulatedInputSourceType::Mouse;
case Inspector::Protocol::Automation::InputSourceType::Touch:
return SimulatedInputSourceType::Touch;
+ case Inspector::Protocol::Automation::InputSourceType::Wheel:
+ return SimulatedInputSourceType::Wheel;
}
RELEASE_ASSERT_NOT_REACHED();
@@ -1965,6 +2038,10 @@
if (inputSourceType == SimulatedInputSourceType::Keyboard)
ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(NotImplemented, "Keyboard input sources are not yet supported.");
#endif
+#if !ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ if (inputSourceType == SimulatedInputSourceType::Wheel)
+ ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(NotImplemented, "Wheel input sources are not yet supported.");
+#endif
if (typeToSourceIdMap.contains(inputSourceType))
ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "Two input sources with the same type were specified.");
if (sourceIdToInputSourceMap.contains(sourceId))
@@ -2052,6 +2129,13 @@
sourceState.location = WebCore::IntPoint(*x, *y);
}
+ if (auto deltaObject = stateObject->getObject("delta"_s)) {
+ auto deltaX = deltaObject->getInteger("width"_s);
+ auto deltaY = deltaObject->getInteger("height"_s);
+ if (deltaX && deltaY)
+ sourceState.scrollDelta = WebCore::IntSize(*deltaX, *deltaY);
+ }
+
if (auto duration = stateObject->getInteger("duration"_s))
sourceState.duration = Seconds::fromMilliseconds(*duration);
diff --git a/Source/WebKit/UIProcess/Automation/WebAutomationSession.h b/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
index a3989ad..36dc37e 100644
--- a/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
+++ b/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
@@ -125,6 +125,7 @@
void inspectorFrontendLoaded(const WebPageProxy&);
void keyboardEventsFlushedForPage(const WebPageProxy&);
void mouseEventsFlushedForPage(const WebPageProxy&);
+ void wheelEventsFlushedForPage(const WebPageProxy&);
void willClosePage(const WebPageProxy&);
void handleRunOpenPanel(const WebPageProxy&, const WebFrameProxy&, const API::OpenPanelParameters&, WebOpenPanelResultListenerProxy&);
void willShowJavaScriptDialog(WebPageProxy&);
@@ -154,6 +155,9 @@
#if ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
void simulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, WTF::Variant<VirtualKey, CharKey>&&, AutomationCompletionHandler&&);
#endif
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ void simulateWheelInteraction(WebPageProxy&, const WebCore::IntPoint& locationInView, const WebCore::IntSize& delta, AutomationCompletionHandler&&);
+#endif
void viewportInViewCenterPointOfElement(WebPageProxy&, Optional<WebCore::FrameIdentifier>, const Inspector::Protocol::Automation::NodeHandle&, Function<void(Optional<WebCore::IntPoint>, Optional<AutomationCommandError>)>&&);
#endif // ENABLE(WEBDRIVER_ACTIONS_API)
@@ -263,6 +267,9 @@
// Simulates key presses to produce the codepoints in a string. One or more code points are delivered atomically at grapheme cluster boundaries.
void platformSimulateKeySequence(WebPageProxy&, const String&);
#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ void platformSimulateWheelInteraction(WebPageProxy&, const WebCore::IntPoint& locationInViewport, const WebCore::IntSize& delta);
+#endif // ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
// Get base64-encoded PNG data from a bitmap.
static Optional<String> platformGetBase64EncodedPNGData(const ShareableBitmap::Handle&);
@@ -306,6 +313,9 @@
#if ENABLE(WEBDRIVER_MOUSE_INTERACTIONS)
HashMap<WebPageProxyIdentifier, Function<void(Optional<AutomationCommandError>)>> m_pendingMouseEventsFlushedCallbacksPerPage;
#endif
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+ HashMap<WebPageProxyIdentifier, Function<void(Optional<AutomationCommandError>)>> m_pendingWheelEventsFlushedCallbacksPerPage;
+#endif
uint64_t m_nextEvaluateJavaScriptCallbackID { 1 };
HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>> m_evaluateJavaScriptFunctionCallbacks;
diff --git a/Source/WebKit/UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp b/Source/WebKit/UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp
index a61d77e..2f39aff 100644
--- a/Source/WebKit/UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp
+++ b/Source/WebKit/UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp
@@ -31,6 +31,7 @@
#include "WebPageProxy.h"
#include <WebCore/GtkUtilities.h>
#include <WebCore/GtkVersioning.h>
+#include <WebCore/Scrollbar.h>
namespace WebKit {
using namespace WebCore;
@@ -328,4 +329,14 @@
}
#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+void WebAutomationSession::platformSimulateWheelInteraction(WebPageProxy& page, const WebCore::IntPoint& locationInViewport, const WebCore::IntSize& delta)
+{
+ auto* viewWidget = reinterpret_cast<WebKitWebViewBase*>(page.viewWidget());
+ FloatSize scrollDelta(delta);
+ scrollDelta.scale(1 / static_cast<float>(Scrollbar::pixelsPerLineStep()));
+ webkitWebViewBaseSynthesizeWheelEvent(viewWidget, -scrollDelta.width(), -scrollDelta.height(), locationInViewport.x(), locationInViewport.y(), WheelEventPhase::NoPhase, WheelEventPhase::NoPhase);
+}
+#endif // ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp b/Source/WebKit/UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp
index cadbdd3..3de9515 100644
--- a/Source/WebKit/UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp
+++ b/Source/WebKit/UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp
@@ -364,5 +364,30 @@
}
#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)
+#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+void WebAutomationSession::platformSimulateWheelInteraction(WebPageProxy& page, const WebCore::IntPoint& locationInView, const WebCore::IntSize& delta)
+{
+#if WPE_CHECK_VERSION(1, 5, 0)
+ struct wpe_input_axis_2d_event event;
+ memset(&event, 0, sizeof(event));
+ event.base.type = static_cast<wpe_input_axis_event_type>(wpe_input_axis_event_type_mask_2d | wpe_input_axis_event_type_motion_smooth);
+ event.base.x = locationInView.x();
+ event.base.y = locationInView.y();
+ event.x_axis = -delta.width();
+ event.y_axis = -delta.height();
+ wpe_view_backend_dispatch_axis_event(page.viewBackend(), &event.base);
+#else
+ if (auto deltaX = delta.width()) {
+ struct wpe_input_axis_event event = { wpe_input_axis_event_type_motion, 0, locationInView.x(), locationInView.y(), 1, -deltaX, 0 };
+ wpe_view_backend_dispatch_axis_event(page.viewBackend(), &event);
+ }
+ if (auto deltaY = delta.height()) {
+ struct wpe_input_axis_event event = { wpe_input_axis_event_type_motion, 0, locationInView.x(), locationInView.y(), 0, -deltaY, 0 };
+ wpe_view_backend_dispatch_axis_event(page.viewBackend(), &event);
+ }
+#endif
+}
+#endif // ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
+
} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index baf7f05..8782808 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -6426,6 +6426,11 @@
return !m_mouseEventQueue.isEmpty();
}
+bool WebPageProxy::isProcessingWheelEvents() const
+{
+ return m_wheelEventCoalescer && m_wheelEventCoalescer->hasEventsBeingProcessed();
+}
+
NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
{
// <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
@@ -6942,6 +6947,8 @@
if (auto eventToSend = wheelEventCoalescer().nextEventToDispatch())
sendWheelEvent(*eventToSend);
+ else if (auto* automationSession = process().processPool().automationSession())
+ automationSession->wheelEventsFlushedForPage(*this);
break;
}
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
index 766db04..ccc5521 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.h
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
@@ -943,6 +943,7 @@
void didFinishProcessingAllPendingMouseEvents();
void flushPendingMouseEventCallbacks();
+ bool isProcessingWheelEvents() const;
void handleWheelEvent(const NativeWebWheelEvent&);
bool isProcessingKeyboardEvents() const;
diff --git a/Source/WebKit/config.h b/Source/WebKit/config.h
index 8748a4e..ee3c03a 100644
--- a/Source/WebKit/config.h
+++ b/Source/WebKit/config.h
@@ -60,7 +60,7 @@
#define USE_CREDENTIAL_STORAGE_WITH_NETWORK_SESSION 1
#endif
-// ENABLE_WEBDRIVER_ACTIONS_API represents whether mouse, keyboard or touch interactions are defined
-#if ENABLE(WEBDRIVER_MOUSE_INTERACTIONS) || ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS) || ENABLE(WEBDRIVER_TOUCH_INTERACTIONS)
+// ENABLE_WEBDRIVER_ACTIONS_API represents whether mouse, keyboard, touch or wheel interactions are defined
+#if ENABLE(WEBDRIVER_MOUSE_INTERACTIONS) || ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS) || ENABLE(WEBDRIVER_TOUCH_INTERACTIONS) || ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)
#define ENABLE_WEBDRIVER_ACTIONS_API 1
#endif
diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake
index a09e213..2800be7 100644
--- a/Source/cmake/OptionsGTK.cmake
+++ b/Source/cmake/OptionsGTK.cmake
@@ -271,6 +271,7 @@
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS ON)
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS ON)
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS OFF)
+ SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_WHEEL_INTERACTIONS ON)
endif ()
SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER TRUE)
diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
index 1ed137c..5fbf72f 100644
--- a/Source/cmake/OptionsWPE.cmake
+++ b/Source/cmake/OptionsWPE.cmake
@@ -165,6 +165,7 @@
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS ON)
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS ON)
SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS OFF)
+ SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_WHEEL_INTERACTIONS ON)
endif ()
if (ENABLE_XSLT)
diff --git a/Source/cmake/WebKitFeatures.cmake b/Source/cmake/WebKitFeatures.cmake
index 6df1971..7136cb9 100644
--- a/Source/cmake/WebKitFeatures.cmake
+++ b/Source/cmake/WebKitFeatures.cmake
@@ -219,6 +219,7 @@
WEBKIT_OPTION_DEFINE(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS "Toggle WebDriver keyboard interactions" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS "Toggle WebDriver mouse interactions" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS "Toggle WebDriver touch interactions" PRIVATE OFF)
+ WEBKIT_OPTION_DEFINE(ENABLE_WEBDRIVER_WHEEL_INTERACTIONS "Toggle WebDriver wheel interactions" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_WEBGL "Toggle WebGL support" PRIVATE ON)
WEBKIT_OPTION_DEFINE(ENABLE_WEBGL2 "Toggle WebGL2 support" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_WEBGPU "Toggle WebGPU support" PRIVATE OFF)
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index a0e9156..358f10e 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,14 @@
+2020-10-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ WebDriver: add support for wheel actions
+ https://bugs.webkit.org/show_bug.cgi?id=217174
+
+ Reviewed by Brian Burg.
+
+ Add webdriver-wheel-interactions option.
+
+ * Scripts/webkitperl/FeatureList.pm:
+
2020-10-21 Lauro Moura <lmoura@igalia.com>
webkitpy: Fix webdriver logging message
diff --git a/Tools/Scripts/webkitperl/FeatureList.pm b/Tools/Scripts/webkitperl/FeatureList.pm
index e1b5cdf..f84eccd 100644
--- a/Tools/Scripts/webkitperl/FeatureList.pm
+++ b/Tools/Scripts/webkitperl/FeatureList.pm
@@ -182,6 +182,7 @@
$webdriverMouseInteractionsSupport,
$webdriverSupport,
$webdriverTouchInteractionsSupport,
+ $webdriverWheelInteractionsSupport,
$webgl2Support,
$webglSupport,
$webgpuSupport,
@@ -553,6 +554,9 @@
{ option => "webdriver-touch-interactions", desc => "Toggle WebDriver touch interactions",
define => "ENABLE_WEBDRIVER_TOUCH_INTERACTIONS", value => \$webdriverTouchInteractionsSupport },
+ { option => "webdriver-wheel-interactions", desc => "Toggle WebDriver wheel interactions",
+ define => "ENABLE_WEBDRIVER_WHEEL_INTERACTIONS", value => \$webdriverWheelInteractionsSupport },
+
{ option => "webgl", desc => "Toggle WebGL support",
define => "ENABLE_WEBGL", value => \$webglSupport },
diff --git a/WebDriverTests/ChangeLog b/WebDriverTests/ChangeLog
index d4765cc..d551ab58 100644
--- a/WebDriverTests/ChangeLog
+++ b/WebDriverTests/ChangeLog
@@ -1,3 +1,14 @@
+2020-10-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ WebDriver: add support for wheel actions
+ https://bugs.webkit.org/show_bug.cgi?id=217174
+
+ Reviewed by Brian Burg.
+
+ Remove expectations for wheel actions test.
+
+ * TestExpectations.json:
+
2020-10-20 Lauro Moura <lmoura@igalia.com>
[WebDriver] Gardening WPE no browsing context failures
diff --git a/WebDriverTests/TestExpectations.json b/WebDriverTests/TestExpectations.json
index 249bf62..29ca09b 100644
--- a/WebDriverTests/TestExpectations.json
+++ b/WebDriverTests/TestExpectations.json
@@ -470,9 +470,6 @@
"imported/w3c/webdriver/tests/perform_actions/key_special_keys.py": {
"expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/184967"}}
},
- "imported/w3c/webdriver/tests/perform_actions/wheel.py": {
- "expected": {"all": {"status": ["FAIL"], "bug": "webkit.org/b/217174"}}
- },
"imported/w3c/webdriver/tests/close_window/close.py": {
"subtests": {