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/content_browser_test.h" 16 #include "content/public/test/content_browser_test_utils.h" 17 #include "content/public/test/test_utils.h" 18 #include "content/shell/browser/shell.h" 19 #include "content/shell/common/shell_switches.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 using base::ASCIIToUTF16; 37 38 namespace content { 39 namespace { 40 41 void SetUrlRequestMock(const base::FilePath& path) { 42 URLRequestMockHTTPJob::AddUrlHandler(path); 43 } 44 45 } 46 47 class PluginTest : public ContentBrowserTest { 48 protected: 49 PluginTest() {} 50 51 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 52 // Some NPAPI tests schedule garbage collection to force object tear-down. 53 command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose_gc"); 54 55 #if defined(OS_WIN) 56 const testing::TestInfo* const test_info = 57 testing::UnitTest::GetInstance()->current_test_info(); 58 if (strcmp(test_info->name(), "MediaPlayerNew") == 0) { 59 // The installer adds our process names to the registry key below. Since 60 // the installer might not have run on this machine, add it manually. 61 base::win::RegKey regkey; 62 if (regkey.Open(HKEY_LOCAL_MACHINE, 63 L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList", 64 KEY_WRITE) == ERROR_SUCCESS) { 65 regkey.CreateKey(L"BROWSER_TESTS.EXE", KEY_READ); 66 } 67 } 68 #elif defined(OS_MACOSX) 69 base::FilePath plugin_dir; 70 PathService::Get(base::DIR_MODULE, &plugin_dir); 71 plugin_dir = plugin_dir.AppendASCII("plugins"); 72 // The plugins directory isn't read by default on the Mac, so it needs to be 73 // explicitly registered. 74 command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir); 75 #endif 76 } 77 78 virtual void SetUpOnMainThread() OVERRIDE { 79 base::FilePath path = GetTestFilePath("", ""); 80 BrowserThread::PostTask( 81 BrowserThread::IO, FROM_HERE, base::Bind(&SetUrlRequestMock, path)); 82 } 83 84 static void LoadAndWaitInWindow(Shell* window, const GURL& url) { 85 base::string16 expected_title(ASCIIToUTF16("OK")); 86 TitleWatcher title_watcher(window->web_contents(), expected_title); 87 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 88 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("plugin_not_found")); 89 NavigateToURL(window, url); 90 base::string16 title = title_watcher.WaitAndGetTitle(); 91 if (title == ASCIIToUTF16("plugin_not_found")) { 92 const testing::TestInfo* const test_info = 93 testing::UnitTest::GetInstance()->current_test_info(); 94 VLOG(0) << "PluginTest." << test_info->name() 95 << " not running because plugin not installed."; 96 } else { 97 EXPECT_EQ(expected_title, title); 98 } 99 } 100 101 void LoadAndWait(const GURL& url) { 102 LoadAndWaitInWindow(shell(), url); 103 } 104 105 GURL GetURL(const char* filename) { 106 return GetTestUrl("npapi", filename); 107 } 108 109 void NavigateAway() { 110 GURL url = GetTestUrl("", "simple_page.html"); 111 LoadAndWait(url); 112 } 113 114 void TestPlugin(const char* filename) { 115 base::FilePath path = GetTestFilePath("plugin", filename); 116 if (!base::PathExists(path)) { 117 const testing::TestInfo* const test_info = 118 testing::UnitTest::GetInstance()->current_test_info(); 119 VLOG(0) << "PluginTest." << test_info->name() 120 << " not running because test data wasn't found."; 121 return; 122 } 123 124 GURL url = GetTestUrl("plugin", filename); 125 LoadAndWait(url); 126 } 127 }; 128 129 // Make sure that navigating away from a plugin referenced by JS doesn't 130 // crash. 131 IN_PROC_BROWSER_TEST_F(PluginTest, UnloadNoCrash) { 132 LoadAndWait(GetURL("layout_test_plugin.html")); 133 NavigateAway(); 134 } 135 136 // Tests if a plugin executing a self deleting script using NPN_GetURL 137 // works without crashing or hanging 138 // Flaky: http://crbug.com/59327 139 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginGetUrl)) { 140 LoadAndWait(GetURL("self_delete_plugin_geturl.html")); 141 } 142 143 // Tests if a plugin executing a self deleting script using Invoke 144 // works without crashing or hanging 145 // Flaky. See http://crbug.com/30702 146 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvoke)) { 147 LoadAndWait(GetURL("self_delete_plugin_invoke.html")); 148 } 149 150 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectReleasedOnDestruction)) { 151 NavigateToURL(shell(), GetURL("npobject_released_on_destruction.html")); 152 NavigateAway(); 153 } 154 155 // Test that a dialog is properly created when a plugin throws an 156 // exception. Should be run for in and out of process plugins, but 157 // the more interesting case is out of process, where we must route 158 // the exception to the correct renderer. 159 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectSetException)) { 160 LoadAndWait(GetURL("npobject_set_exception.html")); 161 } 162 163 #if defined(OS_WIN) 164 // Tests if a plugin executing a self deleting script in the context of 165 // a synchronous mouseup works correctly. 166 // This was never ported to Mac. The only thing remaining is to make 167 // SimulateMouseClick get to Mac plugins, currently it doesn't work. 168 IN_PROC_BROWSER_TEST_F(PluginTest, 169 MAYBE(SelfDeletePluginInvokeInSynchronousMouseUp)) { 170 NavigateToURL(shell(), GetURL("execute_script_delete_in_mouse_up.html")); 171 172 base::string16 expected_title(ASCIIToUTF16("OK")); 173 TitleWatcher title_watcher(shell()->web_contents(), expected_title); 174 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 175 SimulateMouseClick(shell()->web_contents(), 0, 176 blink::WebMouseEvent::ButtonLeft); 177 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 178 } 179 #endif 180 181 // Flaky, http://crbug.com/302274. 182 #if defined(OS_MACOSX) 183 #define MAYBE_GetURLRequest404Response DISABLED_GetURLRequest404Response 184 #else 185 #define MAYBE_GetURLRequest404Response MAYBE(GetURLRequest404Response) 186 #endif 187 188 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_GetURLRequest404Response) { 189 GURL url(URLRequestMockHTTPJob::GetMockUrl( 190 base::FilePath().AppendASCII("npapi"). 191 AppendASCII("plugin_url_request_404.html"))); 192 LoadAndWait(url); 193 } 194 195 // Tests if a plugin executing a self deleting script using Invoke with 196 // a modal dialog showing works without crashing or hanging 197 // Disabled, flakily exceeds timeout, http://crbug.com/46257. 198 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvokeAlert)) { 199 // Navigate asynchronously because if we waitd until it completes, there's a 200 // race condition where the alert can come up before we start watching for it. 201 shell()->LoadURL(GetURL("self_delete_plugin_invoke_alert.html")); 202 203 base::string16 expected_title(ASCIIToUTF16("OK")); 204 TitleWatcher title_watcher(shell()->web_contents(), expected_title); 205 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 206 207 WaitForAppModalDialog(shell()); 208 209 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 210 } 211 212 // Test passing arguments to a plugin. 213 // crbug.com/306318 214 #if !defined(OS_LINUX) 215 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Arguments)) { 216 LoadAndWait(GetURL("arguments.html")); 217 } 218 #endif 219 220 // Test invoking many plugins within a single page. 221 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ManyPlugins)) { 222 LoadAndWait(GetURL("many_plugins.html")); 223 } 224 225 // Test various calls to GetURL from a plugin. 226 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURL)) { 227 LoadAndWait(GetURL("geturl.html")); 228 } 229 230 // Test various calls to GetURL for javascript URLs with 231 // non NULL targets from a plugin. 232 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL)) { 233 LoadAndWait(GetURL("get_javascript_url.html")); 234 } 235 236 // Test that calling GetURL with a javascript URL and target=_self 237 // works properly when the plugin is embedded in a subframe. 238 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL2)) { 239 LoadAndWait(GetURL("get_javascript_url2.html")); 240 } 241 242 // Test is flaky on linux/cros/win builders. http://crbug.com/71904 243 IN_PROC_BROWSER_TEST_F(PluginTest, GetURLRedirectNotification) { 244 LoadAndWait(GetURL("geturl_redirect_notify.html")); 245 } 246 247 // Tests that identity is preserved for NPObjects passed from a plugin 248 // into JavaScript. 249 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectIdentity)) { 250 LoadAndWait(GetURL("npobject_identity.html")); 251 } 252 253 // Tests that if an NPObject is proxies back to its original process, the 254 // original pointer is returned and not a proxy. If this fails the plugin 255 // will crash. 256 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectProxy)) { 257 LoadAndWait(GetURL("npobject_proxy.html")); 258 } 259 260 #if defined(OS_WIN) || defined(OS_MACOSX) 261 // Tests if a plugin executing a self deleting script in the context of 262 // a synchronous paint event works correctly 263 // http://crbug.com/44960 264 IN_PROC_BROWSER_TEST_F(PluginTest, 265 MAYBE(SelfDeletePluginInvokeInSynchronousPaint)) { 266 LoadAndWait(GetURL("execute_script_delete_in_paint.html")); 267 } 268 #endif 269 270 // Tests that if a plugin executes a self resizing script in the context of a 271 // synchronous paint, the plugin doesn't use deallocated memory. 272 // http://crbug.com/139462 273 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ResizeDuringPaint)) { 274 LoadAndWait(GetURL("resize_during_paint.html")); 275 } 276 277 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNewStream)) { 278 LoadAndWait(GetURL("self_delete_plugin_stream.html")); 279 } 280 281 // On Mac this test asserts in plugin_host: http://crbug.com/95558 282 // On all platforms it flakes in ~URLRequestContext: http://crbug.com/310336 283 #if !defined(NDEBUG) 284 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_DeletePluginInDeallocate) { 285 LoadAndWait(GetURL("plugin_delete_in_deallocate.html")); 286 } 287 #endif 288 289 #if defined(OS_WIN) 290 291 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyPluginWindowRect)) { 292 LoadAndWait(GetURL("verify_plugin_window_rect.html")); 293 } 294 295 // Tests that creating a new instance of a plugin while another one is handling 296 // a paint message doesn't cause deadlock. 297 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(CreateInstanceInPaint)) { 298 LoadAndWait(GetURL("create_instance_in_paint.html")); 299 } 300 301 // Tests that putting up an alert in response to a paint doesn't deadlock. 302 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_AlertInWindowMessage) { 303 NavigateToURL(shell(), GetURL("alert_in_window_message.html")); 304 305 WaitForAppModalDialog(shell()); 306 WaitForAppModalDialog(shell()); 307 } 308 309 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyNPObjectLifetimeTest)) { 310 LoadAndWait(GetURL("npobject_lifetime_test.html")); 311 } 312 313 // Tests that we don't crash or assert if NPP_New fails 314 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NewFails)) { 315 LoadAndWait(GetURL("new_fails.html")); 316 } 317 318 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNPNEvaluate)) { 319 LoadAndWait(GetURL("execute_script_delete_in_npn_evaluate.html")); 320 } 321 322 IN_PROC_BROWSER_TEST_F(PluginTest, 323 MAYBE(SelfDeleteCreatePluginInNPNEvaluate)) { 324 LoadAndWait(GetURL("npn_plugin_delete_create_in_evaluate.html")); 325 } 326 327 #endif // OS_WIN 328 329 // If this flakes, reopen http://crbug.com/17645 330 // As of 6 July 2011, this test is flaky on Windows (perhaps due to timing out). 331 #if !defined(OS_MACOSX) && !defined(OS_LINUX) 332 // Disabled on Mac because the plugin side isn't implemented yet, see 333 // "TODO(port)" in plugin_javascript_open_popup.cc. 334 // Disabled on Linux because we don't support NPAPI any more. 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