Bug 1014332 test cleanups that better address some async issues, r=jaws

This commit is contained in:
Shane Caraveo 2014-10-09 12:02:35 -07:00
Родитель d44c10e1f6
Коммит a6061b249e
5 изменённых файлов: 165 добавлений и 158 удалений

Просмотреть файл

@ -19,7 +19,7 @@ let snippet =
' "iconURL": "chrome://branding/content/icon16.png",' +
' "icon32URL": "chrome://branding/content/favicon32.png",' +
' "icon64URL": "chrome://branding/content/icon64.png",' +
' "sidebarURL": "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",' +
' "sidebarURL": "https://example.com/browser/browser/base/content/test/social/social_sidebar_empty.html",' +
' "postActivationURL": "https://example.com/browser/browser/base/content/test/social/social_postActivation.html",' +
' };' +
' function activateProvider(node) {' +
@ -41,7 +41,7 @@ let snippet2 =
' "iconURL": "chrome://branding/content/icon16.png",' +
' "icon32URL": "chrome://branding/content/favicon32.png",' +
' "icon64URL": "chrome://branding/content/icon64.png",' +
' "sidebarURL": "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",' +
' "sidebarURL": "https://example.com/browser/browser/base/content/test/social/social_sidebar_empty.html",' +
' "postActivationURL": "https://example.com/browser/browser/base/content/test/social/social_postActivation.html",' +
' "oneclick": true' +
' };' +

Просмотреть файл

@ -12,15 +12,7 @@ let manifest = { // normal provider
};
let activationPage = "https://example.com/browser/browser/base/content/test/social/share_activate.html";
function waitForProviderEnabled(cb) {
Services.obs.addObserver(function providerSet(subject, topic, data) {
Services.obs.removeObserver(providerSet, "social:provider-enabled");
info("social:provider-enabled observer was notified");
cb();
}, "social:provider-enabled", false);
}
function sendActivationEvent(subframe, callback) {
function sendActivationEvent(subframe) {
// hack Social.lastEventReceived so we don't hit the "too many events" check.
Social.lastEventReceived = 0;
let doc = subframe.contentDocument;
@ -28,18 +20,18 @@ function sendActivationEvent(subframe, callback) {
let button = doc.getElementById("activation");
ok(!!button, "got the activation button");
EventUtils.synthesizeMouseAtCenter(button, {}, doc.defaultView);
if (callback)
executeSoon(callback);
}
function waitForEvent(iframe, eventName, callback) {
function promiseShareFrameEvent(iframe, eventName) {
let deferred = Promise.defer();
iframe.addEventListener(eventName, function load() {
info("page load is " + iframe.contentDocument.location.href);
if (iframe.contentDocument.location.href != "data:text/plain;charset=utf8,") {
iframe.removeEventListener(eventName, load, true);
executeSoon(callback);
deferred.resolve();
}
}, true);
return deferred.promise;
}
function test() {
@ -116,15 +108,6 @@ let corpus = [
}
];
function loadURLInTab(url, callback) {
info("Loading tab with "+url);
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
waitForEvent(tab.linkedBrowser, "load", () => {
is(tab.linkedBrowser.currentURI.spec, url, "tab loaded")
callback(tab)
});
}
function hasoptions(testOptions, options) {
let msg;
for (let option in testOptions) {
@ -175,7 +158,7 @@ var tests = {
SocialUI.onCustomizeEnd(window);
let testData = corpus[0];
loadURLInTab(testData.url, function(tab) {
addTab(testData.url, function(tab) {
SocialService.addProvider(manifest, function(provider) {
is(SocialUI.enabled, true, "SocialUI is enabled");
checkSocialUI();
@ -199,7 +182,7 @@ var tests = {
let testData = corpus[testIndex++];
function runOneTest() {
loadURLInTab(testData.url, function(tab) {
addTab(testData.url, function(tab) {
testTab = tab;
SocialShare.sharePage(manifest.origin);
});
@ -303,7 +286,7 @@ var tests = {
SocialShare._createFrame();
let iframe = SocialShare.iframe;
waitForEvent(iframe, "load", () => {
promiseShareFrameEvent(iframe, "load").then(() => {
let subframe = iframe.contentDocument.getElementById("activation-frame");
waitForCondition(() => {
// sometimes the iframe is ready before the panel is open, we need to
@ -313,7 +296,7 @@ var tests = {
&& subframe.contentDocument.readyState == "complete";
}, () => {
is(subframe.contentDocument.location.href, activationPage, "activation page loaded");
waitForProviderEnabled(() => {
promiseObserverNotified("social:provider-enabled").then(() => {
let provider = Social._getProviderFromOrigin(manifest.origin);
let port = provider.getWorkerPort();
ok(!!port, "got port");
@ -332,7 +315,7 @@ var tests = {
sendActivationEvent(subframe);
}, "share panel did not open and load share page");
});
loadURLInTab(activationPage, function(tab) {
addTab(activationPage, function(tab) {
testTab = tab;
SocialShare.sharePage();
});

Просмотреть файл

@ -28,13 +28,19 @@ let manifests = [
}
];
let ports = [];
function getProviderPort(provider) {
let port = provider.getWorkerPort();
ok(port, "provider has a port");
ports.push(port);
return port;
}
let chatId = 0;
function openChat(provider, callback) {
let chatUrl = provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
let port = provider.getWorkerPort();
let port = getProviderPort(provider);
port.onmessage = function(e) {
if (e.data.topic == "got-chatbox-message") {
port.close();
callback();
}
}
@ -42,6 +48,7 @@ function openChat(provider, callback) {
port.postMessage({topic: "test-init"});
port.postMessage({topic: "test-worker-chat", data: url});
gURLsNotRemembered.push(url);
return port;
}
function windowHasChats(win) {
@ -56,15 +63,22 @@ function test() {
let oldleft = window.screenX;
window.moveTo(0, window.screenY)
let postSubTest = function(cb) {
// ensure ports are closed
for (let port of ports) {
port.close()
ok(port._closed, "port closed");
}
ports = [];
let chats = document.getElementById("pinnedchats");
ok(chats.children.length == 0, "no chatty children left behind");
cb();
};
runSocialTestWithProvider(manifests, function (finishcb) {
ok(Social.enabled, "Social is enabled");
ok(Social.providers[0].getWorkerPort(), "provider 0 has port");
ok(Social.providers[1].getWorkerPort(), "provider 1 has port");
ok(Social.providers[2].getWorkerPort(), "provider 2 has port");
ok(getProviderPort(Social.providers[0]), "provider 0 has port");
ok(getProviderPort(Social.providers[1]), "provider 1 has port");
ok(getProviderPort(Social.providers[2]), "provider 2 has port");
SocialSidebar.show();
runSocialTests(tests, undefined, postSubTest, function() {
window.moveTo(oldleft, window.screenY)
@ -77,8 +91,7 @@ function test() {
var tests = {
testOpenCloseChat: function(next) {
let chats = document.getElementById("pinnedchats");
let port = SocialSidebar.provider.getWorkerPort();
ok(port, "provider has a port");
let port = getProviderPort(SocialSidebar.provider);
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
@ -96,7 +109,6 @@ var tests = {
content.addEventListener("unload", function chatUnload() {
content.removeEventListener("unload", chatUnload, true);
ok(true, "got chatbox unload on close");
port.close();
next();
}, true);
chats.selectedChat.close();
@ -114,8 +126,7 @@ var tests = {
testWorkerChatWindow: function(next) {
const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
let chats = document.getElementById("pinnedchats");
let port = SocialSidebar.provider.getWorkerPort();
ok(port, "provider has a port");
let port = getProviderPort(SocialSidebar.provider);
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
@ -128,7 +139,6 @@ var tests = {
}
ok(!chats.selectedChat, "chats are all closed");
gURLsNotRemembered.push(chatUrl);
port.close();
next();
break;
}
@ -138,8 +148,7 @@ var tests = {
},
testCloseSelf: function(next) {
let chats = document.getElementById("pinnedchats");
let port = SocialSidebar.provider.getWorkerPort();
ok(port, "provider has a port");
let port = getProviderPort(SocialSidebar.provider);
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
@ -157,7 +166,6 @@ var tests = {
evt.initCustomEvent("socialTest-CloseSelf", true, true, {});
doc.documentElement.dispatchEvent(evt);
ok(!chat.parentNode, "chat is now closed");
port.close();
next();
break;
}
@ -172,6 +180,8 @@ var tests = {
let num = 0;
is(chatbar.childNodes.length, 0, "chatbar starting empty");
is(chatbar.menupopup.childNodes.length, 0, "popup starting empty");
let port = getProviderPort(SocialSidebar.provider);
port.postMessage({topic: "test-init"});
makeChat("normal", "first chat", function() {
// got the first one.
@ -202,22 +212,21 @@ var tests = {
},
testShowWhenCollapsed: function(next) {
let port = SocialSidebar.provider.getWorkerPort();
let port = getProviderPort(SocialSidebar.provider);
port.postMessage({topic: "test-init"});
get3ChatsForCollapsing("normal", function(first, second, third) {
let chatbar = getChatBar();
chatbar.showChat(first);
ok(!first.collapsed, "first should no longer be collapsed");
ok(second.collapsed || third.collapsed, false, "one of the others should be collapsed");
is(second.collapsed || third.collapsed, true, "one of the others should be collapsed");
closeAllChats();
port.close();
next();
});
},
testOnlyOneCallback: function(next) {
let chats = document.getElementById("pinnedchats");
let port = SocialSidebar.provider.getWorkerPort();
let port = getProviderPort(SocialSidebar.provider);
let numOpened = 0;
port.onmessage = function (e) {
let topic = e.data.topic;
@ -233,7 +242,6 @@ var tests = {
executeSoon(function() {
is(numOpened, 1, "only got one open message");
chats.selectedChat.close();
port.close();
next();
});
}
@ -243,24 +251,21 @@ var tests = {
testMultipleProviderChat: function(next) {
// test incomming chats from all providers
openChat(Social.providers[0], function() {
openChat(Social.providers[1], function() {
openChat(Social.providers[2], function() {
let port0 = openChat(Social.providers[0], function() {
let port1 = openChat(Social.providers[1], function() {
let port2 = openChat(Social.providers[2], function() {
let chats = document.getElementById("pinnedchats");
waitForCondition(function() chats.children.length == Social.providers.length,
function() {
ok(true, "one chat window per provider opened");
// test logout of a single provider
let provider = Social.providers[2];
let port = provider.getWorkerPort();
port.postMessage({topic: "test-logout"});
port2.postMessage({topic: "test-logout"});
waitForCondition(function() chats.children.length == Social.providers.length - 1,
function() {
closeAllChats();
waitForCondition(function() chats.children.length == 0,
function() {
ok(!chats.selectedChat, "multiprovider chats are all closed");
port.close();
next();
},
"chat windows didn't close");
@ -277,6 +282,7 @@ var tests = {
testCloseOnLogout: function(next) {
const chatUrl = SocialSidebar.provider.origin + "/browser/browser/base/content/test/social/social_chat.html";
let port = SocialSidebar.provider.getWorkerPort();
ports.push(port);
ok(port, "provider has a port");
let opened = false;
port.onmessage = function (e) {
@ -292,7 +298,6 @@ var tests = {
port.postMessage({topic: "test-logout"});
waitForCondition(function() document.getElementById("pinnedchats").firstChild == null,
function() {
port.close();
next();
},
"chat windows didn't close");

Просмотреть файл

@ -15,34 +15,55 @@ let openChatWindow = Cu.import("resource://gre/modules/MozSocialAPI.jsm", {}).op
// (via browser/base/content/test/browser_bookmark_titles.js)
let origProxyType = Services.prefs.getIntPref('network.proxy.type');
function toggleOfflineStatus(goOffline) {
// Bug 968887 fix. when going on/offline, wait for notification before continuing
let deferred = Promise.defer();
if (!goOffline) {
Services.prefs.setIntPref('network.proxy.type', origProxyType);
}
if (goOffline != Services.io.offline) {
info("initial offline state " + Services.io.offline);
let expect = !Services.io.offline;
Services.obs.addObserver(function offlineChange(subject, topic, data) {
Services.obs.removeObserver(offlineChange, "network:offline-status-changed");
info("offline state changed to " + Services.io.offline);
is(expect, Services.io.offline, "network:offline-status-changed successful toggle");
deferred.resolve();
}, "network:offline-status-changed", false);
BrowserOffline.toggleOfflineStatus();
} else {
deferred.resolve();
}
if (goOffline) {
Services.prefs.setIntPref('network.proxy.type', 0);
// LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
Services.cache2.clear();
}
return deferred.promise;
}
function goOffline() {
// Simulate a network outage with offline mode. (Localhost is still
// accessible in offline mode, so disable the test proxy as well.)
if (!Services.io.offline)
BrowserOffline.toggleOfflineStatus();
Services.prefs.setIntPref('network.proxy.type', 0);
// LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
Services.cache2.clear();
return toggleOfflineStatus(true);
}
function goOnline(callback) {
Services.prefs.setIntPref('network.proxy.type', origProxyType);
if (Services.io.offline)
BrowserOffline.toggleOfflineStatus();
if (callback)
callback();
return toggleOfflineStatus(false);
}
function openPanel(url, panelCallback, loadCallback) {
// open a flyout
SocialFlyout.open(url, 0, panelCallback);
SocialFlyout.panel.firstChild.addEventListener("load", function panelLoad(evt) {
if (evt.target != SocialFlyout.panel.firstChild.contentDocument) {
return;
}
SocialFlyout.panel.firstChild.removeEventListener("load", panelLoad, true);
loadCallback();
}, true);
// wait for both open and loaded before callback. Since the test doesn't close
// the panel between opens, we cannot rely on events here. We need to ensure
// popupshown happens before we finish out the tests.
waitForCondition(function() {
return SocialFlyout.panel.state == "open" &&
SocialFlyout.iframe.contentDocument.readyState == "complete";
},
function () { executeSoon(loadCallback) },
"flyout is open and loaded");
}
function openChat(url, panelCallback, loadCallback) {
@ -51,7 +72,7 @@ function openChat(url, panelCallback, loadCallback) {
openChatWindow(null, SocialSidebar.provider, url, panelCallback);
chatbar.firstChild.addEventListener("DOMContentLoaded", function panelLoad() {
chatbar.firstChild.removeEventListener("DOMContentLoaded", panelLoad, true);
loadCallback();
executeSoon(loadCallback);
}, true);
}
@ -59,27 +80,14 @@ function onSidebarLoad(callback) {
let sbrowser = document.getElementById("social-sidebar-browser");
sbrowser.addEventListener("load", function load() {
sbrowser.removeEventListener("load", load, true);
callback();
executeSoon(callback);
}, true);
}
function ensureWorkerLoaded(provider, callback) {
// once the worker responds to a ping we know it must be up.
let port = provider.getWorkerPort();
port.onmessage = function(msg) {
if (msg.data.topic == "pong") {
port.close();
callback();
}
}
port.postMessage({topic: "ping"})
}
let manifest = { // normal provider
name: "provider 1",
origin: "https://example.com",
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar_empty.html",
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
};
@ -87,7 +95,7 @@ function test() {
waitForExplicitFinish();
runSocialTestWithProvider(manifest, function (finishcb) {
runSocialTests(tests, undefined, goOnline, finishcb);
runSocialTests(tests, undefined, function(next) { goOnline().then(next) }, finishcb);
});
}
@ -95,122 +103,123 @@ var tests = {
testSidebar: function(next) {
let sbrowser = document.getElementById("social-sidebar-browser");
onSidebarLoad(function() {
ok(sbrowser.contentDocument.location.href.indexOf("about:socialerror?")==0, "is on social error page");
ok(sbrowser.contentDocument.location.href.indexOf("about:socialerror?")==0, "sidebar is on social error page");
gc();
// Add a new load listener, then find and click the "try again" button.
onSidebarLoad(function() {
// should still be on the error page.
ok(sbrowser.contentDocument.location.href.indexOf("about:socialerror?")==0, "is still on social error page");
ok(sbrowser.contentDocument.location.href.indexOf("about:socialerror?")==0, "sidebar is still on social error page");
// go online and try again - this should work.
goOnline();
onSidebarLoad(function() {
// should now be on the correct page.
is(sbrowser.contentDocument.location.href, manifest.sidebarURL, "is now on social sidebar page");
next();
goOnline().then(function () {
onSidebarLoad(function() {
// should now be on the correct page.
is(sbrowser.contentDocument.location.href, manifest.sidebarURL, "sidebar is now on social sidebar page");
next();
});
sbrowser.contentDocument.getElementById("btnTryAgain").click();
});
sbrowser.contentDocument.getElementById("btnTryAgain").click();
});
sbrowser.contentDocument.getElementById("btnTryAgain").click();
});
// we want the worker to be fully loaded before going offline, otherwise
// it might fail due to going offline.
ensureWorkerLoaded(SocialSidebar.provider, function() {
// go offline then attempt to load the sidebar - it should fail.
goOffline();
// go offline then attempt to load the sidebar - it should fail.
goOffline().then(function() {
SocialSidebar.show();
});
});
},
testFlyout: function(next) {
let panelCallbackCount = 0;
let panel = document.getElementById("social-flyout-panel");
// go offline and open a flyout.
goOffline();
openPanel(
"https://example.com/browser/browser/base/content/test/social/social_panel.html",
function() { // the panel api callback
panelCallbackCount++;
},
function() { // the "load" callback.
executeSoon(function() {
goOffline().then(function() {
openPanel(
manifest.sidebarURL, /* empty html page */
function() { // the panel api callback
panelCallbackCount++;
},
function() { // the "load" callback.
todo_is(panelCallbackCount, 0, "Bug 833207 - should be no callback when error page loads.");
ok(panel.firstChild.contentDocument.location.href.indexOf("about:socialerror?")==0, "is on social error page");
let href = panel.firstChild.contentDocument.location.href;
ok(href.indexOf("about:socialerror?")==0, "flyout is on social error page");
// Bug 832943 - the listeners previously stopped working after a GC, so
// force a GC now and try again.
gc();
openPanel(
"https://example.com/browser/browser/base/content/test/social/social_panel.html",
manifest.sidebarURL, /* empty html page */
function() { // the panel api callback
panelCallbackCount++;
},
function() { // the "load" callback.
executeSoon(function() {
todo_is(panelCallbackCount, 0, "Bug 833207 - should be no callback when error page loads.");
ok(panel.firstChild.contentDocument.location.href.indexOf("about:socialerror?")==0, "is on social error page");
gc();
executeSoon(function() {
SocialFlyout.unload();
next();
});
});
todo_is(panelCallbackCount, 0, "Bug 833207 - should be no callback when error page loads.");
let href = panel.firstChild.contentDocument.location.href;
ok(href.indexOf("about:socialerror?")==0, "flyout is on social error page");
gc();
SocialFlyout.unload();
next();
}
);
});
}
);
}
);
});
},
testChatWindow: function(next) {
let panelCallbackCount = 0;
// go offline and open a chat.
goOffline();
openChat(
"https://example.com/browser/browser/base/content/test/social/social_chat.html",
function() { // the panel api callback
panelCallbackCount++;
},
function() { // the "load" callback.
executeSoon(function() {
// chatwindow tests throw errors, which muddy test output, if the worker
// doesn't get test-init
goOffline().then(function() {
openChat(
manifest.sidebarURL, /* empty html page */
function() { // the panel api callback
panelCallbackCount++;
},
function() { // the "load" callback.
todo_is(panelCallbackCount, 0, "Bug 833207 - should be no callback when error page loads.");
let chat = getChatBar().selectedChat;
waitForCondition(function() chat.contentDocument.location.href.indexOf("about:socialerror?")==0,
waitForCondition(function() chat.content != null && chat.contentDocument.location.href.indexOf("about:socialerror?")==0,
function() {
chat.close();
next();
},
"error page didn't appear");
});
}
);
}
);
});
},
testChatWindowAfterTearOff: function(next) {
// Ensure that the error listener survives the chat window being detached.
let url = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let url = manifest.sidebarURL; /* empty html page */
let panelCallbackCount = 0;
// chatwindow tests throw errors, which muddy test output, if the worker
// doesn't get test-init
// open a chat while we are still online.
openChat(
url,
null,
function() { // the "load" callback.
executeSoon(function() {
let chat = getChatBar().selectedChat;
is(chat.contentDocument.location.href, url, "correct url loaded");
// toggle to a detached window.
chat.swapWindows().then(
chat => {
let chat = getChatBar().selectedChat;
is(chat.contentDocument.location.href, url, "correct url loaded");
// toggle to a detached window.
chat.swapWindows().then(
chat => {
ok(!!chat.content, "we have chat content 1");
waitForCondition(function() chat.content != null && chat.contentDocument.readyState == "complete",
function() {
// now go offline and reload the chat - about:socialerror should be loaded.
goOffline();
chat.contentDocument.location.reload();
waitForCondition(function() chat.contentDocument.location.href.indexOf("about:socialerror?")==0,
function() {
chat.close();
next();
},
"error page didn't appear");
}
);
});
goOffline().then(function() {
ok(!!chat.content, "we have chat content 2");
chat.contentDocument.location.reload();
info("chat reload called");
waitForCondition(function() chat.contentDocument.location.href.indexOf("about:socialerror?")==0,
function() {
chat.close();
next();
},
"error page didn't appear");
});
}, "swapped window loaded");
}
);
}
);
}

Просмотреть файл

@ -33,6 +33,16 @@ function waitForCondition(condition, nextTest, errorMsg) {
var moveOn = function() { clearInterval(interval); nextTest(); };
}
function promiseObserverNotified(aTopic) {
let deferred = Promise.defer();
Services.obs.addObserver(function onNotification(aSubject, aTopic, aData) {
Services.obs.removeObserver(onNotification, aTopic);
deferred.resolve({subject: aSubject, data: aData});
}, aTopic, false);
return deferred.promise;
}
// Check that a specified (string) URL hasn't been "remembered" (ie, is not
// in history, will not appear in about:newtab or auto-complete, etc.)
function promiseSocialUrlNotRemembered(url) {