By moving the call to Load() up in SearchProvider::Start(), we are giving a chance...
[chromium-blink-merge.git] / content / browser / browser_plugin / browser_plugin_host_browsertest.cc
blob4081a5bc630f2e34c4995e14349081e95395fd53
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;
39 namespace {
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;"
49 " do {"
50 " currDate = new Date();"
51 " } while (currDate - date < timems)"
52 "}"
53 "function StartPauseMs(timems) {"
54 " setTimeout(function() { PauseMs(timems); }, 0);"
55 "}"
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\", "
63 " handler);"
64 "}"
65 "function UninstallTouchHandler() { "
66 " document.getElementById(\"touch\").removeEventListener(\"touchstart\", "
67 " handler);"
68 "}"
69 "</script></html>";
70 const char kHTMLForGuestWithTitle[] =
71 "data:text/html,"
72 "<html><head><title>%s</title></head>"
73 "<body>hello world</body>"
74 "</html>";
75 const char kHTMLForGuestAcceptDrag[] =
76 "data:text/html,<html><body>"
77 "<script>"
78 "function dropped() {"
79 " document.title = \"DROPPED\";"
80 "}"
81 "</script>"
82 "<textarea id=\"text\" style=\"width:100%; height: 100%\""
83 " ondrop=\"dropped();\">"
84 "</textarea>"
85 "</body></html>";
86 const char kHTMLForGuestWithSize[] =
87 "data:text/html,"
88 "<html>"
89 "<body style=\"margin: 0px;\">"
90 "<img style=\"width: 100%; height: 400px;\"/>"
91 "</body>"
92 "</html>";
94 std::string GetHTMLForGuestWithTitle(const std::string& title) {
95 return StringPrintf(kHTMLForGuestWithTitle, title.c_str());
98 } // namespace
100 namespace content {
102 // Test factory for creating test instances of BrowserPluginEmbedder and
103 // BrowserPluginGuest.
104 class TestBrowserPluginHostFactory : public BrowserPluginHostFactory {
105 public:
106 virtual BrowserPluginGuest* CreateBrowserPluginGuest(
107 int instance_id,
108 WebContentsImpl* web_contents,
109 const BrowserPluginHostMsg_CreateGuest_Params& params) OVERRIDE {
110 return new TestBrowserPluginGuest(instance_id,
111 web_contents,
112 params);
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);
126 // Singleton getter.
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)
136 return;
137 // Wait otherwise.
138 message_loop_runner_ = new MessageLoopRunner();
139 message_loop_runner_->Run();
142 protected:
143 TestBrowserPluginHostFactory() : embedder_instance_count_(0) {}
144 virtual ~TestBrowserPluginHostFactory() {}
146 private:
147 // For Singleton.
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
157 // timeout.
158 class TestShortHangTimeoutGuestFactory : public TestBrowserPluginHostFactory {
159 public:
160 virtual BrowserPluginGuest* CreateBrowserPluginGuest(
161 int instance_id,
162 WebContentsImpl* web_contents,
163 const BrowserPluginHostMsg_CreateGuest_Params& params) OVERRIDE {
164 BrowserPluginGuest* guest =
165 new TestBrowserPluginGuest(instance_id,
166 web_contents,
167 params);
168 guest->set_guest_hang_timeout_for_testing(TestTimeouts::tiny_timeout());
169 return guest;
172 // Singleton getter.
173 static TestShortHangTimeoutGuestFactory* GetInstance() {
174 return Singleton<TestShortHangTimeoutGuestFactory>::get();
177 protected:
178 TestShortHangTimeoutGuestFactory() {}
179 virtual ~TestShortHangTimeoutGuestFactory() {}
181 private:
182 // For Singleton.
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 {
191 public:
192 RenderViewHostMessageObserver(RenderViewHost* host,
193 uint32 message_id)
194 : RenderViewHostObserver(host),
195 message_id_(message_id),
196 message_received_(false) {
199 virtual ~RenderViewHostMessageObserver() {}
201 void WaitUntilMessageReceived() {
202 if (message_received_)
203 return;
204 message_loop_runner_ = new MessageLoopRunner();
205 message_loop_runner_->Run();
208 void ResetState() {
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();
219 return false;
222 private:
223 scoped_refptr<MessageLoopRunner> message_loop_runner_;
224 uint32 message_id_;
225 bool message_received_;
227 DISALLOW_COPY_AND_ASSIGN(RenderViewHostMessageObserver);
230 class BrowserPluginHostTest : public ContentBrowserTest {
231 public:
232 BrowserPluginHostTest()
233 : test_embedder_(NULL),
234 test_guest_(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,
259 ui::VKEY_SPACE,
260 false, // control.
261 false, // shift.
262 false, // alt.
263 false); // command.
266 static void SimulateTabKeyPress(WebContents* web_contents) {
267 SimulateKeyPress(web_contents,
268 ui::VKEY_TAB,
269 false, // control.
270 false, // shift.
271 false, // alt.
272 false); // command.
275 // Executes the javascript synchronously and makes sure the returned value is
276 // freed properly.
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.
300 rvh->Focus();
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()));
311 } else {
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_; }
339 private:
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
346 // guest.
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
351 #else
352 #define MAYBE_GuestUnresponsive GuestUnresponsive
353 #endif
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(),
366 expected_title);
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(),
379 expected_title);
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'
390 // events.
391 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
392 test_embedder()->web_contents()->GetRenderViewHost());
393 scoped_ptr<base::Value> value(rvh->ExecuteJavascriptAndGetValue(string16(),
394 ASCIIToUTF16("unresponsiveCalled")));
395 bool result = false;
396 ASSERT_TRUE(value->GetAsBoolean(&result));
397 EXPECT_TRUE(result);
399 value.reset(rvh->ExecuteJavascriptAndGetValue(string16(),
400 ASCIIToUTF16("responsiveCalled")));
401 result = false;
402 ASSERT_TRUE(value->GetAsBoolean(&result));
403 EXPECT_TRUE(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
481 // web_contents.
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(),
597 expected_title);
599 ExecuteSyncJSFunction(
600 rvh,
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(),
611 expected_title);
613 ExecuteSyncJSFunction(
614 rvh,
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(),
625 expected_title);
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()")));
633 bool result = false;
634 ASSERT_TRUE(value->GetAsBoolean(&result));
635 EXPECT_TRUE(result);
637 value.reset(rvh->ExecuteJavascriptAndGetValue(string16(),
638 ASCIIToUTF16("CanGoForward()")));
639 result = false;
640 ASSERT_TRUE(value->GetAsBoolean(&result));
641 EXPECT_TRUE(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(),
648 expected_title);
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()")));
656 bool result = true;
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(),
665 expected_title);
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()")));
673 bool result = true;
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'
689 // in the next step.
691 const string16 expected_title = ASCIIToUTF16("modified");
692 content::TitleWatcher title_watcher(test_embedder()->web_contents(),
693 expected_title);
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(),
706 expected_title);
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(),
754 expected_title);
756 ExecuteSyncJSFunction(
757 rvh,
758 StringPrintf("SetSrc('%s');", GetHTMLForGuestWithTitle("P2").c_str()));
760 string16 actual_title = title_watcher.WaitAndGetTitle();
761 EXPECT_EQ(expected_title, actual_title);
763 // Kill the guest.
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(),
772 expected_title);
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(),
791 expected_title);
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(),
809 expected_title);
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(),
823 expected_title);
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(),
837 expected_title);
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(),
854 expected_title);
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")));
870 std::string result;
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
881 // correctly.
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);
901 double end_x, end_y;
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");
906 drop_data.url = url;
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
912 // happens.
913 const string16 expected_title = ASCIIToUTF16("DROPPED");
914 content::TitleWatcher title_watcher(test_guest()->web_contents(),
915 expected_title);
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'
936 // message.
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(),
947 expected_title);
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(),
975 expected_title);
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(
994 guest_rvh,
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();
1078 // Get a new guest.
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.
1106 // crbug.com/170249
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
1116 // current guest.
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();
1135 // Get a new guest.
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
1157 // current guest.
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(),
1203 expected_title);
1204 ExecuteSyncJSFunction(
1205 rvh,
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(),
1218 expected_title);
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,
1237 embedder_code);
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
1240 // embedder.
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")));
1257 std::string result;
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(),
1266 expected_title);
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")));
1273 std::string result;
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(),
1282 expected_title);
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