Bug 1256625 - enable function parameters to gContentAPI wrappers to fix UITour tests in e10s mode, r?MattN draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 15 Mar 2016 11:47:49 +0000
changeset 340482 4490919f92435b722f326dff2fca6306a985446d
parent 340465 c492b319e0c05798bc43e601ac0c406cfecb06b4
child 340591 9e82d21b686646a954ddcf7d4d4849047435dbb8
push id12977
push usergijskruitbosch@gmail.com
push dateTue, 15 Mar 2016 11:48:06 +0000
reviewersMattN
bugs1256625
milestone48.0a1
Bug 1256625 - enable function parameters to gContentAPI wrappers to fix UITour tests in e10s mode, r?MattN MozReview-Commit-ID: 6A4X8bmgaun
browser/components/uitour/test/browser.ini
browser/components/uitour/test/browser_UITour.js
browser/components/uitour/test/head.js
--- a/browser/components/uitour/test/browser.ini
+++ b/browser/components/uitour/test/browser.ini
@@ -4,49 +4,47 @@ support-files =
   image.png
   uitour.html
   ../UITour-lib.js
 
 [browser_backgroundTab.js]
 skip-if = e10s # Intermittent failures, bug 1244991
 [browser_closeTab.js]
 [browser_fxa.js]
-skip-if = e10s || debug || asan # Bug 1240747 - UITour tests not e10s friendly # updateAppMenuItem leaks
+skip-if = debug || asan # updateAppMenuItem leaks
 [browser_no_tabs.js]
 [browser_openPreferences.js]
 [browser_openSearchPanel.js]
 skip-if = true # Bug 1113038 - Intermittent "Popup was opened"
 [browser_trackingProtection.js]
 skip-if = os == "linux" # Intermittent NS_ERROR_NOT_AVAILABLE [nsIUrlClassifierDBService.beginUpdate]
 tag = trackingprotection
 [browser_trackingProtection_tour.js]
 tag = trackingprotection
 [browser_showMenu_controlCenter.js]
 tag = trackingprotection
 [browser_UITour.js]
-skip-if = os == "linux" || e10s # Intermittent failures, bug 951965
+skip-if = os == "linux" # Intermittent failures, bug 951965
 [browser_UITour2.js]
-skip-if = e10s # Bug 1240747 - UITour.jsm not e10s friendly
 [browser_UITour3.js]
-skip-if = os == "linux" || e10s # Linux: Bug 986760, Bug 989101. Bug 1240747 - UITour.jsm not e10s friendly
+skip-if = os == "linux" # Linux: Bug 986760, Bug 989101.
 [browser_UITour_availableTargets.js]
 [browser_UITour_annotation_size_attributes.js]
 [browser_UITour_defaultBrowser.js]
 [browser_UITour_detach_tab.js]
 skip-if = e10s # Bug 1240747 - UITour.jsm not e10s friendly
 [browser_UITour_forceReaderMode.js]
 [browser_UITour_heartbeat.js]
 skip-if = e10s # Bug 1240747 - UITour.jsm not e10s friendly.
 [browser_UITour_loop.js]
 skip-if = true # Bug 1225832 - New Loop architecture is not compatible with test.
 [browser_UITour_loop_panel.js]
 [browser_UITour_modalDialog.js]
 skip-if = os != "mac" # modal dialog disabling only working on OS X.
 [browser_UITour_observe.js]
-skip-if = e10s # Bug 1240747 - UITour.jsm not e10s friendly.
 [browser_UITour_panel_close_annotation.js]
 skip-if = true # Disabled due to frequent failures, bugs 1026310 and 1032137
 [browser_UITour_pocket.js]
-skip-if = os == "linux" || e10s || debug # Bug 1240747 - UITour.jsm not e10s friendly.
+skip-if = os == "linux" || debug
 [browser_UITour_registerPageID.js]
 [browser_UITour_resetProfile.js]
 [browser_UITour_sync.js]
 [browser_UITour_toggleReaderMode.js]
--- a/browser/components/uitour/test/browser_UITour.js
+++ b/browser/components/uitour/test/browser_UITour.js
@@ -279,17 +279,17 @@ var tests = [
     is(popup.popupBoxObject.anchorNode, document.getElementById("searchbar"), "Popup should be anchored to the searchbar");
     is(title.textContent, "search title", "Popup should have correct title");
     is(desc.textContent, "search text", "Popup should have correct description text");
   }),
   function test_getConfigurationVersion(done) {
     function callback(result) {
       let props = ["defaultUpdateChannel", "version"];
       for (let property of props) {
-        ok(typeof(result[property]) !== undefined, "Check " + property + " isn't undefined.");
+        ok(typeof(result[property]) !== "undefined", "Check " + property + " isn't undefined.");
         is(result[property], Services.appinfo[property], "Should have the same " + property + " property.");
       }
       done();
     }
 
     gContentAPI.getConfiguration("appinfo", callback);
   },
   function test_addToolbarButton(done) {
--- a/browser/components/uitour/test/head.js
+++ b/browser/components/uitour/test/head.js
@@ -267,24 +267,67 @@ function loadUITourTestPage(callback, ho
           };
         },
       };
       gContentWindow = new Proxy({}, contentWinHandler);
 
       let UITourHandler = {
         get(target, prop, receiver) {
           return (...args) => {
+            let browser = gTestTab.linkedBrowser;
+            const proxyFunctionName = "UITourHandler:proxiedfunction-";
+            // We need to proxy any callback functions using messages:
+            let callbackMap = new Map();
+            let fnIndices = [];
+            args = args.map((arg, index) => {
+              // Replace function arguments with "", and add them to the list of
+              // forwarded functions. We'll construct a function on the content-side
+              // that forwards all its arguments to a message, and we'll listen for
+              // those messages on our side and call the corresponding function with
+              // the arguments we got from the content side.
+              if (typeof arg == "function") {
+                callbackMap.set(index, arg);
+                fnIndices.push(index);
+                let handler = function(msg) {
+                  browser.messageManager.removeMessageListener(proxyFunctionName + index, handler);
+                  callbackMap.get(index).apply(null, msg.data);
+                };
+                browser.messageManager.addMessageListener(proxyFunctionName + index, handler);
+                return "";
+              }
+              return arg;
+            });
             let taskArgs = {
               methodName: prop,
               args,
+              fnIndices,
             };
-            return ContentTask.spawn(gTestTab.linkedBrowser, taskArgs, args => {
+            return ContentTask.spawn(browser, taskArgs, function*(args) {
               let contentWin = Components.utils.waiveXrays(content);
-              return contentWin.Mozilla.UITour[args.methodName].apply(contentWin.Mozilla.UITour,
-                                                                      args.args);
+              let callbacksCalled = 0;
+              let resolveCallbackPromise;
+              let allCallbacksCalledPromise = new Promise(resolve => resolveCallbackPromise = resolve);
+              let argumentsWithFunctions = args.args.map((arg, index) => {
+                if (arg === "" && args.fnIndices.includes(index)) {
+                  return function() {
+                    callbacksCalled++;
+                    sendAsyncMessage("UITourHandler:proxiedfunction-" + index, Array.from(arguments));
+                    if (callbacksCalled >= args.fnIndices.length) {
+                      resolveCallbackPromise();
+                    }
+                  };
+                }
+                return arg;
+              });
+              let rv = contentWin.Mozilla.UITour[args.methodName].apply(contentWin.Mozilla.UITour,
+                                                                        argumentsWithFunctions);
+              if (args.fnIndices.length) {
+                yield allCallbacksCalledPromise;
+              }
+              return rv;
             });
           };
         },
       };
       gContentAPI = new Proxy({}, UITourHandler);
     } else {
       gContentWindow = Components.utils.waiveXrays(gTestTab.linkedBrowser.contentDocument.defaultView);
       gContentAPI = gContentWindow.Mozilla.UITour;