]> git.donarmstrong.com Git - dactyl.git/blob - common/tests/functional/shared-modules/utils.js
Initial import of 1.0~b6
[dactyl.git] / common / tests / functional / shared-modules / utils.js
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is MozMill Test code.
15  *
16  * The Initial Developer of the Original Code is the Mozilla Foundation.
17  * Portions created by the Initial Developer are Copyright (C) 2009
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  *   Henrik Skupin <hskupin@mozilla.com>
22  *   Anthony Hughes <ahughes@mozilla.com>
23  *   M.-A. Darche <mozdev@cynode.org>
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * ***** END LICENSE BLOCK ***** */
38
39 /**
40  * @fileoverview
41  * The UtilsAPI offers various helper functions for any other API which is
42  * not already covered by another shared module.
43  *
44  * @version 1.0.3
45  */
46
47 // Include required modules
48 var prefs = require("prefs");
49
50 const gTimeout = 5000;
51
52 /**
53  * Get application specific informations
54  * @see http://mxr.mozilla.org/mozilla-central/source/xpcom/system/nsIXULAppInfo.idl
55  */
56 var appInfo = {
57   _service: null,
58
59   /**
60    * Get the application info service
61    * @returns XUL runtime object
62    * @type nsiXULRuntime
63    */
64   get appInfo() {
65     if (!this._appInfo) {
66       this._service = Cc["@mozilla.org/xre/app-info;1"]
67                         .getService(Ci.nsIXULAppInfo)
68                         .QueryInterface(Ci.nsIXULRuntime);
69     }
70     return this._service;
71   },
72
73   /**
74    * Get the build id
75    * @returns Build id
76    * @type string
77    */
78   get buildID() this.appInfo.appBuildID,
79
80   /**
81    * Get the application id
82    * @returns Application id
83    * @type string
84    */
85   get ID() this.appInfo.ID,
86
87   /**
88    * Get the application name
89    * @returns Application name
90    * @type string
91    */
92   get name() this.appInfo.name,
93
94   /**
95    * Get the operation system
96    * @returns Operation system name
97    * @type string
98    */
99   get os() this.appInfo.OS,
100
101   /**
102    * Get the product vendor
103    * @returns Vendor name
104    * @type string
105    */
106   get vendor() this.appInfo.vendor,
107
108   /**
109    * Get the application version
110    * @returns Application version
111    * @type string
112    */
113   get version() this.appInfo.version,
114
115   /**
116    * Get the build id of the Gecko platform
117    * @returns Platform build id
118    * @type string
119    */
120   get platformBuildID() this.appInfo.platformBuildID,
121
122   /**
123    * Get the version of the Gecko platform
124    * @returns Platform version
125    * @type string
126    */
127   get platformVersion() this.appInfo.platformVersion,
128
129   /**
130    * Get the currently used locale
131    * @returns Current locale
132    * @type string
133    */
134   get locale() {
135     var registry = Cc["@mozilla.org/chrome/chrome-registry;1"]
136                      .getService(Ci.nsIXULChromeRegistry);
137     return registry.getSelectedLocale("global");
138   },
139
140   /**
141    * Get the user agent string
142    * @returns User agent
143    * @type string
144    */
145   get userAgent() {
146     var window = mozmill.wm.getMostRecentWindow("navigator:browser");
147     if (window)
148       return window.navigator.userAgent;
149     return "";
150   }
151 };
152
153 /**
154  * Checks the visibility of an element.
155  * XXX: Mozmill doesn't check if an element is visible and also operates on
156  * elements which are invisible. (Bug 490548)
157  *
158  * @param {MozmillController} controller
159  *        MozMillController of the window to operate on
160  * @param {ElemBase} elem
161  *        Element to check its visibility
162  * @param {boolean} expectedVisibility
163  *        Expected visibility state of the element
164  */
165 function assertElementVisible(controller, elem, expectedVisibility) {
166   var element = elem.getNode();
167   var visible;
168
169   switch (element.nodeName) {
170     case 'panel':
171       visible = (element.state == 'open');
172       break;
173     default:
174       var style = controller.window.getComputedStyle(element, '');
175       var state = style.getPropertyValue('visibility');
176       visible = (state == 'visible');
177   }
178
179   controller.assertJS('subject.visible == subject.expectedVisibility', {
180     visible: visible,
181     expectedVisibility: expectedVisibility
182   });
183 }
184
185 /**
186  * Assert if the current URL is identical to the target URL.
187  * With this function also redirects can be tested.
188  *
189  * @param {MozmillController} controller
190  *        MozMillController of the window to operate on
191  * @param {string} targetURL
192  *        URL to check
193  */
194 function assertLoadedUrlEqual(controller, targetUrl) {
195   var locationBar = new elementslib.ID(controller.window.document, "urlbar");
196   var currentURL = locationBar.getNode().value;
197
198   // Load the target URL
199   controller.open(targetUrl);
200   controller.waitForPageLoad();
201
202   // Check the same web page has been opened
203   controller.waitFor(function () { 
204     return locationBar.getNode().value === currentURL;
205   }, "Current URL should be identical to the target URL - got " +
206      locationBar.getNode().value + ", expected " + currentURL);
207 }
208
209 /**
210  * Close the context menu inside the content area of the currently open tab
211  *
212  * @param {MozmillController} controller
213  *        MozMillController of the window to operate on
214  */
215 function closeContentAreaContextMenu(controller) {
216   var contextMenu = new elementslib.ID(controller.window.document, "contentAreaContextMenu");
217   controller.keypress(contextMenu, "VK_ESCAPE", {});
218 }
219
220 /**
221  * Run tests against a given search form
222  *
223  * @param {MozMillController} controller
224  *        MozMillController of the window to operate on
225  * @param {ElemBase} searchField
226  *        The HTML input form element to test
227  * @param {string} searchTerm
228  *        The search term for the test
229  * @param {ElemBase} submitButton
230  *        (Optional) The forms submit button
231  * @param {number} timeout
232  *        The timeout value for the single tests
233  */
234 function checkSearchField(controller, searchField,
235                                                      searchTerm, submitButton,
236                                                      timeout) {
237   controller.waitThenClick(searchField, timeout);
238   controller.type(searchField, searchTerm);
239
240   if (submitButton != undefined) {
241     controller.waitThenClick(submitButton, timeout);
242   }
243 }
244
245 /**
246  * Create a new URI
247  *
248  * @param {string} spec
249  *        The URI string in UTF-8 encoding.
250  * @param {string} originCharset
251  *        The charset of the document from which this URI string originated.
252  * @param {string} baseURI
253  *        If null, spec must specify an absolute URI. Otherwise, spec may be
254  *        resolved relative to baseURI, depending on the protocol.
255  * @return A URI object
256  * @type nsIURI
257  */
258 function createURI(spec, originCharset, baseURI)
259 {
260   let iosvc = Cc["@mozilla.org/network/io-service;1"].
261               getService(Ci.nsIIOService);
262
263   return iosvc.newURI(spec, originCharset, baseURI);
264 }
265
266 /**
267  * Empty the clipboard by assigning an empty string
268  */
269 function emptyClipboard() {
270   var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
271                   getService(Ci.nsIClipboardHelper);
272   clipboard.copyString("");
273 }
274
275 /**
276  * Format a URL by replacing all placeholders
277  *
278  * @param {string} prefName
279  *        The preference name which contains the URL
280  * @return The formatted URL
281  * @type string
282  */
283 function formatUrlPref(prefName) {
284   var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"]
285                      .getService(Ci.nsIURLFormatter);
286
287   return formatter.formatURLPref(prefName);
288 }
289
290 /**
291  * Returns the default home page
292  *
293  * @return The URL of the default homepage
294  * @type string
295  */
296 function getDefaultHomepage() {
297   var preferences = prefs.preferences;
298
299   var prefValue = preferences.getPref("browser.startup.homepage", "",
300                                       true, Ci.nsIPrefLocalizedString);
301   return prefValue.data;
302 }
303
304 /**
305  * Returns the value of an individual entity in a DTD file.
306  *
307  * @param [string] urls
308  *        Array of DTD urls.
309  * @param {string} entityId
310  *        The ID of the entity to get the value of.
311  *
312  * @return The value of the requested entity
313  * @type string
314  */
315 function getEntity(urls, entityId) {
316   // Add xhtml11.dtd to prevent missing entity errors with XHTML files
317   urls.push("resource:///res/dtd/xhtml11.dtd");
318
319   // Build a string of external entities
320   var extEntities = "";
321   for (i = 0; i < urls.length; i++) {
322     extEntities += '<!ENTITY % dtd' + i + ' SYSTEM "' +
323                    urls[i] + '">%dtd' + i + ';';
324   }
325
326   var parser = Cc["@mozilla.org/xmlextras/domparser;1"]
327                   .createInstance(Ci.nsIDOMParser);
328   var header = '<?xml version="1.0"?><!DOCTYPE elem [' + extEntities + ']>';
329   var elem = '<elem id="elementID">&' + entityId + ';</elem>';
330   var doc = parser.parseFromString(header + elem, 'text/xml');
331   var elemNode = doc.querySelector('elem[id="elementID"]');
332
333   if (elemNode == null)
334     throw new Error(arguments.callee.name + ": Unknown entity - " + entityId);
335
336   return elemNode.textContent;
337 }
338
339 /**
340  * Returns the value of an individual property.
341  *
342  * @param {string} url
343  *        URL of the string bundle.
344  * @param {string} prefName
345  *        The property to get the value of.
346  *
347  * @return The value of the requested property
348  * @type string
349  */
350 function getProperty(url, prefName) {
351   var sbs = Cc["@mozilla.org/intl/stringbundle;1"]
352             .getService(Ci.nsIStringBundleService);
353   var bundle = sbs.createBundle(url);
354
355   try {
356     return bundle.GetStringFromName(prefName);
357   } catch (ex) {
358     throw new Error(arguments.callee.name + ": Unknown property - " + prefName);
359   }
360 }
361
362 /**
363  * Function to handle non-modal windows
364  *
365  * @param {string} type
366  *        Specifies how to check for the new window (possible values: type or title)
367  * @param {string} text
368  *        The window type of title string to search for
369  * @param {function} callback (optional)
370  *        Callback function to call for window specific tests
371  * @param {boolean} close (optional - default: true)
372  *        Make sure the window is closed after the return from the callback handler
373  * @returns The MozMillController of the window (if the window hasn't been closed)
374  */
375 function handleWindow(type, text, callback, close) {
376   // Set the window opener function to use depending on the type
377   var func_ptr = null;
378   switch (type) {
379     case "type":
380       func_ptr = mozmill.utils.getWindowByType;
381       break;
382     case "title":
383       func_ptr = mozmill.utils.getWindowByTitle;
384       break;
385     default:
386       throw new Error(arguments.callee.name + ": Unknown opener type - " + type);
387   }
388
389   var window = null;
390   var controller = null;
391
392   try {
393     // Wait until the window has been opened
394     mozmill.utils.waitFor(function () {
395       window = func_ptr(text);
396       return window != null;
397     }, "Window has been found.");
398
399     // XXX: We still have to find a reliable way to wait until the new window
400     // content has been finished loading. Let's wait for now.
401     controller = new mozmill.controller.MozMillController(window);
402     controller.sleep(200);
403
404     if (callback) {
405       callback(controller);
406     }
407
408     // Check if we have to close the window
409     if (close === undefined)
410       close = true;
411
412     if (close && window) {
413       controller.window.close();
414       mozmill.utils.waitFor(function () {
415         return func_ptr(text) != window;
416       }, "Window has been closed.");
417
418       window = null;
419       controller = null;
420     }
421
422     return controller;
423   } catch (ex) {
424     if (window)
425       window.close();
426
427     throw ex;
428   }
429 }
430
431 // Export of variables
432 exports.appInfo = appInfo;
433
434 // Export of functions
435 exports.assertElementVisible = assertElementVisible;
436 exports.assertLoadedUrlEqual = assertLoadedUrlEqual;
437 exports.closeContentAreaContextMenu = closeContentAreaContextMenu;
438 exports.checkSearchField = checkSearchField;
439 exports.createURI = createURI;
440 exports.formatUrlPref = formatUrlPref;
441 exports.emptyClipboard = emptyClipboard;
442 exports.getDefaultHomepage = getDefaultHomepage;
443 exports.getEntity = getEntity;
444 exports.getProperty = getProperty;
445 exports.handleWindow = handleWindow;