Make it possible to test scrolling tree layer manipulation more easily
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Mar 2019 01:10:09 +0000 (01:10 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Mar 2019 01:10:09 +0000 (01:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195780

Reviewed by Tim Horton.
Source/WebKit:

Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that
cuts off communication of scrolling tree scrolls back to the web process
(in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This
allows tests to trigger scrolls which run the scrolling tree layer positioning
logic, but never get another commit from the web process that might mask
scrolling tree bugs.

WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting,
whose getters and setters are overridden by TestRunnerWKWebView. Plumbing
via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _scrollingUpdatesDisabledForTesting]):
(-[WKWebView _setScrollingUpdatesDisabledForTesting:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Cocoa/PageClientImplCocoa.h:
* UIProcess/Cocoa/PageClientImplCocoa.mm:
(WebKit::PageClientImplCocoa::scrollingUpdatesDisabledForTesting):
* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::scrollingUpdatesDisabledForTesting):
* UIProcess/PageClient.h:
(WebKit::PageClient::scrollingUpdatesDisabledForTesting):
* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
* UIProcess/WebPageProxy.h:

Tools:

Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that
cuts off communication of scrolling tree scrolls back to the web process
(in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This
allows tests to trigger scrolls which run the scrolling tree layer positioning
logic, but never get another commit from the web process that might mask
scrolling tree bugs.

WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting,
whose getters and setters are overridden by TestRunnerWKWebView. Plumbing
via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy.

* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::scrollUpdatesDisabled const):
(WTR::UIScriptController::setScrollUpdatesDisabled):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::scrollUpdatesDisabled const):
(WTR::UIScriptController::setScrollUpdatesDisabled):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView _scrollingUpdatesDisabledForTesting]):
(-[TestRunnerWKWebView _setScrollingUpdatesDisabledForTesting:]):
* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformResetStateToConsistentValues):
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::scrollUpdatesDisabled const):
(WTR::UIScriptController::setScrollUpdatesDisabled):

LayoutTests:

Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that
cuts off communication of scrolling tree scrolls back to the web process
(in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This
allows tests to trigger scrolls which run the scrolling tree layer positioning
logic, but never get another commit from the web process that might mask
scrolling tree bugs.

WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting,
whose getters and setters are overridden by TestRunnerWKWebView. Plumbing
via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy.

* resources/ui-helper.js: Some 'async' functions that awaited promises should just return
the promise.
(window.UIHelper.immediateScrollTo):
(window.UIHelper.immediateUnstableScrollTo):
(window.UIHelper.async.delayFor): Deleted.
(window.UIHelper.async.immediateScrollTo): Deleted.
(window.UIHelper.async.immediateUnstableScrollTo): Deleted.

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/resources/ui-helper.js
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h
Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm
Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
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/cocoa/TestRunnerWKWebView.h
Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm
Tools/WebKitTestRunner/ios/TestControllerIOS.mm
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index 8a7cb6b..4ba8378 100644 (file)
@@ -1,3 +1,29 @@
+2019-03-14  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to test scrolling tree layer manipulation more easily
+        https://bugs.webkit.org/show_bug.cgi?id=195780
+
+        Reviewed by Tim Horton.
+
+        Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that
+        cuts off communication of scrolling tree scrolls back to the web process
+        (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This
+        allows tests to trigger scrolls which run the scrolling tree layer positioning
+        logic, but never get another commit from the web process that might mask
+        scrolling tree bugs.
+        
+        WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting,
+        whose getters and setters are overridden by TestRunnerWKWebView. Plumbing
+        via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy.
+
+        * resources/ui-helper.js: Some 'async' functions that awaited promises should just return
+        the promise.
+        (window.UIHelper.immediateScrollTo):
+        (window.UIHelper.immediateUnstableScrollTo):
+        (window.UIHelper.async.delayFor): Deleted.
+        (window.UIHelper.async.immediateScrollTo): Deleted.
+        (window.UIHelper.async.immediateUnstableScrollTo): Deleted.
+
 2019-03-14  Justin Fan  <justin_fan@apple.com>
 
         [Web GPU] Updates to GPUCommandBuffer for new GPUCommandEncoder concept
index 9af5067..e409330 100644 (file)
@@ -222,32 +222,32 @@ window.UIHelper = class UIHelper {
         });
     }
 
-    static async delayFor(ms)
+    static delayFor(ms)
     {
         return new Promise(resolve => setTimeout(resolve, ms));
     }
     
-    static async immediateScrollTo(x, y)
+    static immediateScrollTo(x, y)
     {
         if (!this.isWebKit2()) {
             window.scrollTo(x, y);
             return Promise.resolve();
         }
 
-        await new Promise(resolve => {
+        return new Promise(resolve => {
             testRunner.runUIScript(`
                 uiController.immediateScrollToOffset(${x}, ${y});`, resolve);
         });
     }
 
-    static async immediateUnstableScrollTo(x, y)
+    static immediateUnstableScrollTo(x, y)
     {
         if (!this.isWebKit2()) {
             window.scrollTo(x, y);
             return Promise.resolve();
         }
 
-        await new Promise(resolve => {
+        return new Promise(resolve => {
             testRunner.runUIScript(`
                 uiController.stableStateOverride = false;
                 uiController.immediateScrollToOffset(${x}, ${y});`, resolve);
index a0b1b7f..3b67dd7 100644 (file)
@@ -1,3 +1,36 @@
+2019-03-14  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to test scrolling tree layer manipulation more easily
+        https://bugs.webkit.org/show_bug.cgi?id=195780
+
+        Reviewed by Tim Horton.
+
+        Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that
+        cuts off communication of scrolling tree scrolls back to the web process
+        (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This
+        allows tests to trigger scrolls which run the scrolling tree layer positioning
+        logic, but never get another commit from the web process that might mask
+        scrolling tree bugs.
+        
+        WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting,
+        whose getters and setters are overridden by TestRunnerWKWebView. Plumbing
+        via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _scrollingUpdatesDisabledForTesting]):
+        (-[WKWebView _setScrollingUpdatesDisabledForTesting:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Cocoa/PageClientImplCocoa.h:
+        * UIProcess/Cocoa/PageClientImplCocoa.mm:
+        (WebKit::PageClientImplCocoa::scrollingUpdatesDisabledForTesting):
+        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+        (WebKit::WebPageProxy::scrollingUpdatesDisabledForTesting):
+        * UIProcess/PageClient.h:
+        (WebKit::PageClient::scrollingUpdatesDisabledForTesting):
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
+        * UIProcess/WebPageProxy.h:
+
 2019-03-14  Youenn Fablet  <youenn@apple.com>
 
         Move IDB storage in private browsing mode to NetworkProcess
index da03812..f4cf47b 100644 (file)
@@ -7113,6 +7113,16 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe
     });
 }
 
+- (BOOL)_scrollingUpdatesDisabledForTesting
+{
+    // For subclasses to override;
+    return NO;
+}
+
+- (void)_setScrollingUpdatesDisabledForTesting:(BOOL)disabled
+{
+}
+
 // Execute the supplied block after the next transaction from the WebProcess.
 - (void)_doAfterNextPresentationUpdate:(void (^)(void))updateBlock
 {
index ec691c6..cef3b87 100644 (file)
@@ -551,6 +551,8 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 @property (nonatomic, readonly) _WKInspector *_inspector WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, readonly) _WKFrameHandle *_mainFrame WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
+@property (nonatomic, setter=_setScrollingUpdatesDisabledForTesting:) BOOL _scrollingUpdatesDisabledForTesting WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 - (void)_processWillSuspendImminentlyForTesting;
 - (void)_processDidResumeForTesting;
 
index 7b4a2da..a6f7769 100644 (file)
@@ -43,6 +43,8 @@ public:
     void isPlayingAudioWillChange() final;
     void isPlayingAudioDidChange() final;
 
+    bool scrollingUpdatesDisabledForTesting() final;
+
 #if ENABLE(ATTACHMENT_ELEMENT)
     void didInsertAttachment(API::Attachment&, const String& source) final;
     void didRemoveAttachment(API::Attachment&) final;
index 3e0b9ab..f589e9d 100644 (file)
@@ -41,6 +41,11 @@ void PageClientImplCocoa::isPlayingAudioDidChange()
     [m_webView didChangeValueForKey:NSStringFromSelector(@selector(_isPlayingAudio))];
 }
 
+bool PageClientImplCocoa::scrollingUpdatesDisabledForTesting()
+{
+    return [m_webView _scrollingUpdatesDisabledForTesting];
+}
+
 #if ENABLE(ATTACHMENT_ELEMENT)
 
 void PageClientImplCocoa::didInsertAttachment(API::Attachment& attachment, const String& source)
index 1ec9a2e..fa722b8 100644 (file)
@@ -135,6 +135,11 @@ void WebPageProxy::createSandboxExtensionsIfNeeded(const Vector<String>& files,
     }
 }
 
+bool WebPageProxy::scrollingUpdatesDisabledForTesting()
+{
+    return pageClient().scrollingUpdatesDisabledForTesting();
+}
+
 #if ENABLE(DRAG_SUPPORT)
 
 void WebPageProxy::startDrag(const DragItem& dragItem, const ShareableBitmap::Handle& dragImageHandle)
index 775f507..01f0d16 100644 (file)
@@ -423,8 +423,10 @@ public:
     virtual void didChangeBackgroundColor() = 0;
     virtual void isPlayingAudioWillChange() = 0;
     virtual void isPlayingAudioDidChange() = 0;
+
     virtual void pinnedStateWillChange() { }
     virtual void pinnedStateDidChange() { }
+    virtual bool scrollingUpdatesDisabledForTesting() { return false; }
 
     virtual bool hasSafeBrowsingWarning() const { return false; }
     
index db648f3..3f86de0 100644 (file)
@@ -204,6 +204,9 @@ void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID
     if (!m_propagatesMainFrameScrolls && scrolledNodeID == rootScrollingNodeID())
         return;
 
+    if (m_webPageProxy.scrollingUpdatesDisabledForTesting())
+        return;
+
 #if PLATFORM(IOS_FAMILY)
     m_webPageProxy.scrollingNodeScrollViewDidScroll();
 #endif
index 0a6bdba..473d76c 100644 (file)
@@ -1309,6 +1309,8 @@ public:
     void setFooterBannerHeightForTesting(int);
 #endif
 
+    bool scrollingUpdatesDisabledForTesting();
+
     void installActivityStateChangeCompletionHandler(Function<void()>&&);
 
 #if USE(UNIFIED_TEXT_CHECKING)
index 7de7626..bef44b4 100644 (file)
@@ -1,3 +1,39 @@
+2019-03-14  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to test scrolling tree layer manipulation more easily
+        https://bugs.webkit.org/show_bug.cgi?id=195780
+
+        Reviewed by Tim Horton.
+        
+        Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that
+        cuts off communication of scrolling tree scrolls back to the web process
+        (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This
+        allows tests to trigger scrolls which run the scrolling tree layer positioning
+        logic, but never get another commit from the web process that might mask
+        scrolling tree bugs.
+        
+        WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting,
+        whose getters and setters are overridden by TestRunnerWKWebView. Plumbing
+        via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy.
+
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::scrollUpdatesDisabled const):
+        (WTR::UIScriptController::setScrollUpdatesDisabled):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::scrollUpdatesDisabled const):
+        (WTR::UIScriptController::setScrollUpdatesDisabled):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+        (-[TestRunnerWKWebView _scrollingUpdatesDisabledForTesting]):
+        (-[TestRunnerWKWebView _setScrollingUpdatesDisabledForTesting:]):
+        * WebKitTestRunner/ios/TestControllerIOS.mm:
+        (WTR::TestController::platformResetStateToConsistentValues):
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::scrollUpdatesDisabled const):
+        (WTR::UIScriptController::setScrollUpdatesDisabled):
+
 2019-03-14  Youenn Fablet  <youenn@apple.com>
 
         Move IDB storage in private browsing mode to NetworkProcess
index bd84bcf..c120952 100644 (file)
@@ -238,6 +238,15 @@ double UIScriptController::contentOffsetY() const
     return [gWebScrollView contentOffset].y;
 }
 
+bool UIScriptController::scrollUpdatesDisabled() const
+{
+    return false;
+}
+
+void UIScriptController::setScrollUpdatesDisabled(bool)
+{
+}
+
 void UIScriptController::scrollToOffset(long x, long y)
 {
     [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:YES];
index f58d621..9afc51e 100644 (file)
@@ -244,6 +244,8 @@ interface UIScriptController {
     readonly attribute double contentOffsetX;
     readonly attribute double contentOffsetY;
 
+    attribute boolean scrollUpdatesDisabled; // Turns off notifications back to the web process after scrolls (used for testing scrolling tree).
+
     void scrollToOffset(long x, long y); // Initiate an animated scroll in the UI process.
     attribute object didEndScrollingCallback;
 
index 9779344..ed3e342 100644 (file)
@@ -385,6 +385,15 @@ double UIScriptController::contentOffsetY() const
     return 0;
 }
 
+bool UIScriptController::scrollUpdatesDisabled() const
+{
+    return false;
+}
+
+void UIScriptController::setScrollUpdatesDisabled(bool)
+{
+}
+
 void UIScriptController::scrollToOffset(long x, long y)
 {
 }
index 717e9a5..5a8df6e 100644 (file)
@@ -125,6 +125,9 @@ public:
     double contentOffsetX() const;
     double contentOffsetY() const;
 
+    bool scrollUpdatesDisabled() const;
+    void setScrollUpdatesDisabled(bool);
+
     void scrollToOffset(long x, long y);
 
     void immediateScrollToOffset(long x, long y);
index c2cd3a6..9bf4dfd 100644 (file)
@@ -61,5 +61,6 @@
 #endif
 
 @property (nonatomic, retain, setter=_setStableStateOverride:) NSNumber *_stableStateOverride;
+@property (nonatomic, setter=_setScrollingUpdatesDisabledForTesting:) BOOL _scrollingUpdatesDisabledForTesting;
 
 @end
index 48b0221..60895ec 100644 (file)
@@ -47,7 +47,8 @@
 
 @interface TestRunnerWKWebView () <WKUIDelegatePrivate> {
     RetainPtr<NSNumber> m_stableStateOverride;
-    BOOL m_isInteractingWithFormControl;
+    BOOL _isInteractingWithFormControl;
+    BOOL _scrollingUpdatesDisabled;
 }
 
 @property (nonatomic, copy) void (^zoomToScaleCompletionHandler)(void);
@@ -108,7 +109,7 @@ IGNORE_WARNINGS_END
 
 - (void)didStartFormControlInteraction
 {
-    m_isInteractingWithFormControl = YES;
+    _isInteractingWithFormControl = YES;
 
     if (self.didStartFormControlInteractionCallback)
         self.didStartFormControlInteractionCallback();
@@ -116,7 +117,7 @@ IGNORE_WARNINGS_END
 
 - (void)didEndFormControlInteraction
 {
-    m_isInteractingWithFormControl = NO;
+    _isInteractingWithFormControl = NO;
 
     if (self.didEndFormControlInteractionCallback)
         self.didEndFormControlInteractionCallback();
@@ -124,7 +125,7 @@ IGNORE_WARNINGS_END
 
 - (BOOL)isInteractingWithFormControl
 {
-    return m_isInteractingWithFormControl;
+    return _isInteractingWithFormControl;
 }
 
 - (void)_didShowForcePressPreview
@@ -234,6 +235,16 @@ IGNORE_WARNINGS_END
     [self _scheduleVisibleContentRectUpdate];
 }
 
+- (BOOL)_scrollingUpdatesDisabledForTesting
+{
+    return _scrollingUpdatesDisabled;
+}
+
+- (void)_setScrollingUpdatesDisabledForTesting:(BOOL)disabled
+{
+    _scrollingUpdatesDisabled = disabled;
+}
+
 - (void)_didEndRotation
 {
     if (self.rotationDidEndCallback)
index e5724f1..ff1d6e7 100644 (file)
@@ -146,6 +146,7 @@ void TestController::platformResetStateToConsistentValues(const TestOptions& opt
     if (PlatformWebView* platformWebView = mainWebView()) {
         TestRunnerWKWebView *webView = platformWebView->platformView();
         webView._stableStateOverride = nil;
+        webView._scrollingUpdatesDisabledForTesting = NO;
         webView.usesSafariLikeRotation = NO;
         webView.overrideSafeAreaInsets = UIEdgeInsetsZero;
         [webView _clearOverrideLayoutParameters];
index 7bcd47f..9517b4e 100644 (file)
@@ -546,6 +546,18 @@ double UIScriptController::contentOffsetY() const
     return webView.scrollView.contentOffset.y;
 }
 
+bool UIScriptController::scrollUpdatesDisabled() const
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    return webView._scrollingUpdatesDisabledForTesting;
+}
+
+void UIScriptController::setScrollUpdatesDisabled(bool disabled)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    webView._scrollingUpdatesDisabledForTesting = disabled;
+}
+
 void UIScriptController::scrollToOffset(long x, long y)
 {
     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();