1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
14 * The Original Code is MozMill Test code.
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.
21 * Henrik Skupin <hskupin@mozilla.com>
22 * Anthony Hughes <ahughes@mozilla.com>
23 * M.-A. Darche <mozdev@cynode.org>
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.
37 * ***** END LICENSE BLOCK ***** */
41 * The UtilsAPI offers various helper functions for any other API which is
42 * not already covered by another shared module.
47 // Include required modules
48 var prefs = require("prefs");
50 const gTimeout = 5000;
53 * Get application specific informations
54 * @see http://mxr.mozilla.org/mozilla-central/source/xpcom/system/nsIXULAppInfo.idl
60 * Get the application info service
61 * @returns XUL runtime object
66 this._service = Cc["@mozilla.org/xre/app-info;1"]
67 .getService(Ci.nsIXULAppInfo)
68 .QueryInterface(Ci.nsIXULRuntime);
78 get buildID() this.appInfo.appBuildID,
81 * Get the application id
82 * @returns Application id
85 get ID() this.appInfo.ID,
88 * Get the application name
89 * @returns Application name
92 get name() this.appInfo.name,
95 * Get the operation system
96 * @returns Operation system name
99 get os() this.appInfo.OS,
102 * Get the product vendor
103 * @returns Vendor name
106 get vendor() this.appInfo.vendor,
109 * Get the application version
110 * @returns Application version
113 get version() this.appInfo.version,
116 * Get the build id of the Gecko platform
117 * @returns Platform build id
120 get platformBuildID() this.appInfo.platformBuildID,
123 * Get the version of the Gecko platform
124 * @returns Platform version
127 get platformVersion() this.appInfo.platformVersion,
130 * Get the currently used locale
131 * @returns Current locale
135 var registry = Cc["@mozilla.org/chrome/chrome-registry;1"]
136 .getService(Ci.nsIXULChromeRegistry);
137 return registry.getSelectedLocale("global");
141 * Get the user agent string
142 * @returns User agent
146 var window = mozmill.wm.getMostRecentWindow("navigator:browser");
148 return window.navigator.userAgent;
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)
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
165 function assertElementVisible(controller, elem, expectedVisibility) {
166 var element = elem.getNode();
169 switch (element.nodeName) {
171 visible = (element.state == 'open');
174 var style = controller.window.getComputedStyle(element, '');
175 var state = style.getPropertyValue('visibility');
176 visible = (state == 'visible');
179 controller.assertJS('subject.visible == subject.expectedVisibility', {
181 expectedVisibility: expectedVisibility
186 * Assert if the current URL is identical to the target URL.
187 * With this function also redirects can be tested.
189 * @param {MozmillController} controller
190 * MozMillController of the window to operate on
191 * @param {string} targetURL
194 function assertLoadedUrlEqual(controller, targetUrl) {
195 var locationBar = new elementslib.ID(controller.window.document, "urlbar");
196 var currentURL = locationBar.getNode().value;
198 // Load the target URL
199 controller.open(targetUrl);
200 controller.waitForPageLoad();
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);
210 * Close the context menu inside the content area of the currently open tab
212 * @param {MozmillController} controller
213 * MozMillController of the window to operate on
215 function closeContentAreaContextMenu(controller) {
216 var contextMenu = new elementslib.ID(controller.window.document, "contentAreaContextMenu");
217 controller.keypress(contextMenu, "VK_ESCAPE", {});
221 * Run tests against a given search form
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
234 function checkSearchField(controller, searchField,
235 searchTerm, submitButton,
237 controller.waitThenClick(searchField, timeout);
238 controller.type(searchField, searchTerm);
240 if (submitButton != undefined) {
241 controller.waitThenClick(submitButton, timeout);
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
258 function createURI(spec, originCharset, baseURI)
260 let iosvc = Cc["@mozilla.org/network/io-service;1"].
261 getService(Ci.nsIIOService);
263 return iosvc.newURI(spec, originCharset, baseURI);
267 * Empty the clipboard by assigning an empty string
269 function emptyClipboard() {
270 var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
271 getService(Ci.nsIClipboardHelper);
272 clipboard.copyString("");
276 * Format a URL by replacing all placeholders
278 * @param {string} prefName
279 * The preference name which contains the URL
280 * @return The formatted URL
283 function formatUrlPref(prefName) {
284 var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"]
285 .getService(Ci.nsIURLFormatter);
287 return formatter.formatURLPref(prefName);
291 * Returns the default home page
293 * @return The URL of the default homepage
296 function getDefaultHomepage() {
297 var preferences = prefs.preferences;
299 var prefValue = preferences.getPref("browser.startup.homepage", "",
300 true, Ci.nsIPrefLocalizedString);
301 return prefValue.data;
305 * Returns the value of an individual entity in a DTD file.
307 * @param [string] urls
309 * @param {string} entityId
310 * The ID of the entity to get the value of.
312 * @return The value of the requested entity
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");
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 + ';';
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"]');
333 if (elemNode == null)
334 throw new Error(arguments.callee.name + ": Unknown entity - " + entityId);
336 return elemNode.textContent;
340 * Returns the value of an individual property.
342 * @param {string} url
343 * URL of the string bundle.
344 * @param {string} prefName
345 * The property to get the value of.
347 * @return The value of the requested property
350 function getProperty(url, prefName) {
351 var sbs = Cc["@mozilla.org/intl/stringbundle;1"]
352 .getService(Ci.nsIStringBundleService);
353 var bundle = sbs.createBundle(url);
356 return bundle.GetStringFromName(prefName);
358 throw new Error(arguments.callee.name + ": Unknown property - " + prefName);
363 * Function to handle non-modal windows
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)
375 function handleWindow(type, text, callback, close) {
376 // Set the window opener function to use depending on the type
380 func_ptr = mozmill.utils.getWindowByType;
383 func_ptr = mozmill.utils.getWindowByTitle;
386 throw new Error(arguments.callee.name + ": Unknown opener type - " + type);
390 var controller = null;
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.");
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);
405 callback(controller);
408 // Check if we have to close the window
409 if (close === undefined)
412 if (close && window) {
413 controller.window.close();
414 mozmill.utils.waitFor(function () {
415 return func_ptr(text) != window;
416 }, "Window has been closed.");
431 // Export of variables
432 exports.appInfo = appInfo;
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;