Bug 1426154 - Refactor Marionette content frame script registration. r?automatedtester draft
authorAndreas Tolfsen <ato@sny.no>
Tue, 09 Jan 2018 19:50:30 +0000
changeset 718622 9fe572fe7dbcc539ab3655ff43d331ea7b5290e2
parent 718617 99a4b5f093bc187faa909da615c00c3d197e2516
child 745560 906342e8ba5eabb20a223164e52e6b08d3925d79
push id95006
push userbmo:ato@sny.no
push dateWed, 10 Jan 2018 18:04:44 +0000
reviewersautomatedtester
bugs1426154
milestone59.0a1
Bug 1426154 - Refactor Marionette content frame script registration. r?automatedtester The Marionette:newSession IPC message is never used, and the newSession function is consequently never called. Since we no longer have a need for resetting the content frame script, like had with B2G, removing it is probably fine. This also changes the Marionette:Register command to return an object with the "outerWindowID" key, making it easier to identify and extract. MozReview-Commit-ID: Ae3cPFWshcv
testing/marionette/driver.js
testing/marionette/listener.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -516,58 +516,51 @@ GeckoDriver.prototype.getVisibleText = f
   }
 };
 
 /**
  * Handles registration of new content listener browsers.  Depending on
  * their type they are either accepted or ignored.
  */
 GeckoDriver.prototype.registerBrowser = function(id, be) {
-  let nullPrevious = this.curBrowser.curFrameId === null;
   let listenerWindow = Services.wm.getOuterWindowWithId(id);
 
   // We want to ignore frames that are XUL browsers that aren't in the "main"
   // tabbrowser, but accept things on Fennec (which doesn't have a
   // xul:tabbrowser), and accept HTML iframes (because tests depend on it),
   // as well as XUL frames. Ideally this should be cleaned up and we should
   // keep track of browsers a different way.
   if (this.appId != APP_ID_FIREFOX || be.namespaceURI != XUL_NS ||
       be.nodeName != "browser" || be.getTabBrowser()) {
     // curBrowser holds all the registered frames in knownFrames
     this.curBrowser.register(id, be);
   }
 
   this.wins.set(id, listenerWindow);
-  if (nullPrevious && (this.curBrowser.curFrameId !== null)) {
-    this.sendAsync("newSession");
-  }
-
   return id;
 };
 
 GeckoDriver.prototype.registerPromise = function() {
   const li = "Marionette:Register";
 
   return new Promise(resolve => {
-    let cb = msg => {
-      let wid = msg.json.value;
-      let be = msg.target;
-      let outerWindowID = this.registerBrowser(wid, be);
+    let cb = ({json, target}) => {
+      let {outerWindowID} = json;
+      this.registerBrowser(outerWindowID, target);
 
       if (this.curBrowser.frameRegsPending > 0) {
         this.curBrowser.frameRegsPending--;
       }
 
       if (this.curBrowser.frameRegsPending === 0) {
         this.mm.removeMessageListener(li, cb);
         resolve();
       }
 
-      // this is a sync message and listeners expect the ID back
-      return outerWindowID;
+      return {outerWindowID};
     };
     this.mm.addMessageListener(li, cb);
   });
 };
 
 GeckoDriver.prototype.listeningPromise = function() {
   const li = "Marionette:ListenersAttached";
 
@@ -2769,21 +2762,21 @@ GeckoDriver.prototype.closeChromeWindow 
 };
 
 /** Delete Marionette session. */
 GeckoDriver.prototype.deleteSession = function() {
   if (this.curBrowser !== null) {
     // frame scripts can be safely reused
     Preferences.set(CONTENT_LISTENER_PREF, false);
 
-    // delete session in each frame in each browser
+    // clean up state in each frame in each browser
     for (let win in this.browsers) {
       let browser = this.browsers[win];
       browser.knownFrames.forEach(() => {
-        globalMessageManager.broadcastAsyncMessage("Marionette:deleteSession");
+        globalMessageManager.broadcastAsyncMessage("Marionette:Deregister");
       });
     }
 
     for (let win of this.windows) {
       if (win.messageManager) {
         win.messageManager.removeDelayedFrameScript(FRAME_SCRIPT);
       } else {
         logger.error(
@@ -3327,19 +3320,18 @@ GeckoDriver.prototype.receiveMessage = f
               new ChromeWebElement(message.json.frameValue);
         } else {
           this.currentFrameElement = null;
         }
       }
       break;
 
     case "Marionette:Register":
-      let wid = message.json.value;
-      let be = message.target;
-      let outerWindowID = this.registerBrowser(wid, be);
+      let {outerWindowID} = message.json;
+      this.registerBrowser(outerWindowID, message.target);
       return {outerWindowID};
 
     case "Marionette:ListenersAttached":
       if (message.json.outerWindowID === this.curBrowser.curFrameId) {
         // If the frame script gets reloaded we need to call newSession.
         // In the case of desktop this just sets up a small amount of state
         // that doesn't change over the course of a session.
         this.sendAsync("newSession");
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -443,24 +443,32 @@ const loadListener = {
 };
 
 /**
  * Called when listener is first started up.  The listener sends its
  * unique window ID and its current URI to the actor.  If the actor returns
  * an ID, we start the listeners. Otherwise, nothing happens.
  */
 function registerSelf() {
-  let msg = {value: winUtil.outerWindowID};
-  logger.debug(`Register listener.js for window ${msg.value}`);
+  outerWindowID = winUtil.outerWindowID;
+  logger.debug(`Register listener.js for window ${outerWindowID}`);
+
+  sandboxes.clear();
+  curContainer = {
+    frame: content,
+    shadowRoot: null,
+  };
+  legacyactions.mouseEventsOnly = false;
+  action.inputStateMap = new Map();
+  action.inputsToCancel = [];
 
   // register will have the ID and a boolean describing if this is the
   // main process or not
-  let register = sendSyncMessage("Marionette:Register", msg);
-  if (register[0]) {
-    outerWindowID = register[0].outerWindowID;
+  let register = sendSyncMessage("Marionette:Register", {outerWindowID});
+  if (register[0].outerWindowID === outerWindowID) {
     startListeners();
     sendAsyncMessage("Marionette:ListenersAttached", {outerWindowID});
   }
 }
 
 // Eventually we will not have a closure for every single command,
 // but use a generic dispatch for all listener commands.
 //
@@ -518,17 +526,17 @@ let executeInSandboxFn = dispatch(execut
 let sendKeysToElementFn = dispatch(sendKeysToElement);
 let reftestWaitFn = dispatch(reftestWait);
 
 function startListeners() {
   addMessageListener("Marionette:actionChain", actionChainFn);
   addMessageListener("Marionette:cancelRequest", cancelRequest);
   addMessageListener("Marionette:clearElement", clearElementFn);
   addMessageListener("Marionette:clickElement", clickElement);
-  addMessageListener("Marionette:deleteSession", deleteSession);
+  addMessageListener("Marionette:Deregister", deregister);
   addMessageListener("Marionette:DOM:AddEventListener", domAddEventListener);
   addMessageListener("Marionette:DOM:RemoveEventListener", domRemoveEventListener);
   addMessageListener("Marionette:execute", executeFn);
   addMessageListener("Marionette:executeInSandbox", executeInSandboxFn);
   addMessageListener("Marionette:findElementContent", findElementContentFn);
   addMessageListener("Marionette:findElementsContent", findElementsContentFn);
   addMessageListener("Marionette:getActiveElement", getActiveElementFn);
   addMessageListener("Marionette:getElementAttribute", getElementAttributeFn);
@@ -540,48 +548,35 @@ function startListeners() {
   addMessageListener("Marionette:get", get);
   addMessageListener("Marionette:getPageSource", getPageSourceFn);
   addMessageListener("Marionette:goBack", goBack);
   addMessageListener("Marionette:goForward", goForward);
   addMessageListener("Marionette:isElementDisplayed", isElementDisplayedFn);
   addMessageListener("Marionette:isElementEnabled", isElementEnabledFn);
   addMessageListener("Marionette:isElementSelected", isElementSelectedFn);
   addMessageListener("Marionette:multiAction", multiActionFn);
-  addMessageListener("Marionette:newSession", newSession);
   addMessageListener("Marionette:performActions", performActionsFn);
   addMessageListener("Marionette:refresh", refresh);
   addMessageListener("Marionette:reftestWait", reftestWaitFn);
   addMessageListener("Marionette:releaseActions", releaseActionsFn);
   addMessageListener("Marionette:sendKeysToElement", sendKeysToElementFn);
   addMessageListener("Marionette:singleTap", singleTapFn);
   addMessageListener("Marionette:switchToFrame", switchToFrame);
   addMessageListener("Marionette:switchToParentFrame", switchToParentFrame);
   addMessageListener("Marionette:switchToShadowRoot", switchToShadowRootFn);
   addMessageListener("Marionette:takeScreenshot", takeScreenshotFn);
   addMessageListener("Marionette:waitForPageLoaded", waitForPageLoaded);
 }
 
-/**
- * Called when we start a new session. It registers the
- * current environment, and resets all values
- */
-function newSession() {
-  sandboxes.clear();
-  curContainer = {frame: content, shadowRoot: null};
-  legacyactions.mouseEventsOnly = false;
-  action.inputStateMap = new Map();
-  action.inputsToCancel = [];
-}
-
-function deleteSession() {
+function deregister() {
   removeMessageListener("Marionette:actionChain", actionChainFn);
   removeMessageListener("Marionette:cancelRequest", cancelRequest);
   removeMessageListener("Marionette:clearElement", clearElementFn);
   removeMessageListener("Marionette:clickElement", clickElement);
-  removeMessageListener("Marionette:deleteSession", deleteSession);
+  removeMessageListener("Marionette:Deregister", deregister);
   removeMessageListener("Marionette:execute", executeFn);
   removeMessageListener("Marionette:executeInSandbox", executeInSandboxFn);
   removeMessageListener("Marionette:findElementContent", findElementContentFn);
   removeMessageListener("Marionette:findElementsContent", findElementsContentFn);
   removeMessageListener("Marionette:getActiveElement", getActiveElementFn);
   removeMessageListener("Marionette:getElementAttribute", getElementAttributeFn);
   removeMessageListener("Marionette:getElementProperty", getElementPropertyFn);
   removeMessageListener("Marionette:getElementRect", getElementRectFn);
@@ -591,17 +586,16 @@ function deleteSession() {
   removeMessageListener("Marionette:get", get);
   removeMessageListener("Marionette:getPageSource", getPageSourceFn);
   removeMessageListener("Marionette:goBack", goBack);
   removeMessageListener("Marionette:goForward", goForward);
   removeMessageListener("Marionette:isElementDisplayed", isElementDisplayedFn);
   removeMessageListener("Marionette:isElementEnabled", isElementEnabledFn);
   removeMessageListener("Marionette:isElementSelected", isElementSelectedFn);
   removeMessageListener("Marionette:multiAction", multiActionFn);
-  removeMessageListener("Marionette:newSession", newSession);
   removeMessageListener("Marionette:performActions", performActionsFn);
   removeMessageListener("Marionette:refresh", refresh);
   removeMessageListener("Marionette:releaseActions", releaseActionsFn);
   removeMessageListener("Marionette:sendKeysToElement", sendKeysToElementFn);
   removeMessageListener("Marionette:singleTap", singleTapFn);
   removeMessageListener("Marionette:switchToFrame", switchToFrame);
   removeMessageListener("Marionette:switchToParentFrame", switchToParentFrame);
   removeMessageListener("Marionette:switchToShadowRoot", switchToShadowRootFn);