diff --git a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm index 500acc24b1aa..46983af194a0 100644 --- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm +++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm @@ -23,6 +23,7 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Timer.jsm"); Cu.import("resource://testing-common/TestUtils.jsm"); +Cu.import("resource://testing-common/ContentTask.jsm"); Cc["@mozilla.org/globalmessagemanager;1"] .getService(Ci.nsIMessageListenerManager) @@ -450,6 +451,53 @@ this.BrowserTestUtils = { }); }, + /** + * Like waitForEvent, but adds the event listener to the message manager + * global for browser. + * + * @param {string} eventName + * Name of the event to listen to. + * @param {bool} capture [optional] + * Whether to use a capturing listener. + * @param {function} checkFn [optional] + * Called with the Event object as argument, should return true if the + * event is the expected one, or false if it should be ignored and + * listening should continue. If not specified, the first event with + * the specified name resolves the returned promise. + * + * @note Because this function is intended for testing, any error in checkFn + * will cause the returned promise to be rejected instead of waiting for + * the next event, since this is probably a bug in the test. + * + * @returns {Promise} + */ + waitForContentEvent(browser, eventName, capture, checkFn) { + let parameters = { eventName, + capture, + checkFnSource: checkFn ? checkFn.toSource() : null }; + return ContentTask.spawn(browser, parameters, + function({ eventName, capture, checkFnSource }) { + let checkFn; + if (checkFnSource) { + checkFn = eval(`(() => (${checkFnSource}))()`); + } + return new Promise((resolve, reject) => { + addEventListener(eventName, function listener(event) { + let completion = resolve; + try { + if (checkFn && !checkFn(event)) { + return; + } + } catch (e) { + completion = () => reject(e); + } + removeEventListener(eventName, listener, capture); + completion(); + }, capture); + }); + }); + }, + /** * Versions of EventUtils.jsm synthesizeMouse functions that synthesize a * mouse event in a child process and return promises that resolve when the diff --git a/toolkit/components/places/tests/browser/browser.ini b/toolkit/components/places/tests/browser/browser.ini index 85a9a5b7960a..11a626073713 100644 --- a/toolkit/components/places/tests/browser/browser.ini +++ b/toolkit/components/places/tests/browser/browser.ini @@ -10,7 +10,7 @@ support-files = [browser_bug399606.js] [browser_bug646422.js] [browser_bug680727.js] -skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test times out on try on all platforms, but works locally for markh! +skip-if = buildapp == 'mulet' # Bug ?????? - test times out on try on all platforms, but works locally for markh! [browser_colorAnalyzer.js] [browser_favicon_privatebrowsing_perwindowpb.js] [browser_favicon_setAndFetchFaviconForPage.js] diff --git a/toolkit/components/places/tests/browser/browser_bug680727.js b/toolkit/components/places/tests/browser/browser_bug680727.js index 112b20a5afaf..6d25ef1517c4 100644 --- a/toolkit/components/places/tests/browser/browser_bug680727.js +++ b/toolkit/components/places/tests/browser/browser_bug680727.js @@ -12,12 +12,11 @@ var gAsyncHistory = Cc["@mozilla.org/browser/history;1"].getService(Ci.mozIAsyncHistory); var proxyPrefValue; +var ourTab; function test() { waitForExplicitFinish(); - gBrowser.selectedTab = gBrowser.addTab(); - // Tests always connect to localhost, and per bug 87717, localhost is now // reachable in offline mode. To avoid this, disable any proxy. proxyPrefValue = Services.prefs.getIntPref("network.proxy.type"); @@ -30,33 +29,34 @@ function test() { // Go offline, expecting the error page. Services.io.offline = true; - window.addEventListener("DOMContentLoaded", errorListener, false); - content.location = kUniqueURI.spec; + + BrowserTestUtils.openNewForegroundTab(gBrowser).then(tab => { + ourTab = tab; + BrowserTestUtils.waitForContentEvent(ourTab.linkedBrowser, "DOMContentLoaded", + .then(errorListener); + BrowserTestUtils.loadURI(ourTab.linkedBrowser, kUniqueURI.spec); + }); } //------------------------------------------------------------------------------ // listen to loading the neterror page. (offline mode) function errorListener() { - if(content.location == "about:blank") { - info("got about:blank, which is expected once, so return"); - return; - } - - window.removeEventListener("DOMContentLoaded", errorListener, false); ok(Services.io.offline, "Services.io.offline is true."); // This is an error page. - is(gBrowser.contentDocument.documentURI.substring(0, 27), - "about:neterror?e=netOffline", - "Document URI is the error page."); + ContentTask.spawn(ourTab.linkedBrowser, kUniqueURI.spec, function(uri) { + is(content.document.documentURI.substring(0, 27), + "about:neterror?e=netOffline", + "Document URI is the error page."); - // But location bar should show the original request. - is(content.location.href, kUniqueURI.spec, - "Docshell URI is the original URI."); - - // Global history does not record URI of a failed request. - PlacesTestUtils.promiseAsyncUpdates().then(() => { - gAsyncHistory.isURIVisited(kUniqueURI, errorAsyncListener); + // But location bar should show the original request. + is(content.location.href, uri, + "Docshell URI is the original URI."); + }).then(() => { + // Global history does not record URI of a failed request. + return PlacesTestUtils.promiseAsyncUpdates().then(() => { + gAsyncHistory.isURIVisited(kUniqueURI, errorAsyncListener); + }); }); } @@ -69,30 +69,33 @@ function errorAsyncListener(aURI, aIsVisited) { // Now press the "Try Again" button, with offline mode off. Services.io.offline = false; - window.addEventListener("DOMContentLoaded", reloadListener, false); + BrowserTestUtils.waitForContentEvent(ourTab.linkedBrowser, "DOMContentLoaded") + .then(reloadListener); - ok(gBrowser.contentDocument.getElementById("errorTryAgain"), - "The error page has got a #errorTryAgain element"); - gBrowser.contentDocument.getElementById("errorTryAgain").click(); + ContentTask.spawn(ourTab.linkedBrowser, null, function() { + ok(content.document.getElementById("errorTryAgain"), + "The error page has got a #errorTryAgain element"); + content.document.getElementById("errorTryAgain").click(); + }); } //------------------------------------------------------------------------------ // listen to reload of neterror. function reloadListener() { - window.removeEventListener("DOMContentLoaded", reloadListener, false); - // This listener catches "DOMContentLoaded" on being called // nsIWPL::onLocationChange(...). That is right *AFTER* // IHistory::VisitURI(...) is called. ok(!Services.io.offline, "Services.io.offline is false."); - // This is not an error page. - is(gBrowser.contentDocument.documentURI, kUniqueURI.spec, - "Document URI is not the offline-error page, but the original URI."); - - // Check if global history remembers the successfully-requested URI. - PlacesTestUtils.promiseAsyncUpdates().then(() => { - gAsyncHistory.isURIVisited(kUniqueURI, reloadAsyncListener); + ContentTask.spawn(ourTab.linkedBrowser, kUniqueURI.spec, function(uri) { + // This is not an error page. + is(content.document.documentURI, uri, + "Document URI is not the offline-error page, but the original URI."); + }).then(() => { + // Check if global history remembers the successfully-requested URI. + PlacesTestUtils.promiseAsyncUpdates().then(() => { + gAsyncHistory.isURIVisited(kUniqueURI, reloadAsyncListener); + }); }); } @@ -101,10 +104,8 @@ function reloadAsyncListener(aURI, aIsVisited) { PlacesTestUtils.clearHistory().then(finish); } -registerCleanupFunction(function() { +registerCleanupFunction(function* () { Services.prefs.setIntPref("network.proxy.type", proxyPrefValue); Services.io.offline = false; - window.removeEventListener("DOMContentLoaded", errorListener, false); - window.removeEventListener("DOMContentLoaded", reloadListener, false); - gBrowser.removeCurrentTab(); + yield BrowserTestUtils.removeTab(ourTab); });