Add long press selection test
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Sep 2016 23:53:33 +0000 (23:53 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Sep 2016 23:53:33 +0000 (23:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162367

Patch by Megan Gardner <megan_gardner@apple.com> on 2016-09-22
Reviewed by Simon Fraser.

Tools:

Add support to UIScriptController to synthesize long press events on iOS.
This required adding long-press functionality to HIDEventGenerator.

HIDEventGenerator sends the touchDown, but must then send the touchUp with
a dispatch_after (rather than sleeping, as we do for other events) in order
for the gesture recognizers to correctly detect a long press.

Use the long press synthesis in a test that detects whether a long press
gesture triggers text selection.

Fixed incorrect constants. NSTimeInterval is in seconds, original numbers
were nanoseconds and typedefed to long without regard to the type
differences. Redid constants to be the right value, and converted upon use.

Cleaned up unused enum types.

* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::longPressAtPoint):
(WTR::UIScriptController::forcePressAtPoint):
(WTR::UIScriptController::dragFromPointToPoint): Deleted.
* Scripts/webkitpy/common/config/contributors.json:
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::longPressAtPoint):
(WTR::UIScriptController::forcePressAtPoint):
(WTR::UIScriptController::dragFromPointToPoint): Deleted.
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/ios/HIDEventGenerator.h:
* WebKitTestRunner/ios/HIDEventGenerator.mm:
(-[HIDEventGenerator _createIOHIDEventType:]):
(-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]):
(-[HIDEventGenerator clearTap:]):
(-[HIDEventGenerator longPressTimerCall:]):
(-[HIDEventGenerator longPressFinish:completionBlock:]):
(-[HIDEventGenerator longPress:completionBlock:]):
(-[HIDEventGenerator forcePress:completionBlock:]):
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::longPressAtPoint):
(WTR::UIScriptController::forcePressAtPoint):
(WTR::UIScriptController::dragFromPointToPoint): Deleted.

LayoutTests:

Added test for long press selection.

* fast/events/touch/ios/long-press-to-select-text-expected.txt: Added.
* fast/events/touch/ios/long-press-to-select-text.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206282 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/long-press-to-select-text-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/long-press-to-select-text.html [new file with mode: 0644]
Tools/ChangeLog
Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/ios/HIDEventGenerator.h
Tools/WebKitTestRunner/ios/HIDEventGenerator.mm
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index ab77597..58c2de9 100644 (file)
@@ -1,3 +1,15 @@
+2016-09-22  Megan Gardner  <megan_gardner@apple.com>
+
+        Add long press selection test
+        https://bugs.webkit.org/show_bug.cgi?id=162367
+
+        Reviewed by Simon Fraser.
+
+        Added test for long press selection.
+
+        * fast/events/touch/ios/long-press-to-select-text-expected.txt: Added.
+        * fast/events/touch/ios/long-press-to-select-text.html: Added.
+
 2016-09-22  Brady Eidson  <beidson@apple.com>
 
         IDBIndex.openCursor() matches indices on multiple object stores.
diff --git a/LayoutTests/fast/events/touch/ios/long-press-to-select-text-expected.txt b/LayoutTests/fast/events/touch/ios/long-press-to-select-text-expected.txt
new file mode 100644 (file)
index 0000000..608b432
--- /dev/null
@@ -0,0 +1,2 @@
+PASS: successfully selected the word PressMe
+Done
diff --git a/LayoutTests/fast/events/touch/ios/long-press-to-select-text.html b/LayoutTests/fast/events/touch/ios/long-press-to-select-text.html
new file mode 100644 (file)
index 0000000..9e2e06e
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function getUIScript()
+        {
+            return `
+            (function() {
+                uiController.longPressAtPoint(30, 20, function() {
+                    uiController.uiScriptComplete("Done");
+                });
+            })();`
+        }
+
+        function runTest()
+        {
+            if (!testRunner.runUIScript)
+                return;
+
+            var output = '';
+            var target = document.getElementById('target');
+            target.addEventListener('touchend', function(event) {
+                output += 'PASS: successfully selected the word ';
+            });
+            if (testRunner.runUIScript) {
+                testRunner.runUIScript(getUIScript(), function(result) {
+                    var selectionText = document.getSelection().toString();
+                    if (selectionText !== "")
+                        output += selectionText;
+                    else
+                        output += 'FAIL: failed to select a word as a result of a long press';
+                    output += '<br>';
+                    output += result;
+                    document.getElementById('target').innerHTML = output;
+                    testRunner.notifyDone();
+                });
+            }
+        }
+
+        window.addEventListener('load', runTest, false);
+    </script>
+    <style>
+        #target {
+            height: 100px;
+            width: 200px;
+            background-color: silver;
+        }
+    </style>
+    <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+<div id="target">
+       <p>PressMe</p>
+    This test requires UIScriptController to run.
+</div>
+</body>
+</html>
index ec42b6c..c4d92b9 100644 (file)
@@ -1,3 +1,51 @@
+2016-09-22  Megan Gardner  <megan_gardner@apple.com>
+
+        Add long press selection test
+        https://bugs.webkit.org/show_bug.cgi?id=162367
+
+        Reviewed by Simon Fraser.
+
+        Add support to UIScriptController to synthesize long press events on iOS.
+        This required adding long-press functionality to HIDEventGenerator.
+
+        HIDEventGenerator sends the touchDown, but must then send the touchUp with
+        a dispatch_after (rather than sleeping, as we do for other events) in order
+        for the gesture recognizers to correctly detect a long press.
+
+        Use the long press synthesis in a test that detects whether a long press
+        gesture triggers text selection.
+
+        Fixed incorrect constants. NSTimeInterval is in seconds, original numbers
+        were nanoseconds and typedefed to long without regard to the type
+        differences. Redid constants to be the right value, and converted upon use.
+
+        Cleaned up unused enum types.
+
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::longPressAtPoint):
+        (WTR::UIScriptController::forcePressAtPoint):
+        (WTR::UIScriptController::dragFromPointToPoint): Deleted.
+        * Scripts/webkitpy/common/config/contributors.json:
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::longPressAtPoint):
+        (WTR::UIScriptController::forcePressAtPoint):
+        (WTR::UIScriptController::dragFromPointToPoint): Deleted.
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/ios/HIDEventGenerator.h:
+        * WebKitTestRunner/ios/HIDEventGenerator.mm:
+        (-[HIDEventGenerator _createIOHIDEventType:]):
+        (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]):
+        (-[HIDEventGenerator clearTap:]):
+        (-[HIDEventGenerator longPressTimerCall:]):
+        (-[HIDEventGenerator longPressFinish:completionBlock:]):
+        (-[HIDEventGenerator longPress:completionBlock:]):
+        (-[HIDEventGenerator forcePress:completionBlock:]):
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::longPressAtPoint):
+        (WTR::UIScriptController::forcePressAtPoint):
+        (WTR::UIScriptController::dragFromPointToPoint): Deleted.
+
 2016-09-22  Jonathan Bedard  <jbedard@apple.com>
 
         Automatic Text Replacement Testing in WebKit2
index 50cce44..a8127a8 100644 (file)
@@ -87,6 +87,10 @@ void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback)
 void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
 {
 }
+    
+void UIScriptController::longPressAtPoint(long x, long y, JSValueRef)
+{
+}
 
 void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
 {
index 1c6623f..237637f 100644 (file)
@@ -38,6 +38,8 @@ interface UIScriptController {
     void doubleTapAtPoint(long x, long y, object callback);
     void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, object callback);
 
+    void longPressAtPoint(long x, long y, object callback);
+
     void stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object callback);
     void stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, object callback);
     void stylusUpAtPoint(long x, long y, object callback);
index 610f97d..9453b3b 100644 (file)
@@ -159,6 +159,10 @@ void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef)
 void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
 {
 }
+    
+void UIScriptController::longPressAtPoint(long x, long y, JSValueRef)
+{
+}
 
 void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
 {
index 42255da..26a7a85 100644 (file)
@@ -62,6 +62,8 @@ public:
     void stylusUpAtPoint(long x, long y, JSValueRef callback);
     void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback);
 
+    void longPressAtPoint(long x, long y, JSValueRef callback);
+    
     void typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback);
     void keyDownUsingHardwareKeyboard(JSStringRef character, JSValueRef callback);
     void keyUpUsingHardwareKeyboard(JSStringRef character, JSValueRef callback);
index 2c96fea..e584b69 100644 (file)
@@ -46,6 +46,9 @@
 - (void)doubleTap:(CGPoint)location completionBlock:(void (^)(void))completionBlock;
 - (void)twoFingerTap:(CGPoint)location completionBlock:(void (^)(void))completionBlock;
 
+// Long Press
+- (void)longPress:(CGPoint)location completionBlock:(void (^)(void))completionBlock;
+
 // Drags
 - (void)dragWithStartPoint:(CGPoint)startLocation endPoint:(CGPoint)endLocation duration:(double)seconds completionBlock:(void (^)(void))completionBlock;
 
index facc45a..0a85827 100644 (file)
 #import <WebCore/SoftLinking.h>
 #import <mach/mach_time.h>
 #import <wtf/Assertions.h>
+#import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
 
 SOFT_LINK_PRIVATE_FRAMEWORK(BackBoardServices)
 SOFT_LINK(BackBoardServices, BKSHIDEventSetDigitizerInfo, void, (IOHIDEventRef digitizerEvent, uint32_t contextID, uint8_t systemGestureisPossible, uint8_t isSystemGestureStateChangeEvent, CFStringRef displayUUID, CFTimeInterval initialTouchTimestamp, float maxForce), (digitizerEvent, contextID, systemGestureisPossible, isSystemGestureStateChangeEvent, displayUUID, initialTouchTimestamp, maxForce));
 
-static const NSTimeInterval fingerLiftDelay = 5e7;
-static const NSTimeInterval multiTapInterval = 15e7;
+static const NSTimeInterval fingerLiftDelay = 0.05;
+static const NSTimeInterval multiTapInterval = 0.15;
 static const NSTimeInterval fingerMoveInterval = 0.016;
+static const NSTimeInterval longPressHoldDelay = 2.0;
 static const IOHIDFloat defaultMajorRadius = 5;
 static const IOHIDFloat defaultPathPressure = 0;
 static const NSUInteger maxTouchCount = 5;
@@ -53,8 +55,6 @@ typedef enum {
     HandEventChordChanged,
     HandEventLifted,
     HandEventCanceled,
-    HandEventInRange,
-    HandEventInRangeLift,
     StylusEventTouched,
     StylusEventMoved,
     StylusEventLifted,
@@ -158,9 +158,7 @@ static void delayBetweenMove(int eventIndex, double elapsed)
     } else if (eventType == HandEventChordChanged) {
         eventMask |= kIOHIDDigitizerEventPosition;
         eventMask |= kIOHIDDigitizerEventAttribute;
-    } else if (eventType == HandEventTouched  || eventType == HandEventCanceled) {
-        eventMask |= kIOHIDDigitizerEventIdentity;
-    } else if (eventType == HandEventLifted)
+    } else if (eventType == HandEventTouched || eventType == HandEventCanceled || eventType == HandEventLifted)
         eventMask |= kIOHIDDigitizerEventIdentity;
 
     uint64_t machTime = mach_absolute_time();
@@ -494,7 +492,7 @@ static void delayBetweenMove(int eventIndex, double elapsed)
 
 - (void)stylusTapAtPoint:(CGPoint)location azimuthAngle:(CGFloat)azimuthAngle altitudeAngle:(CGFloat)altitudeAngle pressure:(CGFloat)pressure completionBlock:(void (^)(void))completionBlock
 {
-    struct timespec pressDelay = { 0, static_cast<long>(fingerLiftDelay) };
+    struct timespec pressDelay = { 0, static_cast<long>(fingerLiftDelay * nanosecondsPerSecond) };
 
     [self stylusDownAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure];
     nanosleep(&pressDelay, 0);
@@ -505,8 +503,8 @@ static void delayBetweenMove(int eventIndex, double elapsed)
 
 - (void)sendTaps:(int)tapCount location:(CGPoint)location withNumberOfTouches:(int)touchCount completionBlock:(void (^)(void))completionBlock
 {
-    struct timespec doubleDelay = { 0, static_cast<long>(multiTapInterval) };
-    struct timespec pressDelay = { 0, static_cast<long>(fingerLiftDelay) };
+    struct timespec doubleDelay = { 0, static_cast<long>(multiTapInterval * nanosecondsPerSecond) };
+    struct timespec pressDelay = { 0, static_cast<long>(fingerLiftDelay * nanosecondsPerSecond) };
 
     for (int i = 0; i < tapCount; i++) {
         [self touchDown:location touchCount:touchCount];
@@ -534,6 +532,17 @@ static void delayBetweenMove(int eventIndex, double elapsed)
     [self sendTaps:1 location:location withNumberOfTouches:2 completionBlock:completionBlock];
 }
 
+- (void)longPress:(CGPoint)location completionBlock:(void (^)(void))completionBlock
+{
+    [self touchDown:location touchCount:1];
+    auto completionBlockCopy = makeBlockPtr(completionBlock);
+
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, longPressHoldDelay * nanosecondsPerSecond), dispatch_get_main_queue(), ^ {
+        [self liftUp:location];
+        [self _sendMarkerHIDEventWithCompletionBlock:completionBlockCopy.get()];
+    });
+}
+
 - (void)dragWithStartPoint:(CGPoint)startLocation endPoint:(CGPoint)endLocation duration:(double)seconds completionBlock:(void (^)(void))completionBlock
 {
     [self touchDown:startLocation touchCount:1];
index bd7ec00..05065f1 100644 (file)
@@ -187,6 +187,17 @@ void UIScriptController::dragFromPointToPoint(long startX, long startY, long end
         m_context->asyncTaskComplete(callbackID);
     }];
 }
+    
+void UIScriptController::longPressAtPoint(long x, long y, JSValueRef callback)
+{
+    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
+    
+    [[HIDEventGenerator sharedHIDEventGenerator] longPress:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{
+        if (!m_context)
+            return;
+        m_context->asyncTaskComplete(callbackID);
+    }];
+}
 
 void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)
 {