Latched scrolling tests are flakey on Mavericks
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Jun 2014 17:41:36 +0000 (17:41 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Jun 2014 17:41:36 +0000 (17:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133578
<rdar://problem/17180591>

Reviewed by Brent Fulgham.

Tools:
The latched scrolling tests rely on synthetic mousewheel events whose coordinates can
be wrong on machines with more than one screen. This is because we use
[NSScreen mainScreen] when computing the global coordinates of the events, but
[NSScreen mainScreen] returns the screen with the key window, not the first screen.

So replace calls to [NSScreen mainScreen] with [[NSScreen screens] firstObject]. Also
add comments clarifying why the coordinate math works (which is not obvious given
the events have no target window).

Some scrolling tests also dispatched events outside the 800x600 test window, so
fix those tests, and add logging that will appear in test output when this happens.

* DumpRenderTree/mac/DumpRenderTree.mm:
(createWebViewAndOffscreenWindow):
* DumpRenderTree/mac/EventSendingController.mm:
(-[EventSendingController mouseScrollByX:andY:continuously:]):
(-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]):
* WebKitTestRunner/mac/EventSenderProxy.mm:
(WTR::EventSenderProxy::mouseMoveTo):
(WTR::EventSenderProxy::mouseScrollBy):
(WTR::EventSenderProxy::continuousMouseScrollBy):
(WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases):

LayoutTests:
Fix these tests to not dispatch events outside the window, and correct some of the wording
in the tests.

* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt:
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt:
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt:
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt:
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html:
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html:

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html
Tools/ChangeLog
Tools/DumpRenderTree/mac/DumpRenderTree.mm
Tools/DumpRenderTree/mac/EventSendingController.mm
Tools/WebKitTestRunner/mac/EventSenderProxy.mm

index 02d2380..fedc4f6 100644 (file)
@@ -1,3 +1,28 @@
+2014-06-06  Simon Fraser  <simon.fraser@apple.com>
+
+        Latched scrolling tests are flakey on Mavericks
+        https://bugs.webkit.org/show_bug.cgi?id=133578
+        <rdar://problem/17180591>
+
+        Reviewed by Brent Fulgham.
+        
+        Fix these tests to not dispatch events outside the window, and correct some of the wording
+        in the tests.
+
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html:
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html:
+
 2014-06-06  Alex Christensen  <achristensen@webkit.org>
 
         Run passing WebGL tests on Windows.
index 4553acd..e5cf2d9 100644 (file)
@@ -52,10 +52,10 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
-div display height = 485
-Mouse moved to (28, 610)
-Page before: 0, div before: 451
-Page after:  0, div after: 451
+div display height = 350
+Mouse moved to (28, 475)
+Page before: 0, div before: 586
+Page after:  0, div after: 666
 PASS Page did not receive wheel events.
 (GraphicsLayer
   (anchor 0.00 0.00)
index 9080586..65a297e 100644 (file)
@@ -52,12 +52,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
-div display height = 485
-Mouse moved to (28, 610)
-Page before: 0, div before: 451
-Page after:  0, div after: 451
+div display height = 350
+Mouse moved to (28, 475)
+Page before: 0, div before: 586
+Page after:  0, div after: 666
 PASS Page did not receive wheel events.
-Document was initial target for 0 of the wheel events.
+Document was initial target for 4 of the wheel events.
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 2008.00 2341.00)
index 8f4d1bf..eb280f3 100644 (file)
@@ -71,7 +71,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     divTarget = document.getElementById('target');
@@ -83,7 +82,7 @@ function scrollTest() {
     var startPosX = Math.round(divTarget.offsetLeft) + 20;
     debug("div display height = " + Math.round(divTarget.clientHeight));
     var startPosY = Math.round(divTarget.offsetTop) + Math.round(divTarget.clientHeight) - 42; // One wheel turn before end.
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -109,9 +108,8 @@ function setupTopLevel() {
         var messageLocation = document.getElementById('parent');
         var message = document.createElement('div');
         message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
-            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
-            + "down past the div.<br/><br/>"
-            + "You should not see the row of END labels if this test is successful.</p>";
+            + "near the bottom of the scrollable region, and then use the mouse wheel or a two-finger swipe to scroll up.<br/></br/>"
+            + "The page should not scroll.</p>";
         messageLocation.appendChild(message);
     }
 }
@@ -123,7 +121,7 @@ function setupTopLevel() {
     </div>
     <div class="scrollable_region">
         <h3>Scrollable Region</h3>
-        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; height: 350px;'>
             <table class="table" style='width: 99%'>
                 <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
                 <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
index 5f4170f..eb6c3c8 100644 (file)
@@ -63,7 +63,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     divTarget = document.getElementById('target');
@@ -75,7 +74,7 @@ function scrollTest() {
     var startPosX = Math.round(divTarget.offsetLeft) + 20;
     debug("div display height = " + Math.round(divTarget.clientHeight));
     var startPosY = Math.round(divTarget.offsetTop) + Math.round(divTarget.clientHeight) - 42; // One wheel turn before end.
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -101,9 +100,8 @@ function setupTopLevel() {
         var messageLocation = document.getElementById('parent');
         var message = document.createElement('div');
         message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
-            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
-            + "down past the div.<br/><br/>"
-            + "You should not see the row of END labels if this test is successful.</p>";
+            + "near the bottom of the scrollable region and scroll up.<br/><br/>"
+            + "The page should not scroll.</p>";
         messageLocation.appendChild(message);
     }
 }
@@ -115,7 +113,7 @@ function setupTopLevel() {
     </div>
     <div class="scrollable_region">
         <h3>Scrollable Region</h3>
-        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 350px;'>
             <table class="table" style='width: 99%'>
                 <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
                 <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
index ec15226..87a065c 100644 (file)
@@ -71,7 +71,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     divTarget = document.getElementById('target');
@@ -80,8 +79,8 @@ function scrollTest() {
 
     // Scroll the #source until we reach the #target.
     var startPosX = Math.round(divTarget.offsetLeft) + 20;
-    var startPosY = Math.round(divTarget.offsetTop) - 42; // Slightly more than one wheel scroll away from the IFrame
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    var startPosY = Math.round(divTarget.offsetTop) - 42;
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -109,7 +108,7 @@ function setupTopLevel() {
         message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
             + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
             + "down past the div.<br/><br/>"
-            + "You should not see the row of END labels if this test is successful.</p>";
+            + "The scrollable region should not scroll.</p>";
         messageLocation.appendChild(message);
     }
 }
@@ -121,7 +120,7 @@ function setupTopLevel() {
     </div>
     <div class="scrollable_region">
         <h3>Scrollable Region</h3>
-        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; height: 350px;'>
             <table class="table" style='width: 99%'>
                 <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
                 <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
index fa4289c..1e6cb47 100644 (file)
@@ -63,7 +63,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     divTarget = document.getElementById('target');
@@ -72,8 +71,8 @@ function scrollTest() {
 
     // Scroll the #source until we reach the #target.
     var startPosX = Math.round(divTarget.offsetLeft) + 20;
-    var startPosY = Math.round(divTarget.offsetTop) - 42; // Slightly more than one wheel scroll away from the IFrame
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    var startPosY = Math.round(divTarget.offsetTop) - 42;
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -101,7 +100,7 @@ function setupTopLevel() {
         message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
             + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
             + "down past the div.<br/><br/>"
-            + "You should not see the row of END labels if this test is successful.</p>";
+            + "The scrollable region should not scroll.</p>";
         messageLocation.appendChild(message);
     }
 }
@@ -113,7 +112,7 @@ function setupTopLevel() {
     </div>
     <div class="scrollable_region">
         <h3>Scrollable Region</h3>
-        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; height: 350px;'>
             <table class="table" style='width: 99%'>
                 <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
                 <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
index 130f4a0..e38e8ac 100644 (file)
@@ -35,7 +35,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
     iFrameScrollPositionBefore = window.frames['target'].document.body.scrollTop;
 
@@ -44,7 +43,7 @@ function scrollTest() {
     // Scroll the #source until we reach the #target.
     var startPosX = iframeTarget.offsetLeft + 20;
     var startPosY = iframeTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -71,8 +70,8 @@ function setupTopLevel() {
         var message = document.createElement('div');
         message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
             + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
-            + "down past the IFrame.<br/><br/>"
-            + "You should not see the row of END labels if this test is successful.</p>";
+            + "down past the iframe.<br/><br/>"
+            + "The iframe should not scroll.</p>";
         messageLocation.appendChild(message);
     }
 }
@@ -82,7 +81,7 @@ function setupTopLevel() {
     <div id="source" style="height: 100px">
         Put mouse here and flick downwards
     </div>
-    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+    <iframe id="target" name="target" style="border:solid 1px green; height: 300px; width: 500px;" 
      src= "data:text/html,
      <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
      TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
index 6e0ef0b..636e621 100644 (file)
@@ -71,7 +71,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     selectTarget = document.getElementById('target');
@@ -80,8 +79,8 @@ function scrollTest() {
 
     // Scroll the #source until we reach the #target.
     var startPosX = Math.round(selectTarget.offsetLeft) + 20;
-    var startPosY = Math.round(selectTarget.offsetTop) - 42; // Slightly more than one wheel scroll away from the IFrame
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    var startPosY = Math.round(selectTarget.offsetTop) - 42;
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
index 978ece2..6276d4a 100644 (file)
@@ -63,7 +63,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     selectTarget = document.getElementById('target');
@@ -72,8 +71,8 @@ function scrollTest() {
 
     // Scroll the #source until we reach the #target.
     var startPosX = Math.round(selectTarget.offsetLeft) + 20;
-    var startPosY = Math.round(selectTarget.offsetTop) - 42; // Slightly more than one wheel scroll away from the IFrame
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    var startPosY = Math.round(selectTarget.offsetTop) - 42;
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
index ddc77e6..dc672a2 100644 (file)
@@ -71,7 +71,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     selectTarget = document.getElementById('target');
@@ -79,11 +78,10 @@ function scrollTest() {
 
     selectScrollPositionBefore = selectTarget.scrollTop;
 
-    // Scroll the #source until we reach the #target.
     var startPosX = Math.round(selectTarget.offsetLeft) + 20;
     debug("div display height = " + Math.round(selectTarget.clientHeight));
-    var startPosY = Math.round(selectTarget.offsetTop) + Math.round(selectTarget.clientHeight) - 42; // One wheel turn before end.
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    var startPosY = Math.round(selectTarget.offsetTop) + Math.round(selectTarget.clientHeight) - 42;
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -119,7 +117,7 @@ function setupTopLevel() {
 </script>
 <div id="parent" style="height: 2000px; width: 2000px;">
     <div id="source" style="height: 100px; width: 500px;">
-        Put mouse here and flick downwards
+        Put mouse near the bottom of the select and scroll downwards.
     </div>
         <div class="scrollable_region">
             <h3>Scrollable Select</h3>
index 18bb5c4..0a88e6d 100644 (file)
@@ -63,7 +63,6 @@ function checkForScroll() {
 }
 
 function scrollTest() {
-    // See where our IFrame lives:
     pageScrollPositionBefore = document.body.scrollTop;
 
     selectTarget = document.getElementById('target');
@@ -74,8 +73,8 @@ function scrollTest() {
     // Scroll the #source until we reach the #target.
     var startPosX = Math.round(selectTarget.offsetLeft) + 20;
     debug("div display height = " + Math.round(selectTarget.clientHeight));
-    var startPosY = Math.round(selectTarget.offsetTop) + Math.round(selectTarget.clientHeight) - 42; // One wheel turn before end.
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    var startPosY = Math.round(selectTarget.offsetTop) + Math.round(selectTarget.clientHeight) - 42;
+    eventSender.mouseMoveTo(startPosX, startPosY);
     debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -111,7 +110,7 @@ function setupTopLevel() {
 </script>
 <div id="parent" style="height: 2000px; width: 2000px;">
     <div id="source" style="height: 100px; width: 500px;">
-        Put mouse here and flick downwards
+        Put mouse near the bottom of the select and scroll downwards.
     </div>
         <div class="scrollable_region">
             <h3>Scrollable Select</h3>
index 2a63517..5129fd8 100644 (file)
@@ -1,3 +1,34 @@
+2014-06-06  Simon Fraser  <simon.fraser@apple.com>
+
+        Latched scrolling tests are flakey on Mavericks
+        https://bugs.webkit.org/show_bug.cgi?id=133578
+        <rdar://problem/17180591>
+
+        Reviewed by Brent Fulgham.
+        
+        The latched scrolling tests rely on synthetic mousewheel events whose coordinates can
+        be wrong on machines with more than one screen. This is because we use
+        [NSScreen mainScreen] when computing the global coordinates of the events, but
+        [NSScreen mainScreen] returns the screen with the key window, not the first screen.
+        
+        So replace calls to [NSScreen mainScreen] with [[NSScreen screens] firstObject]. Also
+        add comments clarifying why the coordinate math works (which is not obvious given
+        the events have no target window).
+        
+        Some scrolling tests also dispatched events outside the 800x600 test window, so
+        fix those tests, and add logging that will appear in test output when this happens.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (createWebViewAndOffscreenWindow):
+        * DumpRenderTree/mac/EventSendingController.mm:
+        (-[EventSendingController mouseScrollByX:andY:continuously:]):
+        (-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]):
+        * WebKitTestRunner/mac/EventSenderProxy.mm:
+        (WTR::EventSenderProxy::mouseMoveTo):
+        (WTR::EventSenderProxy::mouseScrollBy):
+        (WTR::EventSenderProxy::continuousMouseScrollBy):
+        (WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases):
+
 2014-06-05  Carlos Alberto Lopez Perez  <clopez@igalia.com>
 
         [GTK] run-perf-tests should run the tests inside the jhbuild shell.
index 543d642..e21628c 100644 (file)
@@ -710,7 +710,7 @@ WebView *createWebViewAndOffscreenWindow()
     NSRect windowRect = NSOffsetRect(rect, -10000, [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - rect.size.height + 10000);
     DumpRenderTreeWindow *window = [[DumpRenderTreeWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
 
-    [window setColorSpace:[[NSScreen mainScreen] colorSpace]];
+    [window setColorSpace:[[[NSScreen screens] firstObject] colorSpace]];
     [window setCollectionBehavior:NSWindowCollectionBehaviorStationary];
     [[window contentView] addSubview:webView];
     [window orderBack:nil];
index b9b626e..fcb3508 100644 (file)
@@ -667,17 +667,16 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
 #endif
 }
 
-- (void)mouseScrollByX:(int)x andY:(int)y continuously:(BOOL)c
+- (void)mouseScrollByX:(int)x andY:(int)y continuously:(BOOL)continuously
 {
 #if !PLATFORM(IOS)
-    CGScrollEventUnit unit = c?kCGScrollEventUnitPixel:kCGScrollEventUnitLine;
+    CGScrollEventUnit unit = continuously ? kCGScrollEventUnitPixel : kCGScrollEventUnitLine;
     CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, unit, 2, y, x);
     
-    // CGEvent locations are in global display coordinates.
-    CGPoint lastGlobalMousePosition = {
-        lastMousePosition.x,
-        [[NSScreen mainScreen] frame].size.height - lastMousePosition.y
-    };
+    // Set the CGEvent location in flipped coords relative to the first screen, which
+    // compensates for the behavior of +[NSEvent eventWithCGEvent:] when the event has
+    // no associated window. See <rdar://problem/17180591>.
+    CGPoint lastGlobalMousePosition = CGPointMake(lastMousePosition.x, [[[NSScreen screens] firstObject] frame].size.height - lastMousePosition.y);
     CGEventSetLocation(cgScrollEvent, lastGlobalMousePosition);
 
     NSEvent *scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent];
@@ -735,8 +734,10 @@ const uint32_t kCGScrollWheelEventMomentumPhase = 123;
 
     CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, 2, y, x);
 
-    // CGEvent locations are in global display coordinates.
-    CGPoint lastGlobalMousePosition = CGPointMake(lastMousePosition.x, [[NSScreen mainScreen] frame].size.height - lastMousePosition.y);
+    // Set the CGEvent location in flipped coords relative to the first screen, which
+    // compensates for the behavior of +[NSEvent eventWithCGEvent:] when the event has
+    // no associated window. See <rdar://problem/17180591>.
+    CGPoint lastGlobalMousePosition = CGPointMake(lastMousePosition.x, [[[NSScreen screens] firstObject] frame].size.height - lastMousePosition.y);
     CGEventSetLocation(cgScrollEvent, lastGlobalMousePosition);
     CGEventSetIntegerValueField(cgScrollEvent, kCGScrollWheelEventIsContinuous, 1);
     CGEventSetIntegerValueField(cgScrollEvent, kCGScrollWheelEventScrollPhase, phase);
index c83b45c..27dba76 100644 (file)
@@ -220,6 +220,9 @@ void EventSenderProxy::mouseMoveTo(double x, double y)
         [NSApp _setCurrentEvent:event];
         [targetView mouseMoved:event];
         [NSApp _setCurrentEvent:nil];
+    } else {
+        CGPoint windowLocation = [event locationInWindow];
+        WTFLogAlways("mouseMoveTo failed to find a target view at %f,%f\n", windowLocation.x, windowLocation.y);
     }
 }
 
@@ -443,8 +446,10 @@ void EventSenderProxy::mouseScrollBy(int x, int y)
 {
     RetainPtr<CGEventRef> cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent(0, kCGScrollEventUnitLine, 2, y, x));
 
-    // CGEvent locations are in global display coordinates.
-    CGPoint lastGlobalMousePosition = CGPointMake(m_position.x, [[NSScreen mainScreen] frame].size.height - m_position.y);
+    // Set the CGEvent location in flipped coords relative to the first screen, which
+    // compensates for the behavior of +[NSEvent eventWithCGEvent:] when the event has
+    // no associated window. See <rdar://problem/17180591>.
+    CGPoint lastGlobalMousePosition = CGPointMake(m_position.x, [[[NSScreen screens] firstObject] frame].size.height - m_position.y);
     CGEventSetLocation(cgScrollEvent.get(), lastGlobalMousePosition);
 
     NSEvent *event = [NSEvent eventWithCGEvent:cgScrollEvent.get()];
@@ -452,12 +457,15 @@ void EventSenderProxy::mouseScrollBy(int x, int y)
         [NSApp _setCurrentEvent:event];
         [targetView scrollWheel:event];
         [NSApp _setCurrentEvent:nil];
+    } else {
+        NSPoint location = [event locationInWindow];
+        WTFLogAlways("mouseScrollByWithWheelAndMomentumPhases failed to find the target view at %f,%f\n", location.x, location.y);
     }
 }
 
 void EventSenderProxy::continuousMouseScrollBy(int x, int y, bool paged)
 {
-    // FIXME: Implement this.
+    WTFLogAlways("EventSenderProxy::continuousMouseScrollBy is not implemented\n");
     return;
 }
 
@@ -469,21 +477,26 @@ void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int
 {
     RetainPtr<CGEventRef> cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent(0, kCGScrollEventUnitLine, 2, y, x));
 
-    // CGEvent locations are in global display coordinates.
-    CGPoint lastGlobalMousePosition = CGPointMake(m_position.x, [[NSScreen mainScreen] frame].size.height - m_position.y);
+    // Set the CGEvent location in flipped coords relative to the first screen, which
+    // compensates for the behavior of +[NSEvent eventWithCGEvent:] when the event has
+    // no associated window. See <rdar://problem/17180591>.
+    CGPoint lastGlobalMousePosition = CGPointMake(m_position.x, [[[NSScreen screens] firstObject] frame].size.height - m_position.y);
     CGEventSetLocation(cgScrollEvent.get(), lastGlobalMousePosition);
 
     CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventIsContinuous, 1);
     CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventScrollPhase, phase);
     CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventMomentumPhase, momentum);
 
-    NSEvent* event = [NSEvent eventWithCGEvent: cgScrollEvent.get()];
+    NSEvent* event = [NSEvent eventWithCGEvent:cgScrollEvent.get()];
 
     // Our event should have the correct settings:
-    if (NSView *targetView = [m_testController->mainWebView()->platformView() hitTest: [event locationInWindow]]) {
-        [NSApp _setCurrentEvent: event];
-        [targetView scrollWheel: event];
-        [NSApp _setCurrentEvent: nil];
+    if (NSView *targetView = [m_testController->mainWebView()->platformView() hitTest:[event locationInWindow]]) {
+        [NSApp _setCurrentEvent:event];
+        [targetView scrollWheel:event];
+        [NSApp _setCurrentEvent:nil];
+    } else {
+        CGPoint windowLocation = [event locationInWindow];
+        WTFLogAlways("mouseScrollByWithWheelAndMomentumPhases failed to find the target view at %f,%f\n", windowLocation.x, windowLocation.y);
     }
 }