зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1021060 - Testing framework for requestAutocomplete. r=MattN
This commit is contained in:
Родитель
ae327468b1
Коммит
4935a3239f
|
@ -4,6 +4,19 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
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 += [
|
||||
'nsIAutofillController.idl',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
../head_common.js
|
||||
head.js
|
||||
|
||||
[browser_infrastructure.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,39 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
"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,
|
||||
};
|
||||
|
||||
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);
|
|
@ -0,0 +1,6 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
../head_common.js
|
||||
head.js
|
||||
|
||||
[test_infrastructure.html]
|
|
@ -0,0 +1,71 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
"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);
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>
|
||||
<!-- 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>
|
|
@ -0,0 +1,174 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Provides shared infrastructure for the automated tests.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths",
|
||||
"resource://gre/modules/DownloadPaths.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.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
|
||||
* 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;
|
||||
}),
|
||||
}
|
||||
|
||||
/* --- 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");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,2 @@
|
|||
[DEFAULT]
|
||||
support-files = head_common.js
|
|
@ -0,0 +1,29 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
"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();
|
||||
}
|
|
@ -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,5 @@
|
|||
[DEFAULT]
|
||||
head = head.js ../head_common.js
|
||||
tail =
|
||||
|
||||
[test_infrastructure.js]
|
Загрузка…
Ссылка в новой задаче