Bug 1063465 - Uplift Add-on SDK to Firefox r=me

This commit is contained in:
Erik Vold 2014-09-09 10:32:37 -07:00
parent e779a84653
commit 1a7a29d7b9
11 changed files with 476 additions and 390 deletions

View File

@ -0,0 +1,63 @@
## Overview
- Changes should follow the [design guidelines], as well as [coding style guide] for Jetpack
- All changes must be accompanied by tests
- In order to land, changes must have review from a core Jetpack developer
- Changes should have additional API review when needed
- Changes should have additional review from a Mozilla platform domain-expert when needed
If you have questions, ask in [#jetpack on IRC][jetpack irc channel] or on the [Jetpack mailing list].
## How to Make Code Contributions
If you have code that you'd like to contribute the Jetpack project, follow these steps:
1. Look for your issue in the [bugs already filed][open bugs]
2. If no bug exists, [submit one][submit bug]
3. Make your changes, per the Overview
4. Write a test ([intro][test intro], [API][test API])
5. Submit pull request with changes and a title in a form of `Bug XXX - description`
6. Copy the pull request link from GitHub and paste it in as an attachment to the bug
7. Each pull request should idealy contain only one commit, so squash the commits if necessary.
8. Flag the attachment for code review from one of the Jetpack reviewers listed below.
This step is optional, but could speed things up.
9. Address any nits (ie style changes), or other issues mentioned in the review.
10. Finally, once review is approved, a team member will do the merging
## Good First Bugs
There is a list of [good first bugs here](https://bugzilla.mozilla.org/buglist.cgi?list_id=7345714&columnlist=bug_severity%2Cpriority%2Cassigned_to%2Cbug_status%2Ctarget_milestone%2Cresolution%2Cshort_desc%2Cchangeddate&query_based_on=jetpack-good-1st-bugs&status_whiteboard_type=allwordssubstr&query_format=advanced&status_whiteboard=[good%20first%20bug]&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=VERIFIED&product=Add-on%20SDK&known_name=jetpack-good-1st-bugs).
## Reviewers
All changes must be reviewed by someone on the Jetpack review crew:
- [@mossop]
- [@gozala]
- [@wbamberg]
- [@ZER0]
- [@erikvold]
- [@jsantell]
- [@zombie]
For review of Mozilla platform usage and best practices, ask [@autonome],
[@0c0w3], or [@mossop] to find the domain expert.
For API and developer ergonomics review, ask [@gozala].
[design guidelines]:https://wiki.mozilla.org/Labs/Jetpack/Design_Guidelines
[jetpack irc channel]:irc://irc.mozilla.org/#jetpack
[Jetpack mailing list]:http://groups.google.com/group/mozilla-labs-jetpack
[open bugs]:https://bugzilla.mozilla.org/buglist.cgi?quicksearch=product%3ASDK
[submit bug]:https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK&component=general
[test intro]:https://jetpack.mozillalabs.com/sdk/latest/docs/#guide/implementing-reusable-module
[test API]:https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/unit-test
[coding style guide]:https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide
[@mossop]:https://github.com/mossop/
[@gozala]:https://github.com/Gozala/
[@wbamberg]:https://github.com/wbamberg/
[@ZER0]:https://github.com/ZER0/
[@erikvold]:https://github.com/erikvold/
[@jsantell]:https://github.com/jsantell
[@zombie]:https://github.com/zombie

View File

@ -135,9 +135,19 @@ TestFinder.prototype = {
let { fileFilter, testFilter } = makeFilters({ filter: this.filter });
return getSuites({ id: id, filter: fileFilter }).then(suites => {
let tests = [];
let testsRemaining = [];
let getNextTest = () => {
if (testsRemaining.length) {
return testsRemaining.shift();
}
if (!suites.length) {
return null;
}
let suite = suites.shift();
suites.forEach(suite => {
// Load each test file as a main module in its own loader instance
// `suite` is defined by cuddlefish/manifest.py:ManifestBuilder.build
let suiteModule;
@ -162,7 +172,7 @@ TestFinder.prototype = {
if (this.testInProcess) {
for (let name of Object.keys(suiteModule).sort()) {
if (NOT_TESTS.indexOf(name) === -1 && testFilter(name)) {
tests.push({
testsRemaining.push({
setup: suiteModule.setup,
teardown: suiteModule.teardown,
testFunction: suiteModule[name],
@ -171,9 +181,13 @@ TestFinder.prototype = {
}
}
}
})
return tests;
return getNextTest();
};
return {
getNext: () => resolve(getNextTest())
};
});
}
};

View File

@ -11,8 +11,9 @@ const memory = require("./memory");
const timer = require("../timers");
const cfxArgs = require("../test/options");
const { getTabs, closeTab, getURI } = require("../tabs/utils");
const { windows, isBrowser } = require("../window/utils");
const { windows, isBrowser, getMostRecentBrowserWindow } = require("../window/utils");
const { defer, all, Debugging: PromiseDebugging } = require("../core/promise");
const { getInnerId } = require("../window/utils");
const findAndRunTests = function findAndRunTests(options) {
var TestFinder = require("./unit-test-finder").TestFinder;
@ -32,11 +33,13 @@ const findAndRunTests = function findAndRunTests(options) {
};
exports.findAndRunTests = findAndRunTests;
let runnerWindows = new WeakMap();
const TestRunner = function TestRunner(options) {
if (options) {
this.fs = options.fs;
}
this.console = (options && "console" in options) ? options.console : console;
options = options || {};
runnerWindows.set(this, getInnerId(getMostRecentBrowserWindow()));
this.fs = options.fs;
this.console = options.console || console;
memory.track(this);
this.passed = 0;
this.failed = 0;
@ -314,7 +317,7 @@ TestRunner.prototype = {
}
let leftover = tabs.slice(1);
if (wins.length != 1)
if (wins.length != 1 || getInnerId(wins[0]) !== runnerWindows.get(this))
this.fail("Should not be any unexpected windows open");
if (tabs.length != 1)
this.fail("Should not be any unexpected tabs open");
@ -483,17 +486,23 @@ TestRunner.prototype = {
startMany: function startMany(options) {
function runNextTest(self) {
var test = options.tests.shift();
if (options.stopOnError && self.test && self.test.failed) {
self.console.error("aborted: test failed and --stop-on-error was specified");
options.onDone(self);
} else if (test) {
self.start({test: test, onDone: runNextTest});
} else {
options.onDone(self);
}
let { tests, onDone } = options;
return tests.getNext().then((test) => {
if (options.stopOnError && self.test && self.test.failed) {
self.console.error("aborted: test failed and --stop-on-error was specified");
onDone(self);
}
else if (test) {
self.start({test: test, onDone: runNextTest});
}
else {
onDone(self);
}
});
}
runNextTest(this);
return runNextTest(this).catch(console.exception);
},
start: function start(options) {

View File

@ -10,6 +10,7 @@ module.metadata = {
var { exit, stdout } = require("../system");
var cfxArgs = require("../test/options");
var events = require("../system/events");
const { resolve } = require("../core/promise");
function runTests(findAndRunTests) {
var harness = require("./harness");
@ -120,7 +121,9 @@ exports.runTestsFromModule = function runTestsFromModule(module) {
var { TestRunner } = loader.require("../deprecated/unit-test");
var runner = new TestRunner();
runner.startMany({
tests: tests,
tests: {
getNext: () => resolve(tests.shift())
},
stopOnError: cfxArgs.stopOnError,
onDone: nextIteration
});

View File

@ -22,8 +22,8 @@ DEFAULT_ICON = 'icon.png'
DEFAULT_ICON64 = 'icon64.png'
METADATA_PROPS = ['name', 'description', 'keywords', 'author', 'version',
'translators', 'contributors', 'license', 'homepage', 'icon',
'icon64', 'main', 'directories', 'permissions', 'preferences']
'developers', 'translators', 'contributors', 'license', 'homepage',
'icon', 'icon64', 'main', 'directories', 'permissions', 'preferences']
RESOURCE_HOSTNAME_RE = re.compile(r'^[a-z0-9_\-]+$')

View File

@ -138,6 +138,11 @@ def gen_manifest(template_root_dir, target_cfg, jid,
elem.appendChild(dom.createTextNode(translator))
dom.documentElement.getElementsByTagName("Description")[0].appendChild(elem)
for developer in target_cfg.get("developers", [ ]):
elem = dom.createElement("em:developer");
elem.appendChild(dom.createTextNode(developer))
dom.documentElement.getElementsByTagName("Description")[0].appendChild(elem)
for contributor in target_cfg.get("contributors", [ ]):
elem = dom.createElement("em:contributor");
elem.appendChild(dom.createTextNode(contributor))
@ -150,7 +155,7 @@ def gen_manifest(template_root_dir, target_cfg, jid,
if target_cfg.get("preferences"):
manifest.set("em:optionsType", "2")
# workaround until bug 971249 is fixed
# https://bugzilla.mozilla.org/show_bug.cgi?id=971249
manifest.set("em:optionsURL", "data:text/xml,<placeholder/>")

View File

@ -0,0 +1,23 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
'use strict';
const { Cu } = require('chrome');
const { id } = require('sdk/self');
const { AddonManager } = Cu.import('resource://gre/modules/AddonManager.jsm', {});
exports.testDevelopers = function(assert, done) {
AddonManager.getAddonByID(id, (addon) => {
let count = 0;
addon.developers.forEach(({ name }) => {
count++;
assert.equal(name, count == 1 ? 'A' : 'B', 'The developers keys are correct');
});
assert.equal(count, 2, 'The key count is correct');
assert.equal(addon.developers.length, 2, 'The key length is correct');
done();
});
}
require('sdk/test/runner').runTestsFromModule(module);

View File

@ -0,0 +1,6 @@
{
"id": "test-developers@jetpack",
"title": "Test developers package key",
"author": "Erik Vold",
"developers": [ "A", "B" ]
}

View File

@ -93,39 +93,29 @@ exports.testIsPrivateOnWindowOpenFromPrivate = function(assert, done) {
then(done, assert.fail);
};
exports.testOpenTabWithPrivateWindow = function(assert, done) {
function start() {
openPromise(null, {
features: {
private: true,
toolbar: true
}
}).then(focus).then(function(window) {
let { promise, resolve } = defer();
assert.equal(isPrivate(window), true, 'the focused window is private');
exports.testOpenTabWithPrivateWindow = function*(assert) {
let { promise, resolve } = defer();
tabs.open({
url: 'about:blank',
onOpen: function(tab) {
assert.equal(isPrivate(tab), false, 'the opened tab is not private');
// not closing this tab on purpose.. for now...
// we keep this tab open because we closed all windows
// and must keep a non-private window open at end of this test for next ones.
resolve(window);
}
});
return promise;
}).then(close).then(done, assert.fail);
}
(function closeWindows() {
if (windows.length > 0) {
return windows.activeWindow.close(closeWindows);
let window = yield openPromise(null, {
features: {
private: true,
toolbar: true
}
assert.pass('all pre test windows have been closed');
return start();
})()
});
yield focus(window);
assert.equal(isPrivate(window), true, 'the focused window is private');
tabs.open({
url: 'about:blank',
onOpen: (tab) => {
assert.equal(isPrivate(tab), false, 'the opened tab is not private');
tab.close(resolve);
}
});
yield promise;
yield close(window);
};
exports.testIsPrivateOnWindowOff = function(assert, done) {

View File

@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
'use strict';
module.metadata = {
@ -25,8 +24,7 @@ const FRAME_URL = "data:text/html;charset=utf-8," + encodeURIComponent(FRAME_HTM
const { defer } = require("sdk/core/promise");
const tabs = require("sdk/tabs");
const { setTabURL } = require("sdk/tabs/utils");
const { getActiveTab, getTabContentWindow, closeTab } = require("sdk/tabs/utils")
const { getActiveTab, getTabContentWindow, closeTab, setTabURL } = require("sdk/tabs/utils")
const { getMostRecentBrowserWindow } = require("sdk/window/utils");
const { open: openNewWindow, close: closeWindow } = require("sdk/window/helpers");
const { Loader } = require("sdk/test/loader");
@ -293,403 +291,390 @@ function createEmptySelections(window) {
// Test cases
exports["test No Selection"] = function(assert, done) {
exports["test No Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL);
open(URL).then(function() {
assert.equal(selection.isContiguous, false,
"selection.isContiguous without selection works.");
assert.equal(selection.isContiguous, false,
"selection.isContiguous without selection works.");
assert.strictEqual(selection.text, null,
"selection.text without selection works.");
assert.strictEqual(selection.text, null,
"selection.text without selection works.");
assert.strictEqual(selection.html, null,
"selection.html without selection works.");
assert.strictEqual(selection.html, null,
"selection.html without selection works.");
let selectionCount = 0;
for (let sel of selection)
selectionCount++;
let selectionCount = 0;
for each (let sel in selection)
selectionCount++;
assert.equal(selectionCount, 0, "No iterable selections");
assert.equal(selectionCount, 0,
"No iterable selections");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Single DOM Selection"] = function(assert, done) {
exports["test Single DOM Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL);
open(URL).then(selectFirstDiv).then(function() {
selectFirstDiv(window)
assert.equal(selection.isContiguous, true,
"selection.isContiguous with single DOM Selection works.");
assert.equal(selection.isContiguous, true,
"selection.isContiguous with single DOM Selection works.");
assert.equal(selection.text, "foo",
"selection.text with single DOM Selection works.");
assert.equal(selection.text, "foo",
"selection.text with single DOM Selection works.");
assert.equal(selection.html, "<div>foo</div>",
"selection.html with single DOM Selection works.");
assert.equal(selection.html, "<div>foo</div>",
"selection.html with single DOM Selection works.");
let selectionCount = 0;
for each (let sel in selection) {
selectionCount++;
let selectionCount = 0;
for (let sel of selection) {
selectionCount++;
assert.equal(sel.text, "foo",
"iterable selection.text with single DOM Selection works.");
assert.equal(sel.text, "foo",
"iterable selection.text with single DOM Selection works.");
assert.equal(sel.html, "<div>foo</div>",
"iterable selection.html with single DOM Selection works.");
}
assert.equal(sel.html, "<div>foo</div>",
"iterable selection.html with single DOM Selection works.");
}
assert.equal(selectionCount, 1,
"One iterable selection");
assert.equal(selectionCount, 1, "One iterable selection");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Multiple DOM Selection"] = function(assert, done) {
exports["test Multiple DOM Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let expectedText = ["foo", "and"];
let expectedHTML = ["<div>foo</div>", "<div>and</div>"];
let window = yield open(URL);
open(URL).then(selectAllDivs).then(function() {
let expectedText = ["foo", "and"];
let expectedHTML = ["<div>foo</div>", "<div>and</div>"];
selectAllDivs(window);
assert.equal(selection.isContiguous, false,
"selection.isContiguous with multiple DOM Selection works.");
assert.equal(selection.isContiguous, false,
"selection.isContiguous with multiple DOM Selection works.");
assert.equal(selection.text, expectedText[0],
"selection.text with multiple DOM Selection works.");
assert.equal(selection.text, expectedText[0],
"selection.text with multiple DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with multiple DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with multiple DOM Selection works.");
let selectionCount = 0;
for each (let sel in selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
let selectionCount = 0;
for (let sel of selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
selectionCount++;
}
selectionCount++;
}
assert.equal(selectionCount, 2,
"Two iterable selections");
assert.equal(selectionCount, 2, "Two iterable selections");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Textarea Selection"] = function(assert, done) {
exports["test Textarea Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL);
open(URL).then(selectTextarea).then(function() {
selectTextarea(window);
assert.equal(selection.isContiguous, true,
"selection.isContiguous with Textarea Selection works.");
assert.equal(selection.isContiguous, true,
"selection.isContiguous with Textarea Selection works.");
assert.equal(selection.text, "noodles",
"selection.text with Textarea Selection works.");
assert.equal(selection.text, "noodles",
"selection.text with Textarea Selection works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection works.");
let selectionCount = 0;
for each (let sel in selection) {
selectionCount++;
let selectionCount = 0;
for (let sel of selection) {
selectionCount++;
assert.equal(sel.text, "noodles",
"iterable selection.text with Textarea Selection works.");
assert.equal(sel.text, "noodles",
"iterable selection.text with Textarea Selection works.");
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection works.");
}
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection works.");
}
assert.equal(selectionCount, 1,
"One iterable selection");
assert.equal(selectionCount, 1, "One iterable selection");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Set Text in Multiple DOM Selection"] = function(assert, done) {
exports["test Set Text in Multiple DOM Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let expectedText = ["bar", "and"];
let expectedHTML = ["bar", "<div>and</div>"];
let window = yield open(URL);
open(URL).then(selectAllDivs).then(function() {
let expectedText = ["bar", "and"];
let expectedHTML = ["bar", "<div>and</div>"];
selectAllDivs(window);
selection.text = "bar";
selection.text = "bar";
assert.equal(selection.text, expectedText[0],
"set selection.text with single DOM Selection works.");
assert.equal(selection.text, expectedText[0],
"set selection.text with single DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with single DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with single DOM Selection works.");
let selectionCount = 0;
for each (let sel in selection) {
let selectionCount = 0;
for (let sel of selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.html with multiple DOM Selection works.");
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.html with multiple DOM Selection works.");
selectionCount++;
}
selectionCount++;
}
assert.equal(selectionCount, 2, "Two iterable selections");
assert.equal(selectionCount, 2,
"Two iterable selections");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Set HTML in Multiple DOM Selection"] = function(assert, done) {
exports["test Set HTML in Multiple DOM Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let html = "<span>b<b>a</b>r</span>";
let expectedText = ["bar", "and"];
let expectedHTML = [html, "<div>and</div>"];
let window = yield open(URL);
open(URL).then(selectAllDivs).then(function() {
let html = "<span>b<b>a</b>r</span>";
selectAllDivs(window);
let expectedText = ["bar", "and"];
let expectedHTML = [html, "<div>and</div>"];
selection.html = html;
selection.html = html;
assert.equal(selection.text, expectedText[0],
"set selection.text with DOM Selection works.");
assert.equal(selection.text, expectedText[0],
"set selection.text with DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with DOM Selection works.");
let selectionCount = 0;
for (let sel of selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
let selectionCount = 0;
for each (let sel in selection) {
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.html with multiple DOM Selection works.");
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
selectionCount++;
}
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.html with multiple DOM Selection works.");
assert.equal(selectionCount, 2, "Two iterable selections");
selectionCount++;
}
assert.equal(selectionCount, 2,
"Two iterable selections");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Set HTML as text in Multiple DOM Selection"] = function(assert, done) {
exports["test Set HTML as text in Multiple DOM Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let text = "<span>b<b>a</b>r</span>";
let html = "&lt;span&gt;b&lt;b&gt;a&lt;/b&gt;r&lt;/span&gt;";
let expectedText = [text, "and"];
let expectedHTML = [html, "<div>and</div>"];
let window = yield open(URL);
open(URL).then(selectAllDivs).then(function() {
let text = "<span>b<b>a</b>r</span>";
let html = "&lt;span&gt;b&lt;b&gt;a&lt;/b&gt;r&lt;/span&gt;";
selectAllDivs(window);
let expectedText = [text, "and"];
let expectedHTML = [html, "<div>and</div>"];
selection.text = text;
selection.text = text;
assert.equal(selection.text, expectedText[0],
"set selection.text with DOM Selection works.");
assert.equal(selection.text, expectedText[0],
"set selection.text with DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with DOM Selection works.");
assert.equal(selection.html, expectedHTML[0],
"selection.html with DOM Selection works.");
let selectionCount = 0;
for (let sel of selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
let selectionCount = 0;
for each (let sel in selection) {
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.html with multiple DOM Selection works.");
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with multiple DOM Selection works.");
selectionCount++;
}
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.html with multiple DOM Selection works.");
assert.equal(selectionCount, 2, "Two iterable selections");
selectionCount++;
}
assert.equal(selectionCount, 2,
"Two iterable selections");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Set Text in Textarea Selection"] = function(assert, done) {
exports["test Set Text in Textarea Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let text = "bar";
let window = yield open(URL);
open(URL).then(selectTextarea).then(function() {
selectTextarea(window);
let text = "bar";
selection.text = text;
selection.text = text;
assert.equal(selection.text, text,
"set selection.text with Textarea Selection works.");
assert.equal(selection.text, text,
"set selection.text with Textarea Selection works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection works.");
let selectionCount = 0;
for (let sel of selection) {
selectionCount++;
let selectionCount = 0;
for each (let sel in selection) {
selectionCount++;
assert.equal(sel.text, text,
"iterable selection.text with Textarea Selection works.");
assert.equal(sel.text, text,
"iterable selection.text with Textarea Selection works.");
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection works.");
}
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection works.");
}
assert.equal(selectionCount, 1, "One iterable selection");
assert.equal(selectionCount, 1,
"One iterable selection");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Set HTML in Textarea Selection"] = function(assert, done) {
exports["test Set HTML in Textarea Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let html = "<span>b<b>a</b>r</span>";
let window = yield open(URL);
open(URL).then(selectTextarea).then(function() {
selectTextarea(window);
let html = "<span>b<b>a</b>r</span>";
// Textarea can't have HTML so set `html` property is equals to set `text`
// property
selection.html = html;
// Textarea can't have HTML so set `html` property is equals to set `text`
// property
selection.html = html;
assert.equal(selection.text, html,
"set selection.text with Textarea Selection works.");
assert.equal(selection.text, html,
"set selection.text with Textarea Selection works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection works.");
let selectionCount = 0;
for (let sel of selection) {
selectionCount++;
let selectionCount = 0;
for each (let sel in selection) {
selectionCount++;
assert.equal(sel.text, html,
"iterable selection.text with Textarea Selection works.");
assert.equal(sel.text, html,
"iterable selection.text with Textarea Selection works.");
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection works.");
}
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection works.");
}
assert.equal(selectionCount, 1, "One iterable selection");
assert.equal(selectionCount, 1,
"One iterable selection");
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test Empty Selections"] = function(assert, done) {
exports["test Empty Selections"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL);
open(URL).then(createEmptySelections).then(function(){
assert.equal(selection.isContiguous, false,
"selection.isContiguous with empty selections works.");
createEmptySelections(window);
assert.strictEqual(selection.text, null,
"selection.text with empty selections works.");
assert.equal(selection.isContiguous, false,
"selection.isContiguous with empty selections works.");
assert.strictEqual(selection.html, null,
"selection.html with empty selections works.");
assert.strictEqual(selection.text, null,
"selection.text with empty selections works.");
let selectionCount = 0;
for each (let sel in selection)
selectionCount++;
assert.strictEqual(selection.html, null,
"selection.html with empty selections works.");
assert.equal(selectionCount, 0,
"No iterable selections");
let selectionCount = 0;
for (let sel of selection)
selectionCount++;
}).then(close).then(loader.unload).then(done, assert.fail);
assert.equal(selectionCount, 0, "No iterable selections");
yield close(window);
loader.unload();
}
exports["test No Selection Exception"] = function(assert, done) {
exports["test No Selection Exception"] = function*(assert) {
const NO_SELECTION = /It isn't possible to change the selection/;
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL);
open(URL).then(function() {
// We're trying to change a selection when there is no selection
assert.throws(function() {
selection.text = "bar";
}, NO_SELECTION);
// We're trying to change a selection when there is no selection
assert.throws(function() {
selection.text = "bar";
}, NO_SELECTION);
assert.throws(function() {
selection.html = "bar";
}, NO_SELECTION);
assert.throws(function() {
selection.html = "bar";
}, NO_SELECTION);
}).then(close).then(loader.unload).then(done, assert.fail);
yield close(window);
loader.unload();
};
exports["test for...of without selections"] = function(assert, done) {
exports["test for...of without selections"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL);
let selectionCount = 0;
open(URL).then(function() {
let selectionCount = 0;
for (let sel of selection)
selectionCount++;
for (let sel of selection)
selectionCount++;
assert.equal(selectionCount, 0, "No iterable selections");
assert.equal(selectionCount, 0,
"No iterable selections");
}).then(close).then(loader.unload).then(null, function(error) {
// iterable are not supported yet in Firefox 16, for example, but
// they are in Firefox 17.
if (error.message.indexOf("is not iterable") > -1)
assert.pass("`iterable` method not supported in this application");
else
assert.fail(error);
}).then(done, assert.fail);
yield close(window);
loader.unload();
}
exports["test for...of with selections"] = function(assert, done) {
exports["test for...of with selections"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let expectedText = ["foo", "and"];
let expectedHTML = ["<div>foo</div>", "<div>and</div>"];
let window = yield open(URL);
open(URL).then(selectAllDivs).then(function(){
let expectedText = ["foo", "and"];
let expectedHTML = ["<div>foo</div>", "<div>and</div>"];
selectAllDivs(window);
let selectionCount = 0;
let selectionCount = 0;
for (let sel of selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with for...of works.");
for (let sel of selection) {
assert.equal(sel.text, expectedText[selectionCount],
"iterable selection.text with for...of works.");
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.text with for...of works.");
assert.equal(sel.html, expectedHTML[selectionCount],
"iterable selection.text with for...of works.");
selectionCount++;
}
selectionCount++;
}
assert.equal(selectionCount, 2,
"Two iterable selections");
assert.equal(selectionCount, 2, "Two iterable selections");
}).then(close).then(loader.unload).then(null, function(error) {
// iterable are not supported yet in Firefox 16, for example, but
// they are in Firefox 17.
if (error.message.indexOf("is not iterable") > -1)
assert.pass("`iterable` method not supported in this application");
else
assert.fail(error);
}).then(done, assert.fail)
yield close(window);
loader.unload();
}
exports["test Selection Listener"] = function(assert, done) {
@ -722,7 +707,7 @@ exports["test Textarea OnSelect Listener"] = function(assert, done) {
then(dispatchOnSelectEvent, assert.fail);
};
exports["test Selection listener removed on unload"] = function(assert, done) {
exports["test Selection listener removed on unload"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
@ -731,17 +716,16 @@ exports["test Selection listener removed on unload"] = function(assert, done) {
});
loader.unload();
assert.pass("unload was a success");
assert.pass();
open(URL).
yield open(URL).
then(selectContentFirstDiv).
then(dispatchSelectionEvent).
then(close).
then(done, assert.fail);
catch(assert.fail);
};
exports["test Textarea onSelect Listener removed on unload"] = function(assert, done) {
exports["test Textarea onSelect Listener removed on unload"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
@ -750,14 +734,13 @@ exports["test Textarea onSelect Listener removed on unload"] = function(assert,
});
loader.unload();
assert.pass("unload was a success");
assert.pass();
open(URL).
yield open(URL).
then(selectTextarea).
then(dispatchOnSelectEvent).
then(close).
then(done, assert.fail);
catch(assert.fail);
};
@ -848,7 +831,7 @@ exports["test Selection Listener on frame"] = function(assert, done) {
then(getFrameWindow).
then(selectContentFirstDiv).
then(dispatchSelectionEvent).
then(null, assert.fail);
catch(assert.fail);
};
exports["test Textarea onSelect Listener on frame"] = function(assert, done) {
@ -867,11 +850,11 @@ exports["test Textarea onSelect Listener on frame"] = function(assert, done) {
then(getFrameWindow).
then(selectTextarea).
then(dispatchOnSelectEvent).
then(null, assert.fail);
catch(assert.fail);
};
exports["test PBPW Selection Listener"] = function(assert, done) {
exports["test PBPW Selection Listener"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
@ -881,15 +864,16 @@ exports["test PBPW Selection Listener"] = function(assert, done) {
assert.pass();
open(URL, {private: true}).
yield open(URL, { private: true }).
then(selectContentFirstDiv).
then(dispatchSelectionEvent).
then(closeWindow).
then(loader.unload).
then(done, assert.fail);
catch(assert.fail);
loader.unload();
};
exports["test PBPW Textarea OnSelect Listener"] = function(assert, done) {
exports["test PBPW Textarea OnSelect Listener"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
@ -899,72 +883,73 @@ exports["test PBPW Textarea OnSelect Listener"] = function(assert, done) {
assert.pass();
open(URL, {private: true}).
yield open(URL, { private: true }).
then(selectTextarea).
then(dispatchOnSelectEvent).
then(closeWindow).
then(loader.unload).
then(done, assert.fail);
catch(assert.fail);
loader.unload();
};
exports["test PBPW Single DOM Selection"] = function(assert, done) {
exports["test PBPW Single DOM Selection"] = function*(assert) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL, { private: true });
open(URL, {private: true}).then(selectFirstDiv).then(function(window) {
selectFirstDiv(window);
assert.equal(selection.isContiguous, false,
"selection.isContiguous with single DOM Selection in PBPW works.");
assert.equal(selection.isContiguous, false,
"selection.isContiguous with single DOM Selection in PBPW works.");
assert.equal(selection.text, null,
"selection.text with single DOM Selection in PBPW works.");
assert.equal(selection.text, null,
"selection.text with single DOM Selection in PBPW works.");
assert.equal(selection.html, null,
"selection.html with single DOM Selection in PBPW works.");
assert.equal(selection.html, null,
"selection.html with single DOM Selection in PBPW works.");
let selectionCount = 0;
for each (let sel in selection)
selectionCount++;
let selectionCount = 0;
for (let sel of selection)
selectionCount++;
assert.equal(selectionCount, 0,
"No iterable selection in PBPW");
assert.equal(selectionCount, 0, "No iterable selection in PBPW");
return window;
}).then(closeWindow).then(loader.unload).then(done, assert.fail);
yield closeWindow(window);
loader.unload();
};
exports["test PBPW Textarea Selection"] = function(assert, done) {
let loader = Loader(module);
let selection = loader.require("sdk/selection");
let window = yield open(URL, { private: true });
open(URL, {private: true}).then(selectTextarea).then(function(window) {
selectTextarea(window);
assert.equal(selection.isContiguous, false,
"selection.isContiguous with Textarea Selection in PBPW works.");
assert.equal(selection.isContiguous, false,
"selection.isContiguous with Textarea Selection in PBPW works.");
assert.equal(selection.text, null,
"selection.text with Textarea Selection in PBPW works.");
assert.equal(selection.text, null,
"selection.text with Textarea Selection in PBPW works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection in PBPW works.");
assert.strictEqual(selection.html, null,
"selection.html with Textarea Selection in PBPW works.");
let selectionCount = 0;
for each (let sel in selection) {
selectionCount++;
let selectionCount = 0;
for (let sel of selection) {
selectionCount++;
assert.equal(sel.text, null,
"iterable selection.text with Textarea Selection in PBPW works.");
assert.equal(sel.text, null,
"iterable selection.text with Textarea Selection in PBPW works.");
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection in PBPW works.");
}
assert.strictEqual(sel.html, null,
"iterable selection.html with Textarea Selection in PBPW works.");
}
assert.equal(selectionCount, 0,
"No iterable selection in PBPW");
assert.equal(selectionCount, 0, "No iterable selection in PBPW");
return window;
}).then(closeWindow).then(loader.unload).then(done, assert.fail);
yield closeWindow(window);
loader.unload();
};
// TODO: test Selection Listener on long-held connection (Bug 661884)
@ -985,7 +970,7 @@ exports["test Selection Listener on long-held connection"] = function(assert, do
// If the platform doesn't support the PBPW, we're replacing PBPW tests
if (!require("sdk/private-browsing/utils").isWindowPBSupported) {
Object.keys(module.exports).forEach(function(key) {
Object.keys(module.exports).forEach((key) => {
if (key.indexOf("test PBPW") === 0) {
module.exports[key] = function Unsupported (assert) {
assert.pass("Private Window Per Browsing is not supported on this platform.");
@ -994,4 +979,4 @@ if (!require("sdk/private-browsing/utils").isWindowPBSupported) {
});
}
require("test").run(exports)
require("sdk/test").run(exports);

View File

@ -211,7 +211,7 @@ exports.testActiveWindow = function(assert, done) {
let rawWindow2, rawWindow3;
let testSteps = [
function() {
() => {
assert.equal(windows.length, 3, "Correct number of browser windows");
let count = 0;
@ -223,20 +223,17 @@ exports.testActiveWindow = function(assert, done) {
continueAfterFocus(rawWindow2);
rawWindow2.focus();
},
function() {
}, () => {
assert.equal(windows.activeWindow.title, window2.title, "Correct active window - 2");
continueAfterFocus(rawWindow2);
window2.activate();
},
function() {
}, () => {
assert.equal(windows.activeWindow.title, window2.title, "Correct active window - 2");
continueAfterFocus(rawWindow3);
window3.activate();
},
function() {
}, () => {
assert.equal(windows.activeWindow.title, window3.title, "Correct active window - 3");
finishTest();
}
@ -251,10 +248,10 @@ exports.testActiveWindow = function(assert, done) {
windows.open({
url: "data:text/html;charset=utf-8,<title>window 2</title>",
onOpen: function(window) {
onOpen: (window) => {
assert.pass('window 2 open');
window.tabs.activeTab.on('ready', function() {
window.tabs.activeTab.once('ready', () => {
assert.pass('window 2 tab activated');
window2 = window;
@ -267,10 +264,10 @@ exports.testActiveWindow = function(assert, done) {
windows.open({
url: "data:text/html;charset=utf-8,<title>window 3</title>",
onOpen: function(window) {
onOpen: (window) => {
assert.pass('window 3 open');
window.tabs.activeTab.on('ready', function onReady() {
window.tabs.activeTab.once('ready', () => {
assert.pass('window 3 tab activated');
window3 = window;
@ -282,7 +279,6 @@ exports.testActiveWindow = function(assert, done) {
assert.equal(rawWindow3.document.title, window3.title, "Saw correct title on window 3");
continueAfterFocus(rawWindow3);
rawWindow3.focus();
});
}
});
@ -290,24 +286,16 @@ exports.testActiveWindow = function(assert, done) {
}
});
function nextStep() {
if (testSteps.length) {
setTimeout(testSteps.shift())
}
}
let continueAfterFocus = function(w) onFocus(w).then(nextStep);
let nextStep = () => testSteps.length ? setTimeout(testSteps.shift()) : null;
let continueAfterFocus = (w) => onFocus(w).then(nextStep);
function finishTest() {
// close unactive window first to avoid unnecessary focus changing
window2.close(function() {
window3.close(function() {
assert.equal(rawWindow2.closed, true, 'window 2 is closed');
assert.equal(rawWindow3.closed, true, 'window 3 is closed');
done();
});
});
window2.close(() => window3.close(() => {
assert.equal(rawWindow2.closed, true, 'window 2 is closed');
assert.equal(rawWindow3.closed, true, 'window 3 is closed');
done();
}));
}
};