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/memory/singleton.h"
7 #include "base/run_loop.h"
8 #include "base/test/test_timeouts.h"
9 #include "base/utf_string_conversions.h"
10 #include "content/browser/browser_plugin/browser_plugin_guest.h"
11 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
12 #include "content/browser/browser_plugin/test_browser_plugin_embedder.h"
13 #include "content/browser/browser_plugin/test_browser_plugin_guest.h"
14 #include "content/browser/renderer_host/render_view_host_impl.h"
15 #include "content/browser/web_contents/web_contents_impl.h"
16 #include "content/common/view_messages.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_types.h"
19 #include "content/public/browser/render_view_host_observer.h"
20 #include "content/public/browser/render_widget_host_view.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "content/public/test/test_utils.h"
24 #include "content/shell/shell.h"
25 #include "content/test/content_browser_test_utils.h"
26 #include "content/test/content_browser_test.h"
27 #include "net/base/net_util.h"
28 #include "net/test/test_server.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
30 #include "webkit/glue/webdropdata.h"
32 using WebKit::WebInputEvent
;
33 using WebKit::WebMouseEvent
;
34 using content::BrowserPluginEmbedder
;
35 using content::BrowserPluginGuest
;
36 using content::BrowserPluginHostFactory
;
37 using content::WebContentsImpl
;
41 const char kHTMLForGuest
[] =
42 "data:text/html,<html><body>hello world</body></html>";
43 const char kHTMLForGuestBusyLoop
[] =
44 "data:text/html,<html><head><script type=\"text/javascript\">"
45 "function PauseMs(timems) {"
46 " document.title = \"start\";"
47 " var date = new Date();"
48 " var currDate = null;"
50 " currDate = new Date();"
51 " } while (currDate - date < timems)"
53 "function StartPauseMs(timems) {"
54 " setTimeout(function() { PauseMs(timems); }, 0);"
56 "</script></head><body></body></html>";
57 const char kHTMLForGuestTouchHandler
[] =
58 "data:text/html,<html><body><div id=\"touch\">With touch</div></body>"
59 "<script type=\"text/javascript\">"
60 "function handler() {}"
61 "function InstallTouchHandler() { "
62 " document.getElementById(\"touch\").addEventListener(\"touchstart\", "
65 "function UninstallTouchHandler() { "
66 " document.getElementById(\"touch\").removeEventListener(\"touchstart\", "
70 const char kHTMLForGuestWithTitle
[] =
72 "<html><head><title>%s</title></head>"
73 "<body>hello world</body>"
75 const char kHTMLForGuestAcceptDrag
[] =
76 "data:text/html,<html><body>"
78 "function dropped() {"
79 " document.title = \"DROPPED\";"
82 "<textarea id=\"text\" style=\"width:100%; height: 100%\""
83 " ondrop=\"dropped();\">"
86 const char kHTMLForGuestWithSize
[] =
89 "<body style=\"margin: 0px;\">"
90 "<img style=\"width: 100%; height: 400px;\"/>"
94 std::string
GetHTMLForGuestWithTitle(const std::string
& title
) {
95 return StringPrintf(kHTMLForGuestWithTitle
, title
.c_str());
102 // Test factory for creating test instances of BrowserPluginEmbedder and
103 // BrowserPluginGuest.
104 class TestBrowserPluginHostFactory
: public BrowserPluginHostFactory
{
106 virtual BrowserPluginGuest
* CreateBrowserPluginGuest(
108 WebContentsImpl
* web_contents
,
109 const BrowserPluginHostMsg_CreateGuest_Params
& params
) OVERRIDE
{
110 return new TestBrowserPluginGuest(instance_id
,
115 // Also keeps track of number of instances created.
116 virtual BrowserPluginEmbedder
* CreateBrowserPluginEmbedder(
117 WebContentsImpl
* web_contents
,
118 RenderViewHost
* render_view_host
) OVERRIDE
{
119 embedder_instance_count_
++;
120 if (message_loop_runner_
)
121 message_loop_runner_
->Quit();
123 return new TestBrowserPluginEmbedder(web_contents
, render_view_host
);
127 static TestBrowserPluginHostFactory
* GetInstance() {
128 return Singleton
<TestBrowserPluginHostFactory
>::get();
131 // Waits for at least one embedder to be created in the test. Returns true if
132 // we have a guest, false if waiting times out.
133 void WaitForEmbedderCreation() {
134 // Check if already have created instance.
135 if (embedder_instance_count_
> 0)
138 message_loop_runner_
= new MessageLoopRunner();
139 message_loop_runner_
->Run();
143 TestBrowserPluginHostFactory() : embedder_instance_count_(0) {}
144 virtual ~TestBrowserPluginHostFactory() {}
148 friend struct DefaultSingletonTraits
<TestBrowserPluginHostFactory
>;
150 scoped_refptr
<MessageLoopRunner
> message_loop_runner_
;
151 int embedder_instance_count_
;
153 DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginHostFactory
);
156 // Test factory class for browser plugin that creates guests with short hang
158 class TestShortHangTimeoutGuestFactory
: public TestBrowserPluginHostFactory
{
160 virtual BrowserPluginGuest
* CreateBrowserPluginGuest(
162 WebContentsImpl
* web_contents
,
163 const BrowserPluginHostMsg_CreateGuest_Params
& params
) OVERRIDE
{
164 BrowserPluginGuest
* guest
=
165 new TestBrowserPluginGuest(instance_id
,
168 guest
->set_guest_hang_timeout_for_testing(TestTimeouts::tiny_timeout());
173 static TestShortHangTimeoutGuestFactory
* GetInstance() {
174 return Singleton
<TestShortHangTimeoutGuestFactory
>::get();
178 TestShortHangTimeoutGuestFactory() {}
179 virtual ~TestShortHangTimeoutGuestFactory() {}
183 friend struct DefaultSingletonTraits
<TestShortHangTimeoutGuestFactory
>;
185 DISALLOW_COPY_AND_ASSIGN(TestShortHangTimeoutGuestFactory
);
188 // A transparent observer that can be used to verify that a RenderViewHost
189 // received a specific message.
190 class RenderViewHostMessageObserver
: public RenderViewHostObserver
{
192 RenderViewHostMessageObserver(RenderViewHost
* host
,
194 : RenderViewHostObserver(host
),
195 message_id_(message_id
),
196 message_received_(false) {
199 virtual ~RenderViewHostMessageObserver() {}
201 void WaitUntilMessageReceived() {
202 if (message_received_
)
204 message_loop_runner_
= new MessageLoopRunner();
205 message_loop_runner_
->Run();
209 message_received_
= false;
212 // IPC::Listener implementation.
213 virtual bool OnMessageReceived(const IPC::Message
& message
) OVERRIDE
{
214 if (message
.type() == message_id_
) {
215 message_received_
= true;
216 if (message_loop_runner_
)
217 message_loop_runner_
->Quit();
223 scoped_refptr
<MessageLoopRunner
> message_loop_runner_
;
225 bool message_received_
;
227 DISALLOW_COPY_AND_ASSIGN(RenderViewHostMessageObserver
);
230 class BrowserPluginHostTest
: public ContentBrowserTest
{
232 BrowserPluginHostTest()
233 : test_embedder_(NULL
),
236 virtual void SetUp() OVERRIDE
{
237 // Override factory to create tests instances of BrowserPlugin*.
238 content::BrowserPluginEmbedder::set_factory_for_testing(
239 TestBrowserPluginHostFactory::GetInstance());
240 content::BrowserPluginGuest::set_factory_for_testing(
241 TestBrowserPluginHostFactory::GetInstance());
243 ContentBrowserTest::SetUp();
245 virtual void TearDown() OVERRIDE
{
246 content::BrowserPluginEmbedder::set_factory_for_testing(NULL
);
247 content::BrowserPluginGuest::set_factory_for_testing(NULL
);
249 ContentBrowserTest::TearDown();
252 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
253 // Enable browser plugin in content_shell for running test.
254 command_line
->AppendSwitch(switches::kEnableBrowserPluginForAllViewTypes
);
257 static void SimulateSpaceKeyPress(WebContents
* web_contents
) {
258 SimulateKeyPress(web_contents
,
266 static void SimulateTabKeyPress(WebContents
* web_contents
) {
267 SimulateKeyPress(web_contents
,
275 // Executes the javascript synchronously and makes sure the returned value is
277 void ExecuteSyncJSFunction(RenderViewHost
* rvh
, const std::string
& jscript
) {
278 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(
279 string16(), UTF8ToUTF16(jscript
)));
282 // This helper method does the following:
283 // 1. Start the test server and navigate the shell to |embedder_url|.
284 // 2. Execute custom pre-navigation |embedder_code| if provided.
285 // 3. Navigate the guest to the |guest_url|.
286 // 4. Verify that the guest has been created and has completed loading.
287 void StartBrowserPluginTest(const std::string
& embedder_url
,
288 const std::string
& guest_url
,
289 bool is_guest_data_url
,
290 const std::string
& embedder_code
) {
291 ASSERT_TRUE(test_server()->Start());
292 GURL
test_url(test_server()->GetURL(embedder_url
));
293 NavigateToURL(shell(), test_url
);
295 WebContentsImpl
* embedder_web_contents
= static_cast<WebContentsImpl
*>(
296 shell()->web_contents());
297 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
298 embedder_web_contents
->GetRenderViewHost());
299 // Focus the embedder.
302 // Allow the test to do some operations on the embedder before we perform
303 // the first navigation of the guest.
304 if (!embedder_code
.empty())
305 ExecuteSyncJSFunction(rvh
, embedder_code
);
307 if (!is_guest_data_url
) {
308 test_url
= test_server()->GetURL(guest_url
);
309 ExecuteSyncJSFunction(
310 rvh
, StringPrintf("SetSrc('%s');", test_url
.spec().c_str()));
312 ExecuteSyncJSFunction(
313 rvh
, StringPrintf("SetSrc('%s');", guest_url
.c_str()));
316 // Wait to make sure embedder is created/attached to WebContents.
317 TestBrowserPluginHostFactory::GetInstance()->WaitForEmbedderCreation();
319 test_embedder_
= static_cast<TestBrowserPluginEmbedder
*>(
320 embedder_web_contents
->GetBrowserPluginEmbedder());
321 ASSERT_TRUE(test_embedder_
);
322 test_embedder_
->WaitForGuestAdded();
324 // Verify that we have exactly one guest.
325 const BrowserPluginEmbedder::ContainerInstanceMap
& instance_map
=
326 test_embedder_
->guest_web_contents_for_testing();
327 EXPECT_EQ(1u, instance_map
.size());
329 WebContentsImpl
* test_guest_web_contents
= static_cast<WebContentsImpl
*>(
330 instance_map
.begin()->second
);
331 test_guest_
= static_cast<TestBrowserPluginGuest
*>(
332 test_guest_web_contents
->GetBrowserPluginGuest());
333 test_guest_
->WaitForLoadStop();
336 TestBrowserPluginEmbedder
* test_embedder() const { return test_embedder_
; }
337 TestBrowserPluginGuest
* test_guest() const { return test_guest_
; }
340 TestBrowserPluginEmbedder
* test_embedder_
;
341 TestBrowserPluginGuest
* test_guest_
;
342 DISALLOW_COPY_AND_ASSIGN(BrowserPluginHostTest
);
345 // This test loads a guest that has a busy loop, and therefore it hangs the
348 // Disabled on Windows and Linux since it is flaky. crbug.com/164812
349 #if defined(OS_WIN) || defined(OS_LINUX)
350 #define MAYBE_GuestUnresponsive DISABLED_GuestUnresponsive
352 #define MAYBE_GuestUnresponsive GuestUnresponsive
354 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
,
355 MAYBE_GuestUnresponsive
) {
356 // Override the hang timeout for guest to be very small.
357 content::BrowserPluginGuest::set_factory_for_testing(
358 TestShortHangTimeoutGuestFactory::GetInstance());
359 const char kEmbedderURL
[] =
360 "files/browser_plugin_embedder_guest_unresponsive.html";
361 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuestBusyLoop
, true, "");
362 // Wait until the busy loop starts.
364 const string16 expected_title
= ASCIIToUTF16("start");
365 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
367 // Hang the guest for a length of time.
368 int spin_time
= 10 * TestTimeouts::tiny_timeout().InMilliseconds();
369 ExecuteSyncJSFunction(
370 test_guest()->web_contents()->GetRenderViewHost(),
371 StringPrintf("StartPauseMs(%d);", spin_time
).c_str());
373 string16 actual_title
= title_watcher
.WaitAndGetTitle();
374 EXPECT_EQ(expected_title
, actual_title
);
377 const string16 expected_title
= ASCIIToUTF16("done");
378 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
381 // Send a mouse event to the guest.
382 SimulateMouseClick(test_embedder()->web_contents(), 0,
383 WebKit::WebMouseEvent::ButtonLeft
);
385 string16 actual_title
= title_watcher
.WaitAndGetTitle();
386 EXPECT_EQ(expected_title
, actual_title
);
389 // Verify that the embedder has received the 'unresponsive' and 'responsive'
391 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
392 test_embedder()->web_contents()->GetRenderViewHost());
393 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
394 ASCIIToUTF16("unresponsiveCalled")));
396 ASSERT_TRUE(value
->GetAsBoolean(&result
));
399 value
.reset(rvh
->ExecuteJavascriptAndGetValue(string16(),
400 ASCIIToUTF16("responsiveCalled")));
402 ASSERT_TRUE(value
->GetAsBoolean(&result
));
406 // This test ensures that if guest isn't there and we resize the guest (from
407 // js), it remembers the size correctly.
409 // Initially we load an embedder with a guest without a src attribute (which has
410 // dimension 640x480), resize it to 100x200, and then we set the source to a
411 // sample guest. In the end we verify that the correct size has been set.
412 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, NavigateAfterResize
) {
413 const gfx::Size nxt_size
= gfx::Size(100, 200);
414 const std::string embedder_code
=
415 StringPrintf("SetSize(%d, %d);", nxt_size
.width(), nxt_size
.height());
416 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
417 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, embedder_code
);
419 // Wait for the guest to receive a damage buffer of size 100x200.
420 // This means the guest will be painted properly at that size.
421 test_guest()->WaitForDamageBufferWithSize(nxt_size
);
424 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, AdvanceFocus
) {
425 const char kEmbedderURL
[] = "files/browser_plugin_focus.html";
426 const char* kGuestURL
= "files/browser_plugin_focus_child.html";
427 StartBrowserPluginTest(kEmbedderURL
, kGuestURL
, false, "");
429 SimulateMouseClick(test_embedder()->web_contents(), 0,
430 WebKit::WebMouseEvent::ButtonLeft
);
431 BrowserPluginHostTest::SimulateTabKeyPress(test_embedder()->web_contents());
432 // Wait until we focus into the guest.
433 test_guest()->WaitForFocus();
435 // TODO(fsamuel): A third Tab key press should not be necessary.
436 // The browser plugin will take keyboard focus but it will not
437 // focus an initial element. The initial element is dependent
438 // upon tab direction which WebKit does not propagate to the plugin.
439 // See http://crbug.com/147644.
440 BrowserPluginHostTest::SimulateTabKeyPress(test_embedder()->web_contents());
441 BrowserPluginHostTest::SimulateTabKeyPress(test_embedder()->web_contents());
442 BrowserPluginHostTest::SimulateTabKeyPress(test_embedder()->web_contents());
443 test_guest()->WaitForAdvanceFocus();
446 // This test opens a page in http and then opens another page in https, forcing
447 // a RenderViewHost swap in the web_contents. We verify that the embedder in the
448 // web_contents gets cleared properly.
449 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, EmbedderChangedAfterSwap
) {
450 net::TestServer
https_server(
451 net::TestServer::TYPE_HTTPS
,
452 net::TestServer::kLocalhost
,
453 FilePath(FILE_PATH_LITERAL("content/test/data")));
454 ASSERT_TRUE(https_server
.Start());
456 // 1. Load an embedder page with one guest in it.
457 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
458 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
460 // 2. Navigate to a URL in https, so we trigger a RenderViewHost swap.
461 GURL
test_https_url(https_server
.GetURL(
462 "files/browser_plugin_title_change.html"));
463 content::WindowedNotificationObserver
swap_observer(
464 content::NOTIFICATION_WEB_CONTENTS_SWAPPED
,
465 content::Source
<WebContents
>(test_embedder()->web_contents()));
466 NavigateToURL(shell(), test_https_url
);
467 swap_observer
.Wait();
469 TestBrowserPluginEmbedder
* test_embedder_after_swap
=
470 static_cast<TestBrowserPluginEmbedder
*>(
471 static_cast<WebContentsImpl
*>(shell()->web_contents())->
472 GetBrowserPluginEmbedder());
473 // Verify we have a no embedder in web_contents (since the new page doesn't
474 // have any browser plugin).
475 ASSERT_TRUE(!test_embedder_after_swap
);
476 ASSERT_NE(test_embedder(), test_embedder_after_swap
);
479 // This test opens two pages in http and there is no RenderViewHost swap,
480 // therefore the embedder created on first page navigation stays the same in
482 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, EmbedderSameAfterNav
) {
483 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
484 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
485 WebContentsImpl
* embedder_web_contents
= test_embedder()->web_contents();
487 // Navigate to another page in same host and port, so RenderViewHost swap
488 // does not happen and existing embedder doesn't change in web_contents.
489 GURL
test_url_new(test_server()->GetURL(
490 "files/browser_plugin_title_change.html"));
491 const string16 expected_title
= ASCIIToUTF16("done");
492 content::TitleWatcher
title_watcher(shell()->web_contents(), expected_title
);
493 NavigateToURL(shell(), test_url_new
);
494 LOG(INFO
) << "Start waiting for title";
495 string16 actual_title
= title_watcher
.WaitAndGetTitle();
496 EXPECT_EQ(expected_title
, actual_title
);
497 LOG(INFO
) << "Done navigating to second page";
499 TestBrowserPluginEmbedder
* test_embedder_after_nav
=
500 static_cast<TestBrowserPluginEmbedder
*>(
501 embedder_web_contents
->GetBrowserPluginEmbedder());
502 // Embedder must not change in web_contents.
503 ASSERT_EQ(test_embedder_after_nav
, test_embedder());
506 // This test verifies that hiding the embedder also hides the guest.
507 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, BrowserPluginVisibilityChanged
) {
508 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
509 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
511 // Hide the Browser Plugin.
512 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
513 test_embedder()->web_contents()->GetRenderViewHost());
514 ExecuteSyncJSFunction(
515 rvh
, "document.getElementById('plugin').style.visibility = 'hidden'");
517 // Make sure that the guest is hidden.
518 test_guest()->WaitUntilHidden();
521 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, EmbedderVisibilityChanged
) {
522 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
523 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
525 // Hide the embedder.
526 test_embedder()->web_contents()->WasHidden();
528 // Make sure that hiding the embedder also hides the guest.
529 test_guest()->WaitUntilHidden();
532 // This test verifies that calling the reload method reloads the guest.
533 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, ReloadGuest
) {
534 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
535 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
537 test_guest()->ResetUpdateRectCount();
539 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
540 test_embedder()->web_contents()->GetRenderViewHost());
541 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').reload()");
542 test_guest()->WaitForReload();
545 // This test verifies that calling the stop method forwards the stop request
546 // to the guest's WebContents.
547 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, StopGuest
) {
548 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
549 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
551 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
552 test_embedder()->web_contents()->GetRenderViewHost());
553 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').stop()");
554 test_guest()->WaitForStop();
557 // Verifies that installing/uninstalling touch-event handlers in the guest
558 // plugin correctly updates the touch-event handling state in the embedder.
559 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, AcceptTouchEvents
) {
560 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
561 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuestTouchHandler
, true, "");
563 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
564 test_embedder()->web_contents()->GetRenderViewHost());
565 // The embedder should not have any touch event handlers at this point.
566 EXPECT_FALSE(rvh
->has_touch_handler());
568 // Install the touch handler in the guest. This should cause the embedder to
569 // start listening for touch events too.
570 RenderViewHostMessageObserver
observer(rvh
,
571 ViewHostMsg_HasTouchEventHandlers::ID
);
572 ExecuteSyncJSFunction(test_guest()->web_contents()->GetRenderViewHost(),
573 "InstallTouchHandler();");
574 observer
.WaitUntilMessageReceived();
575 EXPECT_TRUE(rvh
->has_touch_handler());
577 // Uninstalling the touch-handler in guest should cause the embedder to stop
578 // listening for touch events.
579 observer
.ResetState();
580 ExecuteSyncJSFunction(test_guest()->web_contents()->GetRenderViewHost(),
581 "UninstallTouchHandler();");
582 observer
.WaitUntilMessageReceived();
583 EXPECT_FALSE(rvh
->has_touch_handler());
586 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, Renavigate
) {
587 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
588 StartBrowserPluginTest(
589 kEmbedderURL
, GetHTMLForGuestWithTitle("P1"), true, "");
590 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
591 test_embedder()->web_contents()->GetRenderViewHost());
593 // Navigate to P2 and verify that the navigation occurred.
595 const string16 expected_title
= ASCIIToUTF16("P2");
596 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
599 ExecuteSyncJSFunction(
601 StringPrintf("SetSrc('%s');", GetHTMLForGuestWithTitle("P2").c_str()));
603 string16 actual_title
= title_watcher
.WaitAndGetTitle();
604 EXPECT_EQ(expected_title
, actual_title
);
607 // Navigate to P3 and verify that the navigation occurred.
609 const string16 expected_title
= ASCIIToUTF16("P3");
610 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
613 ExecuteSyncJSFunction(
615 StringPrintf("SetSrc('%s');", GetHTMLForGuestWithTitle("P3").c_str()));
617 string16 actual_title
= title_watcher
.WaitAndGetTitle();
618 EXPECT_EQ(expected_title
, actual_title
);
621 // Go back and verify that we're back at P2.
623 const string16 expected_title
= ASCIIToUTF16("P2");
624 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
627 ExecuteSyncJSFunction(rvh
, "Back();");
628 string16 actual_title
= title_watcher
.WaitAndGetTitle();
629 EXPECT_EQ(expected_title
, actual_title
);
631 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
632 ASCIIToUTF16("CanGoBack()")));
634 ASSERT_TRUE(value
->GetAsBoolean(&result
));
637 value
.reset(rvh
->ExecuteJavascriptAndGetValue(string16(),
638 ASCIIToUTF16("CanGoForward()")));
640 ASSERT_TRUE(value
->GetAsBoolean(&result
));
644 // Go forward and verify that we're back at P3.
646 const string16 expected_title
= ASCIIToUTF16("P3");
647 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
650 ExecuteSyncJSFunction(rvh
, "Forward();");
651 string16 actual_title
= title_watcher
.WaitAndGetTitle();
652 EXPECT_EQ(expected_title
, actual_title
);
654 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
655 ASCIIToUTF16("CanGoForward()")));
657 ASSERT_TRUE(value
->GetAsBoolean(&result
));
658 EXPECT_FALSE(result
);
661 // Go back two entries and verify that we're back at P1.
663 const string16 expected_title
= ASCIIToUTF16("P1");
664 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
667 ExecuteSyncJSFunction(rvh
, "Go(-2);");
668 string16 actual_title
= title_watcher
.WaitAndGetTitle();
669 EXPECT_EQ(expected_title
, actual_title
);
671 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
672 ASCIIToUTF16("CanGoBack()")));
674 ASSERT_TRUE(value
->GetAsBoolean(&result
));
675 EXPECT_FALSE(result
);
679 // This tests verifies that reloading the embedder does not crash the browser
680 // and that the guest is reset.
681 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, ReloadEmbedder
) {
682 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
683 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
684 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
685 test_embedder()->web_contents()->GetRenderViewHost());
687 // Change the title of the page to 'modified' so that we know that
688 // the page has successfully reloaded when it goes back to 'embedder'
691 const string16 expected_title
= ASCIIToUTF16("modified");
692 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
695 ExecuteSyncJSFunction(rvh
, StringPrintf("SetTitle('%s');", "modified"));
697 string16 actual_title
= title_watcher
.WaitAndGetTitle();
698 EXPECT_EQ(expected_title
, actual_title
);
701 // Reload the embedder page, and verify that the reload was successful.
702 // Then navigate the guest to verify that the browser process does not crash.
704 const string16 expected_title
= ASCIIToUTF16("embedder");
705 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
708 test_embedder()->web_contents()->GetController().Reload(false);
709 string16 actual_title
= title_watcher
.WaitAndGetTitle();
710 EXPECT_EQ(expected_title
, actual_title
);
712 ExecuteSyncJSFunction(
713 test_embedder()->web_contents()->GetRenderViewHost(),
714 StringPrintf("SetSrc('%s');", kHTMLForGuest
));
716 const BrowserPluginEmbedder::ContainerInstanceMap
& instance_map
=
717 test_embedder()->guest_web_contents_for_testing();
718 WebContentsImpl
* test_guest_web_contents
= static_cast<WebContentsImpl
*>(
719 instance_map
.begin()->second
);
720 TestBrowserPluginGuest
* new_test_guest
=
721 static_cast<TestBrowserPluginGuest
*>(
722 test_guest_web_contents
->GetBrowserPluginGuest());
724 // Wait for the guest to send an UpdateRectMsg, meaning it is ready.
725 new_test_guest
->WaitForUpdateRectMsg();
729 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, TerminateGuest
) {
730 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
731 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
733 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
734 test_embedder()->web_contents()->GetRenderViewHost());
735 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').terminate()");
737 // Expect the guest to crash.
738 test_guest()->WaitForExit();
741 // This test verifies that the guest is responsive after crashing and going back
742 // to a previous navigation entry.
743 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, BackAfterTerminateGuest
) {
744 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
745 StartBrowserPluginTest(
746 kEmbedderURL
, GetHTMLForGuestWithTitle("P1"), true, "");
747 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
748 test_embedder()->web_contents()->GetRenderViewHost());
750 // Navigate to P2 and verify that the navigation occurred.
752 const string16 expected_title
= ASCIIToUTF16("P2");
753 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
756 ExecuteSyncJSFunction(
758 StringPrintf("SetSrc('%s');", GetHTMLForGuestWithTitle("P2").c_str()));
760 string16 actual_title
= title_watcher
.WaitAndGetTitle();
761 EXPECT_EQ(expected_title
, actual_title
);
764 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').terminate()");
766 // Expect the guest to report that it crashed.
767 test_guest()->WaitForExit();
768 // Go back and verify that we're back at P1.
770 const string16 expected_title
= ASCIIToUTF16("P1");
771 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
774 ExecuteSyncJSFunction(rvh
, "Back();");
776 string16 actual_title
= title_watcher
.WaitAndGetTitle();
777 EXPECT_EQ(expected_title
, actual_title
);
779 // Send an input event and verify that the guest receives the input.
780 SimulateMouseClick(test_embedder()->web_contents(), 0,
781 WebKit::WebMouseEvent::ButtonLeft
);
782 test_guest()->WaitForInput();
785 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, LoadStart
) {
786 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
787 StartBrowserPluginTest(kEmbedderURL
, "about:blank", true, "");
789 const string16 expected_title
= ASCIIToUTF16(kHTMLForGuest
);
790 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
792 // Renavigate the guest to |kHTMLForGuest|.
793 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
794 test_embedder()->web_contents()->GetRenderViewHost());
795 ExecuteSyncJSFunction(rvh
, StringPrintf("SetSrc('%s');", kHTMLForGuest
));
797 string16 actual_title
= title_watcher
.WaitAndGetTitle();
798 EXPECT_EQ(expected_title
, actual_title
);
801 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, LoadAbort
) {
802 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
803 StartBrowserPluginTest(kEmbedderURL
, "about:blank", true, "");
806 // Navigate the guest to "close-socket".
807 const string16 expected_title
= ASCIIToUTF16("ERR_EMPTY_RESPONSE");
808 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
810 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
811 test_embedder()->web_contents()->GetRenderViewHost());
812 GURL test_url
= test_server()->GetURL("close-socket");
813 ExecuteSyncJSFunction(
814 rvh
, StringPrintf("SetSrc('%s');", test_url
.spec().c_str()));
815 string16 actual_title
= title_watcher
.WaitAndGetTitle();
816 EXPECT_EQ(expected_title
, actual_title
);
820 // Navigate the guest to an illegal chrome:// URL.
821 const string16 expected_title
= ASCIIToUTF16("ERR_FAILED");
822 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
824 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
825 test_embedder()->web_contents()->GetRenderViewHost());
826 GURL
test_url("chrome://newtab");
827 ExecuteSyncJSFunction(
828 rvh
, StringPrintf("SetSrc('%s');", test_url
.spec().c_str()));
829 string16 actual_title
= title_watcher
.WaitAndGetTitle();
830 EXPECT_EQ(expected_title
, actual_title
);
834 // Navigate the guest to an illegal file:// URL.
835 const string16 expected_title
= ASCIIToUTF16("ERR_ABORTED");
836 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
838 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
839 test_embedder()->web_contents()->GetRenderViewHost());
840 GURL
test_url("file://foo");
841 ExecuteSyncJSFunction(
842 rvh
, StringPrintf("SetSrc('%s');", test_url
.spec().c_str()));
843 string16 actual_title
= title_watcher
.WaitAndGetTitle();
844 EXPECT_EQ(expected_title
, actual_title
);
848 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, LoadRedirect
) {
849 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
850 StartBrowserPluginTest(kEmbedderURL
, "about:blank", true, "");
852 const string16 expected_title
= ASCIIToUTF16("redirected");
853 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
856 // Navigate with a redirect and wait until the title changes.
857 GURL
redirect_url(test_server()->GetURL(
858 "server-redirect?files/title1.html"));
859 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
860 test_embedder()->web_contents()->GetRenderViewHost());
861 ExecuteSyncJSFunction(
862 rvh
, StringPrintf("SetSrc('%s');", redirect_url
.spec().c_str()));
864 string16 actual_title
= title_watcher
.WaitAndGetTitle();
865 EXPECT_EQ(expected_title
, actual_title
);
867 // Verify that we heard a loadRedirect during the navigation.
868 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(
869 string16(), ASCIIToUTF16("redirectOldUrl")));
871 EXPECT_TRUE(value
->GetAsString(&result
));
872 EXPECT_EQ(redirect_url
.spec().c_str(), result
);
874 value
.reset(rvh
->ExecuteJavascriptAndGetValue(
875 string16(), ASCIIToUTF16("redirectNewUrl")));
876 EXPECT_TRUE(value
->GetAsString(&result
));
877 EXPECT_EQ(test_server()->GetURL("files/title1.html").spec().c_str(), result
);
880 // Tests that a drag-n-drop over the browser plugin in the embedder happens
882 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, AcceptDragEvents
) {
883 const char kEmbedderURL
[] = "files/browser_plugin_dragging.html";
884 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuestAcceptDrag
, true, "");
886 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
887 test_embedder()->web_contents()->GetRenderViewHost());
889 // Get a location in the embedder outside of the plugin.
890 base::ListValue
*start
, *end
;
891 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
892 ASCIIToUTF16("dragLocation()")));
893 ASSERT_TRUE(value
->GetAsList(&start
) && start
->GetSize() == 2);
894 double start_x
, start_y
;
895 ASSERT_TRUE(start
->GetDouble(0, &start_x
) && start
->GetDouble(1, &start_y
));
897 // Get a location in the embedder that falls inside the plugin.
898 value
.reset(rvh
->ExecuteJavascriptAndGetValue(string16(),
899 ASCIIToUTF16("dropLocation()")));
900 ASSERT_TRUE(value
->GetAsList(&end
) && end
->GetSize() == 2);
902 ASSERT_TRUE(end
->GetDouble(0, &end_x
) && end
->GetDouble(1, &end_y
));
904 WebDropData drop_data
;
905 GURL url
= GURL("https://www.domain.com/index.html");
908 // Pretend that the URL is being dragged over the embedder. Start the drag
909 // from outside the plugin, then move the drag inside the plugin and drop.
910 // This should trigger appropriate messages from the embedder to the guest,
911 // and end with a drop on the guest. The guest changes title when a drop
913 const string16 expected_title
= ASCIIToUTF16("DROPPED");
914 content::TitleWatcher
title_watcher(test_guest()->web_contents(),
917 rvh
->DragTargetDragEnter(drop_data
, gfx::Point(start_x
, start_y
),
918 gfx::Point(start_x
, start_y
), WebKit::WebDragOperationEvery
, 0);
919 rvh
->DragTargetDragOver(gfx::Point(end_x
, end_y
), gfx::Point(end_x
, end_y
),
920 WebKit::WebDragOperationEvery
, 0);
921 rvh
->DragTargetDrop(gfx::Point(end_x
, end_y
), gfx::Point(end_x
, end_y
), 0);
923 string16 actual_title
= title_watcher
.WaitAndGetTitle();
924 EXPECT_EQ(expected_title
, actual_title
);
927 // This test verifies that round trip postMessage works as expected.
928 // 1. The embedder posts a message 'testing123' to the guest.
929 // 2. The guest receives and replies to the message using the event object's
930 // source object: event.source.postMessage('foobar', '*')
931 // 3. The embedder receives the message and uses the event's source
932 // object to do one final reply: 'stop'
933 // 4. The guest receives the final 'stop' message.
934 // 5. The guest acks the 'stop' message with a 'stop_ack' message.
935 // 6. The embedder changes its title to 'main guest' when it sees the 'stop_ack'
937 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, PostMessage
) {
938 const char* kTesting
= "testing123";
939 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
940 const char* kGuestURL
= "files/browser_plugin_post_message_guest.html";
941 StartBrowserPluginTest(kEmbedderURL
, kGuestURL
, false, "");
942 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
943 test_embedder()->web_contents()->GetRenderViewHost());
945 const string16 expected_title
= ASCIIToUTF16("main guest");
946 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
949 // By the time we get here 'contentWindow' should be ready because the
950 // guest has completed loading.
951 ExecuteSyncJSFunction(
952 rvh
, StringPrintf("PostMessage('%s, false');", kTesting
));
954 // The title will be updated to "main guest" at the last stage of the
955 // process described above.
956 string16 actual_title
= title_watcher
.WaitAndGetTitle();
957 EXPECT_EQ(expected_title
, actual_title
);
961 // This is the same as BrowserPluginHostTest.PostMessage but also
962 // posts a message to an iframe.
963 // TODO(fsamuel): This test should replace the previous test once postMessage
964 // iframe targeting is fixed (see http://crbug.com/153701).
965 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, DISABLED_PostMessageToIFrame
) {
966 const char* kTesting
= "testing123";
967 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
968 const char* kGuestURL
= "files/browser_plugin_post_message_guest.html";
969 StartBrowserPluginTest(kEmbedderURL
, kGuestURL
, false, "");
970 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
971 test_embedder()->web_contents()->GetRenderViewHost());
973 const string16 expected_title
= ASCIIToUTF16("main guest");
974 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
977 ExecuteSyncJSFunction(
978 rvh
, StringPrintf("PostMessage('%s, false');", kTesting
));
980 // The title will be updated to "main guest" at the last stage of the
981 // process described above.
982 string16 actual_title
= title_watcher
.WaitAndGetTitle();
983 EXPECT_EQ(expected_title
, actual_title
);
986 content::TitleWatcher
ready_watcher(test_embedder()->web_contents(),
987 ASCIIToUTF16("ready"));
989 RenderViewHostImpl
* guest_rvh
= static_cast<RenderViewHostImpl
*>(
990 test_guest()->web_contents()->GetRenderViewHost());
991 GURL test_url
= test_server()->GetURL(
992 "files/browser_plugin_post_message_guest.html");
993 ExecuteSyncJSFunction(
995 StringPrintf("CreateChildFrame('%s');", test_url
.spec().c_str()));
997 string16 actual_title
= ready_watcher
.WaitAndGetTitle();
998 EXPECT_EQ(ASCIIToUTF16("ready"), actual_title
);
1000 content::TitleWatcher
iframe_watcher(test_embedder()->web_contents(),
1001 ASCIIToUTF16("iframe"));
1002 ExecuteSyncJSFunction(
1003 rvh
, StringPrintf("PostMessage('%s', true);", kTesting
));
1005 // The title will be updated to "iframe" at the last stage of the
1006 // process described above.
1007 actual_title
= iframe_watcher
.WaitAndGetTitle();
1008 EXPECT_EQ(ASCIIToUTF16("iframe"), actual_title
);
1012 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, LoadStop
) {
1013 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1014 StartBrowserPluginTest(kEmbedderURL
, "about:blank", true, "");
1016 const string16 expected_title
= ASCIIToUTF16("loadStop");
1017 content::TitleWatcher
title_watcher(
1018 test_embedder()->web_contents(), expected_title
);
1019 // Renavigate the guest to |kHTMLForGuest|.
1020 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1021 test_embedder()->web_contents()->GetRenderViewHost());
1022 ExecuteSyncJSFunction(rvh
, StringPrintf("SetSrc('%s');", kHTMLForGuest
));
1024 string16 actual_title
= title_watcher
.WaitAndGetTitle();
1025 EXPECT_EQ(expected_title
, actual_title
);
1028 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, LoadCommit
) {
1029 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1030 StartBrowserPluginTest(kEmbedderURL
, "about:blank", true, "");
1032 const string16 expected_title
= ASCIIToUTF16(
1033 StringPrintf("loadCommit:%s", kHTMLForGuest
));
1034 content::TitleWatcher
title_watcher(
1035 test_embedder()->web_contents(), expected_title
);
1036 // Renavigate the guest to |kHTMLForGuest|.
1037 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1038 test_embedder()->web_contents()->GetRenderViewHost());
1039 ExecuteSyncJSFunction(rvh
, StringPrintf("SetSrc('%s');", kHTMLForGuest
));
1041 string16 actual_title
= title_watcher
.WaitAndGetTitle();
1042 EXPECT_EQ(expected_title
, actual_title
);
1043 scoped_ptr
<base::Value
> is_top_level(rvh
->ExecuteJavascriptAndGetValue(
1044 string16(), ASCIIToUTF16("commitIsTopLevel")));
1045 bool top_level_bool
= false;
1046 EXPECT_TRUE(is_top_level
->GetAsBoolean(&top_level_bool
));
1047 EXPECT_EQ(true, top_level_bool
);
1050 // This test verifies that if a browser plugin is hidden before navigation,
1051 // the guest starts off hidden.
1052 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, HiddenBeforeNavigation
) {
1053 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1054 const std::string embedder_code
=
1055 "document.getElementById('plugin').style.visibility = 'hidden'";
1056 StartBrowserPluginTest(
1057 kEmbedderURL
, kHTMLForGuest
, true, embedder_code
);
1058 EXPECT_FALSE(test_guest()->visible());
1061 // This test verifies that if we lose the guest, and get a new one,
1062 // the new guest will inherit the visibility state of the old guest.
1064 // Very flaky on Linux, Linux CrOS, somewhat flaky on XP, slightly on
1065 // Mac; http://crbug.com/162809.
1066 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, DISABLED_VisibilityPreservation
) {
1067 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1068 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
1069 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1070 test_embedder()->web_contents()->GetRenderViewHost());
1071 // Hide the BrowserPlugin.
1072 ExecuteSyncJSFunction(
1073 rvh
, "document.getElementById('plugin').style.visibility = 'hidden';");
1074 test_guest()->WaitUntilHidden();
1075 // Kill the current guest.
1076 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').terminate();");
1077 test_guest()->WaitForExit();
1079 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').reload();");
1080 test_guest()->WaitForLoadStop();
1081 // Verify that the guest is told to hide.
1082 test_guest()->WaitUntilHidden();
1085 // This test verifies that if a browser plugin is focused before navigation then
1086 // the guest starts off focused.
1087 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, FocusBeforeNavigation
) {
1088 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1089 const std::string embedder_code
=
1090 "document.getElementById('plugin').focus();";
1091 StartBrowserPluginTest(
1092 kEmbedderURL
, kHTMLForGuest
, true, embedder_code
);
1093 RenderViewHostImpl
* guest_rvh
= static_cast<RenderViewHostImpl
*>(
1094 test_guest()->web_contents()->GetRenderViewHost());
1095 // Verify that the guest is focused.
1096 scoped_ptr
<base::Value
> value(
1097 guest_rvh
->ExecuteJavascriptAndGetValue(string16(),
1098 ASCIIToUTF16("document.hasFocus()")));
1099 bool result
= false;
1100 ASSERT_TRUE(value
->GetAsBoolean(&result
));
1101 EXPECT_TRUE(result
);
1104 // This test verifies that if we lose the guest, and get a new one,
1105 // the new guest will inherit the focus state of the old guest.
1107 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, DISABLED_FocusPreservation
) {
1108 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1109 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
1110 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1111 test_embedder()->web_contents()->GetRenderViewHost());
1112 RenderViewHostImpl
* guest_rvh
= static_cast<RenderViewHostImpl
*>(
1113 test_guest()->web_contents()->GetRenderViewHost());
1115 // Focus the BrowserPlugin. This will have the effect of also focusing the
1117 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').focus();");
1118 // Verify that key presses go to the guest.
1119 SimulateSpaceKeyPress(test_embedder()->web_contents());
1120 test_guest()->WaitForInput();
1121 // Verify that the guest is focused.
1122 scoped_ptr
<base::Value
> value(
1123 guest_rvh
->ExecuteJavascriptAndGetValue(string16(),
1124 ASCIIToUTF16("document.hasFocus()")));
1125 bool result
= false;
1126 ASSERT_TRUE(value
->GetAsBoolean(&result
));
1127 EXPECT_TRUE(result
);
1130 // Kill the current guest.
1131 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').terminate();");
1132 test_guest()->WaitForExit();
1136 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').reload();");
1137 test_guest()->WaitForLoadStop();
1138 // Verify that the guest is focused.
1139 scoped_ptr
<base::Value
> value(
1140 guest_rvh
->ExecuteJavascriptAndGetValue(string16(),
1141 ASCIIToUTF16("document.hasFocus()")));
1142 bool result
= false;
1143 ASSERT_TRUE(value
->GetAsBoolean(&result
));
1144 EXPECT_TRUE(result
);
1148 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, FocusTracksEmbedder
) {
1149 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1150 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuest
, true, "");
1151 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1152 test_embedder()->web_contents()->GetRenderViewHost());
1153 RenderViewHostImpl
* guest_rvh
= static_cast<RenderViewHostImpl
*>(
1154 test_guest()->web_contents()->GetRenderViewHost());
1156 // Focus the BrowserPlugin. This will have the effect of also focusing the
1158 ExecuteSyncJSFunction(rvh
, "document.getElementById('plugin').focus();");
1159 // Verify that key presses go to the guest.
1160 SimulateSpaceKeyPress(test_embedder()->web_contents());
1161 test_guest()->WaitForInput();
1162 // Verify that the guest is focused.
1163 scoped_ptr
<base::Value
> value(
1164 guest_rvh
->ExecuteJavascriptAndGetValue(string16(),
1165 ASCIIToUTF16("document.hasFocus()")));
1166 bool result
= false;
1167 ASSERT_TRUE(value
->GetAsBoolean(&result
));
1168 EXPECT_TRUE(result
);
1170 // Blur the embedder.
1171 test_embedder()->web_contents()->GetRenderViewHost()->Blur();
1172 test_guest()->WaitForBlur();
1175 // This test verifies that if a browser plugin is in autosize mode before
1176 // navigation then the guest starts auto-sized.
1177 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, AutoSizeBeforeNavigation
) {
1178 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1179 const std::string embedder_code
=
1180 "document.getElementById('plugin').minWidth = 300;"
1181 "document.getElementById('plugin').minHeight = 200;"
1182 "document.getElementById('plugin').maxWidth = 600;"
1183 "document.getElementById('plugin').maxHeight = 400;"
1184 "document.getElementById('plugin').autoSize = true;";
1185 StartBrowserPluginTest(
1186 kEmbedderURL
, kHTMLForGuestWithSize
, true, embedder_code
);
1187 // Verify that the guest has been auto-sized.
1188 test_guest()->WaitForViewSize(gfx::Size(300, 400));
1191 // This test verifies that enabling autosize resizes the guest and triggers
1192 // a 'sizechanged' event.
1193 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, AutoSizeAfterNavigation
) {
1194 const char* kEmbedderURL
= "files/browser_plugin_embedder.html";
1195 StartBrowserPluginTest(
1196 kEmbedderURL
, kHTMLForGuestWithSize
, true, "");
1197 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1198 test_embedder()->web_contents()->GetRenderViewHost());
1201 const string16 expected_title
= ASCIIToUTF16("AutoSize(300, 400)");
1202 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
1204 ExecuteSyncJSFunction(
1206 "document.getElementById('plugin').minWidth = 300;"
1207 "document.getElementById('plugin').minHeight = 200;"
1208 "document.getElementById('plugin').maxWidth = 600;"
1209 "document.getElementById('plugin').maxHeight = 400;"
1210 "document.getElementById('plugin').autoSize = true;");
1211 string16 actual_title
= title_watcher
.WaitAndGetTitle();
1212 EXPECT_EQ(expected_title
, actual_title
);
1215 // Change the minWidth and verify that it causes relayout.
1216 const string16 expected_title
= ASCIIToUTF16("AutoSize(350, 400)");
1217 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
1219 ExecuteSyncJSFunction(
1220 rvh
, "document.getElementById('plugin').minWidth = 350;");
1221 string16 actual_title
= title_watcher
.WaitAndGetTitle();
1222 EXPECT_EQ(expected_title
, actual_title
);
1225 // Turn off autoSize and verify that the guest resizes to fit the container.
1226 ExecuteSyncJSFunction(
1227 rvh
, "document.getElementById('plugin').autoSize = false;");
1228 test_guest()->WaitForViewSize(gfx::Size(640, 480));
1232 // Test for regression http://crbug.com/162961.
1233 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, GetRenderViewHostAtPositionTest
) {
1234 const char kEmbedderURL
[] = "files/browser_plugin_embedder.html";
1235 const std::string embedder_code
= StringPrintf("SetSize(%d, %d);", 100, 100);
1236 StartBrowserPluginTest(kEmbedderURL
, kHTMLForGuestWithSize
, true,
1238 // Check for render view host at position (150, 150) that is outside the
1239 // bounds of our guest, so this would respond with the render view host of the
1241 test_embedder()->WaitForRenderViewHostAtPosition(150, 150);
1242 ASSERT_EQ(test_embedder()->web_contents()->GetRenderViewHost(),
1243 test_embedder()->last_rvh_at_position_response());
1246 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest
, ChangeWindowName
) {
1247 const char kEmbedderURL
[] = "files/browser_plugin_naming_embedder.html";
1248 const char* kGuestURL
= "files/browser_plugin_naming_guest.html";
1249 StartBrowserPluginTest(kEmbedderURL
, kGuestURL
, false, "");
1251 RenderViewHostImpl
* rvh
= static_cast<RenderViewHostImpl
*>(
1252 test_embedder()->web_contents()->GetRenderViewHost());
1253 // Verify that the plugin's name is properly initialized.
1255 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
1256 ASCIIToUTF16("document.getElementById('plugin').name")));
1258 EXPECT_TRUE(value
->GetAsString(&result
));
1259 EXPECT_EQ("start", result
);
1262 // Open a channel with the guest, wait until it replies,
1263 // then verify that the plugin's name has been updated.
1264 const string16 expected_title
= ASCIIToUTF16("guest");
1265 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
1267 ExecuteSyncJSFunction(rvh
, "OpenCommChannel();");
1268 string16 actual_title
= title_watcher
.WaitAndGetTitle();
1269 EXPECT_EQ(expected_title
, actual_title
);
1271 scoped_ptr
<base::Value
> value(rvh
->ExecuteJavascriptAndGetValue(string16(),
1272 ASCIIToUTF16("document.getElementById('plugin').name")));
1274 EXPECT_TRUE(value
->GetAsString(&result
));
1275 EXPECT_EQ("guest", result
);
1278 // Set the plugin's name and verify that the window.name of the guest
1279 // has been updated.
1280 const string16 expected_title
= ASCIIToUTF16("foobar");
1281 content::TitleWatcher
title_watcher(test_embedder()->web_contents(),
1283 ExecuteSyncJSFunction(rvh
,
1284 "document.getElementById('plugin').name = 'foobar';");
1285 string16 actual_title
= title_watcher
.WaitAndGetTitle();
1286 EXPECT_EQ(expected_title
, actual_title
);
1291 } // namespace content