|
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 const TEST_MSG = "ContentSearchTest"; |
|
6 const CONTENT_SEARCH_MSG = "ContentSearch"; |
|
7 const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js"; |
|
8 |
|
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 } |
|
25 |
|
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 } |
|
38 |
|
39 function addTest(testGen) { |
|
40 gTests.push(testGen); |
|
41 } |
|
42 |
|
43 var gTests = []; |
|
44 var gMsgMan; |
|
45 |
|
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 }); |
|
56 |
|
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 }); |
|
96 |
|
97 Services.search.currentEngine = oldCurrentEngine; |
|
98 let msg = yield waitForTestMsg("CurrentEngine"); |
|
99 checkMsg(msg, { |
|
100 type: "CurrentEngine", |
|
101 data: currentEngineObj(oldCurrentEngine), |
|
102 }); |
|
103 }); |
|
104 |
|
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 }); |
|
130 |
|
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 }); |
|
147 |
|
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 }); |
|
179 |
|
180 function checkMsg(actualMsg, expectedMsgData) { |
|
181 SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message"); |
|
182 } |
|
183 |
|
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 } |
|
194 |
|
195 function waitForTestMsg(type, callback) { |
|
196 waitForMsg(TEST_MSG, type, callback); |
|
197 } |
|
198 |
|
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 } |
|
217 |
|
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 } |
|
229 |
|
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 } |