2

For purposes of recording Selenium scripts, I need to be able to intercept all events on a page, such as keyup or click. Currently, I do this by attaching an event listener to all elements on the page, but if there is already a listener present that stops the event from bubbling up, it never reaches me.

I tried the "replacing addEventListener" approach from https://stackoverflow.com/a/6434924/15255 in How to find event listeners on a DOM node when debugging or from the JavaScript code? , but this does not seem to work.

This is all in a Firefox addon, so I can do privileged things, but there doesn't seem to be much functionality for enumerating or modifying existing listeners. Does anyone have a suggestion on how to do this?

Edit: The code as it stands:

jQuery(frame.document).
        bind("dblclick", {}, this.listeners.writeJsonClicks, true).
        bind("keyup", {}, this.listeners.writeJsonChange, true).
        bind("change", {}, this.listeners.writeJsonChange, true);

To clarify: I don't have control over the contents of the document in frame.document. It's whatever page the user is recording a script on. The issue is that by the time the document has loaded, its own capturing have already been installed, so mine won't receive the event.

I've been trying to catch the page at a point in its loading when the page DOM is fully loaded but the JS that attaches the listeners hasn't been executed yet. Using NsIObserverService to listen for document-element-inserted looked promising, but that event happens as soon as there is any DOM at all: the document and its head are loaded, but the body is not.

Fundamentally, I need either a way to re-order existing listeners to insert mine before ones that have come earlier, a way of being able to run code when the DOM tree is loaded but the JS hasn't been run yet, or a way of intercepting calls to addEventListener to wrap the added listeners, letting me eavesdrop.

Community
  • 1
  • 1
Zarkonnen
  • 22,200
  • 14
  • 65
  • 81

1 Answers1

2

You should register a capturing listener - events cannot be stopped from being captured.

document.addEventListener("keyup", function(event)
{
  console.log("keyup event received on " + event.target);
}, true);
Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
  • The issue is that the document has already loaded by the time I get to it, so I can't go in and register my listener first. – Zarkonnen Jun 28 '12 at 19:45
  • 1
    Maybe I am misunderstanding your point but you can register a capturing event listener at any time, just set the third parameter to [addEventListener](https://developer.mozilla.org/en/DOM/element.addEventListener) accordingly. A capturing event listener will always receive all events, no matter what. – Wladimir Palant Jun 28 '12 at 19:51
  • Interesting. In my experience, this doesn't seem to happen. The specific page I'm having trouble with is http://www.voyages-sncf.com/, where I am unable to attach a keyup listener to the "Départ" field. – Zarkonnen Jun 28 '12 at 19:54
  • Actually: your suggested code works. It seems that the issue stemmed from my use of jQuery to attach the listeners. – Zarkonnen Jun 28 '12 at 20:01
  • 1
    jQuery emulates DOM events to provide a consistent experience across all browsers (meaning mostly MSIE), IMHO it is creating a bigger mess than what it started with. – Wladimir Palant Jun 29 '12 at 05:23