Arth
Arth

Reputation: 13110

Recording user inputs and confirms in firefox addon sdk

I have a problem that I have been struggling with for a few days now.

I am writing a userInput recording system for firefox with a view to using it to record tests for a web-based application.

I am recording onchange events on form fields and saving them in a store using a contentScript with added listeners to each field's onchange event.

field.addEventListener('change', recordFieldChange);

I am also recording user js confirm responses using an observer-service based override of the window.confirm methods.

var obs = require("observer-service");

obs.add("content-document-global-created", observeWindow);

function observeWindow(subject) {
  var window = subject.wrappedJSObject;
  var standardConfirm = window.confirm;

  window.confirm = function(pMessage) {
    response = standardConfirm(pMessage);
    recordConfirm(response);
    return response;
  }
};

The trouble I am having is that any confirm responses where the confirm is triggered by a field change are recorded before the field change, which is the wrong order for running a test.

I think this is because the page's onchange is evaluated before the addon contentscript, is there any way to change this order?

I am hoping for a solution or work around that doesn't use time-outs or changing the basic page content. I also need to able to record confirms caused by other events like page loads.

Upvotes: 0

Views: 452

Answers (1)

Wladimir Palant
Wladimir Palant

Reputation: 57651

The problem is that the page and your content script register event handlers on the same element - and the order in which they will be called is undefined (however, I think that Firefox consistently calls onchange before any listeners added via addEventListener). You need to get the change event before the web page does and triggers additional actions. The solution would be catching the event during the capture phase at the top level. In the capture phase the event "sinks in" to the actual element and triggers capturing event listeners before the bubble phase starts and the event goes up again triggering regular event listeners. Something like this should work:

window.addEventListener("change", recordFieldChange, true);

function recordFieldChange(event)
{
  var field = event.target;
  ...
}

This no longer registers the event listener at the individual field but rather at the window level. Note that this won't help much if the web page listens for a different event like input or keypress.

Upvotes: 1

Related Questions