bug 841350 - register pageshow handler earlier in browser.js r=ttaubert
[gecko.git] / browser / base / content / test / browser_contentAreaClick.js
blobba89240ea69a239eebb9605c23be4d81e1be3180
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4  
5 /**
6  * Test for bug 549340.
7  * Test for browser.js::contentAreaClick() util.
8  *
9  * The test opens a new browser window, then replaces browser.js methods invoked
10  * by contentAreaClick with a mock function that tracks which methods have been
11  * called.
12  * Each sub-test synthesizes a mouse click event on links injected in content,
13  * the event is collected by a click handler that ensures that contentAreaClick
14  * correctly prevent default events, and follows the correct code path.
15  */
17 let gTests = [
19   {
20     desc: "Simple left click",
21     setup: function() {},
22     clean: function() {},
23     event: {},
24     targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
25     expectedInvokedMethods: [],
26     preventDefault: false,
27   },
29   {
30     desc: "Ctrl/Cmd left click",
31     setup: function() {},
32     clean: function() {},
33     event: { ctrlKey: true,
34              metaKey: true },
35     targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
36     expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
37     preventDefault: true,
38   },
40   // The next test was once handling feedService.forcePreview().  Now it should
41   // just be like Alt click.
42   {
43     desc: "Shift+Alt left click",
44     setup: function() {
45       gPrefService.setBoolPref("browser.altClickSave", true);
46     },
47     clean: function() {
48       gPrefService.clearUserPref("browser.altClickSave"); 
49     },
50     event: { shiftKey: true,
51              altKey: true },
52     targets: [ "commonlink", "maplink" ],
53     expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
54     preventDefault: true,
55   },
57   {
58     desc: "Shift+Alt left click on XLinks",
59     setup: function() {
60       gPrefService.setBoolPref("browser.altClickSave", true);
61     },
62     clean: function() {
63       gPrefService.clearUserPref("browser.altClickSave"); 
64     },
65     event: { shiftKey: true,
66              altKey: true },
67     targets: [ "mathxlink", "svgxlink"],
68     expectedInvokedMethods: [ "saveURL" ],
69     preventDefault: true,
70   },
72   {
73     desc: "Shift click",
74     setup: function() {},
75     clean: function() {},
76     event: { shiftKey: true },
77     targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
78     expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
79     preventDefault: true,
80   },
82   {
83     desc: "Alt click",
84     setup: function() {
85       gPrefService.setBoolPref("browser.altClickSave", true);
86     },
87     clean: function() {
88       gPrefService.clearUserPref("browser.altClickSave"); 
89     },
90     event: { altKey: true },
91     targets: [ "commonlink", "maplink" ],
92     expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
93     preventDefault: true,
94   },
96   {
97     desc: "Alt click on XLinks",
98     setup: function() {
99       gPrefService.setBoolPref("browser.altClickSave", true);
100     },
101     clean: function() {
102       gPrefService.clearUserPref("browser.altClickSave"); 
103     },
104     event: { altKey: true },
105     targets: [ "mathxlink", "svgxlink" ],
106     expectedInvokedMethods: [ "saveURL" ],
107     preventDefault: true,
108   },
110   {
111     desc: "Panel click",
112     setup: function() {},
113     clean: function() {},
114     event: {},
115     targets: [ "panellink" ],
116     expectedInvokedMethods: [ "urlSecurityCheck", "loadURI" ],
117     preventDefault: true,
118   },
120   {
121     desc: "Simple middle click opentab",
122     setup: function() {},
123     clean: function() {},
124     event: { button: 1 },
125     targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
126     expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
127     preventDefault: true,
128   },
130   {
131     desc: "Simple middle click openwin",
132     setup: function() {
133       gPrefService.setBoolPref("browser.tabs.opentabfor.middleclick", false);
134     },
135     clean: function() {
136       gPrefService.clearUserPref("browser.tabs.opentabfor.middleclick");
137     },
138     event: { button: 1 },
139     targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
140     expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
141     preventDefault: true,
142   },
144   {
145     desc: "Middle mouse paste",
146     setup: function() {
147       gPrefService.setBoolPref("middlemouse.contentLoadURL", true);
148       gPrefService.setBoolPref("general.autoScroll", false);
149     },
150     clean: function() {
151       gPrefService.clearUserPref("middlemouse.contentLoadURL");
152       gPrefService.clearUserPref("general.autoScroll");
153     },
154     event: { button: 1 },
155     targets: [ "emptylink" ],
156     expectedInvokedMethods: [ "middleMousePaste" ],
157     preventDefault: true,
158   },
162 // Array of method names that will be replaced in the new window.
163 let gReplacedMethods = [
164   "middleMousePaste",
165   "urlSecurityCheck",
166   "loadURI",
167   "gatherTextUnder",
168   "saveURL",
169   "openLinkIn",
170   "getShortcutOrURI",
173 // Reference to the new window.
174 let gTestWin = null;
176 // List of methods invoked by a specific call to contentAreaClick.
177 let gInvokedMethods = [];
179 // The test currently running.
180 let gCurrentTest = null;
182 function test() {
183   waitForExplicitFinish();
185   gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
186   whenDelayedStartupFinished(gTestWin, function () {
187     info("Browser window opened");
188     waitForFocus(function() {
189       info("Browser window focused");
190       waitForFocus(function() {
191         info("Setting up browser...");
192         setupTestBrowserWindow();
193         info("Running tests...");
194         executeSoon(runNextTest);
195       }, gTestWin.content, true);
196     }, gTestWin);
197   });
200 // Click handler used to steal click events.
201 let gClickHandler = {
202   handleEvent: function (event) {
203     let linkId = event.target.id || event.target.localName;
204     is(event.type, "click",
205        gCurrentTest.desc + ":Handler received a click event on " + linkId);
207     let isPanelClick = linkId == "panellink";
208     gTestWin.contentAreaClick(event, isPanelClick);
209     let prevent = event.defaultPrevented;
210     is(prevent, gCurrentTest.preventDefault,
211        gCurrentTest.desc + ": event.defaultPrevented is correct (" + prevent + ")")
213     // Check that all required methods have been called.
214     gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
215       isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
216             gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
217     });
218     
219     if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
220       ok(false, "Wrong number of invoked methods");
221       gInvokedMethods.forEach(function (method) info(method + " was invoked"));
222     }
224     event.preventDefault();
225     event.stopPropagation();
227     executeSoon(runNextTest);
228   }
231 // Wraps around the methods' replacement mock function.
232 function wrapperMethod(aInvokedMethods, aMethodName) {
233   return function () {
234     aInvokedMethods.push(aMethodName);
235     // At least getShortcutOrURI requires to return url that is the first param.
236     return arguments[0];
237   }
240 function setupTestBrowserWindow() {
241   // Steal click events and don't propagate them.
242   gTestWin.addEventListener("click", gClickHandler, true);
244   // Replace methods.
245   gReplacedMethods.forEach(function (aMethodName) {
246     gTestWin["old_" + aMethodName] = gTestWin[aMethodName];
247     gTestWin[aMethodName] = wrapperMethod(gInvokedMethods, aMethodName);
248   });
250   // Inject links in content.
251   let doc = gTestWin.content.document;
252   let mainDiv = doc.createElement("div");
253   mainDiv.innerHTML =
254     '<p><a id="commonlink" href="http://mochi.test/moz/">Common link</a></p>' +
255     '<p><a id="panellink" href="http://mochi.test/moz/">Panel link</a></p>' +
256     '<p><a id="emptylink">Empty link</a></p>' +
257     '<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>' +
258     '<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>' +
259     '<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>'
260   doc.body.appendChild(mainDiv);
263 function runNextTest() {
264   if (!gCurrentTest) {
265     gCurrentTest = gTests.shift();
266     gCurrentTest.setup();
267   }
269   if (gCurrentTest.targets.length == 0) {
270     info(gCurrentTest.desc + ": cleaning up...")
271     gCurrentTest.clean();
273     if (gTests.length > 0) {
274       gCurrentTest = gTests.shift();
275       gCurrentTest.setup();
276     }
277     else {
278       finishTest();
279       return;
280     }
281   }
283   // Move to next target.
284   gInvokedMethods.length = 0;
285   let target = gCurrentTest.targets.shift();
287   info(gCurrentTest.desc + ": testing " + target);
289   // Fire click event.
290   let targetElt = gTestWin.content.document.getElementById(target);
291   ok(targetElt, gCurrentTest.desc + ": target is valid (" + targetElt.id + ")");
292   EventUtils.synthesizeMouseAtCenter(targetElt, gCurrentTest.event, gTestWin.content);
295 function finishTest() {
296   info("Restoring browser...");
297   gTestWin.removeEventListener("click", gClickHandler, true);
299   // Restore original methods.
300   gReplacedMethods.forEach(function (aMethodName) {
301     gTestWin[aMethodName] = gTestWin["old_" + aMethodName];
302     delete gTestWin["old_" + aMethodName];
303   });
305   gTestWin.close();
306   finish();