mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-19 23:07:33 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/mochitest/browser.eslintrc.js"
|
||||
]
|
||||
};
|
||||
10
toolkit/components/formautofill/test/browser/browser.ini
Normal file
10
toolkit/components/formautofill/test/browser/browser.ini
Normal file
|
|
@ -0,0 +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]
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* 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);
|
||||
});
|
||||
|
||||
add_task(terminationTaskFn);
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Tests the requestAutocomplete user interface.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Open the requestAutocomplete UI and test that selecting a profile results in
|
||||
* the correct data being sent back to the opener.
|
||||
*/
|
||||
add_task(function* test_select_profile() {
|
||||
// Request an e-mail address.
|
||||
let { uiWindow, promiseResult } = yield FormAutofillTest.showUI(
|
||||
TestData.requestEmailOnly);
|
||||
|
||||
// Accept the dialog.
|
||||
let acceptButton = uiWindow.document.getElementById("accept");
|
||||
EventUtils.synthesizeMouseAtCenter(acceptButton, {}, uiWindow);
|
||||
|
||||
let result = yield promiseResult;
|
||||
Assert.equal(result.fields.length, 1);
|
||||
Assert.equal(result.fields[0].section, "");
|
||||
Assert.equal(result.fields[0].addressType, "");
|
||||
Assert.equal(result.fields[0].contactType, "");
|
||||
Assert.equal(result.fields[0].fieldName, "email");
|
||||
Assert.equal(result.fields[0].value, "email@example.org");
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the requestAutocomplete UI and cancel the dialog.
|
||||
*/
|
||||
add_task(function* test_cancel() {
|
||||
// Request an e-mail address.
|
||||
let { uiWindow, promiseResult } = yield FormAutofillTest.showUI(
|
||||
TestData.requestEmailOnly);
|
||||
|
||||
// Cancel the dialog.
|
||||
let acceptButton = uiWindow.document.getElementById("cancel");
|
||||
EventUtils.synthesizeMouseAtCenter(acceptButton, {}, uiWindow);
|
||||
|
||||
let result = yield promiseResult;
|
||||
Assert.ok(result.canceled);
|
||||
});
|
||||
|
||||
add_task(terminationTaskFn);
|
||||
18
toolkit/components/formautofill/test/browser/head.js
Normal file
18
toolkit/components/formautofill/test/browser/head.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Initialization specific to Form Autofill mochitest-browser tests.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// 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);
|
||||
|
||||
// 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.
|
||||
38
toolkit/components/formautofill/test/browser/loader.js
Normal file
38
toolkit/components/formautofill/test/browser/loader.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* 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);
|
||||
|
||||
// Define output functions so they look the same across all frameworks.
|
||||
var Output = {
|
||||
print: info,
|
||||
};
|
||||
|
||||
// Define assertion functions so they look the same across all frameworks.
|
||||
var Assert = {
|
||||
ok: _mochitestAssert.ok,
|
||||
equal: _mochitestAssert.equal,
|
||||
};
|
||||
|
||||
// Define task registration functions, see description in "loader_common.js".
|
||||
var add_task_in_parent_process = add_task;
|
||||
var add_task_in_child_process = function () {};
|
||||
var 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.
|
||||
7
toolkit/components/formautofill/test/chrome/.eslintrc.js
Normal file
7
toolkit/components/formautofill/test/chrome/.eslintrc.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/mochitest/chrome.eslintrc.js"
|
||||
]
|
||||
};
|
||||
17
toolkit/components/formautofill/test/chrome/chrome.ini
Normal file
17
toolkit/components/formautofill/test/chrome/chrome.ini
Normal file
|
|
@ -0,0 +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]
|
||||
15
toolkit/components/formautofill/test/chrome/head.js
Normal file
15
toolkit/components/formautofill/test/chrome/head.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Initialization specific to Form Autofill mochitest-chrome tests.
|
||||
*
|
||||
* This file is loaded by "loader.js".
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// 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.
|
||||
116
toolkit/components/formautofill/test/chrome/loader.js
Normal file
116
toolkit/components/formautofill/test/chrome/loader.js
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/* 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";
|
||||
|
||||
var { 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);
|
||||
|
||||
var sharedUrl = SimpleTest.getTestFileURL("loader_common.js");
|
||||
Services.scriptloader.loadSubScript(sharedUrl, this);
|
||||
|
||||
var parentScript = SpecialPowers.loadChromeScript(
|
||||
SimpleTest.getTestFileURL("loader_parent.js"));
|
||||
|
||||
// Replace the extension of the loaded HTML file with ".js"
|
||||
var testUrl = location.href.replace(/\.\w+$/, ".js");
|
||||
|
||||
// Start loading the test script in the parent process.
|
||||
var 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.
|
||||
var Output = {
|
||||
print: info,
|
||||
};
|
||||
|
||||
// Define assertion functions so they look the same across all frameworks.
|
||||
var Assert = {
|
||||
ok: _mochitestAssert.ok,
|
||||
equal: _mochitestAssert.equal,
|
||||
};
|
||||
|
||||
var executeSoon = SimpleTest.executeSoon;
|
||||
|
||||
var 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);
|
||||
}
|
||||
var 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;
|
||||
});
|
||||
|
||||
var 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.
|
||||
77
toolkit/components/formautofill/test/chrome/loader_parent.js
Normal file
77
toolkit/components/formautofill/test/chrome/loader_parent.js
Normal 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";
|
||||
|
||||
var { 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);
|
||||
|
||||
var 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.
|
||||
var Output = {
|
||||
print: message => assert.ok(true, message),
|
||||
};
|
||||
|
||||
// Define assertion functions so they look the same across all frameworks.
|
||||
var 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, {});
|
||||
});
|
||||
});
|
||||
}
|
||||
var add_task = function () {};
|
||||
var add_task_in_child_process = function () {};
|
||||
var 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.
|
||||
var 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.
|
||||
|
|
@ -0,0 +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>
|
||||
|
||||
</body></html>
|
||||
|
|
@ -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;
|
||||
});
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<!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>
|
||||
|
||||
</body></html>
|
||||
|
|
@ -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");
|
||||
});
|
||||
245
toolkit/components/formautofill/test/head_common.js
Normal file
245
toolkit/components/formautofill/test/head_common.js
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* 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, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
|
||||
/* --- Global helpers --- */
|
||||
|
||||
// Some of these functions are already implemented in other parts of the source
|
||||
// tree, see bug 946708 about sharing more code.
|
||||
|
||||
var TestUtils = {
|
||||
/**
|
||||
* Waits for at least one tick of the event loop. This means that all pending
|
||||
* events at the time of this call will have been processed. Other events may
|
||||
* be processed before the returned promise is resolved.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When pending events have been processed.
|
||||
* @rejects Never.
|
||||
*/
|
||||
waitForTick: function () {
|
||||
return new Promise(resolve => executeSoon(resolve));
|
||||
},
|
||||
|
||||
/**
|
||||
* Waits for the specified timeout.
|
||||
*
|
||||
* @param aTimeMs
|
||||
* Minimum time to wait from the moment of this call, in milliseconds.
|
||||
* The actual wait may be longer, due to system timer resolution and
|
||||
* pending events being processed before the promise is resolved.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When the specified time has passed.
|
||||
* @rejects Never.
|
||||
*/
|
||||
waitMs: function (aTimeMs) {
|
||||
return new Promise(resolve => setTimeout(resolve, aTimeMs));
|
||||
},
|
||||
|
||||
/**
|
||||
* Allows waiting for an observer notification once.
|
||||
*
|
||||
* @param aTopic
|
||||
* Notification topic to observe.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves The array [aSubject, aData] from the observed notification.
|
||||
* @rejects Never.
|
||||
*/
|
||||
waitForNotification: function (aTopic) {
|
||||
Output.print("Waiting for notification: '" + aTopic + "'.");
|
||||
|
||||
return new Promise(resolve => Services.obs.addObserver(
|
||||
function observe(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(observe, aTopic);
|
||||
resolve([aSubject, aData]);
|
||||
}, aTopic, false));
|
||||
},
|
||||
|
||||
/**
|
||||
* Waits for a DOM event on the specified target.
|
||||
*
|
||||
* @param aTarget
|
||||
* The DOM EventTarget on which addEventListener should be called.
|
||||
* @param aEventName
|
||||
* String with the name of the event.
|
||||
* @param aUseCapture
|
||||
* This parameter is passed to the addEventListener call.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves The arguments from the observed event.
|
||||
* @rejects Never.
|
||||
*/
|
||||
waitForEvent: function (aTarget, aEventName, aUseCapture = false) {
|
||||
Output.print("Waiting for event: '" + aEventName + "' on " + aTarget + ".");
|
||||
|
||||
return new Promise(resolve => aTarget.addEventListener(aEventName,
|
||||
function onEvent(...aArgs) {
|
||||
aTarget.removeEventListener(aEventName, onEvent, aUseCapture);
|
||||
resolve(...aArgs);
|
||||
}, aUseCapture));
|
||||
},
|
||||
|
||||
// While the previous test file should have deleted all the temporary files it
|
||||
// used, on Windows these might still be pending deletion on the physical file
|
||||
// system. Thus, start from a new base number every time, to make a collision
|
||||
// with a file that is still pending deletion highly unlikely.
|
||||
_fileCounter: Math.floor(Math.random() * 1000000),
|
||||
|
||||
/**
|
||||
* Returns a reference to a temporary file, that is guaranteed not to exist,
|
||||
* and to have never been created before.
|
||||
*
|
||||
* @param aLeafName
|
||||
* Suggested leaf name for the file to be created.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves Path of a non-existent file in a temporary directory.
|
||||
*
|
||||
* @note It is not enough to delete the file if it exists, or to delete the
|
||||
* file after calling nsIFile.createUnique, because on Windows the
|
||||
* delete operation in the file system may still be pending, preventing
|
||||
* a new file with the same name to be created.
|
||||
*/
|
||||
getTempFile: Task.async(function* (aLeafName) {
|
||||
// Prepend a serial number to the extension in the suggested leaf name.
|
||||
let [base, ext] = DownloadPaths.splitBaseNameAndExtension(aLeafName);
|
||||
let leafName = base + "-" + this._fileCounter + ext;
|
||||
this._fileCounter++;
|
||||
|
||||
// Get a file reference under the temporary directory for this test file.
|
||||
let path = OS.Path.join(OS.Constants.Path.tmpDir, leafName);
|
||||
Assert.ok(!(yield OS.File.exists(path)));
|
||||
|
||||
// Ensure the file is deleted whe the test terminates.
|
||||
add_termination_task(function* () {
|
||||
if (yield OS.File.exists(path)) {
|
||||
yield OS.File.remove(path);
|
||||
}
|
||||
});
|
||||
|
||||
return path;
|
||||
}),
|
||||
};
|
||||
|
||||
/* --- Local helpers --- */
|
||||
|
||||
var FormAutofillTest = {
|
||||
/**
|
||||
* Stores the response that the next call to the mock requestAutocomplete UI
|
||||
* will return to the requester, or null to enable displaying the default UI.
|
||||
*/
|
||||
requestAutocompleteResponse: null,
|
||||
|
||||
/**
|
||||
* Displays the requestAutocomplete user interface using the specified data.
|
||||
*
|
||||
* @param aFormAutofillData
|
||||
* Serializable object containing the set of requested fields.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves An object with the following properties:
|
||||
* {
|
||||
* uiWindow: Reference to the initialized window.
|
||||
* promiseResult: Promise resolved by the UI when it closes.
|
||||
* }
|
||||
*/
|
||||
showUI: Task.async(function* (aFormAutofillData) {
|
||||
Output.print("Opening UI with data: " + JSON.stringify(aFormAutofillData));
|
||||
|
||||
// Wait for the initialization event before opening the window.
|
||||
let promiseUIWindow =
|
||||
TestUtils.waitForNotification("formautofill-window-initialized");
|
||||
let ui = yield FormAutofill.integration.createRequestAutocompleteUI(
|
||||
aFormAutofillData);
|
||||
let promiseResult = ui.show();
|
||||
|
||||
// The window is the subject of the observer notification.
|
||||
return {
|
||||
uiWindow: (yield promiseUIWindow)[0],
|
||||
promiseResult: promiseResult,
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
var TestData = {
|
||||
/**
|
||||
* Autofill UI request for the e-mail field only.
|
||||
*/
|
||||
get requestEmailOnly() {
|
||||
return {
|
||||
sections: [{
|
||||
name: "",
|
||||
addressSections: [{
|
||||
addressType: "",
|
||||
fields: [{
|
||||
fieldName: "email",
|
||||
contactType: "",
|
||||
}],
|
||||
}],
|
||||
}],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
/* --- Initialization and termination functions common to all tests --- */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Return a mock RequestAutocompleteUI object.
|
||||
return {
|
||||
show: Task.async(function* () {
|
||||
let response = FormAutofillTest.requestAutocompleteResponse;
|
||||
Output.print("Mock UI response: " + JSON.stringify(response));
|
||||
return response;
|
||||
}),
|
||||
};
|
||||
}),
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
});
|
||||
120
toolkit/components/formautofill/test/loader_common.js
Normal file
120
toolkit/components/formautofill/test/loader_common.js
Normal 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 --disable-e10s, mochitest-browser
|
||||
* - Child: mochitest-chrome with e10s
|
||||
* In the future, these might run in the child process for "xpcshell".
|
||||
*
|
||||
* 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");
|
||||
|
||||
var 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.
|
||||
var _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.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
|
||||
]
|
||||
};
|
||||
23
toolkit/components/formautofill/test/xpcshell/head.js
Normal file
23
toolkit/components/formautofill/test/xpcshell/head.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Initialization specific to Form Autofill xpcshell tests.
|
||||
*
|
||||
* This file is loaded by "loader.js".
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
// 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.
|
||||
|
||||
add_task_in_parent_process(function* test_xpcshell_initialize_profile() {
|
||||
// We need to send the profile-after-change notification manually to the
|
||||
// startup component to ensure it has been initialized.
|
||||
Cc["@mozilla.org/formautofill/startup;1"]
|
||||
.getService(Ci.nsIObserver)
|
||||
.observe(null, "profile-after-change", "");
|
||||
});
|
||||
46
toolkit/components/formautofill/test/xpcshell/loader.js
Normal file
46
toolkit/components/formautofill/test/xpcshell/loader.js
Normal 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";
|
||||
|
||||
var { 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.
|
||||
var Output = {
|
||||
print: do_print,
|
||||
};
|
||||
|
||||
var executeSoon = do_execute_soon;
|
||||
var setTimeout = (fn, delay) => do_timeout(delay, fn);
|
||||
|
||||
// Define task registration functions, see description in "loader_common.js".
|
||||
var add_task_in_parent_process = add_task;
|
||||
var add_task_in_child_process = function () {};
|
||||
var 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.
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* 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);
|
||||
});
|
||||
|
||||
add_task(terminationTaskFn);
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Tests overriding the FormAutofillIntegration module functions.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The requestAutocomplete UI will not be displayed during these tests.
|
||||
*/
|
||||
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;
|
||||
|
||||
let newIntegrationFn = base => ({
|
||||
createRequestAutocompleteUI: Task.async(function* () {
|
||||
overrideCalled = true;
|
||||
return yield base.createRequestAutocompleteUI.apply(this, arguments);
|
||||
}),
|
||||
});
|
||||
|
||||
FormAutofill.registerIntegration(newIntegrationFn);
|
||||
try {
|
||||
let ui = yield FormAutofill.integration.createRequestAutocompleteUI({});
|
||||
let result = yield ui.show();
|
||||
Assert.ok(result.canceled);
|
||||
} finally {
|
||||
FormAutofill.unregisterIntegration(newIntegrationFn);
|
||||
}
|
||||
|
||||
Assert.ok(overrideCalled);
|
||||
});
|
||||
|
||||
/**
|
||||
* Registers an integration override function that throws an exception, and
|
||||
* ensures that this does not block other functions from being registered.
|
||||
*/
|
||||
add_task(function* test_integration_override_error() {
|
||||
let overrideCalled = false;
|
||||
|
||||
let errorIntegrationFn = base => { throw "Expected error." };
|
||||
|
||||
let newIntegrationFn = base => ({
|
||||
createRequestAutocompleteUI: Task.async(function* () {
|
||||
overrideCalled = true;
|
||||
return yield base.createRequestAutocompleteUI.apply(this, arguments);
|
||||
}),
|
||||
});
|
||||
|
||||
FormAutofill.registerIntegration(errorIntegrationFn);
|
||||
FormAutofill.registerIntegration(newIntegrationFn);
|
||||
try {
|
||||
let ui = yield FormAutofill.integration.createRequestAutocompleteUI({});
|
||||
let result = yield ui.show();
|
||||
Assert.ok(result.canceled);
|
||||
} finally {
|
||||
FormAutofill.unregisterIntegration(errorIntegrationFn);
|
||||
FormAutofill.unregisterIntegration(newIntegrationFn);
|
||||
}
|
||||
|
||||
Assert.ok(overrideCalled);
|
||||
});
|
||||
|
||||
add_task(terminationTaskFn);
|
||||
12
toolkit/components/formautofill/test/xpcshell/xpcshell.ini
Normal file
12
toolkit/components/formautofill/test/xpcshell/xpcshell.ini
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[DEFAULT]
|
||||
head = loader.js head.js
|
||||
tail =
|
||||
skip-if = toolkit == 'android'
|
||||
# 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]
|
||||
Loading…
Add table
Add a link
Reference in a new issue