| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 #include "base/file_util.h" | |
| 6 #include "base/json/json_reader.h" | |
| 7 #include "base/json/json_writer.h" | |
| 8 #include "base/path_service.h" | |
| 9 #include "base/string_util.h" | |
| 10 #include "chrome/common/chrome_paths.h" | |
| 11 #include "chrome/common/render_messages.h" | |
| 12 #include "chrome/renderer/extensions/extension_process_bindings.h" | |
| 13 #include "chrome/renderer/extensions/renderer_extension_bindings.h" | |
| 14 #include "chrome/test/render_view_test.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 | |
| 17 // Make failures easier to locate by using SCOPED_TRACE() to print out the line | |
| 18 // number of a failing call to ExtensionAPIClientTest::ExpectJs(Pass|Fail) . | |
| 19 // Sadly, a #define is the only reasonable way to get the line number. | |
| 20 #define ExpectJsFail(js, expected_failure_message) { \ | |
| 21 SCOPED_TRACE(js); \ | |
| 22 ExpectJsFailInternal(js, expected_failure_message); \ | |
| 23 } | |
| 24 | |
| 25 #define ExpectJsPass(js, function, arg1) { \ | |
| 26 SCOPED_TRACE(js); \ | |
| 27 ExpectJsPassInternal(js, function, arg1); \ | |
| 28 } | |
| 29 | |
| 30 class ExtensionAPIClientTest : public RenderViewTest { | |
| 31 protected: | |
| 32 virtual void SetUp() { | |
| 33 RenderViewTest::SetUp(); | |
| 34 | |
| 35 render_thread_.SetExtensionProcess(true); | |
| 36 render_thread_.sink().ClearMessages(); | |
| 37 LoadHTML("<body></body>"); | |
| 38 } | |
| 39 | |
| 40 std::string GetConsoleMessage() { | |
| 41 const IPC::Message* message = | |
| 42 render_thread_.sink().GetUniqueMessageMatching( | |
| 43 ViewHostMsg_AddMessageToConsole::ID); | |
| 44 ViewHostMsg_AddMessageToConsole::Param params; | |
| 45 if (message) { | |
| 46 ViewHostMsg_AddMessageToConsole::Read(message, ¶ms); | |
| 47 render_thread_.sink().ClearMessages(); | |
| 48 return WideToASCII(params.a); | |
| 49 } else { | |
| 50 return ""; | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 // Don't call this directly. Use the macro ExpectJsFail. | |
| 55 void ExpectJsFailInternal(const std::string& js, const std::string& message) { | |
| 56 ExecuteJavaScript(js.c_str()); | |
| 57 EXPECT_EQ(message, GetConsoleMessage()); | |
| 58 render_thread_.sink().ClearMessages(); | |
| 59 } | |
| 60 | |
| 61 // Don't call this directly. Use the macro ExpectJsPass. | |
| 62 void ExpectJsPassInternal(const std::string& js, | |
| 63 const std::string& function, | |
| 64 const std::string& arg1) { | |
| 65 ExecuteJavaScript(js.c_str()); | |
| 66 const IPC::Message* request_msg = | |
| 67 render_thread_.sink().GetUniqueMessageMatching( | |
| 68 ViewHostMsg_ExtensionRequest::ID); | |
| 69 ASSERT_EQ("", GetConsoleMessage()) << js; | |
| 70 ASSERT_TRUE(request_msg) << js; | |
| 71 ViewHostMsg_ExtensionRequest::Param params; | |
| 72 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 73 ASSERT_EQ(function.c_str(), params.a) << js; | |
| 74 | |
| 75 ASSERT_TRUE(params.b.IsType(Value::TYPE_LIST)); | |
| 76 ListValue* args = ¶ms.b; | |
| 77 | |
| 78 base::JSONReader reader; | |
| 79 scoped_ptr<Value> arg1_value(reader.JsonToValue(arg1, false, false)); | |
| 80 ASSERT_TRUE(arg1_value.get()) | |
| 81 << "Failed to parse expected result as JSON: " << arg1; | |
| 82 | |
| 83 std::string args_as_string; | |
| 84 base::JSONWriter::Write(args, false, &args_as_string); | |
| 85 | |
| 86 ASSERT_TRUE(args->Equals(arg1_value.get())) | |
| 87 << js | |
| 88 << "\n Expected "<< arg1 | |
| 89 << "\n Actual: "<< args_as_string; | |
| 90 render_thread_.sink().ClearMessages(); | |
| 91 } | |
| 92 }; | |
| 93 | |
| 94 // Tests that callback dispatching works correctly and that JSON is properly | |
| 95 // deserialized before handing off to the extension code. We use the createTab | |
| 96 // API here, but we could use any of them since they all dispatch callbacks the | |
| 97 // same way. | |
| 98 TEST_F(ExtensionAPIClientTest, CallbackDispatching) { | |
| 99 ExecuteJavaScript( | |
| 100 "function assert(truth, message) {" | |
| 101 " if (!truth) {" | |
| 102 " throw new Error(message);" | |
| 103 " }" | |
| 104 "}" | |
| 105 "function callback(result) {" | |
| 106 " assert(typeof result == 'object', 'result not object');" | |
| 107 " assert(JSON.stringify(result) == '{\"id\":1,\"index\":1,\"windowId\":1," | |
| 108 "\"selected\":true,\"incognito\":false," | |
| 109 "\"url\":\"http://www.google.com/\"}'," | |
| 110 " 'incorrect result');" | |
| 111 " console.log('pass')" | |
| 112 "}" | |
| 113 "chrome.tabs.create({}, callback);" | |
| 114 ); | |
| 115 | |
| 116 EXPECT_EQ("", GetConsoleMessage()); | |
| 117 | |
| 118 // Ok, we should have gotten a message to create a tab, grab the callback ID. | |
| 119 const IPC::Message* request_msg = | |
| 120 render_thread_.sink().GetUniqueMessageMatching( | |
| 121 ViewHostMsg_ExtensionRequest::ID); | |
| 122 ASSERT_TRUE(request_msg); | |
| 123 ViewHostMsg_ExtensionRequest::Param params; | |
| 124 ViewHostMsg_ExtensionRequest::Read(request_msg, ¶ms); | |
| 125 int callback_id = params.d; | |
| 126 ASSERT_GE(callback_id, 0); | |
| 127 | |
| 128 // Now send the callback a response | |
| 129 ExtensionProcessBindings::HandleResponse( | |
| 130 callback_id, true, "{\"id\":1,\"index\":1,\"windowId\":1,\"selected\":true," | |
| 131 "\"incognito\":false,\"url\":\"http://www.google.com/\"}", ""); | |
| 132 | |
| 133 // And verify that it worked | |
| 134 ASSERT_EQ("pass", GetConsoleMessage()); | |
| 135 } | |
| 136 | |
| 137 // The remainder of these tests exercise the client side of the various | |
| 138 // extension functions. We test both error and success conditions, but do not | |
| 139 // test errors exhaustively as json schema code is well tested by itself. | |
| 140 | |
| 141 // Window API tests | |
| 142 | |
| 143 TEST_F(ExtensionAPIClientTest, GetWindow) { | |
| 144 ExpectJsFail("chrome.windows.get(32, function(){}, 20);", | |
| 145 "Uncaught Error: Too many arguments."); | |
| 146 | |
| 147 ExpectJsFail("chrome.windows.get(32);", | |
| 148 "Uncaught Error: Parameter 1 is required."); | |
| 149 | |
| 150 ExpectJsFail("chrome.windows.get('abc', function(){});", | |
| 151 "Uncaught Error: Invalid value for argument 0. " | |
| 152 "Expected 'integer' but got 'string'."); | |
| 153 | |
| 154 ExpectJsFail("chrome.windows.get(1, 1);", | |
| 155 "Uncaught Error: Invalid value for argument 1. " | |
| 156 "Expected 'function' but got 'integer'."); | |
| 157 | |
| 158 ExpectJsPass("chrome.windows.get(2, function(){})", | |
| 159 "windows.get", "[2]"); | |
| 160 } | |
| 161 | |
| 162 // This test flakily crashes (http://crbug.com/22248) | |
| 163 TEST_F(ExtensionAPIClientTest, DISABLED_GetCurrentWindow) { | |
| 164 ExpectJsFail("chrome.windows.getCurrent(function(){}, 20);", | |
| 165 "Uncaught Error: Too many arguments."); | |
| 166 | |
| 167 ExpectJsFail("chrome.windows.getCurrent();", | |
| 168 "Uncaught Error: Parameter 0 is required."); | |
| 169 | |
| 170 ExpectJsFail("chrome.windows.getCurrent('abc');", | |
| 171 "Uncaught Error: Invalid value for argument 0. " | |
| 172 "Expected 'function' but got 'string'."); | |
| 173 | |
| 174 ExpectJsPass("chrome.windows.getCurrent(function(){})", | |
| 175 "windows.getCurrent", "null"); | |
| 176 } | |
| 177 | |
| 178 // This test flakily crashes (http://crbug.com/22248) | |
| 179 TEST_F(ExtensionAPIClientTest, DISABLED_GetLastFocusedWindow) { | |
| 180 ExpectJsFail("chrome.windows.getLastFocused(function(){}, 20);", | |
| 181 "Uncaught Error: Too many arguments."); | |
| 182 | |
| 183 ExpectJsFail("chrome.windows.getLastFocused();", | |
| 184 "Uncaught Error: Parameter 0 is required."); | |
| 185 | |
| 186 ExpectJsFail("chrome.windows.getLastFocused('abc');", | |
| 187 "Uncaught Error: Invalid value for argument 0. " | |
| 188 "Expected 'function' but got 'string'."); | |
| 189 | |
| 190 ExpectJsPass("chrome.windows.getLastFocused(function(){})", | |
| 191 "windows.getLastFocused", "null"); | |
| 192 } | |
| 193 | |
| 194 // This test flakily crashes (http://crbug.com/22248) | |
| 195 TEST_F(ExtensionAPIClientTest, DISABLED_GetAllWindows) { | |
| 196 ExpectJsFail("chrome.windows.getAll({populate: true}, function(){}, 20);", | |
| 197 "Uncaught Error: Too many arguments."); | |
| 198 | |
| 199 ExpectJsFail("chrome.windows.getAll(1, function(){});", | |
| 200 "Uncaught Error: Invalid value for argument 0. " | |
| 201 "Expected 'object' but got 'integer'."); | |
| 202 | |
| 203 ExpectJsPass("chrome.windows.getAll({populate:true}, function(){})", | |
| 204 "windows.getAll", "{\"populate\":true}"); | |
| 205 | |
| 206 ExpectJsPass("chrome.windows.getAll(null, function(){})", | |
| 207 "windows.getAll", "null"); | |
| 208 | |
| 209 ExpectJsPass("chrome.windows.getAll({}, function(){})", | |
| 210 "windows.getAll", "{}"); | |
| 211 | |
| 212 ExpectJsPass("chrome.windows.getAll(undefined, function(){})", | |
| 213 "windows.getAll", "null"); | |
| 214 } | |
| 215 | |
| 216 // Flaky on Windows. http://crosbug.com/46217 | |
| 217 #if defined(OS_WIN) | |
| 218 #define MAYBE_CreateWindow FLAKY_CreateWindow | |
| 219 #else | |
| 220 #define MAYBE_CreateWindow CreateWindow | |
| 221 #endif | |
| 222 TEST_F(ExtensionAPIClientTest, MAYBE_CreateWindow) { | |
| 223 ExpectJsFail("chrome.windows.create({url: 1}, function(){});", | |
| 224 "Uncaught Error: Invalid value for argument 0. Property " | |
| 225 "'url': Expected 'string' but got 'integer'."); | |
| 226 ExpectJsFail("chrome.windows.create({left: 'foo'}, function(){});", | |
| 227 "Uncaught Error: Invalid value for argument 0. Property " | |
| 228 "'left': Expected 'integer' but got 'string'."); | |
| 229 ExpectJsFail("chrome.windows.create({top: 'foo'}, function(){});", | |
| 230 "Uncaught Error: Invalid value for argument 0. Property " | |
| 231 "'top': Expected 'integer' but got 'string'."); | |
| 232 ExpectJsFail("chrome.windows.create({width: 'foo'}, function(){});", | |
| 233 "Uncaught Error: Invalid value for argument 0. Property " | |
| 234 "'width': Expected 'integer' but got 'string'."); | |
| 235 ExpectJsFail("chrome.windows.create({height: 'foo'}, function(){});", | |
| 236 "Uncaught Error: Invalid value for argument 0. Property " | |
| 237 "'height': Expected 'integer' but got 'string'."); | |
| 238 ExpectJsFail("chrome.windows.create({foo: 42}, function(){});", | |
| 239 "Uncaught Error: Invalid value for argument 0. Property " | |
| 240 "'foo': Unexpected property."); | |
| 241 | |
| 242 ExpectJsPass("chrome.windows.create({" | |
| 243 " url:'http://www.google.com/'," | |
| 244 " left:0," | |
| 245 " top: 10," | |
| 246 " width:100," | |
| 247 " height:200" | |
| 248 "})", | |
| 249 "windows.create", | |
| 250 "[{\"url\":\"http://www.google.com/\"," | |
| 251 "\"left\":0," | |
| 252 "\"top\":10," | |
| 253 "\"width\":100," | |
| 254 "\"height\":200}]"); | |
| 255 } | |
| 256 | |
| 257 TEST_F(ExtensionAPIClientTest, UpdateWindow) { | |
| 258 ExpectJsFail("chrome.windows.update(null);", | |
| 259 "Uncaught Error: Parameter 0 is required."); | |
| 260 ExpectJsFail("chrome.windows.update(42, {left: 'foo'});", | |
| 261 "Uncaught Error: Invalid value for argument 1. Property " | |
| 262 "'left': Expected 'integer' but got 'string'."); | |
| 263 ExpectJsFail("chrome.windows.update(42, {top: 'foo'});", | |
| 264 "Uncaught Error: Invalid value for argument 1. Property " | |
| 265 "'top': Expected 'integer' but got 'string'."); | |
| 266 ExpectJsFail("chrome.windows.update(42, {height: false});", | |
| 267 "Uncaught Error: Invalid value for argument 1. Property " | |
| 268 "'height': Expected 'integer' but got 'boolean'."); | |
| 269 ExpectJsFail("chrome.windows.update(42, {width: false});", | |
| 270 "Uncaught Error: Invalid value for argument 1. Property " | |
| 271 "'width': Expected 'integer' but got 'boolean'."); | |
| 272 ExpectJsFail("chrome.windows.update(42, {foo: false});", | |
| 273 "Uncaught Error: Invalid value for argument 1. Property " | |
| 274 "'foo': Unexpected property."); | |
| 275 | |
| 276 ExpectJsPass("chrome.windows.update(42, {" | |
| 277 " width:100," | |
| 278 " height:200" | |
| 279 "})", | |
| 280 "windows.update", | |
| 281 "[42," | |
| 282 "{\"width\":100," | |
| 283 "\"height\":200}]"); | |
| 284 } | |
| 285 | |
| 286 TEST_F(ExtensionAPIClientTest, RemoveWindow) { | |
| 287 ExpectJsFail("chrome.windows.remove(32, function(){}, 20);", | |
| 288 "Uncaught Error: Too many arguments."); | |
| 289 | |
| 290 ExpectJsFail("chrome.windows.remove('abc', function(){});", | |
| 291 "Uncaught Error: Invalid value for argument 0. " | |
| 292 "Expected 'integer' but got 'string'."); | |
| 293 | |
| 294 ExpectJsFail("chrome.windows.remove(1, 1);", | |
| 295 "Uncaught Error: Invalid value for argument 1. " | |
| 296 "Expected 'function' but got 'integer'."); | |
| 297 | |
| 298 ExpectJsPass("chrome.windows.remove(2, function(){})", | |
| 299 "windows.remove", "[2]"); | |
| 300 | |
| 301 ExpectJsPass("chrome.windows.remove(2)", | |
| 302 "windows.remove", "[2]"); | |
| 303 } | |
| 304 | |
| 305 // Tab API tests | |
| 306 | |
| 307 TEST_F(ExtensionAPIClientTest, GetTab) { | |
| 308 ExpectJsFail("chrome.tabs.get(32, function(){}, 20);", | |
| 309 "Uncaught Error: Too many arguments."); | |
| 310 | |
| 311 ExpectJsFail("chrome.tabs.get(32);", | |
| 312 "Uncaught Error: Parameter 1 is required."); | |
| 313 | |
| 314 ExpectJsFail("chrome.tabs.get('abc', function(){});", | |
| 315 "Uncaught Error: Invalid value for argument 0. " | |
| 316 "Expected 'integer' but got 'string'."); | |
| 317 | |
| 318 ExpectJsFail("chrome.tabs.get(1, 1);", | |
| 319 "Uncaught Error: Invalid value for argument 1. " | |
| 320 "Expected 'function' but got 'integer'."); | |
| 321 | |
| 322 ExpectJsPass("chrome.tabs.get(2, function(){})", | |
| 323 "tabs.get", "[2]"); | |
| 324 } | |
| 325 | |
| 326 TEST_F(ExtensionAPIClientTest, GetCurrentTab) { | |
| 327 ExpectJsFail("chrome.tabs.getCurrent(function(){}, 20);", | |
| 328 "Uncaught Error: Too many arguments."); | |
| 329 | |
| 330 ExpectJsFail("chrome.tabs.getCurrent();", | |
| 331 "Uncaught Error: Parameter 0 is required."); | |
| 332 | |
| 333 ExpectJsFail("chrome.tabs.getCurrent('abc');", | |
| 334 "Uncaught Error: Invalid value for argument 0. " | |
| 335 "Expected 'function' but got 'string'."); | |
| 336 | |
| 337 ExpectJsPass("chrome.tabs.getCurrent(function(){})", | |
| 338 "tabs.getCurrent", "[]"); | |
| 339 } | |
| 340 | |
| 341 TEST_F(ExtensionAPIClientTest, DetectTabLanguage) { | |
| 342 ExpectJsFail("chrome.tabs.detectLanguage(32, function(){}, 20);", | |
| 343 "Uncaught Error: Too many arguments."); | |
| 344 | |
| 345 ExpectJsFail("chrome.tabs.detectLanguage('abc', function(){});", | |
| 346 "Uncaught Error: Invalid value for argument 0. " | |
| 347 "Expected 'integer' but got 'string'."); | |
| 348 | |
| 349 ExpectJsFail("chrome.tabs.detectLanguage(1, 1);", | |
| 350 "Uncaught Error: Invalid value for argument 1. " | |
| 351 "Expected 'function' but got 'integer'."); | |
| 352 | |
| 353 ExpectJsPass("chrome.tabs.detectLanguage(null, function(){})", | |
| 354 "tabs.detectLanguage", "[null]"); | |
| 355 } | |
| 356 | |
| 357 TEST_F(ExtensionAPIClientTest, GetSelectedTab) { | |
| 358 ExpectJsFail("chrome.tabs.getSelected(32, function(){}, 20);", | |
| 359 "Uncaught Error: Too many arguments."); | |
| 360 | |
| 361 ExpectJsFail("chrome.tabs.getSelected(32);", | |
| 362 "Uncaught Error: Parameter 1 is required."); | |
| 363 | |
| 364 ExpectJsFail("chrome.tabs.getSelected('abc', function(){});", | |
| 365 "Uncaught Error: Invalid value for argument 0. " | |
| 366 "Expected 'integer' but got 'string'."); | |
| 367 | |
| 368 ExpectJsFail("chrome.tabs.getSelected(1, 1);", | |
| 369 "Uncaught Error: Invalid value for argument 1. " | |
| 370 "Expected 'function' but got 'integer'."); | |
| 371 | |
| 372 ExpectJsPass("chrome.tabs.getSelected(2, function(){})", | |
| 373 "tabs.getSelected", "[2]"); | |
| 374 | |
| 375 ExpectJsPass("chrome.tabs.getSelected(null, function(){})", | |
| 376 "tabs.getSelected", "[null]"); | |
| 377 } | |
| 378 | |
| 379 | |
| 380 TEST_F(ExtensionAPIClientTest, GetAllTabsInWindow) { | |
| 381 ExpectJsFail("chrome.tabs.getAllInWindow(42, function(){}, 'asd');", | |
| 382 "Uncaught Error: Too many arguments."); | |
| 383 | |
| 384 ExpectJsFail("chrome.tabs.getAllInWindow(32);", | |
| 385 "Uncaught Error: Parameter 1 is required."); | |
| 386 | |
| 387 ExpectJsFail("chrome.tabs.getAllInWindow(1, 1);", | |
| 388 "Uncaught Error: Invalid value for argument 1. " | |
| 389 "Expected 'function' but got 'integer'."); | |
| 390 | |
| 391 ExpectJsFail("chrome.tabs.getAllInWindow('asd', function(){});", | |
| 392 "Uncaught Error: Invalid value for argument 0. " | |
| 393 "Expected 'integer' but got 'string'."); | |
| 394 | |
| 395 ExpectJsPass("chrome.tabs.getAllInWindow(32, function(){})", | |
| 396 "tabs.getAllInWindow", "[32]"); | |
| 397 | |
| 398 ExpectJsPass("chrome.tabs.getAllInWindow(undefined, function(){})", | |
| 399 "tabs.getAllInWindow", "[null]"); | |
| 400 } | |
| 401 | |
| 402 TEST_F(ExtensionAPIClientTest, CreateTab) { | |
| 403 ExpectJsFail("chrome.tabs.create({windowId: 'foo'}, function(){});", | |
| 404 "Uncaught Error: Invalid value for argument 0. Property " | |
| 405 "'windowId': Expected 'integer' but got 'string'."); | |
| 406 ExpectJsFail("chrome.tabs.create({url: 42}, function(){});", | |
| 407 "Uncaught Error: Invalid value for argument 0. Property " | |
| 408 "'url': Expected 'string' but got 'integer'."); | |
| 409 ExpectJsFail("chrome.tabs.create({foo: 42}, function(){});", | |
| 410 "Uncaught Error: Invalid value for argument 0. Property " | |
| 411 "'foo': Unexpected property."); | |
| 412 | |
| 413 ExpectJsPass("chrome.tabs.create({" | |
| 414 " url:'http://www.google.com/'," | |
| 415 " selected:true," | |
| 416 " index: 2," | |
| 417 " windowId:4" | |
| 418 "})", | |
| 419 "tabs.create", | |
| 420 "[{\"url\":\"http://www.google.com/\"," | |
| 421 "\"selected\":true," | |
| 422 "\"index\":2," | |
| 423 "\"windowId\":4}]"); | |
| 424 } | |
| 425 | |
| 426 TEST_F(ExtensionAPIClientTest, UpdateTab) { | |
| 427 ExpectJsFail("chrome.tabs.update(null);", | |
| 428 "Uncaught Error: Parameter 0 is required."); | |
| 429 ExpectJsFail("chrome.tabs.update(42, {selected: 'foo'});", | |
| 430 "Uncaught Error: Invalid value for argument 1. Property " | |
| 431 "'selected': Expected 'boolean' but got 'string'."); | |
| 432 ExpectJsFail("chrome.tabs.update(42, {url: 42});", | |
| 433 "Uncaught Error: Invalid value for argument 1. Property " | |
| 434 "'url': Expected 'string' but got 'integer'."); | |
| 435 | |
| 436 ExpectJsPass("chrome.tabs.update(42, {" | |
| 437 " url:'http://www.google.com/'," | |
| 438 " selected:true" | |
| 439 "})", | |
| 440 "tabs.update", | |
| 441 "[42," | |
| 442 "{\"url\":\"http://www.google.com/\"," | |
| 443 "\"selected\":true}]"); | |
| 444 } | |
| 445 | |
| 446 TEST_F(ExtensionAPIClientTest, MoveTab) { | |
| 447 ExpectJsFail("chrome.tabs.move(null);", | |
| 448 "Uncaught Error: Parameter 0 is required."); | |
| 449 ExpectJsFail("chrome.tabs.move(42, {index: 'foo'});", | |
| 450 "Uncaught Error: Invalid value for argument 1. Property " | |
| 451 "'index': Expected 'integer' but got 'string'."); | |
| 452 ExpectJsFail("chrome.tabs.move(42, {index: 3, windowId: 'foo'});", | |
| 453 "Uncaught Error: Invalid value for argument 1. Property " | |
| 454 "'windowId': Expected 'integer' but got 'string'."); | |
| 455 | |
| 456 ExpectJsPass("chrome.tabs.move(42, {" | |
| 457 " index:3," | |
| 458 " windowId:21" | |
| 459 "})", | |
| 460 "tabs.move", | |
| 461 "[42," | |
| 462 "{\"index\":3," | |
| 463 "\"windowId\":21}]"); | |
| 464 } | |
| 465 | |
| 466 TEST_F(ExtensionAPIClientTest, RemoveTab) { | |
| 467 ExpectJsFail("chrome.tabs.remove(32, function(){}, 20);", | |
| 468 "Uncaught Error: Too many arguments."); | |
| 469 | |
| 470 | |
| 471 ExpectJsFail("chrome.tabs.remove('abc', function(){});", | |
| 472 "Uncaught Error: Invalid value for argument 0. " | |
| 473 "Expected 'integer' but got 'string'."); | |
| 474 | |
| 475 ExpectJsFail("chrome.tabs.remove(1, 1);", | |
| 476 "Uncaught Error: Invalid value for argument 1. " | |
| 477 "Expected 'function' but got 'integer'."); | |
| 478 | |
| 479 ExpectJsPass("chrome.tabs.remove(2, function(){})", | |
| 480 "tabs.remove", "[2]"); | |
| 481 | |
| 482 ExpectJsPass("chrome.tabs.remove(2)", | |
| 483 "tabs.remove", "[2]"); | |
| 484 } | |
| 485 | |
| 486 TEST_F(ExtensionAPIClientTest, CaptureVisibleTab) { | |
| 487 ExpectJsFail("chrome.tabs.captureVisibleTab(0);", | |
| 488 "Uncaught Error: Parameter 2 is required."); | |
| 489 | |
| 490 ExpectJsFail("chrome.tabs.captureVisibleTab(0, null);", | |
| 491 "Uncaught Error: Parameter 2 is required."); | |
| 492 | |
| 493 ExpectJsFail("chrome.tabs.captureVisibleTab(null, {});", | |
| 494 "Uncaught Error: Parameter 2 is required."); | |
| 495 | |
| 496 ExpectJsFail("chrome.tabs.captureVisibleTab(function(){}, 0)", | |
| 497 "Uncaught Error: Invalid value for argument 0. " | |
| 498 "Expected 'integer' but got 'function'."); | |
| 499 | |
| 500 // Use old signiture. Check that a null value of the options paramenter | |
| 501 // is added. | |
| 502 ExpectJsPass("chrome.tabs.captureVisibleTab(null, function(img){});", | |
| 503 "tabs.captureVisibleTab", "[null, null]"); | |
| 504 | |
| 505 ExpectJsPass("chrome.tabs.captureVisibleTab(1, function(img){});", | |
| 506 "tabs.captureVisibleTab", "[1, null]"); | |
| 507 | |
| 508 ExpectJsPass("chrome.tabs.captureVisibleTab(null, null, function(img){});", | |
| 509 "tabs.captureVisibleTab", "[null, null]"); | |
| 510 | |
| 511 ExpectJsPass("chrome.tabs.captureVisibleTab(" | |
| 512 "null, undefined, function(img){});", | |
| 513 "tabs.captureVisibleTab", "[null, null]"); | |
| 514 | |
| 515 ExpectJsPass("chrome.tabs.captureVisibleTab(null, {}, function(img){});", | |
| 516 "tabs.captureVisibleTab", "[null, {}]"); | |
| 517 | |
| 518 ExpectJsFail("chrome.tabs.captureVisibleTab(null, 42, function(img){});", | |
| 519 "Uncaught Error: Invalid value for argument 1. " | |
| 520 "Expected 'object' but got 'integer'."); | |
| 521 | |
| 522 ExpectJsPass("chrome.tabs.captureVisibleTab(" | |
| 523 "null, {\"format\": \"jpeg\"}, function(img){});", | |
| 524 "tabs.captureVisibleTab", "[null, {\"format\": \"jpeg\"}]"); | |
| 525 | |
| 526 ExpectJsPass("chrome.tabs.captureVisibleTab(" | |
| 527 "null, {\"quality\": 100}, function(img){});", | |
| 528 "tabs.captureVisibleTab", "[null, {\"quality\": 100}]"); | |
| 529 | |
| 530 ExpectJsFail("chrome.tabs.captureVisibleTab(" | |
| 531 "null, {\"quality\": 101}, function(img){});", | |
| 532 "Uncaught Error: Invalid value for argument 1. " | |
| 533 "Property 'quality': Value must not be greater than 100."); | |
| 534 | |
| 535 ExpectJsFail("chrome.tabs.captureVisibleTab(" | |
| 536 "null, {'not_a_param': 'jpeg'}, function(img){});", | |
| 537 "Uncaught Error: Invalid value for argument 1. " | |
| 538 "Property 'not_a_param': Unexpected property."); | |
| 539 | |
| 540 ExpectJsFail("chrome.tabs.captureVisibleTab(" | |
| 541 "null, {'format': 'invalid'}, function(img){});", | |
| 542 "Uncaught Error: Invalid value for argument 1. " | |
| 543 "Property 'format': Value must be one of: [jpeg, png]."); | |
| 544 | |
| 545 ExpectJsFail("chrome.tabs.captureVisibleTab(" | |
| 546 "null, {'format': 42}, function(img){});", | |
| 547 "Uncaught Error: Invalid value for argument 1. " | |
| 548 "Property 'format': Value must be one of: [jpeg, png]."); | |
| 549 } | |
| 550 | |
| 551 // Bookmark API tests | |
| 552 // TODO(erikkay) add more variations here | |
| 553 | |
| 554 TEST_F(ExtensionAPIClientTest, CreateBookmark) { | |
| 555 ExpectJsFail( | |
| 556 "chrome.bookmarks.create({parentId:0, title:0}, function(){})", | |
| 557 "Uncaught Error: Invalid value for argument 0. " | |
| 558 "Property 'parentId': Expected 'string' but got 'integer', " | |
| 559 "Property 'title': Expected 'string' but got 'integer'."); | |
| 560 | |
| 561 ExpectJsPass( | |
| 562 "chrome.bookmarks.create({parentId:'0', title:'x'}, function(){})", | |
| 563 "bookmarks.create", | |
| 564 "[{\"parentId\":\"0\",\"title\":\"x\"}]"); | |
| 565 } | |
| 566 | |
| 567 TEST_F(ExtensionAPIClientTest, GetBookmarks) { | |
| 568 ExpectJsPass("chrome.bookmarks.get('0', function(){});", | |
| 569 "bookmarks.get", | |
| 570 "[\"0\"]"); | |
| 571 ExpectJsPass("chrome.bookmarks.get(['0','1','2','3'], function(){});", | |
| 572 "bookmarks.get", | |
| 573 "[[\"0\",\"1\",\"2\",\"3\"]]"); | |
| 574 ExpectJsFail("chrome.bookmarks.get(null, function(){});", | |
| 575 "Uncaught Error: Parameter 0 is required."); | |
| 576 // TODO(erikkay) This is succeeding, when it should fail. | |
| 577 // BUG=13719 | |
| 578 #if 0 | |
| 579 ExpectJsFail("chrome.bookmarks.get({}, function(){});", | |
| 580 "Uncaught Error: Invalid value for argument 0. " | |
| 581 "Expected 'array' but got 'object'."); | |
| 582 #endif | |
| 583 } | |
| 584 | |
| 585 TEST_F(ExtensionAPIClientTest, GetBookmarkChildren) { | |
| 586 ExpectJsPass("chrome.bookmarks.getChildren('42', function(){});", | |
| 587 "bookmarks.getChildren", | |
| 588 "[\"42\"]"); | |
| 589 } | |
| 590 | |
| 591 TEST_F(ExtensionAPIClientTest, GetBookmarkRecent) { | |
| 592 ExpectJsPass("chrome.bookmarks.getRecent(5, function(){});", | |
| 593 "bookmarks.getRecent", | |
| 594 "[5]"); | |
| 595 } | |
| 596 | |
| 597 TEST_F(ExtensionAPIClientTest, GetBookmarkTree) { | |
| 598 ExpectJsPass("chrome.bookmarks.getTree(function(){});", | |
| 599 "bookmarks.getTree", | |
| 600 "[]"); | |
| 601 } | |
| 602 | |
| 603 TEST_F(ExtensionAPIClientTest, SearchBookmarks) { | |
| 604 ExpectJsPass("chrome.bookmarks.search('hello',function(){});", | |
| 605 "bookmarks.search", | |
| 606 "[\"hello\"]"); | |
| 607 } | |
| 608 | |
| 609 TEST_F(ExtensionAPIClientTest, RemoveBookmark) { | |
| 610 ExpectJsPass("chrome.bookmarks.remove('42');", | |
| 611 "bookmarks.remove", | |
| 612 "[\"42\"]"); | |
| 613 } | |
| 614 | |
| 615 TEST_F(ExtensionAPIClientTest, RemoveBookmarkTree) { | |
| 616 ExpectJsPass("chrome.bookmarks.removeTree('42');", | |
| 617 "bookmarks.removeTree", | |
| 618 "[\"42\"]"); | |
| 619 } | |
| 620 | |
| 621 TEST_F(ExtensionAPIClientTest, MoveBookmark) { | |
| 622 ExpectJsPass("chrome.bookmarks.move('42',{parentId:'1',index:0});", | |
| 623 "bookmarks.move", | |
| 624 "[\"42\",{\"parentId\":\"1\",\"index\":0}]"); | |
| 625 } | |
| 626 | |
| 627 TEST_F(ExtensionAPIClientTest, SetBookmarkTitle) { | |
| 628 ExpectJsPass("chrome.bookmarks.update('42',{title:'x'});", | |
| 629 "bookmarks.update", | |
| 630 "[\"42\",{\"title\":\"x\"}]"); | |
| 631 } | |
| 632 | |
| 633 TEST_F(ExtensionAPIClientTest, EnablePageAction) { | |
| 634 // Basic old-school enablePageAction call. | |
| 635 ExpectJsPass("chrome.pageActions.enableForTab(" | |
| 636 "'dummy', {tabId: 0, url: 'http://foo/'});", | |
| 637 "pageActions.enableForTab", | |
| 638 "[\"dummy\",{\"tabId\":0,\"url\":\"http://foo/\"}]"); | |
| 639 // Try both optional parameters (title and iconId). | |
| 640 ExpectJsPass("chrome.pageActions.enableForTab(" | |
| 641 "'dummy', {tabId: 0, url: 'http://foo/'," | |
| 642 "title: 'a', iconId: 0});", | |
| 643 "pageActions.enableForTab", | |
| 644 "[\"dummy\",{\"tabId\":0,\"url\":\"http://foo/\"," | |
| 645 "\"title\":\"a\",\"iconId\":0}]"); | |
| 646 | |
| 647 // Now try disablePageAction. | |
| 648 ExpectJsPass("chrome.pageActions.disableForTab(" | |
| 649 "'dummy', {tabId: 0, url: 'http://foo/'});", | |
| 650 "pageActions.disableForTab", | |
| 651 "[\"dummy\",{\"tabId\":0,\"url\":\"http://foo/\"}]"); | |
| 652 } | |
| 653 | |
| 654 TEST_F(ExtensionAPIClientTest, ExpandToolstrip) { | |
| 655 ExpectJsPass("chrome.toolstrip.expand({height:100, url:'http://foo/'})", | |
| 656 "toolstrip.expand", | |
| 657 "[{\"height\":100,\"url\":\"http://foo/\"}]"); | |
| 658 ExpectJsPass("chrome.toolstrip.expand({height:100}, null)", | |
| 659 "toolstrip.expand", | |
| 660 "[{\"height\":100}]"); | |
| 661 ExpectJsPass("chrome.toolstrip.expand({height:100,url:'http://foo/'}, " | |
| 662 "function(){})", | |
| 663 "toolstrip.expand", | |
| 664 "[{\"height\":100,\"url\":\"http://foo/\"}]"); | |
| 665 | |
| 666 | |
| 667 ExpectJsFail("chrome.toolstrip.expand()", | |
| 668 "Uncaught Error: Parameter 0 is required."); | |
| 669 ExpectJsFail("chrome.toolstrip.expand(1)", | |
| 670 "Uncaught Error: Invalid value for argument 0. " | |
| 671 "Expected 'object' but got 'integer'."); | |
| 672 ExpectJsFail("chrome.toolstrip.expand({height:'100', url:'http://foo/'})", | |
| 673 "Uncaught Error: Invalid value for argument 0. " | |
| 674 "Property 'height': " | |
| 675 "Expected 'integer' but got 'string'."); | |
| 676 ExpectJsFail("chrome.toolstrip.expand({height:100,url:100})", | |
| 677 "Uncaught Error: Invalid value for argument 0. Property 'url': " | |
| 678 "Expected 'string' but got 'integer'."); | |
| 679 ExpectJsFail("chrome.toolstrip.expand({height:100,'url':'http://foo/'}, 32)", | |
| 680 "Uncaught Error: Invalid value for argument 1. " | |
| 681 "Expected 'function' but got 'integer'."); | |
| 682 } | |
| 683 | |
| 684 TEST_F(ExtensionAPIClientTest, CollapseToolstrip) { | |
| 685 ExpectJsPass("chrome.toolstrip.collapse({url:'http://foo/'})", | |
| 686 "toolstrip.collapse", | |
| 687 "[{\"url\":\"http://foo/\"}]"); | |
| 688 ExpectJsPass("chrome.toolstrip.collapse(null)", | |
| 689 "toolstrip.collapse", | |
| 690 "[null]"); | |
| 691 ExpectJsPass("chrome.toolstrip.collapse({url:'http://foo/'}, function(){})", | |
| 692 "toolstrip.collapse", | |
| 693 "[{\"url\":\"http://foo/\"}]"); | |
| 694 | |
| 695 ExpectJsFail("chrome.toolstrip.collapse(1)", | |
| 696 "Uncaught Error: Invalid value for argument 0. " | |
| 697 "Expected 'object' but got 'integer'."); | |
| 698 ExpectJsFail("chrome.toolstrip.collapse(100)", | |
| 699 "Uncaught Error: Invalid value for argument 0. " | |
| 700 "Expected 'object' but got 'integer'."); | |
| 701 ExpectJsFail("chrome.toolstrip.collapse({url:'http://foo/'}, 32)", | |
| 702 "Uncaught Error: Invalid value for argument 1. " | |
| 703 "Expected 'function' but got 'integer'."); | |
| 704 } | |
| 705 | |
| 706 // I18N API | |
| 707 TEST_F(ExtensionAPIClientTest, GetAcceptLanguages) { | |
| 708 ExpectJsFail("chrome.i18n.getAcceptLanguages(32, function(){})", | |
| 709 "Uncaught Error: Too many arguments."); | |
| 710 | |
| 711 ExpectJsFail("chrome.i18n.getAcceptLanguages()", | |
| 712 "Uncaught Error: Parameter 0 is required."); | |
| 713 | |
| 714 ExpectJsFail("chrome.i18n.getAcceptLanguages('abc')", | |
| 715 "Uncaught Error: Invalid value for argument 0. " | |
| 716 "Expected 'function' but got 'string'."); | |
| 717 | |
| 718 ExpectJsPass("chrome.i18n.getAcceptLanguages(function(){})", | |
| 719 "i18n.getAcceptLanguages", "[]"); | |
| 720 } | |
| 721 | |
| 722 // TODO(cira): re-enable when we get validation going for | |
| 723 // renderer_process_bindings.js | |
| 724 TEST_F(ExtensionAPIClientTest, DISABLED_GetL10nMessage) { | |
| 725 ExpectJsFail("chrome.i18n.getMessage()", | |
| 726 "Uncaught Error: Parameter 0 is required."); | |
| 727 | |
| 728 ExpectJsFail("chrome.i18n.getMessage(1)", | |
| 729 "Uncaught Error: Invalid value for argument 0. " | |
| 730 "Expected 'string' but got 'integer'."); | |
| 731 | |
| 732 ExpectJsFail("chrome.i18n.getMessage('name', [])", | |
| 733 "Uncaught Error: Invalid value for argument 1. Value does not " | |
| 734 "match any valid type choices."); | |
| 735 | |
| 736 ExpectJsFail("chrome.i18n.getMessage('name', ['p1', 'p2', 'p3', 'p4', 'p5', " | |
| 737 "'p6', 'p7', 'p8', 'p9', 'p10'])", | |
| 738 "Uncaught Error: Invalid value for argument 1. Value does not " | |
| 739 "match any valid type choices."); | |
| 740 } | |
| OLD | NEW |