Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
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 const TEST_MSG = "ContentSearchTest";
6 const CONTENT_SEARCH_MSG = "ContentSearch";
7 const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js";
9 function generatorTest() {
10 // nextStep() drives the iterator returned by this function. This function's
11 // iterator in turn drives the iterator of each test below.
12 let currentTestIter = yield startNextTest();
13 let arg = undefined;
14 while (currentTestIter) {
15 try {
16 currentTestIter.send(arg);
17 arg = yield null;
18 }
19 catch (err if err instanceof StopIteration) {
20 currentTestIter = yield startNextTest();
21 arg = undefined;
22 }
23 }
24 }
26 function startNextTest() {
27 if (!gTests.length) {
28 setTimeout(() => nextStep(null), 0);
29 return;
30 }
31 let nextTestGen = gTests.shift();
32 let nextTestIter = nextTestGen();
33 addTab(() => {
34 info("Starting test " + nextTestGen.name);
35 nextStep(nextTestIter);
36 });
37 }
39 function addTest(testGen) {
40 gTests.push(testGen);
41 }
43 var gTests = [];
44 var gMsgMan;
46 addTest(function GetState() {
47 gMsgMan.sendAsyncMessage(TEST_MSG, {
48 type: "GetState",
49 });
50 let msg = yield waitForTestMsg("State");
51 checkMsg(msg, {
52 type: "State",
53 data: currentStateObj(),
54 });
55 });
57 addTest(function SetCurrentEngine() {
58 let newCurrentEngine = null;
59 let oldCurrentEngine = Services.search.currentEngine;
60 let engines = Services.search.getVisibleEngines();
61 for (let engine of engines) {
62 if (engine != oldCurrentEngine) {
63 newCurrentEngine = engine;
64 break;
65 }
66 }
67 if (!newCurrentEngine) {
68 info("Couldn't find a non-selected search engine, " +
69 "skipping this part of the test");
70 return;
71 }
72 gMsgMan.sendAsyncMessage(TEST_MSG, {
73 type: "SetCurrentEngine",
74 data: newCurrentEngine.name,
75 });
76 Services.obs.addObserver(function obs(subj, topic, data) {
77 info("Test observed " + data);
78 if (data == "engine-current") {
79 ok(true, "Test observed engine-current");
80 Services.obs.removeObserver(obs, "browser-search-engine-modified", false);
81 nextStep();
82 }
83 }, "browser-search-engine-modified", false);
84 info("Waiting for test to observe engine-current...");
85 waitForTestMsg("CurrentEngine");
86 let maybeMsg1 = yield null;
87 let maybeMsg2 = yield null;
88 let msg = maybeMsg1 || maybeMsg2;
89 ok(!!msg,
90 "Sanity check: One of the yields is for waitForTestMsg and should have " +
91 "therefore produced a message object");
92 checkMsg(msg, {
93 type: "CurrentEngine",
94 data: currentEngineObj(newCurrentEngine),
95 });
97 Services.search.currentEngine = oldCurrentEngine;
98 let msg = yield waitForTestMsg("CurrentEngine");
99 checkMsg(msg, {
100 type: "CurrentEngine",
101 data: currentEngineObj(oldCurrentEngine),
102 });
103 });
105 addTest(function ManageEngines() {
106 gMsgMan.sendAsyncMessage(TEST_MSG, {
107 type: "ManageEngines",
108 });
109 let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
110 getService(Ci.nsIWindowWatcher);
111 winWatcher.registerNotification(function onOpen(subj, topic, data) {
112 if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
113 subj.addEventListener("load", function onLoad() {
114 subj.removeEventListener("load", onLoad);
115 if (subj.document.documentURI ==
116 "chrome://browser/content/search/engineManager.xul") {
117 winWatcher.unregisterNotification(onOpen);
118 ok(true, "Observed search manager window open");
119 is(subj.opener, window,
120 "Search engine manager opener should be this chrome window");
121 subj.close();
122 nextStep();
123 }
124 });
125 }
126 });
127 info("Waiting for search engine manager window to open...");
128 yield null;
129 });
131 addTest(function modifyEngine() {
132 let engine = Services.search.currentEngine;
133 let oldAlias = engine.alias;
134 engine.alias = "ContentSearchTest";
135 let msg = yield waitForTestMsg("State");
136 checkMsg(msg, {
137 type: "State",
138 data: currentStateObj(),
139 });
140 engine.alias = oldAlias;
141 msg = yield waitForTestMsg("State");
142 checkMsg(msg, {
143 type: "State",
144 data: currentStateObj(),
145 });
146 });
148 addTest(function search() {
149 let engine = Services.search.currentEngine;
150 let data = {
151 engineName: engine.name,
152 searchString: "ContentSearchTest",
153 whence: "ContentSearchTest",
154 };
155 gMsgMan.sendAsyncMessage(TEST_MSG, {
156 type: "Search",
157 data: data,
158 });
159 let submissionURL =
160 engine.getSubmission(data.searchString, "", data.whence).uri.spec;
161 let listener = {
162 onStateChange: function (webProg, req, flags, status) {
163 let url = req.originalURI.spec;
164 info("onStateChange " + url);
165 let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
166 Ci.nsIWebProgressListener.STATE_START;
167 if ((flags & docStart) && webProg.isTopLevel && url == submissionURL) {
168 gBrowser.removeProgressListener(listener);
169 ok(true, "Search URL loaded");
170 req.cancel(Components.results.NS_ERROR_FAILURE);
171 nextStep();
172 }
173 }
174 };
175 gBrowser.addProgressListener(listener);
176 info("Waiting for search URL to load: " + submissionURL);
177 yield null;
178 });
180 function checkMsg(actualMsg, expectedMsgData) {
181 SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message");
182 }
184 function waitForMsg(name, type, callback) {
185 info("Waiting for " + name + " message " + type + "...");
186 gMsgMan.addMessageListener(name, function onMsg(msg) {
187 info("Received " + name + " message " + msg.data.type + "\n");
188 if (msg.data.type == type) {
189 gMsgMan.removeMessageListener(name, onMsg);
190 (callback || nextStep)(msg);
191 }
192 });
193 }
195 function waitForTestMsg(type, callback) {
196 waitForMsg(TEST_MSG, type, callback);
197 }
199 function addTab(onLoad) {
200 let tab = gBrowser.addTab();
201 gBrowser.selectedTab = tab;
202 tab.linkedBrowser.addEventListener("load", function load() {
203 tab.removeEventListener("load", load, true);
204 let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
205 gMsgMan = tab.linkedBrowser.messageManager;
206 gMsgMan.sendAsyncMessage(CONTENT_SEARCH_MSG, {
207 type: "AddToWhitelist",
208 data: ["about:blank"],
209 });
210 waitForMsg(CONTENT_SEARCH_MSG, "AddToWhitelistAck", () => {
211 gMsgMan.loadFrameScript(url, false);
212 onLoad();
213 });
214 }, true);
215 registerCleanupFunction(() => gBrowser.removeTab(tab));
216 }
218 function currentStateObj() {
219 return {
220 engines: Services.search.getVisibleEngines().map(engine => {
221 return {
222 name: engine.name,
223 iconURI: engine.getIconURLBySize(16, 16),
224 };
225 }),
226 currentEngine: currentEngineObj(),
227 };
228 }
230 function currentEngineObj(expectedCurrentEngine) {
231 if (expectedCurrentEngine) {
232 is(Services.search.currentEngine.name, expectedCurrentEngine.name,
233 "Sanity check: expected current engine");
234 }
235 return {
236 name: Services.search.currentEngine.name,
237 logoURI: Services.search.currentEngine.getIconURLBySize(65, 26),
238 logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52),
239 };
240 }