1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/modules/test/browser_ContentSearch.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,240 @@ 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 +const TEST_MSG = "ContentSearchTest"; 1.9 +const CONTENT_SEARCH_MSG = "ContentSearch"; 1.10 +const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js"; 1.11 + 1.12 +function generatorTest() { 1.13 + // nextStep() drives the iterator returned by this function. This function's 1.14 + // iterator in turn drives the iterator of each test below. 1.15 + let currentTestIter = yield startNextTest(); 1.16 + let arg = undefined; 1.17 + while (currentTestIter) { 1.18 + try { 1.19 + currentTestIter.send(arg); 1.20 + arg = yield null; 1.21 + } 1.22 + catch (err if err instanceof StopIteration) { 1.23 + currentTestIter = yield startNextTest(); 1.24 + arg = undefined; 1.25 + } 1.26 + } 1.27 +} 1.28 + 1.29 +function startNextTest() { 1.30 + if (!gTests.length) { 1.31 + setTimeout(() => nextStep(null), 0); 1.32 + return; 1.33 + } 1.34 + let nextTestGen = gTests.shift(); 1.35 + let nextTestIter = nextTestGen(); 1.36 + addTab(() => { 1.37 + info("Starting test " + nextTestGen.name); 1.38 + nextStep(nextTestIter); 1.39 + }); 1.40 +} 1.41 + 1.42 +function addTest(testGen) { 1.43 + gTests.push(testGen); 1.44 +} 1.45 + 1.46 +var gTests = []; 1.47 +var gMsgMan; 1.48 + 1.49 +addTest(function GetState() { 1.50 + gMsgMan.sendAsyncMessage(TEST_MSG, { 1.51 + type: "GetState", 1.52 + }); 1.53 + let msg = yield waitForTestMsg("State"); 1.54 + checkMsg(msg, { 1.55 + type: "State", 1.56 + data: currentStateObj(), 1.57 + }); 1.58 +}); 1.59 + 1.60 +addTest(function SetCurrentEngine() { 1.61 + let newCurrentEngine = null; 1.62 + let oldCurrentEngine = Services.search.currentEngine; 1.63 + let engines = Services.search.getVisibleEngines(); 1.64 + for (let engine of engines) { 1.65 + if (engine != oldCurrentEngine) { 1.66 + newCurrentEngine = engine; 1.67 + break; 1.68 + } 1.69 + } 1.70 + if (!newCurrentEngine) { 1.71 + info("Couldn't find a non-selected search engine, " + 1.72 + "skipping this part of the test"); 1.73 + return; 1.74 + } 1.75 + gMsgMan.sendAsyncMessage(TEST_MSG, { 1.76 + type: "SetCurrentEngine", 1.77 + data: newCurrentEngine.name, 1.78 + }); 1.79 + Services.obs.addObserver(function obs(subj, topic, data) { 1.80 + info("Test observed " + data); 1.81 + if (data == "engine-current") { 1.82 + ok(true, "Test observed engine-current"); 1.83 + Services.obs.removeObserver(obs, "browser-search-engine-modified", false); 1.84 + nextStep(); 1.85 + } 1.86 + }, "browser-search-engine-modified", false); 1.87 + info("Waiting for test to observe engine-current..."); 1.88 + waitForTestMsg("CurrentEngine"); 1.89 + let maybeMsg1 = yield null; 1.90 + let maybeMsg2 = yield null; 1.91 + let msg = maybeMsg1 || maybeMsg2; 1.92 + ok(!!msg, 1.93 + "Sanity check: One of the yields is for waitForTestMsg and should have " + 1.94 + "therefore produced a message object"); 1.95 + checkMsg(msg, { 1.96 + type: "CurrentEngine", 1.97 + data: currentEngineObj(newCurrentEngine), 1.98 + }); 1.99 + 1.100 + Services.search.currentEngine = oldCurrentEngine; 1.101 + let msg = yield waitForTestMsg("CurrentEngine"); 1.102 + checkMsg(msg, { 1.103 + type: "CurrentEngine", 1.104 + data: currentEngineObj(oldCurrentEngine), 1.105 + }); 1.106 +}); 1.107 + 1.108 +addTest(function ManageEngines() { 1.109 + gMsgMan.sendAsyncMessage(TEST_MSG, { 1.110 + type: "ManageEngines", 1.111 + }); 1.112 + let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]. 1.113 + getService(Ci.nsIWindowWatcher); 1.114 + winWatcher.registerNotification(function onOpen(subj, topic, data) { 1.115 + if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) { 1.116 + subj.addEventListener("load", function onLoad() { 1.117 + subj.removeEventListener("load", onLoad); 1.118 + if (subj.document.documentURI == 1.119 + "chrome://browser/content/search/engineManager.xul") { 1.120 + winWatcher.unregisterNotification(onOpen); 1.121 + ok(true, "Observed search manager window open"); 1.122 + is(subj.opener, window, 1.123 + "Search engine manager opener should be this chrome window"); 1.124 + subj.close(); 1.125 + nextStep(); 1.126 + } 1.127 + }); 1.128 + } 1.129 + }); 1.130 + info("Waiting for search engine manager window to open..."); 1.131 + yield null; 1.132 +}); 1.133 + 1.134 +addTest(function modifyEngine() { 1.135 + let engine = Services.search.currentEngine; 1.136 + let oldAlias = engine.alias; 1.137 + engine.alias = "ContentSearchTest"; 1.138 + let msg = yield waitForTestMsg("State"); 1.139 + checkMsg(msg, { 1.140 + type: "State", 1.141 + data: currentStateObj(), 1.142 + }); 1.143 + engine.alias = oldAlias; 1.144 + msg = yield waitForTestMsg("State"); 1.145 + checkMsg(msg, { 1.146 + type: "State", 1.147 + data: currentStateObj(), 1.148 + }); 1.149 +}); 1.150 + 1.151 +addTest(function search() { 1.152 + let engine = Services.search.currentEngine; 1.153 + let data = { 1.154 + engineName: engine.name, 1.155 + searchString: "ContentSearchTest", 1.156 + whence: "ContentSearchTest", 1.157 + }; 1.158 + gMsgMan.sendAsyncMessage(TEST_MSG, { 1.159 + type: "Search", 1.160 + data: data, 1.161 + }); 1.162 + let submissionURL = 1.163 + engine.getSubmission(data.searchString, "", data.whence).uri.spec; 1.164 + let listener = { 1.165 + onStateChange: function (webProg, req, flags, status) { 1.166 + let url = req.originalURI.spec; 1.167 + info("onStateChange " + url); 1.168 + let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT | 1.169 + Ci.nsIWebProgressListener.STATE_START; 1.170 + if ((flags & docStart) && webProg.isTopLevel && url == submissionURL) { 1.171 + gBrowser.removeProgressListener(listener); 1.172 + ok(true, "Search URL loaded"); 1.173 + req.cancel(Components.results.NS_ERROR_FAILURE); 1.174 + nextStep(); 1.175 + } 1.176 + } 1.177 + }; 1.178 + gBrowser.addProgressListener(listener); 1.179 + info("Waiting for search URL to load: " + submissionURL); 1.180 + yield null; 1.181 +}); 1.182 + 1.183 +function checkMsg(actualMsg, expectedMsgData) { 1.184 + SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message"); 1.185 +} 1.186 + 1.187 +function waitForMsg(name, type, callback) { 1.188 + info("Waiting for " + name + " message " + type + "..."); 1.189 + gMsgMan.addMessageListener(name, function onMsg(msg) { 1.190 + info("Received " + name + " message " + msg.data.type + "\n"); 1.191 + if (msg.data.type == type) { 1.192 + gMsgMan.removeMessageListener(name, onMsg); 1.193 + (callback || nextStep)(msg); 1.194 + } 1.195 + }); 1.196 +} 1.197 + 1.198 +function waitForTestMsg(type, callback) { 1.199 + waitForMsg(TEST_MSG, type, callback); 1.200 +} 1.201 + 1.202 +function addTab(onLoad) { 1.203 + let tab = gBrowser.addTab(); 1.204 + gBrowser.selectedTab = tab; 1.205 + tab.linkedBrowser.addEventListener("load", function load() { 1.206 + tab.removeEventListener("load", load, true); 1.207 + let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME; 1.208 + gMsgMan = tab.linkedBrowser.messageManager; 1.209 + gMsgMan.sendAsyncMessage(CONTENT_SEARCH_MSG, { 1.210 + type: "AddToWhitelist", 1.211 + data: ["about:blank"], 1.212 + }); 1.213 + waitForMsg(CONTENT_SEARCH_MSG, "AddToWhitelistAck", () => { 1.214 + gMsgMan.loadFrameScript(url, false); 1.215 + onLoad(); 1.216 + }); 1.217 + }, true); 1.218 + registerCleanupFunction(() => gBrowser.removeTab(tab)); 1.219 +} 1.220 + 1.221 +function currentStateObj() { 1.222 + return { 1.223 + engines: Services.search.getVisibleEngines().map(engine => { 1.224 + return { 1.225 + name: engine.name, 1.226 + iconURI: engine.getIconURLBySize(16, 16), 1.227 + }; 1.228 + }), 1.229 + currentEngine: currentEngineObj(), 1.230 + }; 1.231 +} 1.232 + 1.233 +function currentEngineObj(expectedCurrentEngine) { 1.234 + if (expectedCurrentEngine) { 1.235 + is(Services.search.currentEngine.name, expectedCurrentEngine.name, 1.236 + "Sanity check: expected current engine"); 1.237 + } 1.238 + return { 1.239 + name: Services.search.currentEngine.name, 1.240 + logoURI: Services.search.currentEngine.getIconURLBySize(65, 26), 1.241 + logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52), 1.242 + }; 1.243 +}