Proposals/Automated testing support API

From SVG

The W3CTestUtils interface exists to provide functionality for W3C automated tests that is not appropriate for the normal DOM specs and the wider web (due to security considerations and the like). This functionality can be used to synthesize native user interaction events, for example.

W3C tests require an implementation of the W3CTestUtils interface to be made available via a global JavaScript variable called 'w3t'. How the w3t object is added to and enabled for an implementation is implementation dependent. Some implementations may need to be started with a special command line argument, while others may require an add-on/extension to be installed and enabled. Whatever mechanism is used to enable the w3t object, it is recommended that implementations restrict the w3t object to domains that are explicitly added to an "enable" list by the user.

/**
 * Initially developed from:
 *
 *   http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIDOMWindowUtils.idl
 *   http://mxr.mozilla.org/mozilla-central/source/testing/mochitest/tests/SimpleTest/EventUtils.js
 *   http://mxr.mozilla.org/mozilla-central/source/testing/mochitest/tests/SimpleTest/WindowSnapshot.js
 *
 * When adding new things to this interface please consult
 * the documents above to see if they provide what you need,
 * and how they do it. Ask the Mozilla devs questions if
 * something doesn't completely make sense.
 */
interface W3CTestUtils {
  
  /**
   * Synthesize a native mouse event. The event types supported are:
   *
   *   mousedown, mouseup, mousemove
   *
   * Events are sent in coordinates offset by aX and aY from the window.
   *
   * Note that additional events may be fired as a result of this call. For
   * instance, typically a click event will be fired as a result of a
   * mousedown and mouseup in sequence, and mouseover/mouseout events will
   * typically be fired as a result of a mousemove event.
   *
   * The event is dispatched via the toplevel window, so it could go to any
   * window under the toplevel window, in some cases it could never reach this
   * window at all.
   *
   * XXX what happens if the event is outside the browser window, or over a
   * window opened using window.open()?
   *
   * XXX what other native events? mouse wheel scroll? ...?
   *
   * @param aType event type
   * @param aX x offset in CSS pixels
   * @param aY y offset in CSS pixels
   * @param aButton button to synthesize
   * @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
   */
  void sendNativeMouseEvent(in AString aType,
                            in float aX,
                            in float aY,
                            in long aButton,
                            in long aModifiers);
  
  /**
   * Synthesize a key event to the window. The event types supported are:
   *
   *   keydown, keyup
   *
   * Key events generally end up being sent to the focused node.
   *
   * @param aType event type
   * @param aKeyCode key code
   * @param aCharCode character code
   * @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
   *
   * @return false if the event had preventDefault() called on it,
   *               true otherwise.  In other words, true if and only if the
   *               default action was taken.
   */
  boolean sendNativeKeyEvent(in AString aType,
                             in long aKeyCode,
                             in long aCharCode,
                             in long aModifiers);
  
  /**
   * Force a garbage collection.
   */
  void garbageCollect();
  
  /**
   * Disable any events that are not generated by the test. Prevents
   * user events generated by a human tester from interfering with the
   * correct running of a test. Perhaps we should be doing this automatically
   * in all tests that depend on UA events? If so, maybe it's better to have
   * the synthetic UA events methods we provide only work if the test declares
   * up front that it depends on UA events so that the harness knows to
   * disable UA events as soon as the test loads.
   */
  void disableNonTestMouseEvents(in boolean aDisable);
  
  /**
   * Get the number of screen pixels per CSS pixel.
   */
  readonly attribute float screenPixelsPerCSSPixel;
  
  /**
   * Perform the equivalent of:
   *   window.getComputedStyle(aElement, aPseudoElement).
   *     getPropertyValue(aPropertyName)
   * except that, when the link whose presence in history is allowed to
   * influence aElement's style is visited, get the value the property
   * would have if allowed all properties to change as a result of
   * :visited selectors (except for cases where getComputedStyle uses
   * data from the frame).
   *
   * This is easier to implement than adding our property restrictions
   * to this API, and is sufficient for the present testing
   * requirements (which are essentially testing 'color').
   */
  DOMString getVisitedDependentComputedStyle(in nsIDOMElement aElement,
                                          in AString aPseudoElement,
                                          in AString aPropertyName);
  
  // XXX isAfterPaintPending?
  // XXX flushVisualOutput()?
  // XXX sendSimpleGestureEvent()?
  // XXX snapshotWindow(win, withCaret)
  // XXX compareSnapshots(s1, s2, expected)
}

Comments from jwatt: I've initially included only low level, native style functionality in W3CTestUtils. An interface with multiple implementers is a pretty inflexible thing, so to minimize future inflexibility the idea is to get implementations to provide the w3t object with minimal, basic, platform specific functionality that we can't get any other way. We can then use that functionality along with the normal DOM interfaces to provide more friendly higher level utility functionality as necessary in a utils.js file that tests can include.