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.
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/browser/shell.h"
13 #include "content/shell/common/shell_switches.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"
20 #include "base/win/registry.h"
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
33 void SetUrlRequestMock(const base::FilePath
& path
) {
34 URLRequestMockHTTPJob::AddUrlHandler(path
);
39 class PluginTest
: public ContentBrowserTest
{
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");
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
);
59 } else if (strcmp(test_info
->name(), "FlashSecurity") == 0) {
60 command_line
->AppendSwitchASCII(switches::kTestSandbox
,
61 "security_tests.dll");
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
);
73 virtual void SetUpOnMainThread() OVERRIDE
{
74 base::FilePath path
= GetTestFilePath("", "");
75 BrowserThread::PostTask(
76 BrowserThread::IO
, FROM_HERE
, base::Bind(&SetUrlRequestMock
, path
));
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.";
92 EXPECT_EQ(expected_title
, title
);
96 void LoadAndWait(const GURL
& url
) {
97 LoadAndWaitInWindow(shell(), url
);
100 GURL
GetURL(const char* filename
) {
101 return GetTestUrl("npapi", filename
);
104 void NavigateAway() {
105 GURL url
= GetTestUrl("", "simple_page.html");
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.";
119 GURL url
= GetTestUrl("plugin", filename
);
124 // Make sure that navigating away from a plugin referenced by JS doesn't
126 IN_PROC_BROWSER_TEST_F(PluginTest
, UnloadNoCrash
) {
127 LoadAndWait(GetURL("layout_test_plugin.html"));
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"));
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"));
145 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(NPObjectReleasedOnDestruction
)) {
146 NavigateToURL(shell(), GetURL("npobject_released_on_destruction.html"));
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"));
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"));
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());
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")));
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"));
192 string16
expected_title(ASCIIToUTF16("OK"));
193 TitleWatcher
title_watcher(shell()->web_contents(), expected_title
);
194 title_watcher
.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
196 WaitForAppModalDialog(shell());
198 EXPECT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
201 // Test passing arguments to a plugin.
202 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(Arguments
)) {
203 LoadAndWait(GetURL("arguments.html"));
206 // Test invoking many plugins within a single page.
207 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(ManyPlugins
)) {
208 LoadAndWait(GetURL("many_plugins.html"));
211 // Test various calls to GetURL from a plugin.
212 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(GetURL
)) {
213 LoadAndWait(GetURL("geturl.html"));
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"));
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"));
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"));
233 // Tests that identity is preserved for NPObjects passed from a plugin
235 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(NPObjectIdentity
)) {
236 LoadAndWait(GetURL("npobject_identity.html"));
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
242 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(NPObjectProxy
)) {
243 LoadAndWait(GetURL("npobject_proxy.html"));
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"));
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"));
263 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(SelfDeletePluginInNewStream
)) {
264 LoadAndWait(GetURL("self_delete_plugin_stream.html"));
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"));
277 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(VerifyPluginWindowRect
)) {
278 LoadAndWait(GetURL("verify_plugin_window_rect.html"));
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"));
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"));
291 WaitForAppModalDialog(shell());
292 WaitForAppModalDialog(shell());
295 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(VerifyNPObjectLifetimeTest
)) {
296 LoadAndWait(GetURL("npobject_lifetime_test.html"));
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"));
304 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(SelfDeletePluginInNPNEvaluate
)) {
305 LoadAndWait(GetURL("execute_script_delete_in_npn_evaluate.html"));
308 IN_PROC_BROWSER_TEST_F(PluginTest
,
309 MAYBE(SelfDeleteCreatePluginInNPNEvaluate
)) {
310 LoadAndWait(GetURL("npn_plugin_delete_create_in_evaluate.html"));
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"));
325 // Test checking the privacy mode is off.
326 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(PrivateDisabled
)) {
327 LoadAndWait(GetURL("private.html"));
330 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(ScheduleTimer
)) {
331 LoadAndWait(GetURL("schedule_timer.html"));
334 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(PluginThreadAsyncCall
)) {
335 LoadAndWait(GetURL("plugin_thread_async_call.html"));
338 IN_PROC_BROWSER_TEST_F(PluginTest
, PluginSingleRangeRequest
) {
339 LoadAndWait(GetURL("plugin_single_range_request.html"));
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
);
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"));
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")));
366 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(EnsureScriptingWorksInDestroy
)) {
367 LoadAndWait(GetURL("ensure_scripting_works_in_destroy.html"));
370 // This test uses a Windows Event to signal to the plugin that it should crash
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
);
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")));
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
);
394 NavigateToURL(shell(), GetURL("convert_point.html"));
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.
402 // TODO: is this code still needed? It was here when it used to run in
404 //static_cast<WebContentsDelegate*>(shell())->
405 // ActivateContents(shell()->web_contents());
406 EXPECT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
410 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(Flash
)) {
411 TestPlugin("flash.html");
416 IN_PROC_BROWSER_TEST_F(PluginTest
, DISABLED_FlashSecurity
) {
417 TestPlugin("flash.html");
419 #endif // defined(OS_WIN)
422 // TODO(port) Port the following tests to platforms that have the required
424 // Flaky: http://crbug.com/55915
425 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(Quicktime
)) {
426 TestPlugin("quicktime.html");
429 // Disabled - http://crbug.com/44662
430 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(MediaPlayerNew
)) {
431 TestPlugin("wmp_new.html");
434 // Disabled - http://crbug.com/44673
435 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(Real
)) {
436 TestPlugin("real.html");
439 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(FlashOctetStream
)) {
440 TestPlugin("flash-octet-stream.html");
444 // http://crbug.com/53926
445 IN_PROC_BROWSER_TEST_F(PluginTest
, DISABLED_FlashLayoutWhilePainting
) {
447 IN_PROC_BROWSER_TEST_F(PluginTest
, FlashLayoutWhilePainting
) {
449 TestPlugin("flash-layout-while-painting.html");
452 // http://crbug.com/8690
453 IN_PROC_BROWSER_TEST_F(PluginTest
, DISABLED_Java
) {
454 TestPlugin("Java.html");
457 IN_PROC_BROWSER_TEST_F(PluginTest
, MAYBE(Silverlight
)) {
458 TestPlugin("silverlight.html");
460 #endif // defined(OS_WIN)
462 } // namespace content