[iOS WK2] Add viewport tests and fix runUIScript() timing issues
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Sep 2015 00:17:27 +0000 (00:17 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Sep 2015 00:17:27 +0000 (00:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=149577

Reviewed by Tim Horton.

Source/WebKit2:

When calling testRunner.runUIScript() from a page load event, the script could run
in the UI process before the current remote layer tree transaction had been handled
there. This meant that runUIScript() could query state which was about to change.

Fix by delaying the execution of the UI script until a layer tree transaction has
been handled by the UI process, leveraging the existing DrawingAreaProxy::dispatchAfterEnsuringDrawing().

This is done using a new C SPI function WKPageCallAfterNextPresentationUpdate(),
which is mirrored in the Obj-C SPI as -_doAfterNextPresentationUpdate:.

Move WKWebView SPI which is testing-related into a WKTesting category. It is expected
that this will grow significantly.

* UIProcess/API/C/WKPage.cpp:
(WKPageCallAfterNextPresentationUpdate):
* UIProcess/API/C/WKPagePrivate.h:
* UIProcess/API/Cocoa/WKWebView.mm:
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::callAfterNextPresentationUpdate):
* UIProcess/WebPageProxy.h:
* UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h:
* UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm:
(WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing):

Tools:

When calling testRunner.runUIScript() from a page load event, the script could run
in the UI process before the current remote layer tree transaction had been handled
there. This meant that runUIScript() could query state which was about to change.

Fix by delaying the execution of the UI script until a layer tree transaction has
been handled by the UI process, leveraging the existing DrawingAreaProxy::dispatchAfterEnsuringDrawing().

* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
(WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
* WebKitTestRunner/TestInvocation.h:

LayoutTests:

New viewport tests which read the scale etc. in the UI process.

* TestExpectations:
* fast/viewport/ios/resources/viewport-test-utils.js: Added.
(getUIScript):
(tableFromJSON):
(getViewport):
(runTest):
* fast/viewport/ios/width-is-device-width-expected.txt: Added.
* fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall-expected.txt: Added.
* fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall.html: Added.
* fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden.html: Added.
* fast/viewport/ios/width-is-device-width-overflowing-expected.txt: Added.
* fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit-expected.txt: Added.
* fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit.html: Added.
* fast/viewport/ios/width-is-device-width-overflowing.html: Added.
* fast/viewport/ios/width-is-device-width.html: Added.
* platform/ios-simulator-wk2/TestExpectations:

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

25 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/viewport/ios/resources/viewport-test-utils.js [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-expected.txt [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall-expected.txt [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall.html [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden.html [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-expected.txt [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit-expected.txt [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit.html [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width-overflowing.html [new file with mode: 0644]
LayoutTests/fast/viewport/ios/width-is-device-width.html [new file with mode: 0644]
LayoutTests/platform/ios-simulator-wk2/TestExpectations
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/C/WKPage.cpp
Source/WebKit2/UIProcess/API/C/WKPagePrivate.h
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h
Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm
Tools/ChangeLog
Tools/WebKitTestRunner/TestInvocation.cpp
Tools/WebKitTestRunner/TestInvocation.h

index 49cb0c7..c7b556b 100644 (file)
@@ -1,3 +1,29 @@
+2015-09-25  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Add viewport tests and fix runUIScript() timing issues
+        https://bugs.webkit.org/show_bug.cgi?id=149577
+
+        Reviewed by Tim Horton.
+        
+        New viewport tests which read the scale etc. in the UI process.
+
+        * TestExpectations:
+        * fast/viewport/ios/resources/viewport-test-utils.js: Added.
+        (getUIScript):
+        (tableFromJSON):
+        (getViewport):
+        (runTest):
+        * fast/viewport/ios/width-is-device-width-expected.txt: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall-expected.txt: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall.html: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden.html: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing-expected.txt: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit-expected.txt: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit.html: Added.
+        * fast/viewport/ios/width-is-device-width-overflowing.html: Added.
+        * fast/viewport/ios/width-is-device-width.html: Added.
+        * platform/ios-simulator-wk2/TestExpectations:
+
 2015-09-25  Antti Koivisto  <antti@apple.com>
 
         Implement scoped styling for shadow DOM
index 436e6c3..f975f8c 100644 (file)
@@ -15,6 +15,7 @@ editing/pasteboard/gtk [ Skip ]
 tiled-drawing [ Skip ]
 swipe [ Skip ]
 fast/zooming/ios [ Skip ]
+fast/viewport/ios [ Skip ]
 
 fast/forms/attributed-strings.html [ Skip ]
 fast/scrolling/latching [ Skip ]
diff --git a/LayoutTests/fast/viewport/ios/resources/viewport-test-utils.js b/LayoutTests/fast/viewport/ios/resources/viewport-test-utils.js
new file mode 100644 (file)
index 0000000..343a286
--- /dev/null
@@ -0,0 +1,67 @@
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function getUIScript()
+{
+    return "(function() { \
+        var result = { \
+            'scale' : uiController.zoomScale, \
+            'maxScale' : uiController.maximumZoomScale, \
+            'minScale' : uiController.minimumZoomScale, \
+            'visibleRect' : uiController.contentVisibleRect \
+        }; \
+        return JSON.stringify(result, function(key, value) { \
+              if (typeof value === \"number\") \
+                  return value.toFixed(5); \
+            return value; \
+        }); \
+    })();";
+}
+
+function tableFromJSON(value)
+{
+    var result = JSON.parse(value);
+    
+    var table = document.createElement('table');
+    
+    
+    for (var property in result) {
+        var row = document.createElement('tr');
+        
+        var th = document.createElement('th');
+        th.textContent = property;
+        
+        var td = document.createElement('td');
+        var value = result[property];
+        if (typeof value === "object")
+            value = JSON.stringify(value);
+        
+        td.textContent = value;
+    
+        row.appendChild(th);
+        row.appendChild(td);
+        table.appendChild(row);
+    }
+    
+    return table;
+}
+
+function getViewport()
+{
+    var metaTag = document.head.querySelectorAll('meta')[0];
+    document.getElementById('viewport').textContent = metaTag.getAttribute('content');
+}
+
+function runTest()
+{
+    getViewport();
+    
+    if (testRunner.runUIScript) {
+        testRunner.runUIScript(getUIScript(), function(resultString) {
+            document.getElementById('result').appendChild(tableFromJSON(resultString));
+            testRunner.notifyDone();
+        });
+    }
+}
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-expected.txt b/LayoutTests/fast/viewport/ios/width-is-device-width-expected.txt
new file mode 100644 (file)
index 0000000..4e86b53
--- /dev/null
@@ -0,0 +1,6 @@
+Viewport: width=device-width
+
+scale  1.00000
+maxScale       5.00000
+minScale       1.00000
+visibleRect    {"left":"0.00000","top":"0.00000","width":"320.00000","height":"480.00000"}
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall-expected.txt b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall-expected.txt
new file mode 100644 (file)
index 0000000..a08a285
--- /dev/null
@@ -0,0 +1,7 @@
+Viewport: width=device-width
+
+scale  1.05263
+maxScale       5.00000
+minScale       1.05263
+visibleRect    {"left":"0.00000","top":"0.00000","width":"303.99999","height":"455.99998"}
+
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall.html b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-tall.html
new file mode 100644 (file)
index 0000000..75185d6
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <script src="resources/viewport-test-utils.js"></script>
+    <style>
+        body {
+            overflow: hidden;
+            height: 1000px;
+        }
+        .wide {
+            height: 1px;
+            width: 1000px;
+            background-color: gray;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+
+<p>Viewport: <span id="viewport"></span></p>
+<div id="result"></div>
+
+<div class="wide"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden.html b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden.html
new file mode 100644 (file)
index 0000000..831c9a6
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <script src="resources/viewport-test-utils.js"></script>
+    <style>
+        body {
+            overflow: hidden;
+        }
+        .wide {
+            height: 1px;
+            width: 1000px;
+            background-color: gray;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+
+<p>Viewport: <span id="viewport"></span></p>
+<div id="result"></div>
+
+<div class="wide"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-expected.txt b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-expected.txt
new file mode 100644 (file)
index 0000000..4e10ac3
--- /dev/null
@@ -0,0 +1,7 @@
+Viewport: width=device-width
+
+scale  0.31746
+maxScale       5.00000
+minScale       0.31746
+visibleRect    {"left":"0.00000","top":"0.00000","width":"1007.99997","height":"1511.99995"}
+
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit-expected.txt b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit-expected.txt
new file mode 100644 (file)
index 0000000..2296c43
--- /dev/null
@@ -0,0 +1,7 @@
+Viewport: width=device-width, shrink-to-fit=no
+
+scale  1.00000
+maxScale       5.00000
+minScale       1.00000
+visibleRect    {"left":"0.00000","top":"0.00000","width":"320.00000","height":"480.00000"}
+
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit.html b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing-no-shrink-to-fit.html
new file mode 100644 (file)
index 0000000..bac1b33
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width, shrink-to-fit=no">
+    <script src="resources/viewport-test-utils.js"></script>
+    <style>
+        .wide {
+            height: 1px;
+            width: 1000px;
+            background-color: gray;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+
+<p>Viewport: <span id="viewport"></span></p>
+<div id="result"></div>
+
+<div class="wide"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing.html b/LayoutTests/fast/viewport/ios/width-is-device-width-overflowing.html
new file mode 100644 (file)
index 0000000..d68648b
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <script src="resources/viewport-test-utils.js"></script>
+    <style>
+        .wide {
+            height: 1px;
+            width: 1000px;
+            background-color: gray;
+        }
+    </style>
+</head>
+<body onload="runTest()">
+
+<p>Viewport: <span id="viewport"></span></p>
+<div id="result"></div>
+
+<div class="wide"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/viewport/ios/width-is-device-width.html b/LayoutTests/fast/viewport/ios/width-is-device-width.html
new file mode 100644 (file)
index 0000000..08d0957
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <script src="resources/viewport-test-utils.js"></script>
+</head>
+<body onload="runTest()">
+
+<p>Viewport: <span id="viewport"></span></p>
+<div id="result"></div>
+
+</body>
+</html>
index 34922b2..8106724 100644 (file)
@@ -9,6 +9,7 @@
 fast/harness/ui-side-scripts.html [ Pass ]
 fast/harness/concurrent-ui-side-scripts.html [ Pass ]
 fast/zooming/ios [ Pass ]
+fast/viewport/ios [ Pass ]
 
 #//////////////////////////////////////////////////////////////////////////////////////////
 # End platform-specific directories.
index 14b7872..3039653 100644 (file)
@@ -1,3 +1,35 @@
+2015-09-25  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Add viewport tests and fix runUIScript() timing issues
+        https://bugs.webkit.org/show_bug.cgi?id=149577
+
+        Reviewed by Tim Horton.
+        
+        When calling testRunner.runUIScript() from a page load event, the script could run
+        in the UI process before the current remote layer tree transaction had been handled
+        there. This meant that runUIScript() could query state which was about to change.
+        
+        Fix by delaying the execution of the UI script until a layer tree transaction has
+        been handled by the UI process, leveraging the existing DrawingAreaProxy::dispatchAfterEnsuringDrawing().
+        
+        This is done using a new C SPI function WKPageCallAfterNextPresentationUpdate(),
+        which is mirrored in the Obj-C SPI as -_doAfterNextPresentationUpdate:.
+        
+        Move WKWebView SPI which is testing-related into a WKTesting category. It is expected
+        that this will grow significantly.
+
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageCallAfterNextPresentationUpdate):
+        * UIProcess/API/C/WKPagePrivate.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::callAfterNextPresentationUpdate):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h:
+        * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm:
+        (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing):
+
 2015-09-25  Alexey Proskuryakov  <ap@apple.com>
 
         [Mac] Media tests start to time out after a few days of bot uptime
index 414941c..e0ca7d3 100644 (file)
@@ -2469,6 +2469,12 @@ void WKPageClearWheelEventTestTrigger(WKPageRef pageRef)
     toImpl(pageRef)->clearWheelEventTestTrigger();
 }
 
+void WKPageCallAfterNextPresentationUpdate(WKPageRef pageRef, void* context, WKPagePostPresentationUpdateFunction callback)
+{
+    toImpl(pageRef)->callAfterNextPresentationUpdate([context, callback](WebKit::CallbackBase::Error error) {
+        callback(error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context);
+    });
+}
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
 
index ad9a9f8..eb0a7cd 100644 (file)
@@ -121,6 +121,9 @@ WK_EXPORT void WKPageHandleMediaEvent(WKPageRef page, WKMediaEventType event);
 
 WK_EXPORT void WKPageLoadURLWithShouldOpenExternalURLsPolicy(WKPageRef page, WKURLRef url, bool shouldOpenExternalURLs);
 
+typedef void (*WKPagePostPresentationUpdateFunction)(WKErrorRef, void*);
+WK_EXPORT void WKPageCallAfterNextPresentationUpdate(WKPageRef page, void* context, WKPagePostPresentationUpdateFunction function);
+
 #ifdef __cplusplus
 }
 #endif
index aacf5a0..6b06a36 100644 (file)
@@ -3020,21 +3020,6 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     return _viewportMetaTagWidth;
 }
 
-- (CGRect)_contentVisibleRect
-{
-    return [self convertRect:[self bounds] toView:self._currentContentView];
-}
-
-- (CGPoint)_convertPointFromContentsToView:(CGPoint)point
-{
-    return [self convertPoint:point fromView:self._currentContentView];
-}
-
-- (CGPoint)_convertPointFromViewToContents:(CGPoint)point
-{
-    return [self convertPoint:point toView:self._currentContentView];
-}
-
 - (_WKWebViewPrintFormatter *)_webViewPrintFormatter
 {
     UIViewPrintFormatter *viewPrintFormatter = self.viewPrintFormatter;
@@ -3107,13 +3092,51 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     return [_wkView _automaticallyAdjustsContentInsets];
 }
 
-#endif
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 
 #endif
 
 @end
 
-#if !TARGET_OS_IPHONE
+
+@implementation WKWebView (WKTesting)
+
+#if PLATFORM(IOS)
+
+- (CGRect)_contentVisibleRect
+{
+    return [self convertRect:[self bounds] toView:self._currentContentView];
+}
+
+- (CGPoint)_convertPointFromContentsToView:(CGPoint)point
+{
+    return [self convertPoint:point fromView:self._currentContentView];
+}
+
+- (CGPoint)_convertPointFromViewToContents:(CGPoint)point
+{
+    return [self convertPoint:point toView:self._currentContentView];
+}
+
+#endif // PLATFORM(IOS)
+
+// Execute the supplied block after the next transaction from the WebProcess.
+- (void)_doAfterNextPresentationUpdate:(void (^)(void))updateBlock
+{
+    typeof(updateBlock) updateBlockCopy = nil;
+    if (updateBlock)
+        updateBlockCopy = Block_copy(updateBlock);
+
+    _page->callAfterNextPresentationUpdate([updateBlockCopy](WebKit::CallbackBase::Error error) {
+        updateBlockCopy();
+        Block_release(updateBlockCopy);
+    });
+}
+
+@end
+
+
+#if PLATFORM(MAC)
 
 @implementation WKWebView (WKIBActions)
 
@@ -3167,7 +3190,7 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
 
 @end
 
-#endif
+#endif // PLATFORM(MAC)
 
 #if PLATFORM(IOS)
 @implementation WKWebView (_WKWebViewPrintFormatter)
index 7c67951..a1eacd5 100644 (file)
@@ -125,13 +125,8 @@ typedef NS_ENUM(NSInteger, _WKPaginationMode) {
 // The viewport meta tag width is negative if the value is not defined.
 @property (nonatomic, readonly) CGFloat _viewportMetaTagWidth;
 
-@property (nonatomic, readonly) CGRect _contentVisibleRect;
-
 @property (nonatomic, readonly) _WKWebViewPrintFormatter *_webViewPrintFormatter;
 
-- (CGPoint)_convertPointFromContentsToView:(CGPoint)point;
-- (CGPoint)_convertPointFromViewToContents:(CGPoint)point;
-
 - (void)_beginInteractiveObscuredInsetsChange;
 - (void)_endInteractiveObscuredInsetsChange;
 - (void)_hideContentUntilNextUpdate;
@@ -217,4 +212,18 @@ typedef NS_ENUM(NSInteger, _WKPaginationMode) {
 
 @end
 
+
+@interface WKWebView (WKTesting)
+
+#if TARGET_OS_IPHONE
+@property (nonatomic, readonly) CGRect _contentVisibleRect WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+- (CGPoint)_convertPointFromContentsToView:(CGPoint)point WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+- (CGPoint)_convertPointFromViewToContents:(CGPoint)point WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+#endif
+
+- (void)_doAfterNextPresentationUpdate:(void (^)(void))updateBlock WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+
+@end
+
+
 #endif
index 33ae7e4..7879bf9 100644 (file)
@@ -6084,6 +6084,11 @@ void WebPageProxy::clearWheelEventTestTrigger()
     m_process->send(Messages::WebPage::ClearWheelEventTestTrigger(), m_pageID);
 }
 
+void WebPageProxy::callAfterNextPresentationUpdate(std::function<void (CallbackBase::Error)> callback)
+{
+    m_drawingArea->dispatchAfterEnsuringDrawing(callback);
+}
+
 void WebPageProxy::setShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument)
 {
     if (m_shouldScaleViewToFitDocument == shouldScaleViewToFitDocument)
index 4e482d9..cb13e02 100644 (file)
@@ -1057,7 +1057,9 @@ public:
     void didChangeBackgroundColor();
     void didLayoutForCustomContentProvider();
 
+    // For testing
     void clearWheelEventTestTrigger();
+    void callAfterNextPresentationUpdate(std::function<void (CallbackBase::Error)>);
 
     void didLayout(uint32_t layoutMilestones);
 
index 9586727..7b74db8 100644 (file)
@@ -53,6 +53,7 @@ private:
     virtual void commitTransientZoom(double scale, WebCore::FloatPoint origin) override;
 
     virtual void waitForDidUpdateViewState() override;
+    virtual void dispatchAfterEnsuringDrawing(std::function<void (CallbackBase::Error)>) override;
 
     virtual void willSendUpdateGeometry() override;
 
index a0d5c92..6485f02 100644 (file)
@@ -206,6 +206,14 @@ void TiledCoreAnimationDrawingAreaProxy::commitTransientZoom(double scale, Float
     m_webPageProxy.process().send(Messages::DrawingArea::CommitTransientZoom(scale, origin), m_webPageProxy.pageID());
 }
 
+void TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing(std::function<void (CallbackBase::Error)> callback)
+{
+    // This callback is primarily used for testing in RemoteLayerTreeDrawingArea. We could in theory wait for a CA commit here.
+    dispatch_async(dispatch_get_main_queue(), ^{
+        callback(CallbackBase::Error::None);
+    });
+}
+
 } // namespace WebKit
 
 #endif // !PLATFORM(IOS)
index 8417355..d8b456d 100644 (file)
@@ -1,3 +1,22 @@
+2015-09-25  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Add viewport tests and fix runUIScript() timing issues
+        https://bugs.webkit.org/show_bug.cgi?id=149577
+
+        Reviewed by Tim Horton.
+        
+        When calling testRunner.runUIScript() from a page load event, the script could run
+        in the UI process before the current remote layer tree transaction had been handled
+        there. This meant that runUIScript() could query state which was about to change.
+        
+        Fix by delaying the execution of the UI script until a layer tree transaction has
+        been handled by the UI process, leveraging the existing DrawingAreaProxy::dispatchAfterEnsuringDrawing().
+
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+        (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
+        * WebKitTestRunner/TestInvocation.h:
+
 2015-09-25  Alexey Proskuryakov  <ap@apple.com>
 
         [Mac] Media tests start to time out after a few days of bot uptime
index bfe1fc1..c317383 100644 (file)
@@ -668,10 +668,11 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
         WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script"));
         WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
 
-        unsigned callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
-        WKStringRef scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
-
-        runUISideScript(scriptString, callbackID);
+        UIScriptInvocationData* invocationData = new UIScriptInvocationData();
+        invocationData->testInvocation = this;
+        invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
+        invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
+        WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback);
         return;
     }
 
@@ -720,6 +721,13 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
     return nullptr;
 }
 
+void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
+{
+    UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context);
+    data->testInvocation->runUISideScript(data->scriptString.get(), data->callbackID);
+    delete data;
+}
+
 void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
 {
     if (!m_UIScriptContext)
index 100d819..4fb3032 100644 (file)
@@ -74,6 +74,13 @@ private:
     bool compareActualHashToExpectedAndDumpResults(const char[33]);
 
     static void forceRepaintDoneCallback(WKErrorRef, void* context);
+    
+    struct UIScriptInvocationData {
+        unsigned callbackID;
+        WebKit::WKRetainPtr<WKStringRef> scriptString;
+        TestInvocation* testInvocation;
+    };
+    static void runUISideScriptAfterUpdateCallback(WKErrorRef, void* context);
 
     bool shouldLogFrameLoadDelegates() const;
     bool shouldLogHistoryClientCallbacks() const;