Roll leveldb 3f7758:803d69 (v1.17 -> v1.18)
[chromium-blink-merge.git] / chrome / test / data / extensions / hangout_services_test.js
blobb7c9dc97ad8b1c170d6582ad3c89222a32922244
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // JavaScript for invoking methods on APIs used by Hangouts via the
6 // Hangout Services extension, and a JavaScript-based end-to-end test
7 // of the extension.
9 // ID of the Hangout Services component extension.
10 var EXTENSION_ID = "nkeimhogjdpnpccoofpliimaahmaaome";
12 // Sends a message to the Hangout Services extension, expecting
13 // success, and unwraps the value returned.
14 function sendMessage(message, callback) {
15   function unwrapValue(result) {
16     if (callback)
17       callback(result.value);
18   }
19   window.top.chrome.runtime.sendMessage(EXTENSION_ID, message, unwrapValue);
22 // If connected, this port will receive events from the extension.
23 var callbackPort;
25 // Connects callbackPort to the extension, with a connectInfo.name that
26 // indicates we want to receive the onSinksChanged event, and sets its
27 // onMessage to |callback|.
28 function listenForSinksChangedEvent(callback) {
29   callbackPort = window.top.chrome.runtime.connect(
30       EXTENSION_ID, {'name': 'onSinksChangedListener'});
31   callbackPort.onMessage.addListener(callback);
35 // Helpers to invoke functions on the extension.
38 // Will call |callback({'cancelId': ..., 'streamId': ...})| on completion.
39 function chooseDesktopMedia(callback) {
40   sendMessage({'method': 'chooseDesktopMedia'}, callback);
43 // Will call |callback()| when API method has been called (it will
44 // complete later).
45 function cancelChooseDesktopMedia(cancelId, callback) {
46   sendMessage({'method': 'cancelChooseDesktopMedia', 'cancelId': cancelId},
47               callback);
50 // Will call |callback(cpuInfo)| on completion.
51 function cpuGetInfo(callback) {
52   sendMessage({'method': 'cpu.getInfo'}, callback);
55 // Will call |callback()| on completion.
56 function loggingSetMetadata(metaData, callback) {
57   sendMessage({'method': 'logging.setMetadata', 'metaData': metaData},
58               callback);
61 // Will call |callback()| on completion.
62 function loggingStart(callback) {
63   sendMessage({'method': 'logging.start'}, callback);
66 // Will call |callback()| when API method has been called (it will
67 // complete later).
68 function loggingUploadOnRenderClose() {
69   sendMessage({'method': 'logging.uploadOnRenderClose'});
72 // Will call |callback()| when API method has been called (it will
73 // complete later).
74 function loggingNoUploadOnRenderClose() {
75   sendMessage({'method': 'logging.noUploadOnRenderClose'});
78 // Will call |callback()| on completion.
79 function loggingStop(callback) {
80   sendMessage({'method': 'logging.stop'}, callback);
83 // Will call |callback(uploadResult)| on completion.
84 function loggingUpload(callback) {
85   sendMessage({'method': 'logging.upload'}, callback);
88 // Will call |callback(uploadResult)| on completion.
89 function loggingStopAndUpload(callback) {
90   sendMessage({'method': 'logging.stopAndUpload'}, callback);
93 // Will call |callback()| on completion.
94 function loggingDiscard(callback) {
95   sendMessage({'method': 'logging.discard'}, callback);
98 // Will call |callback(sinkList)| on completion.
99 function getSinks(callback) {
100   sendMessage({'method': 'getSinks'}, callback);
103 // Will call |callback(activeSink)| on completion.
104 function getActiveSink(callback) {
105   sendMessage({'method': 'getActiveSink'}, callback);
108 // Will call |callback()| on completion.
109 function setActiveSink(sinkId, callback) {
110   sendMessage({'method': 'setActiveSink', 'sinkId': sinkId}, callback);
113 // Will call |callback(sinkId)| on completion.
114 function getAssociatedSink(sourceId, callback) {
115   sendMessage({'method': 'getAssociatedSink', 'sourceId': sourceId},
116               callback);
119 // Will call |callback()| on completion. If the extension you send to
120 // is not loaded, the extension system will still call |callback()|
121 // but will set lastError.
122 function isExtensionEnabled(callback) {
123   sendMessage({'method': 'isExtensionEnabled'}, callback);
127 // Automated tests.
130 // Very micro test framework. Add all tests to |TESTS|. Each test must
131 // call the passed-in callback eventually with a string indicating
132 // results. Empty results indicate success.
133 var TESTS = [
134   testCpuGetInfo,
135   testLogging,
136   testLoggingSetMetaDataAfterStart,
137   testDisabledLogging,
138   testDisabledLoggingButUpload,
139   testDisabledLoggingWithStopAndUpload,
140   testEnabledLoggingButDiscard,
141   testGetSinks,
142   testGetActiveSink,
143   testSetActiveSink,
144   testGetAssociatedSink,
145   testIsExtensionEnabled,
146   testSendingToInvalidExtension,
148   // Uncomment to manually test timeout logic.
149   //testTimeout,
152 var TEST_TIMEOUT_MS = 3000;
154 function runAllTests(callback) {
155   var results = '';
157   // Run one test at a time, running the next only on completion.
158   // This makes it easier to deal with timing out tests that do not
159   // complete successfully.
160   //
161   // It also seems necessary (instead of starting all the tests in
162   // parallel) as the webrtcLoggingPrivate API does not seem to like
163   // certain sequences of interleaved requests (it may DCHECK in
164   // WebRtcLoggingHandlerHost::NotifyLoggingStarted() when firing the
165   // start callback.
166   //
167   // TODO(grunell): Fix webrtcLoggingPrivate to be stateless.
169   // Index of the test currently executing.
170   var testIndex = 0;
172   function startTest(test) {
173     console.log('Starting ' + test.name);
175     // Start the test function...
176     test(function(currentResults) {
177         nextTest(test.name, currentResults, false);
178       });
180     // ...and also start a timeout.
181     function onTimeout() {
182       nextTest(test.name, '', true);
183     }
184     setTimeout(onTimeout, TEST_TIMEOUT_MS);
185   }
187   function nextTest(testName, currentResults, timedOut) {
188     // The check for testIndex is necessary for timeouts arriving
189     // after testIndex is already past the end of the TESTS array.
190     if (testIndex >= TESTS.length ||
191         testName != TESTS[testIndex].name) {
192       // Either a timeout of a function that already completed, or a
193       // function completing after a timeout. Either way we ignore.
194       console.log('Ignoring results for ' + testName +
195                   ' (timedout: ' + timedOut + ')');
196       return;
197     }
199     if (timedOut) {
200       console.log('Timed out: ' + testName);
201       results = results + 'Timed out: ' + testName + '\n';
202     } else {
203       console.log('Got results for ' + testName + ': ' + currentResults);
204       if (currentResults != '') {
205         results = results + 'Failure in ' + testName + ':\n';
206         results = results + currentResults;
207       }
208     }
210     ++testIndex;
211     if (testIndex == TESTS.length)
212       callback(results);
213     else
214       startTest(TESTS[testIndex]);
215   }
217   startTest(TESTS[testIndex]);
220 function testCpuGetInfo(callback) {
221   cpuGetInfo(function(info) {
222       if (info.numOfProcessors != 0 &&
223           info.archName != '' &&
224           info.modelName != '')
225         callback('');
226       else
227         callback('Missing information in CpuInfo');
228     });
231 // Tests setting metadata, turning on upload, starting and then
232 // stopping the log.
233 function testLogging(callback) {
234   loggingSetMetadata([{'bingo': 'bongo', 'smurf': 'geburf'}], function() {
235       loggingStart(function() {
236           loggingUploadOnRenderClose();
237           loggingStop(function() {
238               callback('');
239             });
240         });
241     });
244 // Tests starting the log, setting metadata, turning on upload, and then
245 // stopping the log.
246 function testLoggingSetMetaDataAfterStart(callback) {
247   loggingStart(function() {
248       loggingSetMetadata([{'bingo': 'bongo', 'smurf': 'geburf'}], function() {
249           loggingUploadOnRenderClose();
250           loggingStop(function() {
251               callback('');
252             });
253         });
254     });
257 // Starts and stops logging while auto-upload is disabled.
258 function testDisabledLogging(callback) {
259   loggingNoUploadOnRenderClose();
260   loggingStart(function() {
261       loggingStop(function() {
262           callback('');
263         });
264     });
267 // Starts and stops logging while auto-upload is disabled, but
268 // requests logs upload after stopping logging.
269 function testDisabledLoggingButUpload(callback) {
270   loggingNoUploadOnRenderClose();
271   loggingStart(function() {
272       loggingStop(function() {
273           loggingUpload(function(loggingResult) {
274               if (loggingResult != '')
275                 callback('');
276               else
277                 callback('Got empty upload result.');
278             });
279         });
280     });
283 // Starts logging while auto-upload is disabled. Uses the
284 // stopAndUpload function to stop, then upload, the results.
285 function testDisabledLoggingWithStopAndUpload(callback) {
286   loggingNoUploadOnRenderClose();
287   loggingStart(function() {
288       loggingStopAndUpload(function(loggingResult) {
289           if (loggingResult != '')
290             callback('');
291           else
292             callback('Got empty upload result.');
293       });
294   });
297 // Starts and stops logging while auto-upload is enabled, but
298 // requests logs be discarded after stopping logging.
299 function testEnabledLoggingButDiscard(callback) {
300   loggingUploadOnRenderClose();
301   loggingStart(function() {
302       loggingStop(function() {
303           loggingDiscard(function() {
304               callback('');
305             });
306         });
307     });
310 function testGetSinks(callback) {
311   getSinks(function(sinks) {
312       // Some bots may have no audio sinks installed, in which case we
313       // will get an empty list here.
314       callback('');
315     });
318 function testGetActiveSink(callback) {
319   getActiveSink(function(sinkId) {
320       if (sinkId == '')
321         callback('Got empty sink ID.');
322       else
323         callback('');
324     });
327 function testSetActiveSink(callback) {
328   getSinks(function(sinks) {
329       for (var i = 0; i < sinks.length; ++i) {
330         setActiveSink(sinks[i].sinkId);
331       }
332       callback('');
333     });
336 function testGetAssociatedSink(callback) {
337   getAssociatedSink('noSuchSourceId', function(sinkId) {
338       if (sinkId != '') {
339         callback('Got non-empty sink ID for nonexistent source ID.');
340       } else {
341         callback('');
342       }
343     });
346 function testIsExtensionEnabled(callback) {
347   isExtensionEnabled(function() {
348       callback('');
349     });
352 function testSendingToInvalidExtension(callback) {
353   // This test verifies that client code can always determine whether
354   // or not the component extension is available without resorting to
355   // timeouts, by sending it the 'isExtensionEnabled' message. If the
356   // extension is there, it will respond (see testIsExtensionEnabled)
357   // and if it's not, the extension framework will send a callback and
358   // set lastError.
359   var NON_EXISTENT_EXTENSION_ID = "aaaaaaagjdpnpccoofpliimaaeeeeeee";
360   window.top.chrome.runtime.sendMessage(
361       NON_EXISTENT_EXTENSION_ID, {'method': 'isExtensionEnabled'},
362       function() {
363           if (window.top.chrome.runtime.lastError.message.indexOf(
364                   'Could not establish connection') == -1) {
365             callback('lastError is not set correctly.');
366           } else {
367             callback('');
368           }
369         });
372 function testTimeout(callback) {
373   // Never call the callback. Used for manually testing that the
374   // timeout logic of the test framework is correct.