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