Skip to content
Permalink
Browse files
WebDriver: [macOS] Add support for Wheel input source and actions
https://bugs.webkit.org/show_bug.cgi?id=244092
rdar://45649400

Reviewed by Devin Rousso.

Enable WEBDRIVER_WHEEL_INTERACTIONS on macOS and properly create and dispatch scroll events. Because NSEvent does not
provide a direct mechanism for creating synthetic scroll events (like it does for Mouse and Keyboard events) we create a
CGEvent to represent the scroll, create an NSEvent from the CGEvent, and then force the event to be relative to and
associated with the window, which makes the events consistent with our other window-relative events and prevents the
event from being thrown out by the window as irrelevant.

This passes the WPT tests in /webdriver/tests/perform_actions/wheel.py when paired with a matching safaridriver change
to support parsing the events.

* Source/WTF/wtf/PlatformEnableCocoa.h:
* Source/WebKit/UIProcess/Automation/mac/WebAutomationSessionMac.mm:
(WebKit::viewportLocationToWindowLocation):
(WebKit::WebAutomationSession::platformSimulateMouseInteraction):
(WebKit::WebAutomationSession::platformSimulateWheelInteraction):
* Source/cmake/OptionsMac.cmake:

Canonical link: https://commits.webkit.org/253578@main
  • Loading branch information
patrickangle committed Aug 19, 2022
1 parent 1166551 commit 26e467ec43ea1c61b517fe20b4bb2d7ad7801a6d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
@@ -678,6 +678,10 @@
#define ENABLE_WEBDRIVER_MOUSE_INTERACTIONS 1
#endif

#if !defined(ENABLE_WEBDRIVER_WHEEL_INTERACTIONS) && PLATFORM(MAC)
#define ENABLE_WEBDRIVER_WHEEL_INTERACTIONS 1
#endif

#if !defined(ENABLE_WEBGL)
#define ENABLE_WEBGL 1
#endif
@@ -39,6 +39,7 @@
#import <WebCore/IntSize.h>
#import <WebCore/PlatformMouseEvent.h>
#import <objc/runtime.h>
#import <pal/spi/mac/NSEventSPI.h>

namespace WebKit {
using namespace WebCore;
@@ -133,6 +134,19 @@

#pragma mark Platform-dependent Implementations

#if ENABLE(WEBDRIVER_MOUSE_INTERACTIONS) || ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)

static WebCore::IntPoint viewportLocationToWindowLocation(WebCore::IntPoint locationInViewport, WebPageProxy& page)
{
IntRect windowRect;

IntPoint locationInView = locationInViewport + IntPoint(0, page.topContentInset());
page.rootViewToWindow(IntRect(locationInView, IntSize()), windowRect);
return windowRect.location();
}

#endif // ENABLE(WEBDRIVER_MOUSE_INTERACTIONS) || ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)

#if ENABLE(WEBDRIVER_MOUSE_INTERACTIONS)

static WebMouseEvent::Button automationMouseButtonToPlatformMouseButton(MouseButton button)
@@ -150,11 +164,7 @@
{
UNUSED_PARAM(pointerType);

IntRect windowRect;

IntPoint locationInView = locationInViewport + IntPoint(0, page.topContentInset());
page.rootViewToWindow(IntRect(locationInView, IntSize()), windowRect);
IntPoint locationInWindow = windowRect.location();
auto locationInWindow = viewportLocationToWindowLocation(locationInViewport, page);

NSEventModifierFlags modifiers = 0;
if (keyModifiers.contains(WebEvent::Modifier::MetaKey))
@@ -789,6 +799,29 @@ static BOOL characterIsProducedUsingShift(NSString *characters)
}
#endif // ENABLE(WEBDRIVER_KEYBOARD_INTERACTIONS)

#if ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)

void WebAutomationSession::platformSimulateWheelInteraction(WebPageProxy& page, const WebCore::IntPoint& locationInViewport, const WebCore::IntSize& delta)
{
static constexpr auto scrollWheelCount = 2;
auto cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent(nullptr, kCGScrollEventUnitPixel, scrollWheelCount, -delta.height(), -delta.width()));

auto locationInWindow = viewportLocationToWindowLocation(locationInViewport, page);
NSWindow *window = page.platformWindow();

// Set the CGEvent location in flipped coords relative to the first screen, which compensates for the behavior of
// +[NSEvent eventWithCGEvent:] when the event has no associated window. See <rdar://problem/17180591>.
auto locationOnScreen = [window convertPointToScreen:locationInWindow];
locationOnScreen = CGPointMake(locationOnScreen.x, NSScreen.screens.firstObject.frame.size.height - locationOnScreen.y);
CGEventSetLocation(cgScrollEvent.get(), locationOnScreen);

NSEvent *scrollEvent = [[NSEvent eventWithCGEvent:cgScrollEvent.get()] _eventRelativeToWindow:window];

sendSynthesizedEventsToPage(page, @[scrollEvent]);
}

#endif // ENABLE(WEBDRIVER_WHEEL_INTERACTIONS)

} // namespace WebKit

#endif // PLATFORM(MAC)
@@ -70,6 +70,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VARIATION_FONTS PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO_PRESENTATION_MODE PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBDRIVER_WHEEL_INTERACTIONS PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL2 PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBXR PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_API_STATISTICS PRIVATE ON)

0 comments on commit 26e467e

Please sign in to comment.