Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
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 },
160 ];
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 "getShortcutOrURIAndPostData",
171 ];
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 });
198 }
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 });
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 }
229 }
231 // Wraps around the methods' replacement mock function.
232 function wrapperMethod(aInvokedMethods, aMethodName) {
233 return function () {
234 aInvokedMethods.push(aMethodName);
235 // At least getShortcutOrURIAndPostData requires to return url
236 return (aMethodName == "getShortcutOrURIAndPostData") ? arguments.url : arguments[0];
237 }
238 }
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);
261 }
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);
293 }
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();
307 }