[iOS WK2] Make rotation tests more reliable
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 7 May 2017 02:53:51 +0000 (02:53 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 7 May 2017 02:53:51 +0000 (02:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171778

Reviewed by Tim Horton.

Source/WebKit2:

Switching between "safari-style" rotation and normal rotation left state on the WKWebView
that would cause later viewport-sensitive tests to fail. The WKWebView would be left
with override layout parameters, and an override orientation, and these caused viewport
size to leak into later tests, and WebCore orientation to not get reset correctly.

Also, WKWebView was unregistering for UIWindowDidRotateNotification notifications when
an override orientation was set, and would never re-register, causing lost orientationchanged
events.

Fix by exposing WKWebView SPI to clear the various bits of overide state. Also don't unregister
from the UIWindowDidRotateNotification notification; it's already ignored anyway if it fires.

Also wait for a visible content rect update after resizing the WKWebVeiw between tests, to make sure
the WebProcess is caught up before proceeding with the test.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _setInterfaceOrientationOverride:]):
(-[WKWebView _clearInterfaceOrientationOverride]):
(-[WKWebView _beginAnimatedResizeWithUpdates:]):
(-[WKWebView _clearOverrideLayoutParameters]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Tools:

Switching between "safari-style" rotation and normal rotation left state on the WKWebView
that would cause later viewport-sensitive tests to fail. The WKWebView would be left
with override layout parameters, and an override orientation, and these caused viewport
size to leak into later tests, and WebCore orientation to not get reset correctly.

Also, WKWebView was unregistering for UIWindowDidRotateNotification notifications when
an override orientation was set, and would never re-register, causing lost orientationchanged
events.

Fix by exposing WKWebView SPI to clear the various bits of overide state. Also don't unregister
from the UIWindowDidRotateNotification notification; it's already ignored anyway if it fires.

Also wait for a visible content rect update after resizing the WKWebVeiw between tests, to make sure
the WebProcess is caught up before proceeding with the test.

* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(-[PlatformWebViewController viewWillTransitionToSize:withTransitionCoordinator:]):
* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformResetStateToConsistentValues):
(WTR::TestController::platformConfigureViewForTest):

LayoutTests:

New baseline.

* fast/events/ios/rotation/zz-no-rotation-expected.txt:
* fast/events/ios/rotation/zz-no-rotation.html:

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

LayoutTests/ChangeLog
LayoutTests/fast/events/ios/rotation/zz-no-rotation-expected.txt
LayoutTests/fast/events/ios/rotation/zz-no-rotation.html
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h
Tools/ChangeLog
Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
Tools/WebKitTestRunner/ios/TestControllerIOS.mm

index f46ae91..2c30d38 100644 (file)
@@ -1,3 +1,15 @@
+2017-05-06  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Make rotation tests more reliable
+        https://bugs.webkit.org/show_bug.cgi?id=171778
+
+        Reviewed by Tim Horton.
+
+        New baseline.
+
+        * fast/events/ios/rotation/zz-no-rotation-expected.txt:
+        * fast/events/ios/rotation/zz-no-rotation.html:
+
 2017-05-06  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, rolling out r216333.
index 25d46a2..4938baf 100644 (file)
@@ -2,5 +2,5 @@ PASS successfullyParsed is true
 
 TEST COMPLETE
 PASS window.innerWidth is 320
-PASS window.innerHeight is 568
+PASS window.innerHeight is 548
 This test checks that the view is not left in a rotated state after the previous tests.
index f20d641..a30561a 100644 (file)
@@ -8,7 +8,7 @@
         function doTest()
         {
             shouldBe("window.innerWidth", "320");
-            shouldBe("window.innerHeight", "568");
+            shouldBe("window.innerHeight", "548");
         }
         window.addEventListener('load', doTest, false);
     </script>
index cc8a648..7fca70e 100644 (file)
@@ -1,3 +1,32 @@
+2017-05-06  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Make rotation tests more reliable
+        https://bugs.webkit.org/show_bug.cgi?id=171778
+
+        Reviewed by Tim Horton.
+
+        Switching between "safari-style" rotation and normal rotation left state on the WKWebView
+        that would cause later viewport-sensitive tests to fail. The WKWebView would be left
+        with override layout parameters, and an override orientation, and these caused viewport
+        size to leak into later tests, and WebCore orientation to not get reset correctly.
+
+        Also, WKWebView was unregistering for UIWindowDidRotateNotification notifications when
+        an override orientation was set, and would never re-register, causing lost orientationchanged
+        events.
+
+        Fix by exposing WKWebView SPI to clear the various bits of overide state. Also don't unregister
+        from the UIWindowDidRotateNotification notification; it's already ignored anyway if it fires.
+
+        Also wait for a visible content rect update after resizing the WKWebVeiw between tests, to make sure
+        the WebProcess is caught up before proceeding with the test.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _setInterfaceOrientationOverride:]):
+        (-[WKWebView _clearInterfaceOrientationOverride]):
+        (-[WKWebView _beginAnimatedResizeWithUpdates:]):
+        (-[WKWebView _clearOverrideLayoutParameters]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
 2017-05-06  Konstantin Tokarev  <annulen@yandex.ru>
 
         Remove unused lambda capture
index 921e08f..303d8d7 100644 (file)
@@ -4562,9 +4562,6 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
 
 - (void)_setInterfaceOrientationOverride:(UIInterfaceOrientation)interfaceOrientation
 {
-    if (!_overridesInterfaceOrientation)
-        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidRotateNotification object:nil];
-
     _overridesInterfaceOrientation = YES;
 
     if (interfaceOrientation == _interfaceOrientationOverride)
@@ -4582,6 +4579,12 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     return _interfaceOrientationOverride;
 }
 
+- (void)_clearInterfaceOrientationOverride
+{
+    _overridesInterfaceOrientation = NO;
+    _interfaceOrientationOverride = UIInterfaceOrientationPortrait;
+}
+
 - (CGSize)_maximumUnobscuredSizeOverride
 {
     ASSERT(_overridesMaximumUnobscuredSize);
@@ -4676,6 +4679,7 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
             _page->setMaximumUnobscuredSize(WebCore::FloatSize(newMaximumUnobscuredSize));
         if (_overridesInterfaceOrientation)
             _page->setDeviceOrientation(newOrientation);
+
         [self _scheduleVisibleContentRectUpdate];
         return;
     }
@@ -4915,6 +4919,15 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     [self _setMaximumUnobscuredSizeOverride:maximumUnobscuredSizeOverride];
 }
 
+- (void)_clearOverrideLayoutParameters
+{
+    _overridesMinimumLayoutSize = NO;
+    _minimumLayoutSizeOverride = CGSizeZero;
+    
+    _overridesMaximumUnobscuredSize = NO;
+    _maximumUnobscuredSizeOverride = CGSizeZero;
+}
+
 - (UIView *)_viewForFindUI
 {
     return [self viewForZoomingInScrollView:[self scrollView]];
index 3700f30..a20f08b 100644 (file)
@@ -190,6 +190,9 @@ typedef NS_ENUM(NSInteger, _WKImmediateActionType) {
 
 - (void)_overrideLayoutParametersWithMinimumLayoutSize:(CGSize)minimumLayoutSize maximumUnobscuredSizeOverride:(CGSize)maximumUnobscuredSizeOverride WK_API_AVAILABLE(ios(9_0));
 
+- (void)_clearOverrideLayoutParameters;
+- (void)_clearInterfaceOrientationOverride;
+
 - (UIView *)_viewForFindUI;
 
 - (void)_setOverlaidAccessoryViewsInset:(CGSize)inset;
index 18c768f..cd197e3 100644 (file)
@@ -1,3 +1,31 @@
+2017-05-06  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Make rotation tests more reliable
+        https://bugs.webkit.org/show_bug.cgi?id=171778
+
+        Reviewed by Tim Horton.
+
+        Switching between "safari-style" rotation and normal rotation left state on the WKWebView
+        that would cause later viewport-sensitive tests to fail. The WKWebView would be left
+        with override layout parameters, and an override orientation, and these caused viewport
+        size to leak into later tests, and WebCore orientation to not get reset correctly.
+
+        Also, WKWebView was unregistering for UIWindowDidRotateNotification notifications when
+        an override orientation was set, and would never re-register, causing lost orientationchanged
+        events.
+
+        Fix by exposing WKWebView SPI to clear the various bits of overide state. Also don't unregister
+        from the UIWindowDidRotateNotification notification; it's already ignored anyway if it fires.
+
+        Also wait for a visible content rect update after resizing the WKWebVeiw between tests, to make sure
+        the WebProcess is caught up before proceeding with the test.
+
+        * WebKitTestRunner/ios/PlatformWebViewIOS.mm:
+        (-[PlatformWebViewController viewWillTransitionToSize:withTransitionCoordinator:]):
+        * WebKitTestRunner/ios/TestControllerIOS.mm:
+        (WTR::TestController::platformResetStateToConsistentValues):
+        (WTR::TestController::platformConfigureViewForTest):
+
 2017-05-06  Csaba Osztrogon├íc  <ossy@webkit.org>
 
         [Mac][cmake] Buildfix after r216047
index 4dde12b..aded88a 100644 (file)
@@ -108,6 +108,17 @@ static Vector<WebKitTestRunnerWindow*> allWindows;
 
 @end
 
+namespace WTR {
+
+enum class WebViewSizingMode {
+    Default,
+    HeightRespectsStatusBar
+};
+
+static CGRect viewRectForWindowRect(CGRect, PlatformWebView::WebViewSizingMode);
+
+} // namespace WTR
+
 @interface PlatformWebViewController : UIViewController
 @end
 
@@ -116,27 +127,28 @@ static Vector<WebKitTestRunnerWindow*> allWindows;
 - (void)viewWillTransitionToSize:(CGSize)toSize withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
 {
     [super viewWillTransitionToSize:toSize withTransitionCoordinator:coordinator];
-    
+
     TestRunnerWKWebView *webView = WTR::TestController::singleton().mainWebView()->platformView();
-    
+
     if (webView.usesSafariLikeRotation)
         [webView _setInterfaceOrientationOverride:[[UIApplication sharedApplication] statusBarOrientation]];
-        
+
     [coordinator animateAlongsideTransition: ^(id<UIViewControllerTransitionCoordinatorContext> context) {
+        // This code assumes that we should take the status bar into account, which we only do for flexible viewport tests,
+        // but it only makes sense to test rotation with a flexible viewport anyway.
         if (webView.usesSafariLikeRotation) {
             [webView _beginAnimatedResizeWithUpdates:^{
-                auto size = self.view.bounds.size;
-                webView.frame = self.view.bounds;
-                [webView _overrideLayoutParametersWithMinimumLayoutSize:size maximumUnobscuredSizeOverride:size];
+                webView.frame = viewRectForWindowRect(self.view.bounds, WTR::PlatformWebView::WebViewSizingMode::HeightRespectsStatusBar);
+                [webView _overrideLayoutParametersWithMinimumLayoutSize:webView.frame.size maximumUnobscuredSizeOverride:webView.frame.size];
                 [webView _setInterfaceOrientationOverride:[[UIApplication sharedApplication] statusBarOrientation]];
             }];
         } else
-            webView.frame = self.view.bounds;
+            webView.frame = viewRectForWindowRect(self.view.bounds, WTR::PlatformWebView::WebViewSizingMode::HeightRespectsStatusBar);
     } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
-        webView.frame = self.view.bounds;
+        webView.frame = viewRectForWindowRect(self.view.bounds, WTR::PlatformWebView::WebViewSizingMode::HeightRespectsStatusBar);
         if (webView.usesSafariLikeRotation)
             [webView _endAnimatedResize];
-            
+
         [webView _didEndRotation];
     }];
 }
@@ -145,11 +157,6 @@ static Vector<WebKitTestRunnerWindow*> allWindows;
 
 namespace WTR {
 
-enum class WebViewSizingMode {
-    Default,
-    HeightRespectsStatusBar
-};
-
 static CGRect viewRectForWindowRect(CGRect windowRect, PlatformWebView::WebViewSizingMode mode)
 {
     CGFloat statusBarBottom = CGRectGetMaxY([[UIApplication sharedApplication] statusBarFrame]);
index 5feadbd..536af17 100644 (file)
@@ -82,26 +82,46 @@ void TestController::platformResetStateToConsistentValues()
 
     [[UIDevice currentDevice] setOrientation:UIDeviceOrientationPortrait animated:NO];
     
-    if (PlatformWebView* webView = mainWebView()) {
-        webView->platformView()._stableStateOverride = nil;
-        webView->platformView().usesSafariLikeRotation = NO;
-        UIScrollView *scrollView = webView->platformView().scrollView;
+    if (PlatformWebView* platformWebView = mainWebView()) {
+        TestRunnerWKWebView *webView = platformWebView->platformView();
+        webView._stableStateOverride = nil;
+        webView.usesSafariLikeRotation = NO;
+        webView.overrideSafeAreaInsets = UIEdgeInsetsZero;
+        [webView _clearOverrideLayoutParameters];
+        [webView _clearInterfaceOrientationOverride];
+
+        UIScrollView *scrollView = webView.scrollView;
         [scrollView _removeAllAnimations:YES];
         [scrollView setZoomScale:1 animated:NO];
         [scrollView setContentOffset:CGPointZero];
-
-        webView->platformView().overrideSafeAreaInsets = UIEdgeInsetsZero;
     }
 }
 
 void TestController::platformConfigureViewForTest(const TestInvocation& test)
 {
-    if (test.options().useFlexibleViewport) {
-        CGRect screenBounds = [UIScreen mainScreen].bounds;
-        mainWebView()->resizeTo(screenBounds.size.width, screenBounds.size.height, PlatformWebView::WebViewSizingMode::HeightRespectsStatusBar);
-        // We also pass data to InjectedBundle::beginTesting() to have it call
-        // WKBundlePageSetUseTestingViewportConfiguration(false).
+    if (!test.options().useFlexibleViewport)
+        return;
+        
+    TestRunnerWKWebView *webView = mainWebView()->platformView();
+    CGRect screenBounds = [UIScreen mainScreen].bounds;
+    
+    CGSize oldSize = webView.bounds.size;
+    mainWebView()->resizeTo(screenBounds.size.width, screenBounds.size.height, PlatformWebView::WebViewSizingMode::HeightRespectsStatusBar);
+    CGSize newSize = webView.bounds.size;
+    
+    if (!CGSizeEqualToSize(oldSize, newSize)) {
+        __block bool doneResizing = false;
+        [webView _doAfterNextVisibleContentRectUpdate: ^{
+            doneResizing = true;
+        }];
+
+        platformRunUntil(doneResizing, 10);
+        if (!doneResizing)
+            WTFLogAlways("Timed out waiting for view resize to complete in platformConfigureViewForTest()");
     }
+    
+    // We also pass data to InjectedBundle::beginTesting() to have it call
+    // WKBundlePageSetUseTestingViewportConfiguration(false).
 }
 
 void TestController::updatePlatformSpecificTestOptionsForTest(TestOptions&, const std::string&) const