author | Paolo Amadini <paolo.mozmail@amadzone.org> |
Sun, 27 Jul 2014 18:18:44 +0100 | |
changeset 196334 | 15c19c592c12451289c384810a037b648a0bcca5 |
parent 196333 | bc751d1d8c1dc23dcdfc76c923f0fde62fc5dded |
child 196335 | d77f6a96ff960d0755cafa0e1dd976d9d285d311 |
child 196529 | 5afb5ea1d0d2f05d5f81c42d6409b86a53e02145 |
push id | 46844 |
push user | cbook@mozilla.com |
push date | Mon, 28 Jul 2014 14:30:47 +0000 |
treeherder | mozilla-inbound@7dd701896de8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | MattN |
bugs | 1023862 |
milestone | 34.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/components/formautofill/moz.build +++ b/toolkit/components/formautofill/moz.build @@ -8,17 +8,16 @@ BROWSER_CHROME_MANIFESTS += [ 'test/browser/browser.ini', ] MOCHITEST_CHROME_MANIFESTS += [ 'test/chrome/chrome.ini', ] XPCSHELL_TESTS_MANIFESTS += [ - 'test/xpcshell.ini', 'test/xpcshell/xpcshell.ini', ] XPIDL_SOURCES += [ 'nsIFormAutofillContentService.idl', ] XPIDL_MODULE = 'toolkit_formautofill'
--- a/toolkit/components/formautofill/test/browser/browser.ini +++ b/toolkit/components/formautofill/test/browser/browser.ini @@ -1,7 +1,10 @@ [DEFAULT] +# The following files starting with ".." are installed in the current folder. support-files = ../head_common.js + ../loader_common.js head.js + loader.js [browser_infrastructure.js] [browser_ui_requestAutocomplete.js]
--- a/toolkit/components/formautofill/test/browser/head.js +++ b/toolkit/components/formautofill/test/browser/head.js @@ -1,39 +1,18 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * This file makes the common testing infrastructure available to the browser - * tests located in this folder. This is only used as an infrastructure file, - * and new common functions should be added to the "head_common.js" file. + * Initialization specific to Form Autofill mochitest-browser tests. */ "use strict"; -let ChromeUtils = {}; -Services.scriptloader.loadSubScript( - "chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils); - -/* --- Adapters for the mochitest-browser-chrome infrastructure --- */ - -let Output = { - print: info, -}; +// We cannot start initialization from "loader.js" like we do in the xpcshell +// and mochitest-chrome frameworks, thus we load the script here. +Services.scriptloader.loadSubScript(getRootDirectory(gTestPath) + "loader.js", + this); -let Assert = { - ok: function (actual) { - let stack = Components.stack.caller; - ok(actual, "[" + stack.name + " : " + stack.lineNumber + "] " + actual + - " == true"); - }, - equal: function (actual, expected) { - let stack = Components.stack.caller; - is(actual, expected, "[" + stack.name + " : " + stack.lineNumber + "] " + - actual + " == " + expected); - }, -}; - -/* --- Shared infrastructure --- */ - -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "toolkit/components/formautofill/test/browser/head_common.js", this); +// The testing framework is fully initialized at this point, you can add +// mochitest-browser specific test initialization here. If you need shared +// functions or initialization that are not specific to mochitest-browser, +// consider adding them to "head_common.js" in the parent folder instead.
copy from toolkit/components/formautofill/test/browser/head.js copy to toolkit/components/formautofill/test/browser/loader.js --- a/toolkit/components/formautofill/test/browser/head.js +++ b/toolkit/components/formautofill/test/browser/loader.js @@ -1,39 +1,42 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * This file makes the common testing infrastructure available to the browser - * tests located in this folder. This is only used as an infrastructure file, - * and new common functions should be added to the "head_common.js" file. + * Infrastructure for the mochitest-browser tests located in this folder. + * + * See "loader_common.js" in the parent folder for a general overview. + * + * Unless you are adding new features to the framework, you shouldn't have to + * modify this file. Use "head_common.js" or "head.js" for shared code. */ "use strict"; +Services.scriptloader.loadSubScript(getRootDirectory(gTestPath) + + "loader_common.js", this); + let ChromeUtils = {}; Services.scriptloader.loadSubScript( "chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils); -/* --- Adapters for the mochitest-browser-chrome infrastructure --- */ - +// Define output functions so they look the same across all frameworks. let Output = { print: info, }; +// Define assertion functions so they look the same across all frameworks. let Assert = { - ok: function (actual) { - let stack = Components.stack.caller; - ok(actual, "[" + stack.name + " : " + stack.lineNumber + "] " + actual + - " == true"); - }, - equal: function (actual, expected) { - let stack = Components.stack.caller; - is(actual, expected, "[" + stack.name + " : " + stack.lineNumber + "] " + - actual + " == " + expected); - }, + ok: _mochitestAssert.ok, + equal: _mochitestAssert.equal, }; -/* --- Shared infrastructure --- */ +// Define task registration functions, see description in "loader_common.js". +let add_task_in_parent_process = add_task; +let add_task_in_child_process = function () {}; +let add_task_in_both_processes = add_task; -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/" + - "toolkit/components/formautofill/test/browser/head_common.js", this); +Services.scriptloader.loadSubScript(getRootDirectory(gTestPath) + + "head_common.js", this); + +// Reminder: unless you are adding new features to the framework, you shouldn't +// have to modify this file. Use "head_common.js" or "head.js" for shared code.
--- a/toolkit/components/formautofill/test/chrome/chrome.ini +++ b/toolkit/components/formautofill/test/chrome/chrome.ini @@ -1,7 +1,17 @@ [DEFAULT] +# The following files starting with ".." are installed in the current folder. support-files = ../head_common.js + ../loader_common.js head.js + test_infrastructure.js + test_requestAutocomplete_cancel.js + loader_parent.js + loader.js + +# For each test defined below, the associated JavaScript file must be declared +# in the list above. This is required because a "support-files" declaration on +# the individual test would override the global list instead of adding entries. [test_infrastructure.html] [test_requestAutocomplete_cancel.html]
--- a/toolkit/components/formautofill/test/chrome/head.js +++ b/toolkit/components/formautofill/test/chrome/head.js @@ -1,71 +1,15 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * This file makes the common testing infrastructure available to the chrome - * tests located in this folder. This is only used as an infrastructure file, - * and new common functions should be added to the "head_common.js" file. + * Initialization specific to Form Autofill mochitest-chrome tests. + * + * This file is loaded by "loader.js". */ "use strict"; -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); -Cu.import("resource://gre/modules/Services.jsm", this); - -Services.scriptloader.loadSubScript( - "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js", this); - -let ChromeUtils = {}; -Services.scriptloader.loadSubScript( - "chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils); - -/* --- Adapters for the mochitest-chrome infrastructure --- */ - -let Output = { - print: info, -}; - -let Assert = { - ok: function (actual) { - let stack = Components.stack.caller; - ok(actual, "[" + stack.name + " : " + stack.lineNumber + "] " + actual + - " == true"); - }, - equal: function (actual, expected) { - let stack = Components.stack.caller; - is(actual, expected, "[" + stack.name + " : " + stack.lineNumber + "] " + - actual + " == " + expected); - }, -}; - -let executeSoon = SimpleTest.executeSoon; - -let gTestTasks = []; -let add_task = taskFn => gTestTasks.push(taskFn); - -SimpleTest.waitForExplicitFinish(); - -window.addEventListener("load", function onLoad() { - window.removeEventListener("load", onLoad); - - Task.spawn(function* () { - try { - for (let taskFn of gTestTasks) { - info("Running " + taskFn.name); - yield Task.spawn(taskFn); - } - } catch (ex) { - ok(false, ex); - } - - SimpleTest.finish(); - }); -}); - -/* --- Shared infrastructure --- */ - -let headUrl = "chrome://mochitests/content/chrome/" + - "toolkit/components/formautofill/test/chrome/head_common.js"; -Services.scriptloader.loadSubScript(headUrl, this); +// The testing framework is fully initialized at this point, you can add +// mochitest-chrome specific test initialization here. If you need shared +// functions or initialization that are not specific to mochitest-chrome, +// consider adding them to "head_common.js" in the parent folder instead.
copy from toolkit/components/formautofill/test/chrome/head.js copy to toolkit/components/formautofill/test/chrome/loader.js --- a/toolkit/components/formautofill/test/chrome/head.js +++ b/toolkit/components/formautofill/test/chrome/loader.js @@ -1,71 +1,120 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * This file makes the common testing infrastructure available to the chrome - * tests located in this folder. This is only used as an infrastructure file, - * and new common functions should be added to the "head_common.js" file. + * Infrastructure for the mochitest-chrome tests located in this folder. + * + * See "loader_common.js" in the parent folder for a general overview. + * + * Unless you are adding new features to the framework, you shouldn't have to + * modify this file. Use "head_common.js" or "head.js" for shared code. */ "use strict"; const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); Cu.import("resource://gre/modules/Services.jsm", this); Services.scriptloader.loadSubScript( "chrome://mochikit/content/tests/SimpleTest/SimpleTest.js", this); +let sharedUrl = SimpleTest.getTestFileURL("loader_common.js"); +Services.scriptloader.loadSubScript(sharedUrl, this); + let ChromeUtils = {}; Services.scriptloader.loadSubScript( "chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils); -/* --- Adapters for the mochitest-chrome infrastructure --- */ +let parentScript = SpecialPowers.loadChromeScript( + SimpleTest.getTestFileURL("loader_parent.js")); + +// Replace the extension of the loaded HTML file with ".js" +let testUrl = location.href.replace(/\.\w+$/, ".js"); +// Start loading the test script in the parent process. +let promiseParentInitFinished = new Promise(function (resolve) { + parentScript.addMessageListener("finish_load_in_parent", resolve); +}); +parentScript.sendAsyncMessage("start_load_in_parent", { testUrl: testUrl }); + +// Define output functions so they look the same across all frameworks. let Output = { print: info, }; +// Define assertion functions so they look the same across all frameworks. let Assert = { - ok: function (actual) { - let stack = Components.stack.caller; - ok(actual, "[" + stack.name + " : " + stack.lineNumber + "] " + actual + - " == true"); - }, - equal: function (actual, expected) { - let stack = Components.stack.caller; - is(actual, expected, "[" + stack.name + " : " + stack.lineNumber + "] " + - actual + " == " + expected); - }, + ok: _mochitestAssert.ok, + equal: _mochitestAssert.equal, }; let executeSoon = SimpleTest.executeSoon; let gTestTasks = []; -let add_task = taskFn => gTestTasks.push(taskFn); -SimpleTest.waitForExplicitFinish(); +// Define task registration functions, see description in "loader_common.js". +function add_task(taskFn) { + gTestTasks.push([taskFn, "content", taskFn.name]); +} +function add_task_in_parent_process(taskFn, taskIdOverride) { + let taskId = taskIdOverride || getTaskId(Components.stack.caller); + gTestTasks.push([taskFn, "parent", taskId]); +}; +function add_task_in_both_processes(taskFn) { + // We need to define a task ID based on our direct caller. + add_task_in_parent_process(taskFn, getTaskId(Components.stack.caller)); + add_task(taskFn); +}; +let add_task_in_child_process = add_task; window.addEventListener("load", function onLoad() { window.removeEventListener("load", onLoad); Task.spawn(function* () { try { - for (let taskFn of gTestTasks) { - info("Running " + taskFn.name); - yield Task.spawn(taskFn); + for (let [taskFn, taskType, taskId] of gTestTasks) { + if (taskType == "content") { + // This is a normal task executed in the current process. + info("Running " + taskFn.name); + yield Task.spawn(taskFn); + } else { + // This is a task executed in the parent process. + info("Running task in parent process: " + taskFn.name); + let promiseFinished = new Promise(function (resolve) { + parentScript.addMessageListener("finish_task_" + taskId, resolve); + }); + parentScript.sendAsyncMessage("start_task_" + taskId); + yield promiseFinished; + info("Finished task in parent process: " + taskFn.name); + } } } catch (ex) { ok(false, ex); } SimpleTest.finish(); }); }); -/* --- Shared infrastructure --- */ +// Wait for the test script to be loaded in the parent process. This means that +// test tasks are registered and ready, but have not been executed yet. +add_task(function* wait_loading_in_parent_process() { + yield promiseParentInitFinished; +}); + +let headUrl = SimpleTest.getTestFileURL("head_common.js"); +Services.scriptloader.loadSubScript(headUrl, this); -let headUrl = "chrome://mochitests/content/chrome/" + - "toolkit/components/formautofill/test/chrome/head_common.js"; -Services.scriptloader.loadSubScript(headUrl, this); +Output.print("Loading test file: " + testUrl); +Services.scriptloader.loadSubScript(testUrl, this); + +// Register the execution of termination tasks after all other tasks. +add_task(terminationTaskFn); +add_task_in_parent_process(terminationTaskFn, terminationTaskFn.name); + +SimpleTest.waitForExplicitFinish(); + +// Reminder: unless you are adding new features to the framework, you shouldn't +// have to modify this file. Use "head_common.js" or "head.js" for shared code.
new file mode 100644 --- /dev/null +++ b/toolkit/components/formautofill/test/chrome/loader_parent.js @@ -0,0 +1,77 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * Infrastructure for the mochitest-chrome tests located in this folder, always + * executed in the parent process. + * + * See "loader_common.js" in the parent folder for a general overview. + * + * Unless you are adding new features to the framework, you shouldn't have to + * modify this file. Use "head_common.js" or "head.js" for shared code. + */ + +"use strict"; + +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); +Cu.import("resource://gre/modules/Services.jsm", this); + +let sharedUrl = "chrome://mochitests/content/chrome/" + + "toolkit/components/formautofill/test/chrome/loader_common.js"; +Services.scriptloader.loadSubScript(sharedUrl, this); + +// Define output functions so they look the same across all frameworks. Since +// we don't have an output function available here, we report as TEST-PASS. +let Output = { + print: message => assert.ok(true, message), +}; + +// Define assertion functions so they look the same across all frameworks. +let Assert = { + ok: assert.ok, + equal: assert.equal, +}; + +// Define task registration functions, see description in "loader_common.js". +function add_task_in_parent_process(taskFn, taskIdOverride) { + let taskId = taskIdOverride || getTaskId(Components.stack.caller); + Output.print("Registering in the parent process: " + taskId); + addMessageListener("start_task_" + taskId, function () { + Task.spawn(function* () { + try { + Output.print("Running in the parent process " + taskId); + yield Task.spawn(taskFn); + } catch (ex) { + assert.ok(false, ex); + } + + sendAsyncMessage("finish_task_" + taskId, {}); + }); + }); +} +let add_task = function () {}; +let add_task_in_child_process = function () {}; +let add_task_in_both_processes = add_task_in_parent_process; + +// We need to wait for the child process to send us the path of the test file +// to load before we can actually start loading it. +let context = this; +addMessageListener("start_load_in_parent", function (message) { + Output.print("Starting loading infrastructure in parent process."); + let headUrl = "chrome://mochitests/content/chrome/" + + "toolkit/components/formautofill/test/chrome/head_common.js"; + Services.scriptloader.loadSubScript(headUrl, context); + + Services.scriptloader.loadSubScript(message.testUrl, context); + + // Register the execution of termination tasks after all other tasks. + add_task_in_parent_process(terminationTaskFn, terminationTaskFn.name); + + Output.print("Finished loading infrastructure in parent process."); + sendAsyncMessage("finish_load_in_parent", {}); +}); + +// Reminder: unless you are adding new features to the framework, you shouldn't +// have to modify this file. Use "head_common.js" or "head.js" for shared code.
--- a/toolkit/components/formautofill/test/chrome/test_infrastructure.html +++ b/toolkit/components/formautofill/test/chrome/test_infrastructure.html @@ -1,72 +1,8 @@ <!DOCTYPE html><html><head><meta charset="utf-8"></head><body> +<script type="application/javascript;version=1.7" src="loader.js"></script> <!-- Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ --> <p id="paragraph">Paragraph contents.</p> -<script type="application/javascript;version=1.7" src="head.js"></script> -<script type="application/javascript;version=1.7"> - -/* - * Tests the local testing infrastructure. - */ - -"use strict"; - -/** - * Tests the truth assertion function. - */ -add_task(function* test_assert_truth() { - Assert.ok(1 != 2); -}); - -/** - * Tests the equality assertion function. - */ -add_task(function* test_assert_equality() { - Assert.equal(1 + 1, 2); -}); - -/** - * Uses some of the utility functions provided by the framework. - */ -add_task(function* test_utility_functions() { - // The "print" function is useful to log information that is not known before. - let randomString = "R" + Math.floor(Math.random() * 10); - Output.print("The random contents will be '" + randomString + "'."); - - // Create the text file with the random contents. - let path = yield TestUtils.getTempFile("test-infrastructure.txt"); - yield OS.File.writeAtomic(path, new TextEncoder().encode(randomString)); - - // Test a few utility functions. - yield TestUtils.waitForTick(); - yield TestUtils.waitMs(50); - - let promiseMyNotification = TestUtils.waitForNotification("my-topic"); - Services.obs.notifyObservers(null, "my-topic", ""); - yield promiseMyNotification; - - // Check the file size. The file will be deleted automatically later. - Assert.equal((yield OS.File.stat(path)).size, randomString.length); -}); - -/** - * This type of test has access to the content declared above. - */ -add_task(function* test_content() { - Assert.equal($("paragraph").innerHTML, "Paragraph contents."); - - let promiseMyEvent = TestUtils.waitForEvent($("paragraph"), "MyEvent"); - - let event = document.createEvent("CustomEvent"); - event.initCustomEvent("MyEvent", true, false, {}); - $("paragraph").dispatchEvent(event); - - yield promiseMyEvent; -}); - -add_task(terminationTaskFn); - -</script> </body></html>
new file mode 100644 --- /dev/null +++ b/toolkit/components/formautofill/test/chrome/test_infrastructure.js @@ -0,0 +1,61 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * Tests the local testing infrastructure. + */ + +"use strict"; + +/** + * Tests the truth assertion function. + */ +add_task(function* test_assert_truth() { + Assert.ok(1 != 2); +}); + +/** + * Tests the equality assertion function. + */ +add_task(function* test_assert_equality() { + Assert.equal(1 + 1, 2); +}); + +/** + * Uses some of the utility functions provided by the framework. + */ +add_task(function* test_utility_functions() { + // The "print" function is useful to log information that is not known before. + let randomString = "R" + Math.floor(Math.random() * 10); + Output.print("The random contents will be '" + randomString + "'."); + + // Create the text file with the random contents. + let path = yield TestUtils.getTempFile("test-infrastructure.txt"); + yield OS.File.writeAtomic(path, new TextEncoder().encode(randomString)); + + // Test a few utility functions. + yield TestUtils.waitForTick(); + yield TestUtils.waitMs(50); + + let promiseMyNotification = TestUtils.waitForNotification("my-topic"); + Services.obs.notifyObservers(null, "my-topic", ""); + yield promiseMyNotification; + + // Check the file size. The file will be deleted automatically later. + Assert.equal((yield OS.File.stat(path)).size, randomString.length); +}); + +/** + * This type of test has access to the content declared above. + */ +add_task(function* test_content() { + Assert.equal($("paragraph").innerHTML, "Paragraph contents."); + + let promiseMyEvent = TestUtils.waitForEvent($("paragraph"), "MyEvent"); + + let event = document.createEvent("CustomEvent"); + event.initCustomEvent("MyEvent", true, false, {}); + $("paragraph").dispatchEvent(event); + + yield promiseMyEvent; +});
--- a/toolkit/components/formautofill/test/chrome/test_requestAutocomplete_cancel.html +++ b/toolkit/components/formautofill/test/chrome/test_requestAutocomplete_cancel.html @@ -1,38 +1,9 @@ -<!DOCTYPE HTML><html><head><meta charset="utf-8"></head><body> +<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> +<script type="application/javascript;version=1.7" src="loader.js"></script> <!-- Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ --> <form id="form"> </form> -<script type="application/javascript;version=1.7" src="head.js"></script> -<script type="application/javascript;version=1.7"> - -/* - * Tests the response sent when requestAutocomplete is canceled by the user. - */ - -"use strict"; - -/** - * The requestAutocomplete UI will not be displayed during these tests. - */ -add_task(function* test_initialize() { - FormAutofillTest.requestAutocompleteResponse = { canceled: true }; -}); - -/** - * Tests the case where the feature is canceled. - */ -add_task(function* test_cancel() { - let promise = TestUtils.waitForEvent($("form"), "autocompleteerror"); - $("form").requestAutocomplete(); - let errorEvent = yield promise; - - Assert.equal(errorEvent.reason, "cancel"); -}); - -add_task(terminationTaskFn); - -</script> </body></html>
new file mode 100644 --- /dev/null +++ b/toolkit/components/formautofill/test/chrome/test_requestAutocomplete_cancel.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * Tests the response sent when requestAutocomplete is canceled by the user. + */ + +"use strict"; + +/** + * The requestAutocomplete UI will not be displayed during these tests. + */ +add_task_in_parent_process(function* test_cancel_init() { + FormAutofillTest.requestAutocompleteResponse = { canceled: true }; +}); + +/** + * Tests the case where the feature is canceled. + */ +add_task(function* test_cancel() { + let promise = TestUtils.waitForEvent($("form"), "autocompleteerror"); + $("form").requestAutocomplete(); + let errorEvent = yield promise; + + Assert.equal(errorEvent.reason, "cancel"); +});
--- a/toolkit/components/formautofill/test/head_common.js +++ b/toolkit/components/formautofill/test/head_common.js @@ -1,54 +1,37 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * Provides shared infrastructure for the automated tests. + * Initialization of Form Autofill tests shared between all frameworks. + * + * A copy of this file is installed in each of the framework subfolders, this + * means it becomes a sibling of the test files in the final layout. This is + * determined by how manifest "support-files" installation works. */ "use strict"; +// The requestAutocomplete framework is available at this point, you can add +// mochitest-chrome specific test initialization here. If you need shared +// functions or initialization that are not specific to mochitest-chrome, +// consider adding them to "head_common.js" in the parent folder instead. + XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths", "resource://gre/modules/DownloadPaths.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FormAutofill", "resource://gre/modules/FormAutofill.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); -let gTerminationTasks = []; -let add_termination_task = taskFn => gTerminationTasks.push(taskFn); - -/** - * None of the testing frameworks support asynchronous termination functions, so - * this task must be registered later, after the other "add_task" calls. - * - * Even xpcshell doesn't support calling "add_task" in the "tail.js" file, - * because it registers the task but does not wait for its termination, - * potentially leading to intermittent failures in subsequent tests. - */ -let terminationTaskFn = function* test_common_terminate() { - for (let taskFn of gTerminationTasks) { - try { - yield Task.spawn(taskFn); - } catch (ex) { - Output.print(ex); - Assert.ok(false); - } - } -}; - /* --- Global helpers --- */ // Some of these functions are already implemented in other parts of the source // tree, see bug 946708 about sharing more code. let TestUtils = { /** * Waits for at least one tick of the event loop. This means that all pending @@ -222,23 +205,17 @@ let TestData = { }], }], }; }, }; /* --- Initialization and termination functions common to all tests --- */ -add_task(function* test_common_initialize() { - // We must manually enable the feature while testing. - Services.prefs.setBoolPref("dom.forms.requestAutocomplete", true); - add_termination_task(function* () { - Services.prefs.clearUserPref("dom.forms.requestAutocomplete"); - }); - +add_task_in_parent_process(function* () { // If required, we return a mock response instead of displaying the UI. let mockIntegrationFn = base => ({ createRequestAutocompleteUI: Task.async(function* () { // Call the base method to display the UI if override is not requested. if (FormAutofillTest.requestAutocompleteResponse === null) { return yield base.createRequestAutocompleteUI.apply(this, arguments); } @@ -253,8 +230,16 @@ add_task(function* test_common_initializ }), }); FormAutofill.registerIntegration(mockIntegrationFn); add_termination_task(function* () { FormAutofill.unregisterIntegration(mockIntegrationFn); }); }); + +add_task_in_both_processes(function* () { + // We must manually enable the feature while testing. + Services.prefs.setBoolPref("dom.forms.requestAutocomplete", true); + add_termination_task(function* () { + Services.prefs.clearUserPref("dom.forms.requestAutocomplete"); + }); +});
new file mode 100644 --- /dev/null +++ b/toolkit/components/formautofill/test/loader_common.js @@ -0,0 +1,120 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * Infrastructure common to the test frameworks located in subfolders. + * + * A copy of this file is installed in each of the framework subfolders, this + * means it becomes a sibling of the test files in the final layout. This is + * determined by how manifest "support-files" installation works. + * + * Unless you are adding new features to the framework, you shouldn't have to + * modify this file. Use "head_common.js" or the "head.js" file of each + * framework for shared code. + */ + +"use strict"; + +/* + * -------------------- + * FRAMEWORK OVERVIEW + * -------------------- + * + * This framework is designed in such a way that test can be written in similar + * ways in the xpcshell, mochitest-chrome, and mochitest-browser frameworks, + * both when tests are running in the parent process or in a content process. + * + * There are some basic self-documenting assertion and output functions: + * + * Assert.ok(actualValue); + * Assert.is(actualValue, expectedValue); + * Output.print(string); + * + * Test cases and initialization functions are declared in shared head files + * ("head_common.js" and "head.js") as well as individual test files. When + * tests run in an Elecrolysis (e10s) environment, they are executed in both + * processes at first. Normally, at this point only the registration of test + * cases happen. When everything has finished loading, tests are started and + * appropriately synchronized between processes. + * + * Tests can be declared using the add_task syntax: + * + * add_task(function* test_something () { ... }); + * This adds a test either in the parent process or child process: + * - Parent: xpcshell, mochitest-chrome without --e10s, mochitest-browser + * - Child: mochitest-chrome with --e10s + * In the future, these might run in the child process for "xpcshell --e10s". + * + * add_task_in_parent_process(function* test_something () { ... }); + * This test runs in the parent process, but the child process will wait for + * its completion before continuing with the next task. This wait currently + * happens only in mochitest-chrome with --e10s, in other frameworks that run + * only in the parent process this is the same as a normal add_task. + * + * add_task_in_child_process(function* test_something () { ... }); + * This test runs only in the child process. This means that the test is not + * run unless this is an e10s test, currently mochitest-chrome with --e10s. + * + * add_task_in_both_processes(function* test_something () { ... }); + * Useful for initialization that must be done both in the parent and the + * child, like setting preferences. + * + * add_termination_task(function* () { ... }); + * Registers a new asynchronous termination task. This is executed after all + * test cases in the file finished, and always in the same process where the + * termination task is registered. + */ +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/Promise.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Task", + "resource://gre/modules/Task.jsm"); + +let gTerminationTasks = []; + +/** + * None of the testing frameworks support asynchronous termination functions, so + * this task must be registered later, after the other "add_task" calls. + * + * Even xpcshell doesn't support calling "add_task" in the "tail.js" file, + * because it registers the task but does not wait for its termination, + * potentially leading to intermittent failures in subsequent tests. + */ +function* terminationTaskFn() { + for (let taskFn of gTerminationTasks) { + try { + yield Task.spawn(taskFn); + } catch (ex) { + Output.print(ex); + Assert.ok(false); + } + } +}; + +function add_termination_task(taskFn) { + gTerminationTasks.push(taskFn); +} + +/** + * Returns a unique identifier used for synchronizing the given test task + * between the parent and child processes. + */ +function getTaskId(stackFrame) { + return stackFrame.filename + ":" + stackFrame.lineNumber; +} + +// This is a shared helper for mochitest-chrome and mochitest-browser. +let _mochitestAssert = { + ok: function (actual) { + let stack = Components.stack.caller; + ok(actual, "[" + stack.name + " : " + stack.lineNumber + "] " + actual + + " == true"); + }, + equal: function (actual, expected) { + let stack = Components.stack.caller; + is(actual, expected, "[" + stack.name + " : " + stack.lineNumber + "] " + + actual + " == " + expected); + }, +}; + +// Reminder: unless you are adding new features to the framework, you shouldn't +// have to modify this file. Use "head_common.js" or "head.js" for shared code.
deleted file mode 100644 --- a/toolkit/components/formautofill/test/xpcshell.ini +++ /dev/null @@ -1,2 +0,0 @@ -[DEFAULT] -support-files = head_common.js
--- a/toolkit/components/formautofill/test/xpcshell/head.js +++ b/toolkit/components/formautofill/test/xpcshell/head.js @@ -1,29 +1,15 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * This file makes the common testing infrastructure available to the xpcshell - * tests located in this folder. This is only used as an infrastructure file, - * and new common functions should be added to the "head_common.js" file. + * Initialization specific to Form Autofill xpcshell tests. + * + * This file is loaded by "loader.js". */ "use strict"; -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); -Cu.import("resource://gre/modules/Services.jsm", this); - -/* --- Adapters for the xpcshell infrastructure --- */ - -let Output = { - print: do_print, -}; - -let executeSoon = do_execute_soon; -let setTimeout = (fn, delay) => do_timeout(delay, fn); - -function run_test() { - do_get_profile(); - run_next_test(); -} +// The testing framework is fully initialized at this point, you can add +// xpcshell specific test initialization here. If you need shared functions or +// initialization that are not specific to xpcshell, consider adding them to +// "head_common.js" in the parent folder instead.
copy from toolkit/components/formautofill/test/xpcshell/head.js copy to toolkit/components/formautofill/test/xpcshell/loader.js --- a/toolkit/components/formautofill/test/xpcshell/head.js +++ b/toolkit/components/formautofill/test/xpcshell/loader.js @@ -1,29 +1,46 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* - * This file makes the common testing infrastructure available to the xpcshell - * tests located in this folder. This is only used as an infrastructure file, - * and new common functions should be added to the "head_common.js" file. + * Infrastructure for the xpcshell tests located in this folder. + * + * See "loader_common.js" in the parent folder for a general overview. + * + * Unless you are adding new features to the framework, you shouldn't have to + * modify this file. Use "head_common.js" or "head.js" for shared code. */ "use strict"; const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); Cu.import("resource://gre/modules/Services.jsm", this); -/* --- Adapters for the xpcshell infrastructure --- */ +Services.scriptloader.loadSubScript( + Services.io.newFileURI(do_get_file("loader_common.js")).spec, this); +// Define output functions so they look the same across all frameworks. let Output = { print: do_print, }; let executeSoon = do_execute_soon; let setTimeout = (fn, delay) => do_timeout(delay, fn); +// Define task registration functions, see description in "loader_common.js". +let add_task_in_parent_process = add_task; +let add_task_in_child_process = function () {}; +let add_task_in_both_processes = add_task; + +Services.scriptloader.loadSubScript( + Services.io.newFileURI(do_get_file("head_common.js")).spec, this); + +// Tests are always run asynchronously and with the profile loaded. function run_test() { do_get_profile(); run_next_test(); } + +// Reminder: unless you are adding new features to the framework, you shouldn't +// have to modify this file. Use "head_common.js" or "head.js" for shared code.
--- a/toolkit/components/formautofill/test/xpcshell/test_integration.js +++ b/toolkit/components/formautofill/test/xpcshell/test_integration.js @@ -5,17 +5,17 @@ * Tests overriding the FormAutofillIntegration module functions. */ "use strict"; /** * The requestAutocomplete UI will not be displayed during these tests. */ -add_task(function* test_initialize() { +add_task_in_parent_process(function* test_initialize() { FormAutofillTest.requestAutocompleteResponse = { canceled: true }; }); /** * Registers and unregisters an integration override function. */ add_task(function* test_integration_override() { let overrideCalled = false;
--- a/toolkit/components/formautofill/test/xpcshell/xpcshell.ini +++ b/toolkit/components/formautofill/test/xpcshell/xpcshell.ini @@ -1,6 +1,11 @@ [DEFAULT] -head = head.js ../head_common.js +head = loader.js head.js tail = +# The following files starting with ".." are installed in the current folder. +# However, they cannot be referenced directly in the "head" directive above. +support-files = + ../head_common.js + ../loader_common.js [test_infrastructure.js] [test_integration.js]