20

I'm trying to do automated testing with WebDriver, but it currently has no ability to simulate mouse wheel events. As a workaround I'm trying to fire these events with JavaScript instead. I'm doing all my wheel experimenting on a straight HTML page right now, not within the WebDriver framework.

I'm specifically trying to fire a mouse wheel event on a scrolling div element.

So far I've been able to do this with Chrome and IE9, but I can't seem to get anything to work in Firefox (5.x).

I'm using the following cross-browser code to detect when mouse wheel events are fired, which I snagged off the net. This code is able to pick up the event in all browsers when I scroll the mouse wheel within the scrolling div I've created (id='view').

<script type="text/javascript">
  function wheel(event) {
    var delta = 0;
    if (!event) {
      event = view.event;
    }
    if (event.wheelDelta) {
      delta = event.wheelDelta / 120;
    }
    else if (event.detail) {
      delta = -event.detail / 3;
    }
    
    alert(delta);
  }
  
  var view = document.getElementById('view');
  
  if (view.addEventListener) {
    view.addEventListener('DOMMouseScroll', wheel, false);
  }
  
  view.onmousewheel = wheel;
</script>

The function below, when called, is able fire the mouse wheel event in Chrome and IE9, and gets picked up in the above handler with expected behavior.

function ChromeWheel () {
  var evt = document.createEvent("MouseEvents");
  evt.initEvent('mousewheel', true, true);
  evt.wheelDelta = 120;
  view.dispatchEvent(evt);
}

Of course, it does not work for Firefox. I've found existing documentation to be too sparse and confusing to know how FF handles this. Can anyone show me the bare minimum to fire a mouse wheel event in Firefox with a wheel delta (placed where Firefox expects it), such that my handler will pick it up?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Justin Aquadro
  • 2,280
  • 3
  • 21
  • 31
  • I always wonder why people want to fire native events directly like this. If it's your page and your code and you want to see the effect of a mouse scroll, why don't you just call the function directly that executes when your code receives a mouse scroll event. You should be able to factor that out of your code and call it directly without going through the event system at all and then it would have zero browser dependency and would just work everywhere. – jfriend00 Jul 18 '11 at 16:22
  • 3
    Because it's not just my code and I'm not even interested in firing events as part of my application. I'm trying to exercise the application as part of a QA process, and it's important to us that we don't start modifying the code all over the place to do so. – Justin Aquadro Jul 18 '11 at 16:27
  • OK - helps to know what you're trying to do. Aren't there professional tools meant for QA testing of web pages that will simulate all sorts of user events, including all sorts of mouse events and those tools inject events at the system level so they work with all browsers? – jfriend00 Jul 18 '11 at 16:31
  • I said in the first paragraph that I am using WebDriver (part of Selenium) for this purpose. It simulates some things; mouse wheel is not one of them at this time. – Justin Aquadro Jul 18 '11 at 16:36
  • Sorry, I missed that the first time. – jfriend00 Jul 18 '11 at 16:37
  • Does the posted code here work for IE8? – David Jan 25 '13 at 00:52

1 Answers1

15

Well,

  1. In the Mozilla part of the code, if you're listening for DOMMouseScroll you should dispatch a DOMMouseScroll event too, no? (mousewheel seems to be a Microsoft invention copied by webkit, but not Gecko).
  2. Instead of setting (readonly) properties on the event, you're supposed to call the appropriate init...() method, which for the mouse event is initMouseEvent(). (spec)

Here's a fixed up testcase, which works in Firefox: http://jsfiddle.net/6nnMV/

Probably not useful to you, but may be of interest to other people looking to simulate events, here's how (privileged) unit tests in mozilla simulate 'real' events: http://hg.mozilla.org/mozilla-central/annotate/a666b4f809f0/testing/mochitest/tests/SimpleTest/EventUtils.js#l248

Nickolay
  • 31,095
  • 13
  • 107
  • 185
  • According to the spec it appears that initWheelEvent() might be a better choice (or is it a case that this is not generally implemented yet?). The demo clearly works however, and the references are invaluable. Thank you. – Justin Aquadro Jul 18 '11 at 23:53
  • @jaquadro: yeah, not in Mozilla yet: http://mxr.mozilla.org/mozilla-central/search?string=initWheelEvent – Nickolay Jul 19 '11 at 06:20
  • Why did you choose the value "120" for what I presume is the "scroll amount" value? What does that translate into in practical terms? – thisissami Nov 27 '12 at 02:25
  • @thisissami: sorry, I just copied the value from the original question. There's documentation at https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/DOMMouseScroll#detail_value , but I guess it's wrong and the meaning of 'detail' depends on the OS. – Nickolay Dec 02 '12 at 17:00
  • Looking at the following link, 120 appears to be the unit increment for a scroll. Negative 120 will scroll the other direction. http://www.javascriptkit.com/javatutors/onmousewheel.shtml – David Jan 25 '13 at 00:15
  • I was wondering, anyone know if recent versions of FF have addressed the scroll wheel issue to work as other browsers do w/o it's own DOMMouseScroll event, etc.? Like FF10+ or do they still work the same as FF3.X / FF5.x? – David Jan 25 '13 at 00:16
  • Looking at the JS fiddle example, if one already has existing web app that listens for wheel event, how do we fire event against it? Set the view variable to (or directly access) the DOM element that is listening for it, and invoke dispatchEvent for the ChromeWheel function? Assume for existing web app, don't need attach listener as it's already listening. – David Jan 25 '13 at 00:35
  • Looks like this solution doens't work for IE8. How to support that? – David Jan 25 '13 at 00:52
  • but this doesn't actually scroll the page. Nor does it scroll the page if I change it to window.dispatchEvent. Is there a way to do this? – Jason B Feb 18 '13 at 00:05
  • Is it possible to use this to simulate Ctrl + mouse wheel event. This would zoom the page? Can anyone provide help on this? – Janaka Jun 28 '19 at 09:35
  • 1
    You could test or ask in a separate question. I would guess not, as firing a synthetic events [usually doesn't have any effect other than triggering event listeners](https://www.w3.org/TR/uievents/#trusted-events). – Nickolay Jun 28 '19 at 21:20