Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / test / data / extensions / api_test / messaging / externally_connectable / sites / assertions.js
blobb6fb3151db8870a1a4aa43d77870c2bcfbcb597b
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.
5 (function() {
7 // We are going to kill all of the builtins, so hold onto the ones we need.
8 var defineGetter = Object.prototype.__defineGetter__;
9 var defineSetter = Object.prototype.__defineSetter__;
10 var Error = window.Error;
11 var forEach = Array.prototype.forEach;
12 var push = Array.prototype.push;
13 var hasOwnProperty = Object.prototype.hasOwnProperty;
14 var getOwnPropertyNames = Object.getOwnPropertyNames;
15 var stringify = JSON.stringify;
17 // Kill all of the builtins functions to give us a fairly high confidence that
18 // the environment our bindings run in can't interfere with our code.
19 // These are taken from the ECMAScript spec.
20 var builtinTypes = [
21 Object, Function, Array, String, Boolean, Number, Math, Date, RegExp, JSON,
24 function clobber(obj, name, qualifiedName) {
25 // Clobbering constructors would break everything.
26 // Clobbering toString is annoying.
27 // Clobbering __proto__ breaks in ways that grep can't find.
28 // Clobbering function name will break because
29 // SafeBuiltins does not support getters yet. See crbug.com/463526.
30 // Clobbering Function.call would make it impossible to implement these tests.
31 // Clobbering Object.valueOf breaks v8.
32 // Clobbering %FunctionPrototype%.caller and .arguments will break because
33 // these properties are poisoned accessors in ES6.
34 if (name == 'constructor' ||
35 name == 'toString' ||
36 name == '__proto__' ||
37 name == 'name' && typeof obj == 'function' ||
38 qualifiedName == 'Function.call' ||
39 (obj !== Function && qualifiedName == 'Function.caller') ||
40 (obj !== Function && qualifiedName == 'Function.arguments') ||
41 qualifiedName == 'Object.valueOf') {
42 return;
44 if (typeof obj[name] == 'function') {
45 obj[name] = function() {
46 throw new Error('Clobbered ' + qualifiedName + ' function');
48 } else {
49 defineGetter.call(obj, name, function() {
50 throw new Error('Clobbered ' + qualifiedName + ' getter');
51 });
55 forEach.call(builtinTypes, function(builtin) {
56 var prototype = builtin.prototype;
57 var typename = '<unknown>';
58 if (prototype) {
59 typename = prototype.constructor.name;
60 forEach.call(getOwnPropertyNames(prototype), function(name) {
61 clobber(prototype, name, typename + '.' + name);
62 });
64 forEach.call(getOwnPropertyNames(builtin), function(name) {
65 clobber(builtin, name, typename + '.' + name);
66 });
67 if (builtin.name)
68 clobber(window, builtin.name, 'window.' + builtin.name);
69 });
71 // Codes for test results. Must match ExternallyConnectableMessagingTest::Result
72 // in c/b/extensions/extension_messages_apitest.cc.
73 var results = {
74 OK: 0,
75 NAMESPACE_NOT_DEFINED: 1,
76 FUNCTION_NOT_DEFINED: 2,
77 COULD_NOT_ESTABLISH_CONNECTION_ERROR: 3,
78 OTHER_ERROR: 4,
79 INCORRECT_RESPONSE_SENDER: 5,
80 INCORRECT_RESPONSE_MESSAGE: 6,
83 // Make the messages sent vaguely complex, but unambiguously JSON-ifiable.
84 var kMessage = [{'a': {'b': 10}}, 20, 'c\x10\x11'];
86 // Our tab's location. Normally this would be our document's location but if
87 // we're an iframe it will be the location of the parent - in which case,
88 // expect to be told.
89 var tabLocationHref = null;
91 if (parent == window) {
92 tabLocationHref = document.location.href;
93 } else {
94 window.addEventListener('message', function listener(event) {
95 window.removeEventListener('message', listener);
96 tabLocationHref = event.data;
97 });
100 function checkLastError(reply) {
101 if (!chrome.runtime.lastError)
102 return true;
103 var kCouldNotEstablishConnection =
104 'Could not establish connection. Receiving end does not exist.';
105 if (chrome.runtime.lastError.message == kCouldNotEstablishConnection)
106 reply(results.COULD_NOT_ESTABLISH_CONNECTION_ERROR);
107 else
108 reply(results.OTHER_ERROR);
109 return false;
112 function checkResponse(response, reply, expectedMessage, isApp) {
113 // The response will be an echo of both the original message *and* the
114 // MessageSender (with the tab field stripped down).
116 // First check the sender was correct.
117 var incorrectSender = false;
118 if (!isApp) {
119 // Only extensions get access to a 'tab' property.
120 if (!hasOwnProperty.call(response.sender, 'tab')) {
121 console.warn('Expected a tab, got none');
122 incorrectSender = true;
124 if (response.sender.tab.url != tabLocationHref) {
125 console.warn('Expected tab url ' + tabLocationHref + ' got ' +
126 response.sender.tab.url);
127 incorrectSender = true;
130 if (hasOwnProperty.call(response.sender, 'id')) {
131 console.warn('Expected no id, got "' + response.sender.id + '"');
132 incorrectSender = true;
134 if (response.sender.url != document.location.href) {
135 console.warn('Expected url ' + document.location.href + ' got ' +
136 response.sender.url);
137 incorrectSender = true;
139 if (incorrectSender) {
140 reply(results.INCORRECT_RESPONSE_SENDER);
141 return false;
144 // Check the correct content was echoed.
145 var expectedJson = stringify(expectedMessage);
146 var actualJson = stringify(response.message);
147 if (actualJson == expectedJson)
148 return true;
149 console.warn('Expected message ' + expectedJson + ' got ' + actualJson);
150 reply(results.INCORRECT_RESPONSE_MESSAGE);
151 return false;
154 function sendToBrowser(msg) {
155 domAutomationController.send(msg);
158 function sendToBrowserForTlsChannelId(result) {
159 // Because the TLS channel ID tests read the TLS either an error code or the
160 // TLS channel ID string from the same value, they require the result code
161 // to be sent as a string.
162 // String() is clobbered, so coerce string creation with +.
163 sendToBrowser("" + result);
166 function checkRuntime(reply) {
167 if (!reply)
168 reply = sendToBrowser;
170 if (!chrome.runtime) {
171 reply(results.NAMESPACE_NOT_DEFINED);
172 return false;
175 if (!chrome.runtime.connect || !chrome.runtime.sendMessage) {
176 reply(results.FUNCTION_NOT_DEFINED);
177 return false;
179 return true;
182 function checkRuntimeForTlsChannelId() {
183 return checkRuntime(sendToBrowserForTlsChannelId);
186 function checkTlsChannelIdResponse(response) {
187 if (chrome.runtime.lastError) {
188 if (chrome.runtime.lastError.message == kCouldNotEstablishConnection)
189 sendToBrowserForTlsChannelId(
190 results.COULD_NOT_ESTABLISH_CONNECTION_ERROR);
191 else
192 sendToBrowserForTlsChannelId(results.OTHER_ERROR);
193 return;
195 if (response.sender.tlsChannelId !== undefined)
196 sendToBrowserForTlsChannelId(response.sender.tlsChannelId);
197 else
198 sendToBrowserForTlsChannelId('');
201 window.actions = {
202 appendIframe: function(src) {
203 var iframe = document.createElement('iframe');
204 // When iframe has loaded, notify it of our tab location (probably
205 // document.location) to use in its assertions, then continue.
206 iframe.addEventListener('load', function listener() {
207 iframe.removeEventListener('load', listener);
208 iframe.contentWindow.postMessage(tabLocationHref, '*');
209 sendToBrowser(true);
211 iframe.src = src;
212 document.body.appendChild(iframe);
216 window.assertions = {
217 canConnectAndSendMessages: function(extensionId, isApp, message) {
218 if (!checkRuntime())
219 return;
221 if (!message)
222 message = kMessage;
224 function canSendMessage(reply) {
225 chrome.runtime.sendMessage(extensionId, message, function(response) {
226 if (checkLastError(reply) &&
227 checkResponse(response, reply, message, isApp)) {
228 reply(results.OK);
233 function canConnectAndSendMessages(reply) {
234 var port = chrome.runtime.connect(extensionId);
235 port.postMessage(message, function() {
236 checkLastError(reply);
238 port.postMessage(message, function() {
239 checkLastError(reply);
241 var pendingResponses = 2;
242 var ok = true;
243 port.onMessage.addListener(function(response) {
244 pendingResponses--;
245 ok = ok && checkLastError(reply) &&
246 checkResponse(response, reply, message, isApp);
247 if (pendingResponses == 0 && ok)
248 reply(results.OK);
252 canSendMessage(function(result) {
253 if (result != results.OK)
254 sendToBrowser(result);
255 else
256 canConnectAndSendMessages(sendToBrowser);
260 trySendMessage: function(extensionId) {
261 chrome.runtime.sendMessage(extensionId, kMessage, function(response) {
262 // The result is unimportant. All that matters is the attempt.
266 tryIllegalArguments: function() {
267 // Tests that illegal arguments to messaging functions throw exceptions.
268 // Regression test for crbug.com/472700, where they crashed the renderer.
269 function runIllegalFunction(fun) {
270 try {
271 fun();
272 } catch(e) {
273 return true;
275 console.error('Function did not throw exception: ' + fun);
276 sendToBrowser(false);
277 return false;
279 var result =
280 runIllegalFunction(chrome.runtime.connect) &&
281 runIllegalFunction(function() {
282 chrome.runtime.connect('');
283 }) &&
284 runIllegalFunction(function() {
285 chrome.runtime.connect(42);
286 }) &&
287 runIllegalFunction(function() {
288 chrome.runtime.connect('', 42);
289 }) &&
290 runIllegalFunction(function() {
291 chrome.runtime.connect({name: 'noname'});
292 }) &&
293 runIllegalFunction(chrome.runtime.sendMessage) &&
294 runIllegalFunction(function() {
295 chrome.runtime.sendMessage('');
296 }) &&
297 runIllegalFunction(function() {
298 chrome.runtime.sendMessage(42);
299 }) &&
300 runIllegalFunction(function() {
301 chrome.runtime.sendMessage('', 42);
302 }) &&
303 sendToBrowser(true);
306 areAnyRuntimePropertiesDefined: function(names) {
307 var result = false;
308 if (chrome.runtime) {
309 forEach.call(names, function(name) {
310 if (chrome.runtime[name]) {
311 console.log('runtime.' + name + ' is defined');
312 result = true;
316 sendToBrowser(result);
319 getTlsChannelIdFromPortConnect: function(extensionId, includeTlsChannelId,
320 message) {
321 if (!checkRuntimeForTlsChannelId())
322 return;
324 if (!message)
325 message = kMessage;
327 var port = chrome.runtime.connect(extensionId,
328 {'includeTlsChannelId': includeTlsChannelId});
329 port.onMessage.addListener(checkTlsChannelIdResponse);
330 port.postMessage(message);
333 getTlsChannelIdFromSendMessage: function(extensionId, includeTlsChannelId,
334 message) {
335 if (!checkRuntimeForTlsChannelId())
336 return;
338 if (!message)
339 message = kMessage;
341 chrome.runtime.sendMessage(extensionId, message,
342 {'includeTlsChannelId': includeTlsChannelId},
343 checkTlsChannelIdResponse);
347 }());