1 // Copyright (c) 2012 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 // Helper function to log message to both the local console and to the
6 // background page, so that the latter can output the message via the
7 // chrome.test.log() function.
8 function logToConsoleAndStdout(msg) {
10 chrome.extension.sendRequest("log: " + msg);
13 // We ask the background page to get the extension API to test against. When it
14 // responds we start the test.
15 console.log("asking for api ...");
16 chrome.extension.sendRequest("getApi", function(apis) {
17 var apiFeatures = chrome.test.getApiFeatures();
18 function isAvailableToContentScripts(namespace, path) {
19 function checkContexts(contextList) {
20 return contextList == 'all' ||
21 contextList.indexOf('content_script') != -1;
23 function checkFeature(feature) {
24 if (feature.contexts) {
26 return checkContexts(feature.contexts);
29 for (var i = 0; i < feature.length; i++) {
30 if (checkContexts(feature[i].contexts))
37 if (apiFeatures.hasOwnProperty(path))
38 return checkFeature(apiFeatures[path]);
39 return apiFeatures.hasOwnProperty(namespace) &&
40 checkFeature(apiFeatures[namespace]);
43 console.log("got api response");
44 var privilegedPaths = [];
45 var unprivilegedPaths = [];
46 apis.forEach(function(module) {
47 var namespace = module.namespace;
49 ["functions", "events"].forEach(function(section) {
50 if (typeof(module[section]) == "undefined")
52 module[section].forEach(function(entry) {
53 // Ignore entries that are not applicable to the manifest that we're
55 if (entry.maximumManifestVersion && entry.maximumManifestVersion < 2) {
59 var path = namespace + "." + entry.name;
60 if (module.unprivileged || entry.unprivileged ||
61 isAvailableToContentScripts(namespace, path)) {
62 unprivilegedPaths.push(path);
64 privilegedPaths.push(path);
69 if (module.properties) {
70 for (var propName in module.properties) {
71 var path = namespace + "." + propName;
72 if (module.unprivileged || module.properties[propName].unprivileged ||
73 isAvailableToContentScripts(namespace, path)) {
74 unprivilegedPaths.push(path);
76 privilegedPaths.push(path);
81 doTest(privilegedPaths, unprivilegedPaths);
85 // Tests whether missing properties of the chrome object correctly throw an
86 // error on access. The path is a namespace or function/property/event etc.
87 // within a namespace, and is dot-separated.
88 function testPath(path, expectError) {
89 var parts = path.split('.');
92 for (var i = 0; i < parts.length; i++) {
93 if (i < parts.length - 1) {
94 // Not the last component. Allowed to be undefined because some paths are
95 // only defined on some platforms.
96 module = module[parts[i]];
97 if (typeof(module) == "undefined")
100 // This is the last component - we expect it to either be undefined or
101 // to throw an error on access.
102 if (typeof(module[parts[i]]) == "undefined" &&
103 // lastError being defined depends on there being an error obviously.
104 path != "extension.lastError" &&
105 path != "runtime.lastError") {
109 logToConsoleAndStdout(" fail (should not be undefined): " + path);
112 } else if (!expectError) {
117 logToConsoleAndStdout(" fail (no error when we were expecting one): " + path);
121 function displayResult(status) {
122 var div = document.createElement("div");
123 div.innerHTML = "<h1>" + status + "</h2>";
124 document.body.appendChild(div);
127 function reportSuccess() {
128 displayResult("pass");
129 chrome.extension.sendRequest("pass");
132 function reportFailure() {
133 displayResult("fail");
134 // Let the "fail" show for a little while so you can see it when running
135 // browser_tests in the debugger.
136 setTimeout(function() {
137 chrome.extension.sendRequest("fail");
141 // Runs over each string path in privilegedPaths and unprivilegedPaths, testing
142 // to ensure a proper error is thrown on access or the path is defined.
143 function doTest(privilegedPaths, unprivilegedPaths) {
144 console.log("starting");
146 if (!privilegedPaths || privilegedPaths.length < 1 || !unprivilegedPaths ||
147 unprivilegedPaths.length < 1) {
155 // Returns a function that will test a path and record any failures.
156 function makeTestFunction(expectError) {
157 return function(path) {
158 // runtime.connect and runtime.sendMessage are available in all contexts,
159 // unlike the runtime API in general.
160 var expectErrorForPath = expectError &&
161 path != 'runtime.connect' &&
162 path != 'runtime.sendMessage';
163 if (!testPath(path, expectErrorForPath)) {
169 privilegedPaths.forEach(makeTestFunction(true));
170 unprivilegedPaths.forEach(makeTestFunction(false));
172 console.log(success ? "pass" : "fail");
176 logToConsoleAndStdout("failures on:\n" + failures.join("\n") +
177 "\n\n\n>>> See comment in stubs_apitest.cc for a " +
178 "hint about fixing this failure.\n\n");