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

This commit is contained in:
Erik Vold 2014-07-02 14:37:05 -07:00
parent fc2483e662
commit 737a51a228
12 changed files with 171 additions and 59 deletions

View File

@ -125,8 +125,9 @@ function run(options) {
// Do not enable HTML localization while running test as it is hard to
// disable. Because unit tests are evaluated in a another Loader who
// doesn't have access to this current loader.
if (options.main !== 'test-harness/run-tests')
if (options.main !== 'sdk/test/runner') {
require('../l10n/html').enable();
}
}
catch(error) {
console.exception(error);

View File

@ -259,9 +259,13 @@ function populateCallbackNodeData(node) {
data.selectionText = selection.text;
data.srcURL = node.src || null;
data.linkURL = node.href || null;
data.value = node.value || null;
while (!data.linkURL && node) {
data.linkURL = node.href || null;
node = node.parentNode;
}
return data;
}

View File

@ -10,7 +10,11 @@ module.metadata = {
const file = require("../io/file");
const memory = require('./memory');
const { Loader } = require("../test/loader");
const cuddlefish = require("../loader/cuddlefish");
const { isNative } = require('@loader/options');
const cuddlefish = isNative ? require("toolkit/loader") : require("../loader/cuddlefish");
const { defer, resolve } = require("../core/promise");
const { getAddon } = require("../addon/installer");
const { id } = require("sdk/self");
@ -22,7 +26,7 @@ const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {}
var ios = Cc['@mozilla.org/network/io-service;1']
.getService(Ci.nsIIOService);
const TEST_REGEX = /(([^\/]+\/)(?:lib\/)?)(tests?\/test-[^\.\/]+)\.js$/;
const TEST_REGEX = /(([^\/]+\/)(?:lib\/)?)?(tests?\/test-[^\.\/]+)\.js$/;
const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence");
@ -54,8 +58,9 @@ const getSuites = function getSuites({ id }) {
let file = xpiURI.QueryInterface(Ci.nsIFileURL).file;
let suites = [];
let addEntry = (entry) => {
if (TEST_REGEX.test(entry)) {
let suite = RegExp.$2 + RegExp.$3;
let pass = TEST_REGEX.test(entry);
if (pass) {
let suite = (isNative ? "./" : "") + RegExp.$2 + RegExp.$3;
suites.push(suite);
}
}

View File

@ -12,7 +12,7 @@ const timer = require("../timers");
var cfxArgs = require("@test/options");
const { getTabs, getURI } = require("../tabs/utils");
const { windows, isBrowser } = require("../window/utils");
const { defer } = require("../core/promise");
const { defer, all } = require("../core/promise");
const findAndRunTests = function findAndRunTests(options) {
var TestFinder = require("./unit-test-finder").TestFinder;
@ -285,43 +285,58 @@ TestRunner.prototype = {
}
let wins = windows(null, { includePrivate: true });
let tabs = [];
for (let win of wins.filter(isBrowser)) {
for (let tab of getTabs(win)) {
tabs.push(tab);
let winPromises = wins.map(win => {
let { promise, resolve } = defer();
if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) {
resolve()
}
}
if (wins.length != 1)
this.fail("Should not be any unexpected windows open");
if (tabs.length != 1)
this.fail("Should not be any unexpected tabs open");
if (tabs.length != 1 || wins.length != 1) {
console.log("Windows open:");
for (let win of wins) {
if (isBrowser(win)) {
tabs = getTabs(win);
console.log(win.location + " - " + tabs.map(getURI).join(", "));
}
else {
console.log(win.location);
}
else {
win.addEventListener("DOMContentLoaded", function onLoad() {
win.removeEventListener("DOMContentLoaded", onLoad, false);
resolve();
}, false);
}
}
this.testRunSummary.push({
name: this.test.name,
passed: this.test.passed,
failed: this.test.failed,
errors: [error for (error in this.test.errors)].join(", ")
return promise;
});
if (this.onDone !== null) {
var onDone = this.onDone;
var self = this;
this.onDone = null;
timer.setTimeout(function() { onDone(self); }, 0);
}
all(winPromises).then(_ => {
let tabs = [];
for (let win of wins.filter(isBrowser)) {
for (let tab of getTabs(win)) {
tabs.push(tab);
}
}
if (wins.length != 1)
this.fail("Should not be any unexpected windows open");
if (tabs.length != 1)
this.fail("Should not be any unexpected tabs open");
if (tabs.length != 1 || wins.length != 1) {
console.log("Windows open:");
for (let win of wins) {
if (isBrowser(win)) {
tabs = getTabs(win);
console.log(win.location + " - " + tabs.map(getURI).join(", "));
}
else {
console.log(win.location);
}
}
}
this.testRunSummary.push({
name: this.test.name,
passed: this.test.passed,
failed: this.test.failed,
errors: [error for (error in this.test.errors)].join(", ")
});
if (this.onDone !== null) {
let onDone = this.onDone;
this.onDone = null;
timer.setTimeout(_ => onDone(this), 0);
}
});
}
},

View File

@ -7,9 +7,9 @@ const { Cc, Ci } = require('chrome');
const { Class } = require('../core/heritage');
const { tabNS, rawTabNS } = require('./namespace');
const { EventTarget } = require('../event/target');
const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL, getTabContentWindow,
getTabForBrowser,
setTabURL, getOwnerWindow, getTabContentType, getTabId } = require('./utils');
const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL,
getTabContentWindow, getTabForBrowser, setTabURL, getOwnerWindow,
getTabContentDocument, getTabContentType, getTabId } = require('./utils');
const { emit } = require('../event/core');
const { isPrivate } = require('../private-browsing/utils');
const { isWindowPrivate } = require('../window/utils');
@ -97,6 +97,14 @@ const Tab = Class({
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAtCAYAAAA5reyyAAAAJElEQVRoge3BAQEAAACCIP+vbkhAAQAAAAAAAAAAAAAAAADXBjhtAAGQ0AF/AAAAAElFTkSuQmCC';
},
/**
* tab's document readyState, or 'uninitialized' if it doesn't even exist yet.
*/
get readyState() {
let doc = getTabContentDocument(tabNS(this).tab);
return doc && doc.readyState || 'uninitialized';
},
get id() {
return getTabId(tabNS(this).tab);
},

View File

@ -10,8 +10,9 @@ const { has } = require("../util/array");
const { EVENTS } = require("./events");
const { getThumbnailURIForWindow } = require("../content/thumbnail");
const { getFaviconURIForLocation } = require("../io/data");
const { activateTab, getOwnerWindow, getBrowserForTab, getTabTitle, setTabTitle,
getTabURL, setTabURL, getTabContentType, getTabId } = require('./utils');
const { activateTab, getOwnerWindow, getBrowserForTab, getTabTitle,
setTabTitle, getTabContentDocument, getTabURL, setTabURL,
getTabContentType, getTabId } = require('./utils');
const { isPrivate } = require('../private-browsing/utils');
const { isWindowPrivate } = require('../window/utils');
const viewNS = require('../core/namespace').ns();
@ -143,12 +144,20 @@ const TabTrait = Trait.compose(EventEmitter, {
/**
* Document object of the page that is currently loaded in this tab.
*/
get _contentDocument() this._browser.contentDocument,
get _contentDocument() getTabContentDocument(this._tab),
/**
* Window object of the page that is currently loaded in this tab.
*/
get _contentWindow() this._browser.contentWindow,
/**
* tab's document readyState, or 'uninitialized' if it doesn't even exist yet.
*/
get readyState() {
let doc = this._contentDocument;
return doc && doc.readyState || 'uninitialized';
},
/**
* Unique id for the tab, actually maps to tab.linkedPanel but with some munging.
*/

View File

@ -226,6 +226,11 @@ function setTabTitle(tab, title) {
}
exports.setTabTitle = setTabTitle;
function getTabContentDocument(tab) {
return getBrowserForTab(tab).contentDocument;
}
exports.getTabContentDocument = getTabContentDocument;
function getTabContentWindow(tab) {
return getBrowserForTab(tab).contentWindow;
}

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 = {
@ -13,19 +12,10 @@ const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
const { defer } = require("sdk/core/promise");
const BaseAssert = require("sdk/test/assert").Assert;
const { isFunction, isObject } = require("sdk/lang/type");
const { extend } = require("sdk/util/object");
exports.Assert = BaseAssert;
function extend(target) {
let descriptor = {}
Array.slice(arguments, 1).forEach(function(source) {
Object.getOwnPropertyNames(source).forEach(function onEach(name) {
descriptor[name] = Object.getOwnPropertyDescriptor(source, name);
});
});
return Object.create(target, descriptor);
}
/**
* Function takes test `suite` object in CommonJS format and defines all of the
* tests from that suite and nested suites in a jetpack format on a given
@ -110,7 +100,6 @@ function defineTestSuite(target, suite, prefix) {
* test runner will be able to run CommonJS test without manual changes.
*/
exports.run = function run(exports) {
// We can't leave old properties on exports since those are test in a CommonJS
// format that why we move everything to a new `suite` object.
let suite = {};

View File

@ -791,7 +791,6 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
extra_environment = {}
if command == "test":
# This should be contained in the test runner package.
# maybe just do: target_cfg.main = 'test-harness/run-tests'
harness_options['main'] = 'sdk/test/runner'
harness_options['mainPath'] = 'sdk/test/runner'
else:

View File

@ -62,6 +62,23 @@
</a>
</p>
<p>
<a class="predicate-test-b" href="#nested-image">
<img id="predicate-test-nested-image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==">
</a>
</p>
<p>
<a class="predicate-test-c" href="#nested-structure">
<span>
<span>
<span id="predicate-test-nested-structure">
A complex nested structure.
</span>
</span>
</span>
</a>
</p>
<p>
<input type="text" id="textbox" value="test value">
</p>

View File

@ -3572,6 +3572,48 @@ exports.testPredicateContextTargetLinkNotSet = function (assert, done) {
});
};
// Test that the data object has the correct link for a nested image
exports.testPredicateContextTargetLinkSetNestedImage = function (assert, done) {
let test = new TestHelper(assert, done);
let loader = test.newLoader();
let items = [loader.cm.Item({
label: "item",
context: loader.cm.PredicateContext(function (data) {
assert.strictEqual(data.linkURL, TEST_DOC_URL + "#nested-image");
return true;
})
})];
test.withTestDoc(function (window, doc) {
test.showMenu(doc.getElementById("predicate-test-nested-image"), function (popup) {
test.checkMenu(items, [], []);
test.done();
});
});
};
// Test that the data object has the correct link for a complex nested structure
exports.testPredicateContextTargetLinkSetNestedStructure = function (assert, done) {
let test = new TestHelper(assert, done);
let loader = test.newLoader();
let items = [loader.cm.Item({
label: "item",
context: loader.cm.PredicateContext(function (data) {
assert.strictEqual(data.linkURL, TEST_DOC_URL + "#nested-structure");
return true;
})
})];
test.withTestDoc(function (window, doc) {
test.showMenu(doc.getElementById("predicate-test-nested-structure"), function (popup) {
test.checkMenu(items, [], []);
test.done();
});
});
};
// Test that the data object has the value for an input textbox
exports.testPredicateContextTargetValueSet = function (assert, done) {
let test = new TestHelper(assert, done);

View File

@ -172,4 +172,22 @@ exports["test modelFor(xulTab)"] = (assert, done) => {
});
};
exports["test tab.readyState"] = (assert, done) => {
tabs.open({
url: "data:text/html;charset=utf-8,test_readyState",
onOpen: (tab) => {
assert.equal(tab.readyState, "uninitialized",
"tab is 'uninitialized' when opened");
},
onReady: (tab) => {
assert.notEqual(["interactive", "complete"].indexOf(tab.readyState), -1,
"tab is either interactive or complete when onReady");
},
onLoad: (tab) => {
assert.equal(tab.readyState, "complete", "tab is complete onLoad");
tab.close(defer(done));
}
});
}
require("sdk/test").run(exports);