Bug 1023862 - Electrolysis (e10s) support for the requestAutocomplete testing framework. r=MattN

--HG--
rename : toolkit/components/formautofill/test/browser/head.js => toolkit/components/formautofill/test/browser/loader.js
rename : toolkit/components/formautofill/test/chrome/head.js => toolkit/components/formautofill/test/chrome/loader.js
rename : toolkit/components/formautofill/test/xpcshell/head.js => toolkit/components/formautofill/test/xpcshell/loader.js
This commit is contained in:
Paolo Amadini 2014-07-27 18:18:44 +01:00
parent d160b2bddf
commit 4d3ce75496
19 changed files with 557 additions and 249 deletions

View File

@ -13,7 +13,6 @@ MOCHITEST_CHROME_MANIFESTS += [
]
XPCSHELL_TESTS_MANIFESTS += [
'test/xpcshell.ini',
'test/xpcshell/xpcshell.ini',
]

View File

@ -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]

View File

@ -2,38 +2,17 @@
* 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);
// 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);
/* --- Adapters for the mochitest-browser-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);
},
};
/* --- 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.

View File

@ -0,0 +1,42 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* 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);
// 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: _mochitestAssert.ok,
equal: _mochitestAssert.equal,
};
// 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(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.

View File

@ -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]

View File

@ -2,70 +2,14 @@
* 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.

View File

@ -0,0 +1,120 @@
/* 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.
*
* 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);
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: _mochitestAssert.ok,
equal: _mochitestAssert.equal,
};
let executeSoon = SimpleTest.executeSoon;
let gTestTasks = [];
// 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, 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();
});
});
// 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);
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.

View File

@ -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.

View File

@ -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>

View File

@ -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;
});

View File

@ -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>

View File

@ -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");
});

View File

@ -2,11 +2,20 @@
* 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",
@ -15,35 +24,9 @@ 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
@ -227,13 +210,7 @@ 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* () {
@ -258,3 +235,11 @@ add_task(function* test_common_initialize() {
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");
});
});

View File

@ -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.

View File

@ -1,2 +0,0 @@
[DEFAULT]
support-files = head_common.js

View File

@ -2,28 +2,14 @@
* 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.

View File

@ -0,0 +1,46 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* 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);
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.

View File

@ -10,7 +10,7 @@
/**
* 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 };
});

View File

@ -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]