gecko-dev/addon-sdk/source/test/test-panel.js

532 строки
16 KiB
JavaScript
Исходник Обычный вид История

/* 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/. */
let { Cc, Ci } = require("chrome");
const { Loader } = require('sdk/test/loader');
const timer = require("sdk/timers");
const self = require('sdk/self');
exports["test Panel"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let panel = Panel({
contentURL: "about:buildconfig",
contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));",
onMessage: function (message) {
assert.equal(this, panel, "The 'this' object is the panel.");
switch(message) {
case 1:
assert.pass("The panel was loaded.");
panel.postMessage('');
break;
case 2:
assert.pass("The panel posted a message and received a response.");
panel.destroy();
done();
break;
}
}
});
};
exports["test Panel Emit"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let panel = Panel({
contentURL: "about:buildconfig",
contentScript: "self.port.emit('loaded');" +
"self.port.on('addon-to-content', " +
" function() self.port.emit('received'));",
});
panel.port.on("loaded", function () {
assert.pass("The panel was loaded and sent a first event.");
panel.port.emit("addon-to-content");
});
panel.port.on("received", function () {
assert.pass("The panel posted a message and received a response.");
panel.destroy();
done();
});
};
exports["test Panel Emit Early"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let panel = Panel({
contentURL: "about:buildconfig",
contentScript: "self.port.on('addon-to-content', " +
" function() self.port.emit('received'));",
});
panel.port.on("received", function () {
assert.pass("The panel posted a message early and received a response.");
panel.destroy();
done();
});
panel.port.emit("addon-to-content");
};
exports["test Show Hide Panel"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let panel = Panel({
contentScript: "self.postMessage('')",
contentScriptWhen: "end",
contentURL: "data:text/html;charset=utf-8,",
onMessage: function (message) {
panel.show();
},
onShow: function () {
assert.pass("The panel was shown.");
assert.equal(this, panel, "The 'this' object is the panel.");
assert.equal(this.isShowing, true, "panel.isShowing == true.");
panel.hide();
},
onHide: function () {
assert.pass("The panel was hidden.");
assert.equal(this, panel, "The 'this' object is the panel.");
assert.equal(this.isShowing, false, "panel.isShowing == false.");
panel.destroy();
done();
}
});
};
exports["test Document Reload"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let content =
"<script>" +
"setTimeout(function () {" +
" window.location = 'about:blank';" +
"}, 250);" +
"</script>";
let messageCount = 0;
let panel = Panel({
contentURL: "data:text/html;charset=utf-8," + encodeURIComponent(content),
contentScript: "self.postMessage(window.location.href)",
onMessage: function (message) {
messageCount++;
if (messageCount == 1) {
assert.ok(/data:text\/html/.test(message), "First document had a content script");
}
else if (messageCount == 2) {
assert.equal(message, "about:blank", "Second document too");
panel.destroy();
done();
}
}
});
};
exports["test Parent Resize Hack"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser");
let docShell = browserWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!("allowWindowControl" in docShell)) {
// bug 635673 is not fixed in this firefox build
assert.pass("allowWindowControl attribute that allow to fix browser window " +
"resize is not available on this build.");
return;
}
let previousWidth = browserWindow.outerWidth, previousHeight = browserWindow.outerHeight;
let content = "<script>" +
"function contentResize() {" +
" resizeTo(200,200);" +
" resizeBy(200,200);" +
"}" +
"</script>" +
"Try to resize browser window";
let panel = Panel({
contentURL: "data:text/html;charset=utf-8," + encodeURIComponent(content),
contentScript: "self.on('message', function(message){" +
" if (message=='resize') " +
" unsafeWindow.contentResize();" +
"});",
contentScriptWhen: "ready",
onMessage: function (message) {
},
onShow: function () {
panel.postMessage('resize');
timer.setTimeout(function () {
assert.equal(previousWidth,browserWindow.outerWidth,"Size doesn't change by calling resizeTo/By/...");
assert.equal(previousHeight,browserWindow.outerHeight,"Size doesn't change by calling resizeTo/By/...");
panel.destroy();
done();
},0);
}
});
panel.show();
}
exports["test Resize Panel"] = function(assert, done) {
const { Panel } = require('sdk/panel');
// These tests fail on Linux if the browser window in which the panel
// is displayed is not active. And depending on what other tests have run
// before this one, it might not be (the untitled window in which the test
// runner executes is often active). So we make sure the browser window
// is focused by focusing it before running the tests. Then, to be the best
// possible test citizen, we refocus whatever window was focused before we
// started running these tests.
let activeWindow = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher).
activeWindow;
let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser");
function onFocus() {
browserWindow.removeEventListener("focus", onFocus, true);
let panel = Panel({
contentScript: "self.postMessage('')",
contentScriptWhen: "end",
contentURL: "data:text/html;charset=utf-8,",
height: 10,
width: 10,
onMessage: function (message) {
panel.show();
},
onShow: function () {
panel.resize(100,100);
panel.hide();
},
onHide: function () {
assert.ok((panel.width == 100) && (panel.height == 100),
"The panel was resized.");
if (activeWindow)
activeWindow.focus();
done();
}
});
}
if (browserWindow === activeWindow) {
onFocus();
}
else {
browserWindow.addEventListener("focus", onFocus, true);
browserWindow.focus();
}
};
exports["test Hide Before Show"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let showCalled = false;
let panel = Panel({
onShow: function () {
showCalled = true;
},
onHide: function () {
assert.ok(!showCalled, 'must not emit show if was hidden before');
done();
}
});
panel.show();
panel.hide();
};
exports["test Several Show Hides"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let hideCalled = 0;
let panel = Panel({
contentURL: "about:buildconfig",
onShow: function () {
panel.hide();
},
onHide: function () {
hideCalled++;
if (hideCalled < 3)
panel.show();
else {
assert.pass("onHide called three times as expected");
done();
}
}
});
panel.on('error', function(e) {
assert.fail('error was emitted:' + e.message + '\n' + e.stack);
});
panel.show();
};
exports["test Anchor And Arrow"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let count = 0;
function newPanel(tab, anchor) {
let panel = Panel({
contentURL: "data:text/html;charset=utf-8,<html><body style='padding: 0; margin: 0; " +
"background: gray; text-align: center;'>Anchor: " +
anchor.id + "</body></html>",
width: 200,
height: 100,
onShow: function () {
count++;
panel.destroy();
if (count==5) {
assert.pass("All anchored panel test displayed");
tab.close(function () {
done();
});
}
}
});
panel.show(anchor);
}
let tabs= require("sdk/tabs");
let url = 'data:text/html;charset=utf-8,' +
'<html><head><title>foo</title></head><body>' +
'<style>div {background: gray; position: absolute; width: 300px; ' +
'border: 2px solid black;}</style>' +
'<div id="tl" style="top: 0px; left: 0px;">Top Left</div>' +
'<div id="tr" style="top: 0px; right: 0px;">Top Right</div>' +
'<div id="bl" style="bottom: 0px; left: 0px;">Bottom Left</div>' +
'<div id="br" style="bottom: 0px; right: 0px;">Bottom right</div>' +
'</body></html>';
tabs.open({
url: url,
onReady: function(tab) {
let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser");
let window = browserWindow.content;
newPanel(tab, window.document.getElementById('tl'));
newPanel(tab, window.document.getElementById('tr'));
newPanel(tab, window.document.getElementById('bl'));
newPanel(tab, window.document.getElementById('br'));
let anchor = browserWindow.document.getElementById("identity-box");
newPanel(tab, anchor);
}
});
};
exports["test Panel Text Color"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let html = "<html><head><style>body {color: yellow}</style></head>" +
"<body><p>Foo</p></body></html>";
let panel = Panel({
contentURL: "data:text/html;charset=utf-8," + encodeURI(html),
contentScript: "self.port.emit('color', " +
"window.getComputedStyle(document.body.firstChild, null). " +
" getPropertyValue('color'));"
});
panel.port.on("color", function (color) {
assert.equal(color, "rgb(255, 255, 0)",
"The panel text color style is preserved when a style exists.");
panel.destroy();
done();
});
};
// Bug 696552: Ensure panel.contentURL modification support
exports["test Change Content URL"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let panel = Panel({
contentURL: "about:blank",
contentScript: "self.port.emit('ready', document.location.href);"
});
let count = 0;
panel.port.on("ready", function (location) {
count++;
if (count == 1) {
assert.equal(location, "about:blank");
assert.equal(panel.contentURL, "about:blank");
panel.contentURL = "about:buildconfig";
}
else {
assert.equal(location, "about:buildconfig");
assert.equal(panel.contentURL, "about:buildconfig");
panel.destroy();
done();
}
});
};
function makeEventOrderTest(options) {
let expectedEvents = [];
return function(assert, done) {
const { Panel } = require('sdk/panel');
let panel = Panel({ contentURL: "about:buildconfig" });
function expect(event, cb) {
expectedEvents.push(event);
panel.on(event, function() {
assert.equal(event, expectedEvents.shift());
if (cb)
timer.setTimeout(cb, 1);
});
return {then: expect};
}
options.test(assert, done, expect, panel);
}
}
exports["test Automatic Destroy"] = function(assert) {
let loader = Loader(module);
let panel = loader.require("sdk/panel").Panel({
contentURL: "about:buildconfig",
contentScript:
"self.port.on('event', function() self.port.emit('event-back'));"
});
loader.unload();
panel.port.on("event-back", function () {
assert.fail("Panel should have been destroyed on module unload");
});
panel.port.emit("event");
assert.pass("check automatic destroy");
};
exports["test Wait For Init Then Show Then Destroy"] = makeEventOrderTest({
test: function(assert, done, expect, panel) {
expect('inited', function() { panel.show(); }).
then('show', function() { panel.destroy(); }).
then('hide', function() { done(); });
}
});
exports["test Show Then Wait For Init Then Destroy"] = makeEventOrderTest({
test: function(assert, done, expect, panel) {
panel.show();
expect('inited').
then('show', function() { panel.destroy(); }).
then('hide', function() { done(); });
}
});
exports["test Show Then Hide Then Destroy"] = makeEventOrderTest({
test: function(assert, done, expect, panel) {
panel.show();
expect('show', function() { panel.hide(); }).
then('hide', function() { panel.destroy(); done(); });
}
});
exports["test Content URL Option"] = function(assert) {
const { Panel } = require('sdk/panel');
const URL_STRING = "about:buildconfig";
const HTML_CONTENT = "<html><title>Test</title><p>This is a test.</p></html>";
let (panel = Panel({ contentURL: URL_STRING })) {
assert.pass("contentURL accepts a string URL.");
assert.equal(panel.contentURL, URL_STRING,
"contentURL is the string to which it was set.");
}
let dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML_CONTENT);
let (panel = Panel({ contentURL: dataURL })) {
assert.pass("contentURL accepts a data: URL.");
}
let (panel = Panel({})) {
assert.ok(panel.contentURL == null,
"contentURL is undefined.");
}
assert.throws(function () Panel({ contentURL: "foo" }),
/The `contentURL` option must be a valid URL./,
"Panel throws an exception if contentURL is not a URL.");
};
exports["test SVG Document"] = function(assert) {
let SVG_URL = self.data.url("mofo_logo.SVG");
let panel = require("sdk/panel").Panel({ contentURL: SVG_URL });
panel.show();
panel.hide();
panel.destroy();
assert.pass("contentURL accepts a svg document");
assert.equal(panel.contentURL, SVG_URL,
"contentURL is the string to which it was set.");
};
exports["test ContentScriptOptions Option"] = function(assert, done) {
let loader = Loader(module);
let panel = loader.require("sdk/panel").Panel({
contentScript: "self.postMessage( [typeof self.options.d, self.options] );",
contentScriptWhen: "end",
contentScriptOptions: {a: true, b: [1,2,3], c: "string", d: function(){ return 'test'}},
contentURL: "data:text/html;charset=utf-8,",
onMessage: function(msg) {
assert.equal( msg[0], 'undefined', 'functions are stripped from contentScriptOptions' );
assert.equal( typeof msg[1], 'object', 'object as contentScriptOptions' );
assert.equal( msg[1].a, true, 'boolean in contentScriptOptions' );
assert.equal( msg[1].b.join(), '1,2,3', 'array and numbers in contentScriptOptions' );
assert.equal( msg[1].c, 'string', 'string in contentScriptOptions' );
done();
}
});
};
exports["test console.log in Panel"] = function(assert, done) {
let text = 'console.log() in Panel works!';
let html = '<script>onload = function log(){\
console.log("' + text + '");\
}</script>';
let panel;
let loader = Loader(module, {
console: {
log: function (message) {
assert.equal(message, text, 'console.log() works');
panel.destroy();
done();
}
}
});
let { Panel } = loader.require('sdk/panel');
panel = Panel({
contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(html)
});
panel.show();
};
try {
require("sdk/panel");
}
catch (e) {
if (!/^Unsupported Application/.test(e.message))
throw e;
module.exports = {
"test Unsupported Application": function Unsupported (assert) {
assert.pass(e.message);
}
}
}
require("test").run(exports);