browser/base/content/test/general/browser_contentAreaClick.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/base/content/test/general/browser_contentAreaClick.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,307 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 + 
     1.8 +/**
     1.9 + * Test for bug 549340.
    1.10 + * Test for browser.js::contentAreaClick() util.
    1.11 + *
    1.12 + * The test opens a new browser window, then replaces browser.js methods invoked
    1.13 + * by contentAreaClick with a mock function that tracks which methods have been
    1.14 + * called.
    1.15 + * Each sub-test synthesizes a mouse click event on links injected in content,
    1.16 + * the event is collected by a click handler that ensures that contentAreaClick
    1.17 + * correctly prevent default events, and follows the correct code path.
    1.18 + */
    1.19 +
    1.20 +let gTests = [
    1.21 +
    1.22 +  {
    1.23 +    desc: "Simple left click",
    1.24 +    setup: function() {},
    1.25 +    clean: function() {},
    1.26 +    event: {},
    1.27 +    targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
    1.28 +    expectedInvokedMethods: [],
    1.29 +    preventDefault: false,
    1.30 +  },
    1.31 +
    1.32 +  {
    1.33 +    desc: "Ctrl/Cmd left click",
    1.34 +    setup: function() {},
    1.35 +    clean: function() {},
    1.36 +    event: { ctrlKey: true,
    1.37 +             metaKey: true },
    1.38 +    targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
    1.39 +    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
    1.40 +    preventDefault: true,
    1.41 +  },
    1.42 +
    1.43 +  // The next test was once handling feedService.forcePreview().  Now it should
    1.44 +  // just be like Alt click.
    1.45 +  {
    1.46 +    desc: "Shift+Alt left click",
    1.47 +    setup: function() {
    1.48 +      gPrefService.setBoolPref("browser.altClickSave", true);
    1.49 +    },
    1.50 +    clean: function() {
    1.51 +      gPrefService.clearUserPref("browser.altClickSave"); 
    1.52 +    },
    1.53 +    event: { shiftKey: true,
    1.54 +             altKey: true },
    1.55 +    targets: [ "commonlink", "maplink" ],
    1.56 +    expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
    1.57 +    preventDefault: true,
    1.58 +  },
    1.59 +
    1.60 +  {
    1.61 +    desc: "Shift+Alt left click on XLinks",
    1.62 +    setup: function() {
    1.63 +      gPrefService.setBoolPref("browser.altClickSave", true);
    1.64 +    },
    1.65 +    clean: function() {
    1.66 +      gPrefService.clearUserPref("browser.altClickSave"); 
    1.67 +    },
    1.68 +    event: { shiftKey: true,
    1.69 +             altKey: true },
    1.70 +    targets: [ "mathxlink", "svgxlink"],
    1.71 +    expectedInvokedMethods: [ "saveURL" ],
    1.72 +    preventDefault: true,
    1.73 +  },
    1.74 +
    1.75 +  {
    1.76 +    desc: "Shift click",
    1.77 +    setup: function() {},
    1.78 +    clean: function() {},
    1.79 +    event: { shiftKey: true },
    1.80 +    targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
    1.81 +    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
    1.82 +    preventDefault: true,
    1.83 +  },
    1.84 +
    1.85 +  {
    1.86 +    desc: "Alt click",
    1.87 +    setup: function() {
    1.88 +      gPrefService.setBoolPref("browser.altClickSave", true);
    1.89 +    },
    1.90 +    clean: function() {
    1.91 +      gPrefService.clearUserPref("browser.altClickSave"); 
    1.92 +    },
    1.93 +    event: { altKey: true },
    1.94 +    targets: [ "commonlink", "maplink" ],
    1.95 +    expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
    1.96 +    preventDefault: true,
    1.97 +  },
    1.98 +
    1.99 +  {
   1.100 +    desc: "Alt click on XLinks",
   1.101 +    setup: function() {
   1.102 +      gPrefService.setBoolPref("browser.altClickSave", true);
   1.103 +    },
   1.104 +    clean: function() {
   1.105 +      gPrefService.clearUserPref("browser.altClickSave"); 
   1.106 +    },
   1.107 +    event: { altKey: true },
   1.108 +    targets: [ "mathxlink", "svgxlink" ],
   1.109 +    expectedInvokedMethods: [ "saveURL" ],
   1.110 +    preventDefault: true,
   1.111 +  },
   1.112 +
   1.113 +  {
   1.114 +    desc: "Panel click",
   1.115 +    setup: function() {},
   1.116 +    clean: function() {},
   1.117 +    event: {},
   1.118 +    targets: [ "panellink" ],
   1.119 +    expectedInvokedMethods: [ "urlSecurityCheck", "loadURI" ],
   1.120 +    preventDefault: true,
   1.121 +  },
   1.122 +
   1.123 +  {
   1.124 +    desc: "Simple middle click opentab",
   1.125 +    setup: function() {},
   1.126 +    clean: function() {},
   1.127 +    event: { button: 1 },
   1.128 +    targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
   1.129 +    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
   1.130 +    preventDefault: true,
   1.131 +  },
   1.132 +
   1.133 +  {
   1.134 +    desc: "Simple middle click openwin",
   1.135 +    setup: function() {
   1.136 +      gPrefService.setBoolPref("browser.tabs.opentabfor.middleclick", false);
   1.137 +    },
   1.138 +    clean: function() {
   1.139 +      gPrefService.clearUserPref("browser.tabs.opentabfor.middleclick");
   1.140 +    },
   1.141 +    event: { button: 1 },
   1.142 +    targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
   1.143 +    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
   1.144 +    preventDefault: true,
   1.145 +  },
   1.146 +
   1.147 +  {
   1.148 +    desc: "Middle mouse paste",
   1.149 +    setup: function() {
   1.150 +      gPrefService.setBoolPref("middlemouse.contentLoadURL", true);
   1.151 +      gPrefService.setBoolPref("general.autoScroll", false);
   1.152 +    },
   1.153 +    clean: function() {
   1.154 +      gPrefService.clearUserPref("middlemouse.contentLoadURL");
   1.155 +      gPrefService.clearUserPref("general.autoScroll");
   1.156 +    },
   1.157 +    event: { button: 1 },
   1.158 +    targets: [ "emptylink" ],
   1.159 +    expectedInvokedMethods: [ "middleMousePaste" ],
   1.160 +    preventDefault: true,
   1.161 +  },
   1.162 +
   1.163 +];
   1.164 +
   1.165 +// Array of method names that will be replaced in the new window.
   1.166 +let gReplacedMethods = [
   1.167 +  "middleMousePaste",
   1.168 +  "urlSecurityCheck",
   1.169 +  "loadURI",
   1.170 +  "gatherTextUnder",
   1.171 +  "saveURL",
   1.172 +  "openLinkIn",
   1.173 +  "getShortcutOrURIAndPostData",
   1.174 +];
   1.175 +
   1.176 +// Reference to the new window.
   1.177 +let gTestWin = null;
   1.178 +
   1.179 +// List of methods invoked by a specific call to contentAreaClick.
   1.180 +let gInvokedMethods = [];
   1.181 +
   1.182 +// The test currently running.
   1.183 +let gCurrentTest = null;
   1.184 +
   1.185 +function test() {
   1.186 +  waitForExplicitFinish();
   1.187 +
   1.188 +  gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
   1.189 +  whenDelayedStartupFinished(gTestWin, function () {
   1.190 +    info("Browser window opened");
   1.191 +    waitForFocus(function() {
   1.192 +      info("Browser window focused");
   1.193 +      waitForFocus(function() {
   1.194 +        info("Setting up browser...");
   1.195 +        setupTestBrowserWindow();
   1.196 +        info("Running tests...");
   1.197 +        executeSoon(runNextTest);
   1.198 +      }, gTestWin.content, true);
   1.199 +    }, gTestWin);
   1.200 +  });
   1.201 +}
   1.202 +
   1.203 +// Click handler used to steal click events.
   1.204 +let gClickHandler = {
   1.205 +  handleEvent: function (event) {
   1.206 +    let linkId = event.target.id || event.target.localName;
   1.207 +    is(event.type, "click",
   1.208 +       gCurrentTest.desc + ":Handler received a click event on " + linkId);
   1.209 +
   1.210 +    let isPanelClick = linkId == "panellink";
   1.211 +    gTestWin.contentAreaClick(event, isPanelClick);
   1.212 +    let prevent = event.defaultPrevented;
   1.213 +    is(prevent, gCurrentTest.preventDefault,
   1.214 +       gCurrentTest.desc + ": event.defaultPrevented is correct (" + prevent + ")")
   1.215 +
   1.216 +    // Check that all required methods have been called.
   1.217 +    gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
   1.218 +      isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
   1.219 +            gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
   1.220 +    });
   1.221 +    
   1.222 +    if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
   1.223 +      ok(false, "Wrong number of invoked methods");
   1.224 +      gInvokedMethods.forEach(function (method) info(method + " was invoked"));
   1.225 +    }
   1.226 +
   1.227 +    event.preventDefault();
   1.228 +    event.stopPropagation();
   1.229 +
   1.230 +    executeSoon(runNextTest);
   1.231 +  }
   1.232 +}
   1.233 +
   1.234 +// Wraps around the methods' replacement mock function.
   1.235 +function wrapperMethod(aInvokedMethods, aMethodName) {
   1.236 +  return function () {
   1.237 +    aInvokedMethods.push(aMethodName);
   1.238 +    // At least getShortcutOrURIAndPostData requires to return url
   1.239 +    return (aMethodName == "getShortcutOrURIAndPostData") ? arguments.url : arguments[0];
   1.240 +  }
   1.241 +}
   1.242 +
   1.243 +function setupTestBrowserWindow() {
   1.244 +  // Steal click events and don't propagate them.
   1.245 +  gTestWin.addEventListener("click", gClickHandler, true);
   1.246 +
   1.247 +  // Replace methods.
   1.248 +  gReplacedMethods.forEach(function (aMethodName) {
   1.249 +    gTestWin["old_" + aMethodName] = gTestWin[aMethodName];
   1.250 +    gTestWin[aMethodName] = wrapperMethod(gInvokedMethods, aMethodName);
   1.251 +  });
   1.252 +
   1.253 +  // Inject links in content.
   1.254 +  let doc = gTestWin.content.document;
   1.255 +  let mainDiv = doc.createElement("div");
   1.256 +  mainDiv.innerHTML =
   1.257 +    '<p><a id="commonlink" href="http://mochi.test/moz/">Common link</a></p>' +
   1.258 +    '<p><a id="panellink" href="http://mochi.test/moz/">Panel link</a></p>' +
   1.259 +    '<p><a id="emptylink">Empty link</a></p>' +
   1.260 +    '<p><math id="mathxlink" xmlns="http://www.w3.org/1998/Math/MathML" xlink:type="simple" xlink:href="http://mochi.test/moz/"><mtext>MathML XLink</mtext></math></p>' +
   1.261 +    '<p><svg id="svgxlink" xmlns="http://www.w3.org/2000/svg" width="100px" height="50px" version="1.1"><a xlink:type="simple" xlink:href="http://mochi.test/moz/"><text transform="translate(10, 25)">SVG XLink</text></a></svg></p>' +
   1.262 +    '<p><map name="map" id="map"><area href="http://mochi.test/moz/" shape="rect" coords="0,0,128,128" /></map><img id="maplink" usemap="#map" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAABGdBTUEAALGPC%2FxhBQAAAOtJREFUeF7t0IEAAAAAgKD9qRcphAoDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGBgwIAAAT0N51AAAAAASUVORK5CYII%3D"/></p>'
   1.263 +  doc.body.appendChild(mainDiv);
   1.264 +}
   1.265 +
   1.266 +function runNextTest() {
   1.267 +  if (!gCurrentTest) {
   1.268 +    gCurrentTest = gTests.shift();
   1.269 +    gCurrentTest.setup();
   1.270 +  }
   1.271 +
   1.272 +  if (gCurrentTest.targets.length == 0) {
   1.273 +    info(gCurrentTest.desc + ": cleaning up...")
   1.274 +    gCurrentTest.clean();
   1.275 +
   1.276 +    if (gTests.length > 0) {
   1.277 +      gCurrentTest = gTests.shift();
   1.278 +      gCurrentTest.setup();
   1.279 +    }
   1.280 +    else {
   1.281 +      finishTest();
   1.282 +      return;
   1.283 +    }
   1.284 +  }
   1.285 +
   1.286 +  // Move to next target.
   1.287 +  gInvokedMethods.length = 0;
   1.288 +  let target = gCurrentTest.targets.shift();
   1.289 +
   1.290 +  info(gCurrentTest.desc + ": testing " + target);
   1.291 +
   1.292 +  // Fire click event.
   1.293 +  let targetElt = gTestWin.content.document.getElementById(target);
   1.294 +  ok(targetElt, gCurrentTest.desc + ": target is valid (" + targetElt.id + ")");
   1.295 +  EventUtils.synthesizeMouseAtCenter(targetElt, gCurrentTest.event, gTestWin.content);
   1.296 +}
   1.297 +
   1.298 +function finishTest() {
   1.299 +  info("Restoring browser...");
   1.300 +  gTestWin.removeEventListener("click", gClickHandler, true);
   1.301 +
   1.302 +  // Restore original methods.
   1.303 +  gReplacedMethods.forEach(function (aMethodName) {
   1.304 +    gTestWin[aMethodName] = gTestWin["old_" + aMethodName];
   1.305 +    delete gTestWin["old_" + aMethodName];
   1.306 +  });
   1.307 +
   1.308 +  gTestWin.close();
   1.309 +  finish();
   1.310 +}

mercurial