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/command_line.h" 6 #include "base/file_util.h" 7 #include "base/path_service.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "content/browser/loader/resource_dispatcher_host_impl.h" 11 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/resource_dispatcher_host_delegate.h" 13 #include "content/public/common/content_switches.h" 14 #include "content/public/test/browser_test_utils.h" 15 #include "content/public/test/test_utils.h" 16 #include "content/shell/browser/shell.h" 17 #include "content/shell/common/shell_switches.h" 18 #include "content/test/content_browser_test.h" 19 #include "content/test/content_browser_test_utils.h" 20 #include "content/test/net/url_request_mock_http_job.h" 21 #include "net/test/embedded_test_server/embedded_test_server.h" 22 #include "net/url_request/url_request.h" 23 #include "ui/gfx/rect.h" 24 25 #if defined(OS_WIN) 26 #include "base/win/registry.h" 27 #endif 28 29 // TODO(jschuh): Finish plugins on Win64. crbug.com/180861 30 #if defined(OS_WIN) && defined(ARCH_CPU_X86_64) 31 #define MAYBE(x) DISABLED_##x 32 #else 33 #define MAYBE(x) x 34 #endif 35 36 namespace content { 37 namespace { 38 39 void SetUrlRequestMock(const base::FilePath& path) { 40 URLRequestMockHTTPJob::AddUrlHandler(path); 41 } 42 43 } 44 45 class PluginTest : public ContentBrowserTest { 46 protected: 47 PluginTest() {} 48 49 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 50 // Some NPAPI tests schedule garbage collection to force object tear-down. 51 command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose_gc"); 52 53 #if defined(OS_WIN) 54 const testing::TestInfo* const test_info = 55 testing::UnitTest::GetInstance()->current_test_info(); 56 if (strcmp(test_info->name(), "MediaPlayerNew") == 0) { 57 // The installer adds our process names to the registry key below. Since 58 // the installer might not have run on this machine, add it manually. 59 base::win::RegKey regkey; 60 if (regkey.Open(HKEY_LOCAL_MACHINE, 61 L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList", 62 KEY_WRITE) == ERROR_SUCCESS) { 63 regkey.CreateKey(L"BROWSER_TESTS.EXE", KEY_READ); 64 } 65 } else if (strcmp(test_info->name(), "FlashSecurity") == 0) { 66 command_line->AppendSwitchASCII(switches::kTestSandbox, 67 "security_tests.dll"); 68 } 69 #elif defined(OS_MACOSX) 70 base::FilePath plugin_dir; 71 PathService::Get(base::DIR_MODULE, &plugin_dir); 72 plugin_dir = plugin_dir.AppendASCII("plugins"); 73 // The plugins directory isn't read by default on the Mac, so it needs to be 74 // explicitly registered. 75 command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir); 76 #endif 77 } 78 79 virtual void SetUpOnMainThread() OVERRIDE { 80 base::FilePath path = GetTestFilePath("", ""); 81 BrowserThread::PostTask( 82 BrowserThread::IO, FROM_HERE, base::Bind(&SetUrlRequestMock, path)); 83 } 84 85 static void LoadAndWaitInWindow(Shell* window, const GURL& url) { 86 base::string16 expected_title(ASCIIToUTF16("OK")); 87 TitleWatcher title_watcher(window->web_contents(), expected_title); 88 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 89 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("plugin_not_found")); 90 NavigateToURL(window, url); 91 base::string16 title = title_watcher.WaitAndGetTitle(); 92 if (title == ASCIIToUTF16("plugin_not_found")) { 93 const testing::TestInfo* const test_info = 94 testing::UnitTest::GetInstance()->current_test_info(); 95 VLOG(0) << "PluginTest." << test_info->name() 96 << " not running because plugin not installed."; 97 } else { 98 EXPECT_EQ(expected_title, title); 99 } 100 } 101 102 void LoadAndWait(const GURL& url) { 103 LoadAndWaitInWindow(shell(), url); 104 } 105 106 GURL GetURL(const char* filename) { 107 return GetTestUrl("npapi", filename); 108 } 109 110 void NavigateAway() { 111 GURL url = GetTestUrl("", "simple_page.html"); 112 LoadAndWait(url); 113 } 114 115 void TestPlugin(const char* filename) { 116 base::FilePath path = GetTestFilePath("plugin", filename); 117 if (!base::PathExists(path)) { 118 const testing::TestInfo* const test_info = 119 testing::UnitTest::GetInstance()->current_test_info(); 120 VLOG(0) << "PluginTest." << test_info->name() 121 << " not running because test data wasn't found."; 122 return; 123 } 124 125 GURL url = GetTestUrl("plugin", filename); 126 LoadAndWait(url); 127 } 128 }; 129 130 // Make sure that navigating away from a plugin referenced by JS doesn't 131 // crash. 132 IN_PROC_BROWSER_TEST_F(PluginTest, UnloadNoCrash) { 133 LoadAndWait(GetURL("layout_test_plugin.html")); 134 NavigateAway(); 135 } 136 137 // Tests if a plugin executing a self deleting script using NPN_GetURL 138 // works without crashing or hanging 139 // Flaky: http://crbug.com/59327 140 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginGetUrl)) { 141 LoadAndWait(GetURL("self_delete_plugin_geturl.html")); 142 } 143 144 // Tests if a plugin executing a self deleting script using Invoke 145 // works without crashing or hanging 146 // Flaky. See http://crbug.com/30702 147 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvoke)) { 148 LoadAndWait(GetURL("self_delete_plugin_invoke.html")); 149 } 150 151 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectReleasedOnDestruction)) { 152 NavigateToURL(shell(), GetURL("npobject_released_on_destruction.html")); 153 NavigateAway(); 154 } 155 156 // Test that a dialog is properly created when a plugin throws an 157 // exception. Should be run for in and out of process plugins, but 158 // the more interesting case is out of process, where we must route 159 // the exception to the correct renderer. 160 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectSetException)) { 161 LoadAndWait(GetURL("npobject_set_exception.html")); 162 } 163 164 #if defined(OS_WIN) 165 // Tests if a plugin executing a self deleting script in the context of 166 // a synchronous mouseup works correctly. 167 // This was never ported to Mac. The only thing remaining is to make 168 // SimulateMouseClick get to Mac plugins, currently it doesn't work. 169 IN_PROC_BROWSER_TEST_F(PluginTest, 170 MAYBE(SelfDeletePluginInvokeInSynchronousMouseUp)) { 171 NavigateToURL(shell(), GetURL("execute_script_delete_in_mouse_up.html")); 172 173 base::string16 expected_title(ASCIIToUTF16("OK")); 174 TitleWatcher title_watcher(shell()->web_contents(), expected_title); 175 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 176 SimulateMouseClick(shell()->web_contents(), 0, 177 blink::WebMouseEvent::ButtonLeft); 178 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 179 } 180 #endif 181 182 // Flaky, http://crbug.com/302274. 183 #if defined(OS_MACOSX) 184 #define MAYBE_GetURLRequest404Response DISABLED_GetURLRequest404Response 185 #else 186 #define MAYBE_GetURLRequest404Response MAYBE(GetURLRequest404Response) 187 #endif 188 189 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_GetURLRequest404Response) { 190 GURL url(URLRequestMockHTTPJob::GetMockUrl( 191 base::FilePath().AppendASCII("npapi"). 192 AppendASCII("plugin_url_request_404.html"))); 193 LoadAndWait(url); 194 } 195 196 // Tests if a plugin executing a self deleting script using Invoke with 197 // a modal dialog showing works without crashing or hanging 198 // Disabled, flakily exceeds timeout, http://crbug.com/46257. 199 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvokeAlert)) { 200 // Navigate asynchronously because if we waitd until it completes, there's a 201 // race condition where the alert can come up before we start watching for it. 202 shell()->LoadURL(GetURL("self_delete_plugin_invoke_alert.html")); 203 204 base::string16 expected_title(ASCIIToUTF16("OK")); 205 TitleWatcher title_watcher(shell()->web_contents(), expected_title); 206 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 207 208 WaitForAppModalDialog(shell()); 209 210 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 211 } 212 213 // Test passing arguments to a plugin. 214 // crbug.com/306318 215 #if !defined(OS_LINUX) 216 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Arguments)) { 217 LoadAndWait(GetURL("arguments.html")); 218 } 219 #endif 220 221 // Test invoking many plugins within a single page. 222 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ManyPlugins)) { 223 LoadAndWait(GetURL("many_plugins.html")); 224 } 225 226 // Test various calls to GetURL from a plugin. 227 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURL)) { 228 LoadAndWait(GetURL("geturl.html")); 229 } 230 231 // Test various calls to GetURL for javascript URLs with 232 // non NULL targets from a plugin. 233 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL)) { 234 LoadAndWait(GetURL("get_javascript_url.html")); 235 } 236 237 // Test that calling GetURL with a javascript URL and target=_self 238 // works properly when the plugin is embedded in a subframe. 239 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL2)) { 240 LoadAndWait(GetURL("get_javascript_url2.html")); 241 } 242 243 // Test is flaky on linux/cros/win builders. http://crbug.com/71904 244 IN_PROC_BROWSER_TEST_F(PluginTest, GetURLRedirectNotification) { 245 LoadAndWait(GetURL("geturl_redirect_notify.html")); 246 } 247 248 // Tests that identity is preserved for NPObjects passed from a plugin 249 // into JavaScript. 250 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectIdentity)) { 251 LoadAndWait(GetURL("npobject_identity.html")); 252 } 253 254 // Tests that if an NPObject is proxies back to its original process, the 255 // original pointer is returned and not a proxy. If this fails the plugin 256 // will crash. 257 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectProxy)) { 258 LoadAndWait(GetURL("npobject_proxy.html")); 259 } 260 261 #if defined(OS_WIN) || defined(OS_MACOSX) 262 // Tests if a plugin executing a self deleting script in the context of 263 // a synchronous paint event works correctly 264 // http://crbug.com/44960 265 IN_PROC_BROWSER_TEST_F(PluginTest, 266 MAYBE(SelfDeletePluginInvokeInSynchronousPaint)) { 267 LoadAndWait(GetURL("execute_script_delete_in_paint.html")); 268 } 269 #endif 270 271 // Tests that if a plugin executes a self resizing script in the context of a 272 // synchronous paint, the plugin doesn't use deallocated memory. 273 // http://crbug.com/139462 274 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ResizeDuringPaint)) { 275 LoadAndWait(GetURL("resize_during_paint.html")); 276 } 277 278 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNewStream)) { 279 LoadAndWait(GetURL("self_delete_plugin_stream.html")); 280 } 281 282 // On Mac this test asserts in plugin_host: http://crbug.com/95558 283 // On all platforms it flakes in ~URLRequestContext: http://crbug.com/310336 284 #if !defined(NDEBUG) 285 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_DeletePluginInDeallocate) { 286 LoadAndWait(GetURL("plugin_delete_in_deallocate.html")); 287 } 288 #endif 289 290 #if defined(OS_WIN) 291 292 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyPluginWindowRect)) { 293 LoadAndWait(GetURL("verify_plugin_window_rect.html")); 294 } 295 296 // Tests that creating a new instance of a plugin while another one is handling 297 // a paint message doesn't cause deadlock. 298 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(CreateInstanceInPaint)) { 299 LoadAndWait(GetURL("create_instance_in_paint.html")); 300 } 301 302 // Tests that putting up an alert in response to a paint doesn't deadlock. 303 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_AlertInWindowMessage) { 304 NavigateToURL(shell(), GetURL("alert_in_window_message.html")); 305 306 WaitForAppModalDialog(shell()); 307 WaitForAppModalDialog(shell()); 308 } 309 310 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyNPObjectLifetimeTest)) { 311 LoadAndWait(GetURL("npobject_lifetime_test.html")); 312 } 313 314 // Tests that we don't crash or assert if NPP_New fails 315 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NewFails)) { 316 LoadAndWait(GetURL("new_fails.html")); 317 } 318 319 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNPNEvaluate)) { 320 LoadAndWait(GetURL("execute_script_delete_in_npn_evaluate.html")); 321 } 322 323 IN_PROC_BROWSER_TEST_F(PluginTest, 324 MAYBE(SelfDeleteCreatePluginInNPNEvaluate)) { 325 LoadAndWait(GetURL("npn_plugin_delete_create_in_evaluate.html")); 326 } 327 328 #endif // OS_WIN 329 330 // If this flakes, reopen http://crbug.com/17645 331 // As of 6 July 2011, this test is flaky on Windows (perhaps due to timing out). 332 #if !defined(OS_MACOSX) 333 // Disabled on Mac because the plugin side isn't implemented yet, see 334 // "TODO(port)" in plugin_javascript_open_popup.cc. 335 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(OpenPopupWindowWithPlugin)) { 336 LoadAndWait(GetURL("get_javascript_open_popup_with_plugin.html")); 337 } 338 #endif 339 340 // Test checking the privacy mode is off. 341 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateDisabled)) { 342 LoadAndWait(GetURL("private.html")); 343 } 344 345 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ScheduleTimer)) { 346 LoadAndWait(GetURL("schedule_timer.html")); 347 } 348 349 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginThreadAsyncCall)) { 350 LoadAndWait(GetURL("plugin_thread_async_call.html")); 351 } 352 353 IN_PROC_BROWSER_TEST_F(PluginTest, PluginSingleRangeRequest) { 354 LoadAndWait(GetURL("plugin_single_range_request.html")); 355 } 356 357 // Test checking the privacy mode is on. 358 // If this flakes on Linux, use http://crbug.com/104380 359 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateEnabled)) { 360 GURL url = GetURL("private.html"); 361 url = GURL(url.spec() + "?private"); 362 LoadAndWaitInWindow(CreateOffTheRecordBrowser(), url); 363 } 364 365 #if defined(OS_WIN) || defined(OS_MACOSX) 366 // Test a browser hang due to special case of multiple 367 // plugin instances indulged in sync calls across renderer. 368 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MultipleInstancesSyncCalls)) { 369 LoadAndWait(GetURL("multiple_instances_sync_calls.html")); 370 } 371 #endif 372 373 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURLRequestFailWrite)) { 374 GURL url(URLRequestMockHTTPJob::GetMockUrl( 375 base::FilePath().AppendASCII("npapi"). 376 AppendASCII("plugin_url_request_fail_write.html"))); 377 LoadAndWait(url); 378 } 379 380 #if defined(OS_WIN) 381 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(EnsureScriptingWorksInDestroy)) { 382 LoadAndWait(GetURL("ensure_scripting_works_in_destroy.html")); 383 } 384 385 // This test uses a Windows Event to signal to the plugin that it should crash 386 // on NP_Initialize. 387 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NoHangIfInitCrashes)) { 388 HANDLE crash_event = CreateEvent(NULL, TRUE, FALSE, L"TestPluginCrashOnInit"); 389 SetEvent(crash_event); 390 LoadAndWait(GetURL("no_hang_if_init_crashes.html")); 391 CloseHandle(crash_event); 392 } 393 #endif 394 395 // If this flakes on Mac, use http://crbug.com/111508 396 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginReferrerTest)) { 397 GURL url(URLRequestMockHTTPJob::GetMockUrl( 398 base::FilePath().AppendASCII("npapi"). 399 AppendASCII("plugin_url_request_referrer_test.html"))); 400 LoadAndWait(url); 401 } 402 403 #if defined(OS_MACOSX) 404 // Test is flaky, see http://crbug.com/134515. 405 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_PluginConvertPointTest) { 406 gfx::Rect bounds(50, 50, 400, 400); 407 SetWindowBounds(shell()->window(), bounds); 408 409 NavigateToURL(shell(), GetURL("convert_point.html")); 410 411 base::string16 expected_title(ASCIIToUTF16("OK")); 412 TitleWatcher title_watcher(shell()->web_contents(), expected_title); 413 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 414 // TODO(stuartmorgan): When the automation system supports sending clicks, 415 // change the test to trigger on mouse-down rather than window focus. 416 417 // TODO: is this code still needed? It was here when it used to run in 418 // browser_tests. 419 //static_cast<WebContentsDelegate*>(shell())-> 420 // ActivateContents(shell()->web_contents()); 421 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 422 } 423 #endif 424 425 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Flash)) { 426 TestPlugin("flash.html"); 427 } 428 429 #if defined(OS_WIN) 430 // Windows only test 431 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashSecurity) { 432 TestPlugin("flash.html"); 433 } 434 #endif // defined(OS_WIN) 435 436 #if defined(OS_WIN) 437 // TODO(port) Port the following tests to platforms that have the required 438 // plugins. 439 // Flaky: http://crbug.com/55915 440 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Quicktime)) { 441 TestPlugin("quicktime.html"); 442 } 443 444 // Disabled - http://crbug.com/44662 445 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MediaPlayerNew)) { 446 TestPlugin("wmp_new.html"); 447 } 448 449 // Disabled - http://crbug.com/44673 450 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Real)) { 451 TestPlugin("real.html"); 452 } 453 454 // http://crbug.com/320041 455 #if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \ 456 (defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN)) 457 #define MAYBE_FlashOctetStream DISABLED_FlashOctetStream 458 #else 459 #define MAYBE_FlashOctetStream FlashOctetStream 460 #endif 461 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_FlashOctetStream) { 462 TestPlugin("flash-octet-stream.html"); 463 } 464 465 #if defined(OS_WIN) 466 // http://crbug.com/53926 467 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashLayoutWhilePainting) { 468 #else 469 IN_PROC_BROWSER_TEST_F(PluginTest, FlashLayoutWhilePainting) { 470 #endif 471 TestPlugin("flash-layout-while-painting.html"); 472 } 473 474 // http://crbug.com/8690 475 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_Java) { 476 TestPlugin("Java.html"); 477 } 478 479 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Silverlight)) { 480 TestPlugin("silverlight.html"); 481 } 482 #endif // defined(OS_WIN) 483 484 class TestResourceDispatcherHostDelegate 485 : public ResourceDispatcherHostDelegate { 486 public: 487 TestResourceDispatcherHostDelegate() : found_cookie_(false) {} 488 489 bool found_cookie() { return found_cookie_; } 490 491 void WaitForPluginRequest() { 492 if (found_cookie_) 493 return; 494 495 runner_ = new MessageLoopRunner; 496 runner_->Run(); 497 } 498 499 private: 500 // ResourceDispatcherHostDelegate implementation: 501 virtual void OnResponseStarted( 502 net::URLRequest* request, 503 ResourceContext* resource_context, 504 ResourceResponse* response, 505 IPC::Sender* sender) OVERRIDE { 506 // The URL below comes from plugin_geturl_test.cc. 507 if (!EndsWith(request->url().spec(), 508 "npapi/plugin_ref_target_page.html", 509 true)) { 510 return; 511 } 512 net::HttpRequestHeaders headers; 513 bool found_cookie = false; 514 if (request->GetFullRequestHeaders(&headers) && 515 headers.ToString().find("Cookie: blah") != std::string::npos) { 516 found_cookie = true; 517 } 518 BrowserThread::PostTask( 519 BrowserThread::UI, 520 FROM_HERE, 521 base::Bind(&TestResourceDispatcherHostDelegate::GotCookie, 522 base::Unretained(this), found_cookie)); 523 } 524 525 void GotCookie(bool found_cookie) { 526 found_cookie_ = found_cookie; 527 if (runner_) 528 runner_->QuitClosure().Run(); 529 } 530 531 scoped_refptr<MessageLoopRunner> runner_; 532 bool found_cookie_; 533 534 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate); 535 }; 536 537 // Ensure that cookies get sent with plugin requests. 538 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Cookies)) { 539 // Create a new browser just to ensure that the plugin process' child_id is 540 // not equal to its type (PROCESS_TYPE_PLUGIN), as that was the error which 541 // caused this bug. 542 NavigateToURL(CreateBrowser(), GURL("about:blank")); 543 544 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 545 GURL url(embedded_test_server()->GetURL("/npapi/cookies.html")); 546 547 TestResourceDispatcherHostDelegate test_delegate; 548 ResourceDispatcherHostDelegate* old_delegate = 549 ResourceDispatcherHostImpl::Get()->delegate(); 550 ResourceDispatcherHostImpl::Get()->SetDelegate(&test_delegate); 551 LoadAndWait(url); 552 test_delegate.WaitForPluginRequest(); 553 ASSERT_TRUE(test_delegate.found_cookie()); 554 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate); 555 } 556 557 } // namespace content 558