[iOS 13] imported/mozilla/svg/text/textpath-selection.svg is flaky
https://bugs.webkit.org/show_bug.cgi?id=203247
<rdar://problem/52124292>

Reviewed by Tim Horton.

Tools:

Roughly 1 in 3000 runs, this test fails due to an image diff, where only the expectation or test page shows a
native selection view on iOS. Both the test and expectation create DOM selections on the page, which is then
followed by a native selection view on the page at some point in the future.

This "point in the future" depends on both WebKit implementation details (i.e. when the next remote layer tree
commit happens) as well as UIKit implementation details (for example, many methods in UITextSelectionView and
UIWKTextInteractionAssistant will schedule changes to UIView geometry using a runloop timer, instead of applying
the updates immediately). Because of the latter, it's impractical to expect native selection views on iOS to
always appear or not appear after finishing this layout test.

To mitigate this rare source of flakiness, we hide these native text selection views when snapshotting iOS
WKWebViews for the purposes of ref and pixel testing.

Note that we still have a considerable number of layout tests that inspect these native selection views on iOS,
but they work by waiting until the native selection views reach a particular state (e.g. by polling for the
number of ranged selection subviews, or the presence of selection handles, or waiting for a caret selection with
a given geometry, etc.), which ensures that they are robust against subtle changes to the timing of selection
updates in the UI process.

* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(WTR::PlatformWebView::windowSnapshotImage):

LayoutTests:

Remove the failing test expectation. See Tools/ChangeLog for more details.

* platform/ios-wk2/TestExpectations:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251526 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index a2151d19..a52f008 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2019-10-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS 13] imported/mozilla/svg/text/textpath-selection.svg is flaky
+        https://bugs.webkit.org/show_bug.cgi?id=203247
+        <rdar://problem/52124292>
+
+        Reviewed by Tim Horton.
+
+        Remove the failing test expectation. See Tools/ChangeLog for more details.
+
+        * platform/ios-wk2/TestExpectations:
+
 2019-10-23  Megan Gardner  <megan_gardner@apple.com>
 
         Rename force-press-related functions to refer to context menus, and fix a former force-press test
diff --git a/LayoutTests/platform/ios-wk2/TestExpectations b/LayoutTests/platform/ios-wk2/TestExpectations
index fbf5776..47ac2d4 100644
--- a/LayoutTests/platform/ios-wk2/TestExpectations
+++ b/LayoutTests/platform/ios-wk2/TestExpectations
@@ -1332,9 +1332,6 @@
 
 webkit.org/b/190882 [ Debug ] animations/change-one-anim.html [ Pass Failure ]
 
-webkit.org/b/199196 [ Release ] imported/mozilla/svg/text/textpath-selection.svg [ Pass ImageOnlyFailure ]
-webkit.org/b/199196 [ Release ] imported/mozilla/svg/text/selectSubString-2.svg [ Pass ImageOnlyFailure ]
-
 webkit.org/b/199213 [ Release ] imported/blink/editing/selection/deleteFromDocument-crash.html [ Pass ImageOnlyFailure ]
 
 webkit.org/b/199370 [ Release ] imported/mozilla/svg/text/selectSubString.svg [ Pass ImageOnlyFailure ]
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 47efe87..e8fb8f5 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,33 @@
+2019-10-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS 13] imported/mozilla/svg/text/textpath-selection.svg is flaky
+        https://bugs.webkit.org/show_bug.cgi?id=203247
+        <rdar://problem/52124292>
+
+        Reviewed by Tim Horton.
+
+        Roughly 1 in 3000 runs, this test fails due to an image diff, where only the expectation or test page shows a
+        native selection view on iOS. Both the test and expectation create DOM selections on the page, which is then
+        followed by a native selection view on the page at some point in the future.
+
+        This "point in the future" depends on both WebKit implementation details (i.e. when the next remote layer tree
+        commit happens) as well as UIKit implementation details (for example, many methods in UITextSelectionView and
+        UIWKTextInteractionAssistant will schedule changes to UIView geometry using a runloop timer, instead of applying
+        the updates immediately). Because of the latter, it's impractical to expect native selection views on iOS to
+        always appear or not appear after finishing this layout test.
+
+        To mitigate this rare source of flakiness, we hide these native text selection views when snapshotting iOS
+        WKWebViews for the purposes of ref and pixel testing.
+
+        Note that we still have a considerable number of layout tests that inspect these native selection views on iOS,
+        but they work by waiting until the native selection views reach a particular state (e.g. by polling for the
+        number of ranged selection subviews, or the presence of selection handles, or waiting for a caret selection with
+        a given geometry, etc.), which ensures that they are robust against subtle changes to the timing of selection
+        updates in the UI process.
+
+        * WebKitTestRunner/ios/PlatformWebViewIOS.mm:
+        (WTR::PlatformWebView::windowSnapshotImage):
+
 2019-10-23  Chris Dumez  <cdumez@apple.com>
 
         WebBackForwardCache::removeEntriesMatching() may re-enter and crash
diff --git a/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm b/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
index 661f28e..28877cc 100644
--- a/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
+++ b/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
@@ -37,6 +37,7 @@
 #import <pal/spi/cocoa/QuartzCoreSPI.h>
 #import <wtf/BlockObjCExceptions.h>
 #import <wtf/RetainPtr.h>
+#import <wtf/WeakObjCPtr.h>
 
 @interface WKWebView (Details)
 - (WKPageRef)_pageForTesting;
@@ -323,6 +324,13 @@
     RELEASE_ASSERT(viewSize.width);
     RELEASE_ASSERT(viewSize.height);
 
+    BOOL shouldUnhideSelectionView = NO;
+    WeakObjCPtr<UIView> selectionView = [platformView() valueForKeyPath:@"_currentContentView.interactionAssistant.selectionView"];
+    if (![selectionView isHidden]) {
+        shouldUnhideSelectionView = YES;
+        [selectionView setHidden:YES];
+    }
+
 #if HAVE(IOSURFACE)
     __block bool isDone = false;
     __block RetainPtr<CGImageRef> result;
@@ -342,8 +350,6 @@
     }];
     while (!isDone)
         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
-    return result;
-
 #else
     CGFloat deviceScaleFactor = 2; // FIXME: hardcode 2x for now. In future we could respect 1x and 3x as we do on Mac.
     CATransform3D transform = CATransform3DMakeScale(deviceScaleFactor, deviceScaleFactor, 1);
@@ -360,13 +366,15 @@
     size_t rowBytes = CARenderServerGetBufferRowBytes(buffer);
 
     static CGColorSpaceRef sRGBSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
-    RetainPtr<CGDataProviderRef> provider = adoptCF(CGDataProviderCreateWithData(buffer, data, CARenderServerGetBufferDataSize(buffer), releaseDataProviderData));
+    auto provider = adoptCF(CGDataProviderCreateWithData(buffer, data, CARenderServerGetBufferDataSize(buffer), releaseDataProviderData));
     
-    RetainPtr<CGImageRef> cgImage = adoptCF(CGImageCreate(bufferWidth, bufferHeight, 8, 32, rowBytes, sRGBSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, provider.get(), 0, false, kCGRenderingIntentDefault));
-    RELEASE_ASSERT(cgImage);
-
-    return cgImage;
+    auto result = adoptCF(CGImageCreate(bufferWidth, bufferHeight, 8, 32, rowBytes, sRGBSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, provider.get(), 0, false, kCGRenderingIntentDefault));
+    RELEASE_ASSERT(result);
 #endif
+    if (shouldUnhideSelectionView)
+        [selectionView setHidden:NO];
+
+    return result;
     END_BLOCK_OBJC_EXCEPTIONS;
 }