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. 4 5 #include "base/strings/stringprintf.h" 6 #include "base/strings/utf_string_conversions.h" 7 #include "chrome/browser/automation/automation_util.h" 8 #include "chrome/browser/extensions/extension_test_message_listener.h" 9 #include "chrome/browser/extensions/platform_app_browsertest_util.h" 10 #include "chrome/browser/prerender/prerender_link_manager.h" 11 #include "chrome/browser/prerender/prerender_link_manager_factory.h" 12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/tabs/tab_strip_model.h" 15 #include "chrome/common/extensions/extension.h" 16 #include "chrome/test/base/ui_test_utils.h" 17 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/render_process_host.h" 19 #include "content/public/browser/web_contents_delegate.h" 20 #include "content/public/test/browser_test_utils.h" 21 #include "content/public/test/fake_speech_recognition_manager.h" 22 #include "net/test/embedded_test_server/embedded_test_server.h" 23 #include "net/test/embedded_test_server/http_request.h" 24 #include "net/test/embedded_test_server/http_response.h" 25 #include "ui/gl/gl_switches.h" 26 27 // For fine-grained suppression on flaky tests. 28 #if defined(OS_WIN) 29 #include "base/win/windows_version.h" 30 #endif 31 32 using prerender::PrerenderLinkManager; 33 using prerender::PrerenderLinkManagerFactory; 34 35 namespace { 36 const char kEmptyResponsePath[] = "/close-socket"; 37 const char kRedirectResponsePath[] = "/server-redirect"; 38 const char kRedirectResponseFullPath[] = 39 "/extensions/platform_apps/web_view/shim/guest_redirect.html"; 40 41 class EmptyHttpResponse : public net::test_server::HttpResponse { 42 public: 43 virtual std::string ToResponseString() const OVERRIDE { 44 return std::string(); 45 } 46 }; 47 } // namespace 48 49 // This class intercepts media access request from the embedder. The request 50 // should be triggered only if the embedder API (from tests) allows the request 51 // in Javascript. 52 // We do not issue the actual media request; the fact that the request reached 53 // embedder's WebContents is good enough for our tests. This is also to make 54 // the test run successfully on trybots. 55 class MockWebContentsDelegate : public content::WebContentsDelegate { 56 public: 57 MockWebContentsDelegate() : requested_(false) {} 58 virtual ~MockWebContentsDelegate() {} 59 60 virtual void RequestMediaAccessPermission( 61 content::WebContents* web_contents, 62 const content::MediaStreamRequest& request, 63 const content::MediaResponseCallback& callback) OVERRIDE { 64 requested_ = true; 65 if (message_loop_runner_.get()) 66 message_loop_runner_->Quit(); 67 } 68 69 void WaitForSetMediaPermission() { 70 if (requested_) 71 return; 72 message_loop_runner_ = new content::MessageLoopRunner; 73 message_loop_runner_->Run(); 74 } 75 76 private: 77 bool requested_; 78 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 79 80 DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate); 81 }; 82 83 // This class intercepts download request from the guest. 84 class MockDownloadWebContentsDelegate : public content::WebContentsDelegate { 85 public: 86 explicit MockDownloadWebContentsDelegate( 87 content::WebContentsDelegate* orig_delegate) 88 : orig_delegate_(orig_delegate), 89 waiting_for_decision_(false), 90 expect_allow_(false), 91 decision_made_(false), 92 last_download_allowed_(false) {} 93 virtual ~MockDownloadWebContentsDelegate() {} 94 95 virtual void CanDownload( 96 content::RenderViewHost* render_view_host, 97 int request_id, 98 const std::string& request_method, 99 const base::Callback<void(bool)>& callback) OVERRIDE { 100 orig_delegate_->CanDownload( 101 render_view_host, request_id, request_method, 102 base::Bind(&MockDownloadWebContentsDelegate::DownloadDecided, 103 base::Unretained(this))); 104 } 105 106 void WaitForCanDownload(bool expect_allow) { 107 EXPECT_FALSE(waiting_for_decision_); 108 waiting_for_decision_ = true; 109 110 if (decision_made_) { 111 EXPECT_EQ(expect_allow, last_download_allowed_); 112 return; 113 } 114 115 expect_allow_ = expect_allow; 116 message_loop_runner_ = new content::MessageLoopRunner; 117 message_loop_runner_->Run(); 118 } 119 120 void DownloadDecided(bool allow) { 121 EXPECT_FALSE(decision_made_); 122 decision_made_ = true; 123 124 if (waiting_for_decision_) { 125 EXPECT_EQ(expect_allow_, allow); 126 if (message_loop_runner_.get()) 127 message_loop_runner_->Quit(); 128 return; 129 } 130 last_download_allowed_ = allow; 131 } 132 133 void Reset() { 134 waiting_for_decision_ = false; 135 decision_made_ = false; 136 } 137 138 private: 139 content::WebContentsDelegate* orig_delegate_; 140 bool waiting_for_decision_; 141 bool expect_allow_; 142 bool decision_made_; 143 bool last_download_allowed_; 144 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 145 146 DISALLOW_COPY_AND_ASSIGN(MockDownloadWebContentsDelegate); 147 }; 148 149 class WebViewTest : public extensions::PlatformAppBrowserTest { 150 protected: 151 virtual void SetUp() OVERRIDE { 152 const testing::TestInfo* const test_info = 153 testing::UnitTest::GetInstance()->current_test_info(); 154 155 // SpeechRecognition test specific SetUp. 156 if (!strcmp(test_info->name(), "SpeechRecognition")) { 157 fake_speech_recognition_manager_.reset( 158 new content::FakeSpeechRecognitionManager()); 159 fake_speech_recognition_manager_->set_should_send_fake_response(true); 160 // Inject the fake manager factory so that the test result is returned to 161 // the web page. 162 content::SpeechRecognitionManager::SetManagerForTests( 163 fake_speech_recognition_manager_.get()); 164 } 165 166 extensions::PlatformAppBrowserTest::SetUp(); 167 } 168 169 virtual void TearDown() OVERRIDE { 170 // SpeechRecognition test specific TearDown. 171 const testing::TestInfo* const test_info = 172 testing::UnitTest::GetInstance()->current_test_info(); 173 if (!strcmp(test_info->name(), "SpeechRecognition")) 174 content::SpeechRecognitionManager::SetManagerForTests(NULL); 175 176 extensions::PlatformAppBrowserTest::TearDown(); 177 } 178 179 virtual void SetUpOnMainThread() OVERRIDE { 180 const testing::TestInfo* const test_info = 181 testing::UnitTest::GetInstance()->current_test_info(); 182 // Mock out geolocation for geolocation specific tests. 183 if (!strncmp(test_info->name(), "GeolocationAPI", 184 strlen("GeolocationAPI"))) { 185 ui_test_utils::OverrideGeolocation(10, 20); 186 } 187 } 188 189 // This method is responsible for initializing a packaged app, which contains 190 // multiple webview tags. The tags have different partition identifiers and 191 // their WebContent objects are returned as output. The method also verifies 192 // the expected process allocation and storage partition assignment. 193 // The |navigate_to_url| parameter is used to navigate the main browser 194 // window. 195 // 196 // TODO(ajwong): This function is getting to be too large. Either refactor it 197 // so the test can specify a configuration of WebView tags that we will 198 // dynamically inject JS to generate, or move this test wholesale into 199 // something that RunPlatformAppTest() can execute purely in Javascript. This 200 // won't let us do a white-box examination of the StoragePartition equivalence 201 // directly, but we will be able to view the black box effects which is good 202 // enough. http://crbug.com/160361 203 void NavigateAndOpenAppForIsolation( 204 GURL navigate_to_url, 205 content::WebContents** default_tag_contents1, 206 content::WebContents** default_tag_contents2, 207 content::WebContents** named_partition_contents1, 208 content::WebContents** named_partition_contents2, 209 content::WebContents** persistent_partition_contents1, 210 content::WebContents** persistent_partition_contents2, 211 content::WebContents** persistent_partition_contents3) { 212 GURL::Replacements replace_host; 213 std::string host_str("localhost"); // Must stay in scope with replace_host. 214 replace_host.SetHostStr(host_str); 215 216 navigate_to_url = navigate_to_url.ReplaceComponents(replace_host); 217 218 GURL tag_url1 = embedded_test_server()->GetURL( 219 "/extensions/platform_apps/web_view/isolation/cookie.html"); 220 tag_url1 = tag_url1.ReplaceComponents(replace_host); 221 GURL tag_url2 = embedded_test_server()->GetURL( 222 "/extensions/platform_apps/web_view/isolation/cookie2.html"); 223 tag_url2 = tag_url2.ReplaceComponents(replace_host); 224 GURL tag_url3 = embedded_test_server()->GetURL( 225 "/extensions/platform_apps/web_view/isolation/storage1.html"); 226 tag_url3 = tag_url3.ReplaceComponents(replace_host); 227 GURL tag_url4 = embedded_test_server()->GetURL( 228 "/extensions/platform_apps/web_view/isolation/storage2.html"); 229 tag_url4 = tag_url4.ReplaceComponents(replace_host); 230 GURL tag_url5 = embedded_test_server()->GetURL( 231 "/extensions/platform_apps/web_view/isolation/storage1.html#p1"); 232 tag_url5 = tag_url5.ReplaceComponents(replace_host); 233 GURL tag_url6 = embedded_test_server()->GetURL( 234 "/extensions/platform_apps/web_view/isolation/storage1.html#p2"); 235 tag_url6 = tag_url6.ReplaceComponents(replace_host); 236 GURL tag_url7 = embedded_test_server()->GetURL( 237 "/extensions/platform_apps/web_view/isolation/storage1.html#p3"); 238 tag_url7 = tag_url7.ReplaceComponents(replace_host); 239 240 ui_test_utils::NavigateToURLWithDisposition( 241 browser(), navigate_to_url, CURRENT_TAB, 242 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 243 244 ui_test_utils::UrlLoadObserver observer1( 245 tag_url1, content::NotificationService::AllSources()); 246 ui_test_utils::UrlLoadObserver observer2( 247 tag_url2, content::NotificationService::AllSources()); 248 ui_test_utils::UrlLoadObserver observer3( 249 tag_url3, content::NotificationService::AllSources()); 250 ui_test_utils::UrlLoadObserver observer4( 251 tag_url4, content::NotificationService::AllSources()); 252 ui_test_utils::UrlLoadObserver observer5( 253 tag_url5, content::NotificationService::AllSources()); 254 ui_test_utils::UrlLoadObserver observer6( 255 tag_url6, content::NotificationService::AllSources()); 256 ui_test_utils::UrlLoadObserver observer7( 257 tag_url7, content::NotificationService::AllSources()); 258 LoadAndLaunchPlatformApp("web_view/isolation"); 259 observer1.Wait(); 260 observer2.Wait(); 261 observer3.Wait(); 262 observer4.Wait(); 263 observer5.Wait(); 264 observer6.Wait(); 265 observer7.Wait(); 266 267 content::Source<content::NavigationController> source1 = observer1.source(); 268 EXPECT_TRUE(source1->GetWebContents()->GetRenderProcessHost()->IsGuest()); 269 content::Source<content::NavigationController> source2 = observer2.source(); 270 EXPECT_TRUE(source2->GetWebContents()->GetRenderProcessHost()->IsGuest()); 271 content::Source<content::NavigationController> source3 = observer3.source(); 272 EXPECT_TRUE(source3->GetWebContents()->GetRenderProcessHost()->IsGuest()); 273 content::Source<content::NavigationController> source4 = observer4.source(); 274 EXPECT_TRUE(source4->GetWebContents()->GetRenderProcessHost()->IsGuest()); 275 content::Source<content::NavigationController> source5 = observer5.source(); 276 EXPECT_TRUE(source5->GetWebContents()->GetRenderProcessHost()->IsGuest()); 277 content::Source<content::NavigationController> source6 = observer6.source(); 278 EXPECT_TRUE(source6->GetWebContents()->GetRenderProcessHost()->IsGuest()); 279 content::Source<content::NavigationController> source7 = observer7.source(); 280 EXPECT_TRUE(source7->GetWebContents()->GetRenderProcessHost()->IsGuest()); 281 282 // Check that the first two tags use the same process and it is different 283 // than the process used by the other two. 284 EXPECT_EQ(source1->GetWebContents()->GetRenderProcessHost()->GetID(), 285 source2->GetWebContents()->GetRenderProcessHost()->GetID()); 286 EXPECT_EQ(source3->GetWebContents()->GetRenderProcessHost()->GetID(), 287 source4->GetWebContents()->GetRenderProcessHost()->GetID()); 288 EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(), 289 source3->GetWebContents()->GetRenderProcessHost()->GetID()); 290 291 // The two sets of tags should also be isolated from the main browser. 292 EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(), 293 browser()->tab_strip_model()->GetWebContentsAt(0)-> 294 GetRenderProcessHost()->GetID()); 295 EXPECT_NE(source3->GetWebContents()->GetRenderProcessHost()->GetID(), 296 browser()->tab_strip_model()->GetWebContentsAt(0)-> 297 GetRenderProcessHost()->GetID()); 298 299 // Check that the storage partitions of the first two tags match and are 300 // different than the other two. 301 EXPECT_EQ( 302 source1->GetWebContents()->GetRenderProcessHost()-> 303 GetStoragePartition(), 304 source2->GetWebContents()->GetRenderProcessHost()-> 305 GetStoragePartition()); 306 EXPECT_EQ( 307 source3->GetWebContents()->GetRenderProcessHost()-> 308 GetStoragePartition(), 309 source4->GetWebContents()->GetRenderProcessHost()-> 310 GetStoragePartition()); 311 EXPECT_NE( 312 source1->GetWebContents()->GetRenderProcessHost()-> 313 GetStoragePartition(), 314 source3->GetWebContents()->GetRenderProcessHost()-> 315 GetStoragePartition()); 316 317 // Ensure the persistent storage partitions are different. 318 EXPECT_EQ( 319 source5->GetWebContents()->GetRenderProcessHost()-> 320 GetStoragePartition(), 321 source6->GetWebContents()->GetRenderProcessHost()-> 322 GetStoragePartition()); 323 EXPECT_NE( 324 source5->GetWebContents()->GetRenderProcessHost()-> 325 GetStoragePartition(), 326 source7->GetWebContents()->GetRenderProcessHost()-> 327 GetStoragePartition()); 328 EXPECT_NE( 329 source1->GetWebContents()->GetRenderProcessHost()-> 330 GetStoragePartition(), 331 source5->GetWebContents()->GetRenderProcessHost()-> 332 GetStoragePartition()); 333 EXPECT_NE( 334 source1->GetWebContents()->GetRenderProcessHost()-> 335 GetStoragePartition(), 336 source7->GetWebContents()->GetRenderProcessHost()-> 337 GetStoragePartition()); 338 339 *default_tag_contents1 = source1->GetWebContents(); 340 *default_tag_contents2 = source2->GetWebContents(); 341 *named_partition_contents1 = source3->GetWebContents(); 342 *named_partition_contents2 = source4->GetWebContents(); 343 if (persistent_partition_contents1) { 344 *persistent_partition_contents1 = source5->GetWebContents(); 345 } 346 if (persistent_partition_contents2) { 347 *persistent_partition_contents2 = source6->GetWebContents(); 348 } 349 if (persistent_partition_contents3) { 350 *persistent_partition_contents3 = source7->GetWebContents(); 351 } 352 } 353 354 void ExecuteScriptWaitForTitle(content::WebContents* web_contents, 355 const char* script, 356 const char* title) { 357 string16 expected_title(ASCIIToUTF16(title)); 358 string16 error_title(ASCIIToUTF16("error")); 359 360 content::TitleWatcher title_watcher(web_contents, expected_title); 361 title_watcher.AlsoWaitForTitle(error_title); 362 EXPECT_TRUE(content::ExecuteScript(web_contents, script)); 363 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 364 } 365 366 // Handles |request| by serving a redirect response. 367 static scoped_ptr<net::test_server::HttpResponse> RedirectResponseHandler( 368 const std::string& path, 369 const GURL& redirect_target, 370 const net::test_server::HttpRequest& request) { 371 if (!StartsWithASCII(path, request.relative_url, true)) 372 return scoped_ptr<net::test_server::HttpResponse>(); 373 374 scoped_ptr<net::test_server::BasicHttpResponse> http_response( 375 new net::test_server::BasicHttpResponse); 376 http_response->set_code(net::HTTP_MOVED_PERMANENTLY); 377 http_response->AddCustomHeader("Location", redirect_target.spec()); 378 return http_response.PassAs<net::test_server::HttpResponse>(); 379 } 380 381 // Handles |request| by serving an empty response. 382 static scoped_ptr<net::test_server::HttpResponse> EmptyResponseHandler( 383 const std::string& path, 384 const net::test_server::HttpRequest& request) { 385 if (StartsWithASCII(path, request.relative_url, true)) { 386 return scoped_ptr<net::test_server::HttpResponse>( 387 new EmptyHttpResponse); 388 } 389 390 return scoped_ptr<net::test_server::HttpResponse>(); 391 } 392 393 void TestHelper(const std::string& test_name, 394 const std::string& test_passed_msg, 395 const std::string& test_failed_msg, 396 const std::string& app_location) { 397 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 398 ExtensionTestMessageListener launched_listener("Launched", false); 399 LoadAndLaunchPlatformApp(app_location.c_str()); 400 ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); 401 402 embedded_test_server()->RegisterRequestHandler( 403 base::Bind(&WebViewTest::RedirectResponseHandler, 404 kRedirectResponsePath, 405 embedded_test_server()->GetURL(kRedirectResponseFullPath))); 406 407 embedded_test_server()->RegisterRequestHandler( 408 base::Bind(&WebViewTest::EmptyResponseHandler, kEmptyResponsePath)); 409 410 content::WebContents* embedder_web_contents = 411 GetFirstShellWindowWebContents(); 412 ASSERT_TRUE(embedder_web_contents); 413 414 ExtensionTestMessageListener done_listener(test_passed_msg, false); 415 done_listener.AlsoListenForFailureMessage(test_failed_msg); 416 EXPECT_TRUE(content::ExecuteScript( 417 embedder_web_contents, 418 base::StringPrintf("runTest('%s')", test_name.c_str()))); 419 ASSERT_TRUE(done_listener.WaitUntilSatisfied()); 420 } 421 422 content::WebContents* LoadGuest(const std::string& guest_path, 423 const std::string& app_path) { 424 GURL::Replacements replace_host; 425 std::string host_str("localhost"); // Must stay in scope with replace_host. 426 replace_host.SetHostStr(host_str); 427 428 GURL guest_url = embedded_test_server()->GetURL(guest_path); 429 guest_url = guest_url.ReplaceComponents(replace_host); 430 431 ui_test_utils::UrlLoadObserver guest_observer( 432 guest_url, content::NotificationService::AllSources()); 433 434 ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false); 435 LoadAndLaunchPlatformApp(app_path.c_str()); 436 guest_observer.Wait(); 437 438 content::Source<content::NavigationController> source = 439 guest_observer.source(); 440 EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest()); 441 442 bool satisfied = guest_loaded_listener.WaitUntilSatisfied(); 443 if (!satisfied) 444 return NULL; 445 446 content::WebContents* guest_web_contents = source->GetWebContents(); 447 return guest_web_contents; 448 } 449 450 // Runs media_access/allow tests. 451 void MediaAccessAPIAllowTestHelper(const std::string& test_name); 452 453 // Runs media_access/deny tests, each of them are run separately otherwise 454 // they timeout (mostly on Windows). 455 void MediaAccessAPIDenyTestHelper(const std::string& test_name) { 456 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 457 ExtensionTestMessageListener loaded_listener("loaded", false); 458 LoadAndLaunchPlatformApp("web_view/media_access/deny"); 459 ASSERT_TRUE(loaded_listener.WaitUntilSatisfied()); 460 461 content::WebContents* embedder_web_contents = 462 GetFirstShellWindowWebContents(); 463 ASSERT_TRUE(embedder_web_contents); 464 465 ExtensionTestMessageListener test_run_listener("PASSED", false); 466 test_run_listener.AlsoListenForFailureMessage("FAILED"); 467 EXPECT_TRUE( 468 content::ExecuteScript( 469 embedder_web_contents, 470 base::StringPrintf("startDenyTest('%s')", test_name.c_str()))); 471 ASSERT_TRUE(test_run_listener.WaitUntilSatisfied()); 472 } 473 474 private: 475 scoped_ptr<content::FakeSpeechRecognitionManager> 476 fake_speech_recognition_manager_; 477 }; 478 479 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestSize) { 480 TestHelper("testSize", 481 "DoneShimTest.PASSED", 482 "DoneShimTest.FAILED", 483 "web_view/shim"); 484 } 485 486 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAPIMethodExistence) { 487 TestHelper("testAPIMethodExistence", 488 "DoneShimTest.PASSED", 489 "DoneShimTest.FAILED", 490 "web_view/shim"); 491 } 492 493 // Tests the existence of WebRequest API event objects on the request 494 // object, on the webview element, and hanging directly off webview. 495 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPIExistence) { 496 TestHelper("testWebRequestAPIExistence", 497 "DoneShimTest.PASSED", 498 "DoneShimTest.FAILED", 499 "web_view/shim"); 500 } 501 502 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestEventName) { 503 TestHelper("testEventName", 504 "DoneShimTest.PASSED", 505 "DoneShimTest.FAILED", 506 "web_view/shim"); 507 } 508 509 // WebViewTest.Shim_TestDestroyOnEventListener is flaky, so disable it. 510 // http://crbug.com/255106 511 IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_Shim_TestDestroyOnEventListener) { 512 TestHelper("testDestroyOnEventListener", 513 "DoneShimTest.PASSED", 514 "DoneShimTest.FAILED", 515 "web_view/shim"); 516 } 517 518 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestCannotMutateEventName) { 519 TestHelper("testCannotMutateEventName", 520 "DoneShimTest.PASSED", 521 "DoneShimTest.FAILED", 522 "web_view/shim"); 523 } 524 525 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestPartitionRaisesException) { 526 #if defined(OS_WIN) 527 // Flaky on XP bot http://crbug.com/267304 528 if (base::win::GetVersion() <= base::win::VERSION_XP) 529 return; 530 #endif 531 532 TestHelper("testPartitionRaisesException", 533 "DoneShimTest.PASSED", 534 "DoneShimTest.FAILED", 535 "web_view/shim"); 536 } 537 538 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestExecuteScriptFail) { 539 #if defined(OS_WIN) 540 // Flaky on XP bot http://crbug.com/266185 541 if (base::win::GetVersion() <= base::win::VERSION_XP) 542 return; 543 #endif 544 545 TestHelper("testExecuteScriptFail", 546 "DoneShimTest.PASSED", 547 "DoneShimTest.FAILED", 548 "web_view/shim"); 549 } 550 551 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestExecuteScript) { 552 TestHelper("testExecuteScript", 553 "DoneShimTest.PASSED", 554 "DoneShimTest.FAILED", 555 "web_view/shim"); 556 } 557 558 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestTerminateAfterExit) { 559 TestHelper("testTerminateAfterExit", 560 "DoneShimTest.PASSED", 561 "DoneShimTest.FAILED", 562 "web_view/shim"); 563 } 564 565 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAssignSrcAfterCrash) { 566 TestHelper("testAssignSrcAfterCrash", 567 "DoneShimTest.PASSED", 568 "DoneShimTest.FAILED", 569 "web_view/shim"); 570 } 571 572 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveSrcAttribute) { 573 TestHelper("testRemoveSrcAttribute", 574 "DoneShimTest.PASSED", 575 "DoneShimTest.FAILED", 576 "web_view/shim"); 577 } 578 579 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestBrowserPluginNotAllowed) { 580 #if defined(OS_WIN) 581 // Flaky on XP bots. http://crbug.com/267300 582 if (base::win::GetVersion() <= base::win::VERSION_XP) 583 return; 584 #endif 585 586 TestHelper("testBrowserPluginNotAllowed", 587 "DoneShimTest.PASSED", 588 "DoneShimTest.FAILED", 589 "web_view/shim"); 590 } 591 592 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindow) { 593 TestHelper("testNewWindow", 594 "DoneShimTest.PASSED", 595 "DoneShimTest.FAILED", 596 "web_view/shim"); 597 } 598 599 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowTwoListeners) { 600 TestHelper("testNewWindowTwoListeners", 601 "DoneShimTest.PASSED", 602 "DoneShimTest.FAILED", 603 "web_view/shim"); 604 } 605 606 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowNoPreventDefault) { 607 TestHelper("testNewWindowNoPreventDefault", 608 "DoneShimTest.PASSED", 609 "DoneShimTest.FAILED", 610 "web_view/shim"); 611 } 612 613 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowNoReferrerLink) { 614 TestHelper("testNewWindowNoReferrerLink", 615 "DoneShimTest.PASSED", 616 "DoneShimTest.FAILED", 617 "web_view/shim"); 618 } 619 620 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestContentLoadEvent) { 621 TestHelper("testContentLoadEvent", 622 "DoneShimTest.PASSED", 623 "DoneShimTest.FAILED", 624 "web_view/shim"); 625 } 626 627 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPI) { 628 TestHelper("testWebRequestAPI", 629 "DoneShimTest.PASSED", 630 "DoneShimTest.FAILED", 631 "web_view/shim"); 632 } 633 634 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadStartLoadRedirect) { 635 TestHelper("testLoadStartLoadRedirect", 636 "DoneShimTest.PASSED", 637 "DoneShimTest.FAILED", 638 "web_view/shim"); 639 } 640 641 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortEmptyResponse) { 642 TestHelper("testLoadAbortEmptyResponse", 643 "DoneShimTest.PASSED", 644 "DoneShimTest.FAILED", 645 "web_view/shim"); 646 } 647 648 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalChromeURL) { 649 TestHelper("testLoadAbortIllegalChromeURL", 650 "DoneShimTest.PASSED", 651 "DoneShimTest.FAILED", 652 "web_view/shim"); 653 } 654 655 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalFileURL) { 656 TestHelper("testLoadAbortIllegalFileURL", 657 "DoneShimTest.PASSED", 658 "DoneShimTest.FAILED", 659 "web_view/shim"); 660 } 661 662 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReload) { 663 TestHelper("testReload", 664 "DoneShimTest.PASSED", 665 "DoneShimTest.FAILED", 666 "web_view/shim"); 667 } 668 669 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestGetProcessId) { 670 TestHelper("testGetProcessId", 671 "DoneShimTest.PASSED", 672 "DoneShimTest.FAILED", 673 "web_view/shim"); 674 } 675 676 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveWebviewOnExit) { 677 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 678 679 // Launch the app and wait until it's ready to load a test. 680 ExtensionTestMessageListener launched_listener("Launched", false); 681 LoadAndLaunchPlatformApp("web_view/shim"); 682 ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); 683 684 content::WebContents* embedder_web_contents = 685 GetFirstShellWindowWebContents(); 686 ASSERT_TRUE(embedder_web_contents); 687 688 GURL::Replacements replace_host; 689 std::string host_str("localhost"); // Must stay in scope with replace_host. 690 replace_host.SetHostStr(host_str); 691 692 std::string guest_path( 693 "/extensions/platform_apps/web_view/shim/empty_guest.html"); 694 GURL guest_url = embedded_test_server()->GetURL(guest_path); 695 guest_url = guest_url.ReplaceComponents(replace_host); 696 697 ui_test_utils::UrlLoadObserver guest_observer( 698 guest_url, content::NotificationService::AllSources()); 699 700 // Run the test and wait until the guest WebContents is available and has 701 // finished loading. 702 ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false); 703 EXPECT_TRUE(content::ExecuteScript( 704 embedder_web_contents, 705 "runTest('testRemoveWebviewOnExit')")); 706 guest_observer.Wait(); 707 708 content::Source<content::NavigationController> source = 709 guest_observer.source(); 710 EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest()); 711 712 ASSERT_TRUE(guest_loaded_listener.WaitUntilSatisfied()); 713 714 content::WindowedNotificationObserver observer( 715 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 716 content::Source<content::WebContents>(source->GetWebContents())); 717 718 // Tell the embedder to kill the guest. 719 EXPECT_TRUE(content::ExecuteScript( 720 embedder_web_contents, 721 "removeWebviewOnExitDoCrash();")); 722 723 // Wait until the guest WebContents is destroyed. 724 observer.Wait(); 725 } 726 727 IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) { 728 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/src_attribute")) 729 << message_; 730 } 731 732 // This test verifies that prerendering has been disabled inside <webview>. 733 // This test is here rather than in PrerenderBrowserTest for testing convenience 734 // only. If it breaks then this is a bug in the prerenderer. 735 IN_PROC_BROWSER_TEST_F(WebViewTest, NoPrerenderer) { 736 ASSERT_TRUE(StartEmbeddedTestServer()); 737 content::WebContents* guest_web_contents = 738 LoadGuest( 739 "/extensions/platform_apps/web_view/noprerenderer/guest.html", 740 "web_view/noprerenderer"); 741 ASSERT_TRUE(guest_web_contents != NULL); 742 743 PrerenderLinkManager* prerender_link_manager = 744 PrerenderLinkManagerFactory::GetForProfile( 745 Profile::FromBrowserContext(guest_web_contents->GetBrowserContext())); 746 ASSERT_TRUE(prerender_link_manager != NULL); 747 EXPECT_TRUE(prerender_link_manager->IsEmpty()); 748 } 749 750 // This tests cookie isolation for packaged apps with webview tags. It navigates 751 // the main browser window to a page that sets a cookie and loads an app with 752 // multiple webview tags. Each tag sets a cookie and the test checks the proper 753 // storage isolation is enforced. 754 IN_PROC_BROWSER_TEST_F(WebViewTest, CookieIsolation) { 755 ASSERT_TRUE(StartEmbeddedTestServer()); 756 const std::string kExpire = 757 "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);"; 758 std::string cookie_script1(kExpire); 759 cookie_script1.append( 760 "document.cookie = 'guest1=true; path=/; expires=' + expire + ';';"); 761 std::string cookie_script2(kExpire); 762 cookie_script2.append( 763 "document.cookie = 'guest2=true; path=/; expires=' + expire + ';';"); 764 765 GURL::Replacements replace_host; 766 std::string host_str("localhost"); // Must stay in scope with replace_host. 767 replace_host.SetHostStr(host_str); 768 769 GURL set_cookie_url = embedded_test_server()->GetURL( 770 "/extensions/platform_apps/isolation/set_cookie.html"); 771 set_cookie_url = set_cookie_url.ReplaceComponents(replace_host); 772 773 // The first two partitions will be used to set cookies and ensure they are 774 // shared. The named partition is used to ensure that cookies are isolated 775 // between partitions within the same app. 776 content::WebContents* cookie_contents1; 777 content::WebContents* cookie_contents2; 778 content::WebContents* named_partition_contents1; 779 content::WebContents* named_partition_contents2; 780 781 NavigateAndOpenAppForIsolation(set_cookie_url, &cookie_contents1, 782 &cookie_contents2, &named_partition_contents1, 783 &named_partition_contents2, NULL, NULL, NULL); 784 785 EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1)); 786 EXPECT_TRUE(content::ExecuteScript(cookie_contents2, cookie_script2)); 787 788 int cookie_size; 789 std::string cookie_value; 790 791 // Test the regular browser context to ensure we have only one cookie. 792 automation_util::GetCookies(GURL("http://localhost"), 793 browser()->tab_strip_model()->GetWebContentsAt(0), 794 &cookie_size, &cookie_value); 795 EXPECT_EQ("testCookie=1", cookie_value); 796 797 // The default behavior is to combine webview tags with no explicit partition 798 // declaration into the same in-memory partition. Test the webview tags to 799 // ensure we have properly set the cookies and we have both cookies in both 800 // tags. 801 automation_util::GetCookies(GURL("http://localhost"), 802 cookie_contents1, 803 &cookie_size, &cookie_value); 804 EXPECT_EQ("guest1=true; guest2=true", cookie_value); 805 806 automation_util::GetCookies(GURL("http://localhost"), 807 cookie_contents2, 808 &cookie_size, &cookie_value); 809 EXPECT_EQ("guest1=true; guest2=true", cookie_value); 810 811 // The third tag should not have any cookies as it is in a separate partition. 812 automation_util::GetCookies(GURL("http://localhost"), 813 named_partition_contents1, 814 &cookie_size, &cookie_value); 815 EXPECT_EQ("", cookie_value); 816 } 817 818 // This tests that in-memory storage partitions are reset on browser restart, 819 // but persistent ones maintain state for cookies and HTML5 storage. 820 IN_PROC_BROWSER_TEST_F(WebViewTest, PRE_StoragePersistence) { 821 ASSERT_TRUE(StartEmbeddedTestServer()); 822 const std::string kExpire = 823 "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);"; 824 std::string cookie_script1(kExpire); 825 cookie_script1.append( 826 "document.cookie = 'inmemory=true; path=/; expires=' + expire + ';';"); 827 std::string cookie_script2(kExpire); 828 cookie_script2.append( 829 "document.cookie = 'persist1=true; path=/; expires=' + expire + ';';"); 830 std::string cookie_script3(kExpire); 831 cookie_script3.append( 832 "document.cookie = 'persist2=true; path=/; expires=' + expire + ';';"); 833 834 // We don't care where the main browser is on this test. 835 GURL blank_url("about:blank"); 836 837 // The first two partitions will be used to set cookies and ensure they are 838 // shared. The named partition is used to ensure that cookies are isolated 839 // between partitions within the same app. 840 content::WebContents* cookie_contents1; 841 content::WebContents* cookie_contents2; 842 content::WebContents* named_partition_contents1; 843 content::WebContents* named_partition_contents2; 844 content::WebContents* persistent_partition_contents1; 845 content::WebContents* persistent_partition_contents2; 846 content::WebContents* persistent_partition_contents3; 847 NavigateAndOpenAppForIsolation(blank_url, &cookie_contents1, 848 &cookie_contents2, &named_partition_contents1, 849 &named_partition_contents2, 850 &persistent_partition_contents1, 851 &persistent_partition_contents2, 852 &persistent_partition_contents3); 853 854 // Set the inmemory=true cookie for tags with inmemory partitions. 855 EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1)); 856 EXPECT_TRUE(content::ExecuteScript(named_partition_contents1, 857 cookie_script1)); 858 859 // For the two different persistent storage partitions, set the 860 // two different cookies so we can check that they aren't comingled below. 861 EXPECT_TRUE(content::ExecuteScript(persistent_partition_contents1, 862 cookie_script2)); 863 864 EXPECT_TRUE(content::ExecuteScript(persistent_partition_contents3, 865 cookie_script3)); 866 867 int cookie_size; 868 std::string cookie_value; 869 870 // Check that all in-memory partitions have a cookie set. 871 automation_util::GetCookies(GURL("http://localhost"), 872 cookie_contents1, 873 &cookie_size, &cookie_value); 874 EXPECT_EQ("inmemory=true", cookie_value); 875 automation_util::GetCookies(GURL("http://localhost"), 876 cookie_contents2, 877 &cookie_size, &cookie_value); 878 EXPECT_EQ("inmemory=true", cookie_value); 879 automation_util::GetCookies(GURL("http://localhost"), 880 named_partition_contents1, 881 &cookie_size, &cookie_value); 882 EXPECT_EQ("inmemory=true", cookie_value); 883 automation_util::GetCookies(GURL("http://localhost"), 884 named_partition_contents2, 885 &cookie_size, &cookie_value); 886 EXPECT_EQ("inmemory=true", cookie_value); 887 888 // Check that all persistent partitions kept their state. 889 automation_util::GetCookies(GURL("http://localhost"), 890 persistent_partition_contents1, 891 &cookie_size, &cookie_value); 892 EXPECT_EQ("persist1=true", cookie_value); 893 automation_util::GetCookies(GURL("http://localhost"), 894 persistent_partition_contents2, 895 &cookie_size, &cookie_value); 896 EXPECT_EQ("persist1=true", cookie_value); 897 automation_util::GetCookies(GURL("http://localhost"), 898 persistent_partition_contents3, 899 &cookie_size, &cookie_value); 900 EXPECT_EQ("persist2=true", cookie_value); 901 } 902 903 // This is the post-reset portion of the StoragePersistence test. See 904 // PRE_StoragePersistence for main comment. 905 IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_StoragePersistence) { 906 ASSERT_TRUE(StartEmbeddedTestServer()); 907 908 // We don't care where the main browser is on this test. 909 GURL blank_url("about:blank"); 910 911 // The first two partitions will be used to set cookies and ensure they are 912 // shared. The named partition is used to ensure that cookies are isolated 913 // between partitions within the same app. 914 content::WebContents* cookie_contents1; 915 content::WebContents* cookie_contents2; 916 content::WebContents* named_partition_contents1; 917 content::WebContents* named_partition_contents2; 918 content::WebContents* persistent_partition_contents1; 919 content::WebContents* persistent_partition_contents2; 920 content::WebContents* persistent_partition_contents3; 921 NavigateAndOpenAppForIsolation(blank_url, &cookie_contents1, 922 &cookie_contents2, &named_partition_contents1, 923 &named_partition_contents2, 924 &persistent_partition_contents1, 925 &persistent_partition_contents2, 926 &persistent_partition_contents3); 927 928 int cookie_size; 929 std::string cookie_value; 930 931 // Check that all in-memory partitions lost their state. 932 automation_util::GetCookies(GURL("http://localhost"), 933 cookie_contents1, 934 &cookie_size, &cookie_value); 935 EXPECT_EQ("", cookie_value); 936 automation_util::GetCookies(GURL("http://localhost"), 937 cookie_contents2, 938 &cookie_size, &cookie_value); 939 EXPECT_EQ("", cookie_value); 940 automation_util::GetCookies(GURL("http://localhost"), 941 named_partition_contents1, 942 &cookie_size, &cookie_value); 943 EXPECT_EQ("", cookie_value); 944 automation_util::GetCookies(GURL("http://localhost"), 945 named_partition_contents2, 946 &cookie_size, &cookie_value); 947 EXPECT_EQ("", cookie_value); 948 949 // Check that all persistent partitions kept their state. 950 automation_util::GetCookies(GURL("http://localhost"), 951 persistent_partition_contents1, 952 &cookie_size, &cookie_value); 953 EXPECT_EQ("persist1=true", cookie_value); 954 automation_util::GetCookies(GURL("http://localhost"), 955 persistent_partition_contents2, 956 &cookie_size, &cookie_value); 957 EXPECT_EQ("persist1=true", cookie_value); 958 automation_util::GetCookies(GURL("http://localhost"), 959 persistent_partition_contents3, 960 &cookie_size, &cookie_value); 961 EXPECT_EQ("persist2=true", cookie_value); 962 } 963 964 #if defined(OS_WIN) 965 // This test is very flaky on Win Aura, Win XP, Win 7. http://crbug.com/248873 966 #define MAYBE_DOMStorageIsolation DISABLED_DOMStorageIsolation 967 #else 968 #define MAYBE_DOMStorageIsolation DOMStorageIsolation 969 #endif 970 971 // This tests DOM storage isolation for packaged apps with webview tags. It 972 // loads an app with multiple webview tags and each tag sets DOM storage 973 // entries, which the test checks to ensure proper storage isolation is 974 // enforced. 975 IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_DOMStorageIsolation) { 976 ASSERT_TRUE(StartEmbeddedTestServer()); 977 GURL regular_url = embedded_test_server()->GetURL("/title1.html"); 978 979 std::string output; 980 std::string get_local_storage("window.domAutomationController.send(" 981 "window.localStorage.getItem('foo') || 'badval')"); 982 std::string get_session_storage("window.domAutomationController.send(" 983 "window.sessionStorage.getItem('bar') || 'badval')"); 984 985 content::WebContents* default_tag_contents1; 986 content::WebContents* default_tag_contents2; 987 content::WebContents* storage_contents1; 988 content::WebContents* storage_contents2; 989 990 NavigateAndOpenAppForIsolation(regular_url, &default_tag_contents1, 991 &default_tag_contents2, &storage_contents1, 992 &storage_contents2, NULL, NULL, NULL); 993 994 // Initialize the storage for the first of the two tags that share a storage 995 // partition. 996 EXPECT_TRUE(content::ExecuteScript(storage_contents1, 997 "initDomStorage('page1')")); 998 999 // Let's test that the expected values are present in the first tag, as they 1000 // will be overwritten once we call the initDomStorage on the second tag. 1001 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1, 1002 get_local_storage.c_str(), 1003 &output)); 1004 EXPECT_STREQ("local-page1", output.c_str()); 1005 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1, 1006 get_session_storage.c_str(), 1007 &output)); 1008 EXPECT_STREQ("session-page1", output.c_str()); 1009 1010 // Now, init the storage in the second tag in the same storage partition, 1011 // which will overwrite the shared localStorage. 1012 EXPECT_TRUE(content::ExecuteScript(storage_contents2, 1013 "initDomStorage('page2')")); 1014 1015 // The localStorage value now should reflect the one written through the 1016 // second tag. 1017 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1, 1018 get_local_storage.c_str(), 1019 &output)); 1020 EXPECT_STREQ("local-page2", output.c_str()); 1021 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2, 1022 get_local_storage.c_str(), 1023 &output)); 1024 EXPECT_STREQ("local-page2", output.c_str()); 1025 1026 // Session storage is not shared though, as each webview tag has separate 1027 // instance, even if they are in the same storage partition. 1028 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1, 1029 get_session_storage.c_str(), 1030 &output)); 1031 EXPECT_STREQ("session-page1", output.c_str()); 1032 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2, 1033 get_session_storage.c_str(), 1034 &output)); 1035 EXPECT_STREQ("session-page2", output.c_str()); 1036 1037 // Also, let's check that the main browser and another tag that doesn't share 1038 // the same partition don't have those values stored. 1039 EXPECT_TRUE(ExecuteScriptAndExtractString( 1040 browser()->tab_strip_model()->GetWebContentsAt(0), 1041 get_local_storage.c_str(), 1042 &output)); 1043 EXPECT_STREQ("badval", output.c_str()); 1044 EXPECT_TRUE(ExecuteScriptAndExtractString( 1045 browser()->tab_strip_model()->GetWebContentsAt(0), 1046 get_session_storage.c_str(), 1047 &output)); 1048 EXPECT_STREQ("badval", output.c_str()); 1049 EXPECT_TRUE(ExecuteScriptAndExtractString(default_tag_contents1, 1050 get_local_storage.c_str(), 1051 &output)); 1052 EXPECT_STREQ("badval", output.c_str()); 1053 EXPECT_TRUE(ExecuteScriptAndExtractString(default_tag_contents1, 1054 get_session_storage.c_str(), 1055 &output)); 1056 EXPECT_STREQ("badval", output.c_str()); 1057 } 1058 1059 // See crbug.com/248500 1060 #if defined(OS_WIN) 1061 #define MAYBE_IndexedDBIsolation DISABLED_IndexedDBIsolation 1062 #else 1063 #define MAYBE_IndexedDBIsolation IndexedDBIsolation 1064 #endif 1065 1066 // This tests IndexedDB isolation for packaged apps with webview tags. It loads 1067 // an app with multiple webview tags and each tag creates an IndexedDB record, 1068 // which the test checks to ensure proper storage isolation is enforced. 1069 IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_IndexedDBIsolation) { 1070 ASSERT_TRUE(StartEmbeddedTestServer()); 1071 GURL regular_url = embedded_test_server()->GetURL("/title1.html"); 1072 1073 content::WebContents* default_tag_contents1; 1074 content::WebContents* default_tag_contents2; 1075 content::WebContents* storage_contents1; 1076 content::WebContents* storage_contents2; 1077 1078 NavigateAndOpenAppForIsolation(regular_url, &default_tag_contents1, 1079 &default_tag_contents2, &storage_contents1, 1080 &storage_contents2, NULL, NULL, NULL); 1081 1082 // Initialize the storage for the first of the two tags that share a storage 1083 // partition. 1084 ExecuteScriptWaitForTitle(storage_contents1, "initIDB()", "idb created"); 1085 ExecuteScriptWaitForTitle(storage_contents1, "addItemIDB(7, 'page1')", 1086 "addItemIDB complete"); 1087 ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)", 1088 "readItemIDB complete"); 1089 1090 std::string output; 1091 std::string get_value( 1092 "window.domAutomationController.send(getValueIDB() || 'badval')"); 1093 1094 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1, 1095 get_value.c_str(), &output)); 1096 EXPECT_STREQ("page1", output.c_str()); 1097 1098 // Initialize the db in the second tag. 1099 ExecuteScriptWaitForTitle(storage_contents2, "initIDB()", "idb open"); 1100 1101 // Since we share a partition, reading the value should return the existing 1102 // one. 1103 ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)", 1104 "readItemIDB complete"); 1105 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2, 1106 get_value.c_str(), &output)); 1107 EXPECT_STREQ("page1", output.c_str()); 1108 1109 // Now write through the second tag and read it back. 1110 ExecuteScriptWaitForTitle(storage_contents2, "addItemIDB(7, 'page2')", 1111 "addItemIDB complete"); 1112 ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)", 1113 "readItemIDB complete"); 1114 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2, 1115 get_value.c_str(), &output)); 1116 EXPECT_STREQ("page2", output.c_str()); 1117 1118 // Reset the document title, otherwise the next call will not see a change and 1119 // will hang waiting for it. 1120 EXPECT_TRUE(content::ExecuteScript(storage_contents1, 1121 "document.title = 'foo'")); 1122 1123 // Read through the first tag to ensure we have the second value. 1124 ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)", 1125 "readItemIDB complete"); 1126 EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1, 1127 get_value.c_str(), &output)); 1128 EXPECT_STREQ("page2", output.c_str()); 1129 1130 // Now, let's confirm there is no database in the main browser and another 1131 // tag that doesn't share the same partition. Due to the IndexedDB API design, 1132 // open will succeed, but the version will be 1, since it creates the database 1133 // if it is not found. The two tags use database version 3, so we avoid 1134 // ambiguity. 1135 const char* script = 1136 "indexedDB.open('isolation').onsuccess = function(e) {" 1137 " if (e.target.result.version == 1)" 1138 " document.title = 'db not found';" 1139 " else " 1140 " document.title = 'error';" 1141 "}"; 1142 ExecuteScriptWaitForTitle(browser()->tab_strip_model()->GetWebContentsAt(0), 1143 script, "db not found"); 1144 ExecuteScriptWaitForTitle(default_tag_contents1, script, "db not found"); 1145 } 1146 1147 // This test ensures that closing app window on 'loadcommit' does not crash. 1148 // The test launches an app with guest and closes the window on loadcommit. It 1149 // then launches the app window again. The process is repeated 3 times. 1150 IN_PROC_BROWSER_TEST_F(WebViewTest, CloseOnLoadcommit) { 1151 ExtensionTestMessageListener done_test_listener( 1152 "done-close-on-loadcommit", false); 1153 LoadAndLaunchPlatformApp("web_view/close_on_loadcommit"); 1154 ASSERT_TRUE(done_test_listener.WaitUntilSatisfied()); 1155 } 1156 1157 IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIDeny_TestDeny) { 1158 MediaAccessAPIDenyTestHelper("testDeny"); 1159 } 1160 1161 IN_PROC_BROWSER_TEST_F(WebViewTest, 1162 MediaAccessAPIDeny_TestDenyThenAllowThrows) { 1163 MediaAccessAPIDenyTestHelper("testDenyThenAllowThrows"); 1164 1165 } 1166 1167 IN_PROC_BROWSER_TEST_F(WebViewTest, 1168 MediaAccessAPIDeny_TestDenyWithPreventDefault) { 1169 MediaAccessAPIDenyTestHelper("testDenyWithPreventDefault"); 1170 } 1171 1172 IN_PROC_BROWSER_TEST_F(WebViewTest, 1173 MediaAccessAPIDeny_TestNoListenersImplyDeny) { 1174 MediaAccessAPIDenyTestHelper("testNoListenersImplyDeny"); 1175 } 1176 1177 IN_PROC_BROWSER_TEST_F(WebViewTest, 1178 MediaAccessAPIDeny_TestNoPreventDefaultImpliesDeny) { 1179 MediaAccessAPIDenyTestHelper("testNoPreventDefaultImpliesDeny"); 1180 } 1181 1182 void WebViewTest::MediaAccessAPIAllowTestHelper(const std::string& test_name) { 1183 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 1184 ExtensionTestMessageListener launched_listener("Launched", false); 1185 LoadAndLaunchPlatformApp("web_view/media_access/allow"); 1186 ASSERT_TRUE(launched_listener.WaitUntilSatisfied()); 1187 1188 content::WebContents* embedder_web_contents = 1189 GetFirstShellWindowWebContents(); 1190 ASSERT_TRUE(embedder_web_contents); 1191 MockWebContentsDelegate* mock = new MockWebContentsDelegate; 1192 embedder_web_contents->SetDelegate(mock); 1193 1194 ExtensionTestMessageListener done_listener("DoneMediaTest.PASSED", false); 1195 done_listener.AlsoListenForFailureMessage("DoneMediaTest.FAILED"); 1196 EXPECT_TRUE( 1197 content::ExecuteScript( 1198 embedder_web_contents, 1199 base::StringPrintf("startAllowTest('%s')", 1200 test_name.c_str()))); 1201 ASSERT_TRUE(done_listener.WaitUntilSatisfied()); 1202 1203 mock->WaitForSetMediaPermission(); 1204 } 1205 1206 IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllow) { 1207 MediaAccessAPIAllowTestHelper("testAllow"); 1208 } 1209 1210 IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowAndThenDeny) { 1211 MediaAccessAPIAllowTestHelper("testAllowAndThenDeny"); 1212 } 1213 1214 IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowTwice) { 1215 MediaAccessAPIAllowTestHelper("testAllowTwice"); 1216 } 1217 1218 IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowAsync) { 1219 MediaAccessAPIAllowTestHelper("testAllowAsync"); 1220 } 1221 1222 // Checks that window.screenX/screenY/screenLeft/screenTop works correctly for 1223 // guests. 1224 IN_PROC_BROWSER_TEST_F(WebViewTest, ScreenCoordinates) { 1225 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 1226 ASSERT_TRUE(RunPlatformAppTestWithArg( 1227 "platform_apps/web_view/common", "screen_coordinates")) 1228 << message_; 1229 } 1230 1231 IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognition) { 1232 ASSERT_TRUE(StartEmbeddedTestServer()); 1233 content::WebContents* guest_web_contents = LoadGuest( 1234 "/extensions/platform_apps/web_view/speech/guest.html", 1235 "web_view/speech"); 1236 ASSERT_TRUE(guest_web_contents); 1237 1238 // Click on the guest (center of the WebContents), the guest is rendered in a 1239 // way that this will trigger clicking on speech recognition input mic. 1240 SimulateMouseClick(guest_web_contents, 0, WebKit::WebMouseEvent::ButtonLeft); 1241 1242 string16 expected_title(ASCIIToUTF16("PASSED")); 1243 string16 error_title(ASCIIToUTF16("FAILED")); 1244 content::TitleWatcher title_watcher(guest_web_contents, expected_title); 1245 title_watcher.AlsoWaitForTitle(error_title); 1246 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 1247 } 1248 1249 IN_PROC_BROWSER_TEST_F(WebViewTest, TearDownTest) { 1250 ExtensionTestMessageListener first_loaded_listener("guest-loaded", false); 1251 const extensions::Extension* extension = 1252 LoadAndLaunchPlatformApp("web_view/teardown"); 1253 ASSERT_TRUE(first_loaded_listener.WaitUntilSatisfied()); 1254 apps::ShellWindow* window = NULL; 1255 if (!GetShellWindowCount()) 1256 window = CreateShellWindow(extension); 1257 else 1258 window = GetFirstShellWindow(); 1259 CloseShellWindow(window); 1260 1261 // Load the app again. 1262 ExtensionTestMessageListener second_loaded_listener("guest-loaded", false); 1263 LoadAndLaunchPlatformApp("web_view/teardown"); 1264 ASSERT_TRUE(second_loaded_listener.WaitUntilSatisfied()); 1265 } 1266 1267 // In following GeolocationAPIEmbedderHasNoAccess* tests, embedder (i.e. the 1268 // platform app) does not have geolocation permission for this test. 1269 // No matter what the API does, geolocation permission would be denied. 1270 // Note that the test name prefix must be "GeolocationAPI". 1271 IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasNoAccessAllow) { 1272 TestHelper("testDenyDenies", 1273 "DoneGeolocationTest.PASSED", 1274 "DoneGeolocationTest.FAILED", 1275 "web_view/geolocation/embedder_has_no_permission"); 1276 } 1277 1278 IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasNoAccessDeny) { 1279 TestHelper("testDenyDenies", 1280 "DoneGeolocationTest.PASSED", 1281 "DoneGeolocationTest.FAILED", 1282 "web_view/geolocation/embedder_has_no_permission"); 1283 } 1284 1285 // In following GeolocationAPIEmbedderHasAccess* tests, embedder (i.e. the 1286 // platform app) has geolocation permission 1287 // 1288 // Note that these test names must be "GeolocationAPI" prefixed (b/c we mock out 1289 // geolocation in this case). 1290 // 1291 // Also note that these are run separately because OverrideGeolocation() doesn't 1292 // mock out geolocation for multiple navigator.geolocation calls properly and 1293 // the tests become flaky. 1294 // GeolocationAPI* test 1 of 3. 1295 IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasAccessAllow) { 1296 TestHelper("testAllow", 1297 "DoneGeolocationTest.PASSED", 1298 "DoneGeolocationTest.FAILED", 1299 "web_view/geolocation/embedder_has_permission"); 1300 } 1301 1302 // GeolocationAPI* test 2 of 3. 1303 IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasAccessDeny) { 1304 TestHelper("testDeny", 1305 "DoneGeolocationTest.PASSED", 1306 "DoneGeolocationTest.FAILED", 1307 "web_view/geolocation/embedder_has_permission"); 1308 } 1309 1310 // GeolocationAPI* test 3 of 3. 1311 IN_PROC_BROWSER_TEST_F(WebViewTest, 1312 GeolocationAPIEmbedderHasAccessMultipleBridgeIdAllow) { 1313 TestHelper("testMultipleBridgeIdAllow", 1314 "DoneGeolocationTest.PASSED", 1315 "DoneGeolocationTest.FAILED", 1316 "web_view/geolocation/embedder_has_permission"); 1317 } 1318 1319 // Tests that 1320 // BrowserPluginGeolocationPermissionContext::CancelGeolocationPermissionRequest 1321 // is handled correctly (and does not crash). 1322 IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPICancelGeolocation) { 1323 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 1324 ASSERT_TRUE(RunPlatformAppTest( 1325 "platform_apps/web_view/geolocation/cancel_request")) << message_; 1326 } 1327 1328 IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationRequestGone) { 1329 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 1330 ASSERT_TRUE(RunPlatformAppTest( 1331 "platform_apps/web_view/geolocation/geolocation_request_gone")) 1332 << message_; 1333 } 1334 1335 IN_PROC_BROWSER_TEST_F(WebViewTest, ConsoleMessage) { 1336 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 1337 ASSERT_TRUE(RunPlatformAppTestWithArg( 1338 "platform_apps/web_view/common", "console_messages")) 1339 << message_; 1340 } 1341 1342 IN_PROC_BROWSER_TEST_F(WebViewTest, DownloadPermission) { 1343 ASSERT_TRUE(StartEmbeddedTestServer()); // For serving guest pages. 1344 content::WebContents* guest_web_contents = 1345 LoadGuest("/extensions/platform_apps/web_view/download/guest.html", 1346 "web_view/download"); 1347 ASSERT_TRUE(guest_web_contents); 1348 1349 // Replace WebContentsDelegate with mock version so we can intercept download 1350 // requests. 1351 content::WebContentsDelegate* delegate = guest_web_contents->GetDelegate(); 1352 MockDownloadWebContentsDelegate* mock_delegate = 1353 new MockDownloadWebContentsDelegate(delegate); 1354 guest_web_contents->SetDelegate(mock_delegate); 1355 1356 // Start test. 1357 // 1. Guest requests a download that its embedder denies. 1358 EXPECT_TRUE(content::ExecuteScript(guest_web_contents, 1359 "startDownload('download-link-1')")); 1360 mock_delegate->WaitForCanDownload(false); // Expect to not allow. 1361 mock_delegate->Reset(); 1362 1363 // 2. Guest requests a download that its embedder allows. 1364 EXPECT_TRUE(content::ExecuteScript(guest_web_contents, 1365 "startDownload('download-link-2')")); 1366 mock_delegate->WaitForCanDownload(true); // Expect to allow. 1367 mock_delegate->Reset(); 1368 1369 // 3. Guest requests a download that its embedder ignores, this implies deny. 1370 EXPECT_TRUE(content::ExecuteScript(guest_web_contents, 1371 "startDownload('download-link-3')")); 1372 mock_delegate->WaitForCanDownload(false); // Expect to not allow. 1373 } 1374 1375 // This test makes sure loading <webview> does not crash when there is an 1376 // extension which has content script whitelisted/forced. 1377 IN_PROC_BROWSER_TEST_F(WebViewTest, WhitelistedContentScript) { 1378 // Whitelist the extension for running content script we are going to load. 1379 extensions::Extension::ScriptingWhitelist whitelist; 1380 const std::string extension_id = "imeongpbjoodlnmlakaldhlcmijmhpbb"; 1381 whitelist.push_back(extension_id); 1382 extensions::Extension::SetScriptingWhitelist(whitelist); 1383 1384 // Load the extension. 1385 const extensions::Extension* content_script_whitelisted_extension = 1386 LoadExtension(test_data_dir_.AppendASCII( 1387 "platform_apps/web_view/legacy/content_script")); 1388 ASSERT_TRUE(content_script_whitelisted_extension); 1389 ASSERT_EQ(extension_id, content_script_whitelisted_extension->id()); 1390 1391 // Now load an app with <webview>. 1392 ExtensionTestMessageListener done_listener("DoneTest", false); 1393 LoadAndLaunchPlatformApp("web_view/content_script_whitelisted"); 1394 ASSERT_TRUE(done_listener.WaitUntilSatisfied()); 1395 } 1396 1397 IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentReady) { 1398 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_ready")) 1399 << message_; 1400 } 1401 1402 IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentInteractive) { 1403 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_interactive")) 1404 << message_; 1405 } 1406 1407 IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestAlertDialog) { 1408 TestHelper("testAlertDialog", 1409 "DoneDialogTest.PASSED", 1410 "DoneDialogTest.FAILED", 1411 "web_view/dialog"); 1412 } 1413 1414 IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialog) { 1415 TestHelper("testConfirmDialog", 1416 "DoneDialogTest.PASSED", 1417 "DoneDialogTest.FAILED", 1418 "web_view/dialog"); 1419 } 1420 1421 IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogCancel) { 1422 TestHelper("testConfirmDialogCancel", 1423 "DoneDialogTest.PASSED", 1424 "DoneDialogTest.FAILED", 1425 "web_view/dialog"); 1426 } 1427 1428 IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogDefaultCancel) { 1429 TestHelper("testConfirmDialogDefaultCancel", 1430 "DoneDialogTest.PASSED", 1431 "DoneDialogTest.FAILED", 1432 "web_view/dialog"); 1433 } 1434 1435 IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogDefaultGCCancel) { 1436 TestHelper("testConfirmDialogDefaultGCCancel", 1437 "DoneDialogTest.PASSED", 1438 "DoneDialogTest.FAILED", 1439 "web_view/dialog"); 1440 } 1441 1442 IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestPromptDialog) { 1443 TestHelper("testPromptDialog", 1444 "DoneDialogTest.PASSED", 1445 "DoneDialogTest.FAILED", 1446 "web_view/dialog"); 1447 } 1448