Title: [281068] trunk
Revision
281068
Author
[email protected]
Date
2021-08-15 20:34:05 -0700 (Sun, 15 Aug 2021)

Log Message

[iOS 15] editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html is a flaky timeout
https://bugs.webkit.org/show_bug.cgi?id=229126
rdar://80384801

Reviewed by Tim Horton.

Source/WebKit:

Remove the (now-unused) testing SPI `-[WKWebView _doAfterResettingSingleTapGesture:]`. See Tools/ChangeLog for
more information.

* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _doAfterResettingSingleTapGesture:]): Deleted.
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _singleTapDidReset:]):
(-[WKContentView _doAfterResettingSingleTapGesture:]): Deleted.

Tools:

This test exercises the ability to cause platform selection views to show up after tapping the web view while a
DOM selection is set. In this codepath, selection views are installed when the web view becomes first responder,
when we call into `-[UIWKTextInteractionAssistant activateSelection]`; the call to `-becomeFirstResponder`, in
turn, comes from UIKit's internal `UITextTapRecognizer` gesture, which recognizes the single tap and makes the
content view first responder.

In the case where this test fails, the synthesized tap gesture fails to activate the text tap recognizer; this
happens because the timing of when the `UITextTapRecognizer` gets reset (i.e. `-_resetGestureRecognizer`) races
against the timing of when the synthesized touch event is sent to the gesture recognizer. When the touch is
delivered to the gesture *before* the text tap gesture is reset, we end up timing out because the text tap
gesture's action never fires and makes the content view first responder.

To ensure that we don't lose this race and time out, we augment the existing mechanism in
`UIScriptControllerIOS::waitForSingleTapToReset()` to wait for *all* enabled single tap (and single touch)
gestures to reset, instead of only waiting for the web view's synthetic click gesture. Importantly, this
includes `UITextTapRecognizer`, which ensures that the touches are delivered to the gesture only after the text
tap gesture has been reset (and transitions to Possible state).

* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::waitForSingleTapToReset const):

Instead of using testing SPI (`-_doAfterResettingSingleTapGesture:`) to wait for the single tap to reset, we can
just directly iterate through all the gestures on the content view and wait for all enabled single tap gestures
to transition back to Possible state.

LayoutTests:

Update test expectations for this flaky test.

* platform/ios-14/TestExpectations:
* platform/ios/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (281067 => 281068)


--- trunk/LayoutTests/ChangeLog	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/LayoutTests/ChangeLog	2021-08-16 03:34:05 UTC (rev 281068)
@@ -1,3 +1,16 @@
+2021-08-15  Wenson Hsieh  <[email protected]>
+
+        [iOS 15] editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html is a flaky timeout
+        https://bugs.webkit.org/show_bug.cgi?id=229126
+        rdar://80384801
+
+        Reviewed by Tim Horton.
+
+        Update test expectations for this flaky test.
+
+        * platform/ios-14/TestExpectations:
+        * platform/ios/TestExpectations:
+
 2021-08-15  Arcady Goldmints-Orlov  <[email protected]>
 
         [GLIB] Update test expectations after r280077

Modified: trunk/LayoutTests/platform/ios/TestExpectations (281067 => 281068)


--- trunk/LayoutTests/platform/ios/TestExpectations	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2021-08-16 03:34:05 UTC (rev 281068)
@@ -3364,9 +3364,6 @@
 # rdar://80384447 ([ iOS15 ] editing/selection/ios/hide-selection-after-tap-on-prevent-default-element.html is a Flaky timeout)
 editing/selection/ios/hide-selection-after-tap-on-prevent-default-element.html [ Pass Timeout ]
 
-# rdar://80384801 ([ iOS15 ] editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html is a flaky timeout)
-editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html  [ Pass Timeout ]
-
 # rdar://80392795 ([ iOS15 ] http/tests/misc/object-embedding-svg-delayed-size-negotiation-2.htm is a flaky failure)
 http/tests/misc/object-embedding-svg-delayed-size-negotiation-2.htm [ Pass Failure ]
 

Modified: trunk/LayoutTests/platform/ios-14/TestExpectations (281067 => 281068)


--- trunk/LayoutTests/platform/ios-14/TestExpectations	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/LayoutTests/platform/ios-14/TestExpectations	2021-08-16 03:34:05 UTC (rev 281068)
@@ -27,9 +27,6 @@
 # rdar://80384447 ([ iOS15 ] editing/selection/ios/hide-selection-after-tap-on-prevent-default-element.html is a Flaky timeout)
 editing/selection/ios/hide-selection-after-tap-on-prevent-default-element.html [ Pass ]
 
-# rdar://80384801 ([ iOS15 ] editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html is a flaky timeout)
-editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html  [ Pass ]
-
 # rdar://80392795 ([ iOS15 ] http/tests/misc/object-embedding-svg-delayed-size-negotiation-2.htm is a flaky failure)
 http/tests/misc/object-embedding-svg-delayed-size-negotiation-2.htm [ Pass ]
 

Modified: trunk/Source/WebKit/ChangeLog (281067 => 281068)


--- trunk/Source/WebKit/ChangeLog	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Source/WebKit/ChangeLog	2021-08-16 03:34:05 UTC (rev 281068)
@@ -1,3 +1,22 @@
+2021-08-15  Wenson Hsieh  <[email protected]>
+
+        [iOS 15] editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html is a flaky timeout
+        https://bugs.webkit.org/show_bug.cgi?id=229126
+        rdar://80384801
+
+        Reviewed by Tim Horton.
+
+        Remove the (now-unused) testing SPI `-[WKWebView _doAfterResettingSingleTapGesture:]`. See Tools/ChangeLog for
+        more information.
+
+        * UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
+        * UIProcess/API/ios/WKWebViewTestingIOS.mm:
+        (-[WKWebView _doAfterResettingSingleTapGesture:]): Deleted.
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _singleTapDidReset:]):
+        (-[WKContentView _doAfterResettingSingleTapGesture:]): Deleted.
+
 2021-08-15  David Kilzer  <[email protected]>
 
         Bug 229112: ThreadSanitizer: data races of WTF::String in WebResourceLoadStatisticsStore

Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h (281067 => 281068)


--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h	2021-08-16 03:34:05 UTC (rev 281068)
@@ -76,8 +76,6 @@
 
 - (void)applyAutocorrection:(NSString *)newString toString:(NSString *)oldString withCompletionHandler:(void (^)(void))completionHandler;
 
-- (void)_doAfterResettingSingleTapGesture:(dispatch_block_t)action;
-
 - (NSDictionary *)_propertiesOfLayerWithID:(unsigned long long)layerID;
 - (void)_simulateElementAction:(_WKElementActionType)actionType atLocation:(CGPoint)location;
 - (void)_simulateLongPressActionAtLocation:(CGPoint)location;

Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm (281067 => 281068)


--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm	2021-08-16 03:34:05 UTC (rev 281068)
@@ -390,11 +390,6 @@
     };
 }
 
-- (void)_doAfterResettingSingleTapGesture:(dispatch_block_t)action
-{
-    [_contentView _doAfterResettingSingleTapGesture:action];
-}
-
 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action
 {
     [_contentView _doAfterReceivingEditDragSnapshotForTesting:action];

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (281067 => 281068)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2021-08-16 03:34:05 UTC (rev 281068)
@@ -495,8 +495,6 @@
     std::unique_ptr<WebKit::TextCheckingController> _textCheckingController;
 #endif
 
-    Vector<BlockPtr<void()>> _actionsToPerformAfterResettingSingleTapGestureRecognizer;
-
 #if ENABLE(IMAGE_ANALYSIS)
     RetainPtr<WKImageAnalysisGestureRecognizer> _imageAnalysisGestureRecognizer;
     RetainPtr<UILongPressGestureRecognizer> _imageAnalysisTimeoutGestureRecognizer;
@@ -779,7 +777,6 @@
 - (double)timePickerValueHour;
 - (double)timePickerValueMinute;
 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem;
-- (void)_doAfterResettingSingleTapGesture:(dispatch_block_t)action;
 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action;
 - (void)_dismissContactPickerWithContacts:(NSArray *)contacts;
 

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (281067 => 281068)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-08-16 03:34:05 UTC (rev 281068)
@@ -3140,9 +3140,6 @@
         if (m_commitPotentialTapPointerId != pointerId)
             _page->touchWithIdentifierWasRemoved(pointerId);
     }
-    auto actionsToPerform = std::exchange(_actionsToPerformAfterResettingSingleTapGestureRecognizer, { });
-    for (const auto& action : actionsToPerform)
-        action();
 
     if (!_isTapHighlightIDValid)
         [self _fadeTapHighlightViewIfNeeded];
@@ -10476,15 +10473,6 @@
 
 @implementation WKContentView (WKTesting)
 
-- (void)_doAfterResettingSingleTapGesture:(dispatch_block_t)action
-{
-    if ([_singleTapGestureRecognizer state] != UIGestureRecognizerStateEnded) {
-        action();
-        return;
-    }
-    _actionsToPerformAfterResettingSingleTapGestureRecognizer.append(makeBlockPtr(action));
-}
-
 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action
 {
 #if ENABLE(DRAG_SUPPORT)

Modified: trunk/Tools/ChangeLog (281067 => 281068)


--- trunk/Tools/ChangeLog	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Tools/ChangeLog	2021-08-16 03:34:05 UTC (rev 281068)
@@ -1,3 +1,36 @@
+2021-08-15  Wenson Hsieh  <[email protected]>
+
+        [iOS 15] editing/selection/ios/select-all-in-readonly-input-does-not-overflow.html is a flaky timeout
+        https://bugs.webkit.org/show_bug.cgi?id=229126
+        rdar://80384801
+
+        Reviewed by Tim Horton.
+
+        This test exercises the ability to cause platform selection views to show up after tapping the web view while a
+        DOM selection is set. In this codepath, selection views are installed when the web view becomes first responder,
+        when we call into `-[UIWKTextInteractionAssistant activateSelection]`; the call to `-becomeFirstResponder`, in
+        turn, comes from UIKit's internal `UITextTapRecognizer` gesture, which recognizes the single tap and makes the
+        content view first responder.
+
+        In the case where this test fails, the synthesized tap gesture fails to activate the text tap recognizer; this
+        happens because the timing of when the `UITextTapRecognizer` gets reset (i.e. `-_resetGestureRecognizer`) races
+        against the timing of when the synthesized touch event is sent to the gesture recognizer. When the touch is
+        delivered to the gesture *before* the text tap gesture is reset, we end up timing out because the text tap
+        gesture's action never fires and makes the content view first responder.
+
+        To ensure that we don't lose this race and time out, we augment the existing mechanism in
+        `UIScriptControllerIOS::waitForSingleTapToReset()` to wait for *all* enabled single tap (and single touch)
+        gestures to reset, instead of only waiting for the web view's synthetic click gesture. Importantly, this
+        includes `UITextTapRecognizer`, which ensures that the touches are delivered to the gesture only after the text
+        tap gesture has been reset (and transitions to Possible state).
+
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptControllerIOS::waitForSingleTapToReset const):
+
+        Instead of using testing SPI (`-_doAfterResettingSingleTapGesture:`) to wait for the single tap to reset, we can
+        just directly iterate through all the gestures on the content view and wait for all enabled single tap gestures
+        to transition back to Possible state.
+
 2021-08-13  Jonathan Bedard  <[email protected]>
 
         [webkitscmpy] Fix SVN relative URL parsing

Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (281067 => 281068)


--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2021-08-15 20:46:16 UTC (rev 281067)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2021-08-16 03:34:05 UTC (rev 281068)
@@ -46,6 +46,7 @@
 #import <WebKit/WebKit.h>
 #import <pal/spi/ios/GraphicsServicesSPI.h>
 #import <wtf/BlockPtr.h>
+#import <wtf/MonotonicTime.h>
 #import <wtf/SoftLinking.h>
 #import <wtf/Vector.h>
 
@@ -252,11 +253,26 @@
 
 void UIScriptControllerIOS::waitForSingleTapToReset() const
 {
-    bool doneWaitingForSingleTapToReset = false;
-    [webView() _doAfterResettingSingleTapGesture:[&doneWaitingForSingleTapToReset] {
-        doneWaitingForSingleTapToReset = true;
-    }];
-    TestController::singleton().runUntil(doneWaitingForSingleTapToReset, 0.5_s);
+    auto allPendingSingleTapGesturesHaveBeenReset = [&]() -> bool {
+        for (UIGestureRecognizer *gesture in [platformContentView() gestureRecognizers]) {
+            if (!gesture.enabled || ![gesture isKindOfClass:UITapGestureRecognizer.class])
+                continue;
+
+            UITapGestureRecognizer *tapGesture = (UITapGestureRecognizer *)gesture;
+            if (tapGesture.numberOfTapsRequired != 1 || tapGesture.numberOfTouches != 1 || tapGesture.state == UIGestureRecognizerStatePossible)
+                continue;
+
+            return false;
+        }
+        return true;
+    };
+
+    auto startTime = MonotonicTime::now();
+    while (!allPendingSingleTapGesturesHaveBeenReset()) {
+        [NSRunLoop.currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:NSDate.distantFuture];
+        if (MonotonicTime::now() - startTime > 1_s)
+            break;
+    }
 }
 
 void UIScriptControllerIOS::twoFingerSingleTapAtPoint(long x, long y, JSValueRef callback)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to