• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/strings/stringprintf.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/app/chrome_command_ids.h"
8 #include "chrome/browser/apps/app_browsertest_util.h"
9 #include "chrome/browser/chrome_content_browser_client.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
12 #include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
13 #include "chrome/test/base/interactive_test_utils.h"
14 #include "chrome/test/base/test_launcher_utils.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/render_widget_host_iterator.h"
20 #include "content/public/browser/render_widget_host_view.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "extensions/browser/app_window/app_window.h"
25 #include "extensions/browser/app_window/app_window_registry.h"
26 #include "extensions/browser/guest_view/guest_view_base.h"
27 #include "extensions/browser/guest_view/guest_view_manager.h"
28 #include "extensions/browser/guest_view/guest_view_manager_factory.h"
29 #include "extensions/test/extension_test_message_listener.h"
30 #include "net/test/embedded_test_server/embedded_test_server.h"
31 #include "ui/base/ime/composition_text.h"
32 #include "ui/base/ime/text_input_client.h"
33 #include "ui/base/test/ui_controls.h"
34 #include "ui/events/keycodes/keyboard_codes.h"
35 
36 using extensions::AppWindow;
37 
38 class TestGuestViewManager : public extensions::GuestViewManager {
39  public:
TestGuestViewManager(content::BrowserContext * context)40   explicit TestGuestViewManager(content::BrowserContext* context)
41       : GuestViewManager(context),
42         guest_add_count_(0),
43         guest_remove_count_(0),
44         web_contents_(NULL) {}
45 
WaitForGuestAdded()46   content::WebContents* WaitForGuestAdded() {
47     if (web_contents_)
48       return web_contents_;
49 
50     add_message_loop_runner_ = new content::MessageLoopRunner;
51     add_message_loop_runner_->Run();
52     return web_contents_;
53   }
54 
55   // Waits so that at least |expected_remove_count| guests' creation
56   // has been seen by this manager.
WaitForGuestRemoved(size_t expected_remove_count)57   void WaitForGuestRemoved(size_t expected_remove_count) {
58     if (guest_remove_count_ >= expected_remove_count)
59       return;
60 
61     remove_message_loop_runner_ = new content::MessageLoopRunner;
62     remove_message_loop_runner_->Run();
63   }
64 
guest_add_count()65   size_t guest_add_count() { return guest_add_count_; }
66 
67  private:
68   // GuestViewManager override:
AddGuest(int guest_instance_id,content::WebContents * guest_web_contents)69   virtual void AddGuest(int guest_instance_id,
70                         content::WebContents* guest_web_contents) OVERRIDE{
71     GuestViewManager::AddGuest(guest_instance_id, guest_web_contents);
72     web_contents_ = guest_web_contents;
73     ++guest_add_count_;
74 
75     if (add_message_loop_runner_.get())
76       add_message_loop_runner_->Quit();
77   }
78 
RemoveGuest(int guest_instance_id)79   virtual void RemoveGuest(int guest_instance_id) OVERRIDE {
80     GuestViewManager::RemoveGuest(guest_instance_id);
81     ++guest_remove_count_;
82 
83     if (remove_message_loop_runner_.get())
84       remove_message_loop_runner_->Quit();
85   }
86 
87   size_t guest_add_count_;
88   size_t guest_remove_count_;
89   content::WebContents* web_contents_;
90   scoped_refptr<content::MessageLoopRunner> add_message_loop_runner_;
91   scoped_refptr<content::MessageLoopRunner> remove_message_loop_runner_;
92 };
93 
94 // Test factory for creating test instances of GuestViewManager.
95 class TestGuestViewManagerFactory : public extensions::GuestViewManagerFactory {
96  public:
TestGuestViewManagerFactory()97   TestGuestViewManagerFactory() :
98       test_guest_view_manager_(NULL) {}
99 
~TestGuestViewManagerFactory()100   virtual ~TestGuestViewManagerFactory() {}
101 
CreateGuestViewManager(content::BrowserContext * context)102   virtual extensions::GuestViewManager* CreateGuestViewManager(
103       content::BrowserContext* context) OVERRIDE {
104     return GetManager(context);
105   }
106 
GetManager(content::BrowserContext * context)107   TestGuestViewManager* GetManager(content::BrowserContext* context) {
108     if (!test_guest_view_manager_) {
109       test_guest_view_manager_ = new TestGuestViewManager(context);
110     }
111     return test_guest_view_manager_;
112   }
113 
114  private:
115   TestGuestViewManager* test_guest_view_manager_;
116 
117   DISALLOW_COPY_AND_ASSIGN(TestGuestViewManagerFactory);
118 };
119 
120 class WebViewInteractiveTest
121     : public extensions::PlatformAppBrowserTest {
122  public:
WebViewInteractiveTest()123   WebViewInteractiveTest()
124       : guest_web_contents_(NULL),
125         embedder_web_contents_(NULL),
126         corner_(gfx::Point()),
127         mouse_click_result_(false),
128         first_click_(true) {
129     extensions::GuestViewManager::set_factory_for_testing(&factory_);
130   }
131 
GetGuestViewManager()132   TestGuestViewManager* GetGuestViewManager() {
133     return factory_.GetManager(browser()->profile());
134   }
135 
MoveMouseInsideWindowWithListener(gfx::Point point,const std::string & message)136   void MoveMouseInsideWindowWithListener(gfx::Point point,
137                                          const std::string& message) {
138     ExtensionTestMessageListener move_listener(message, false);
139     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
140         gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
141     ASSERT_TRUE(move_listener.WaitUntilSatisfied());
142   }
143 
SendMouseClickWithListener(ui_controls::MouseButton button,const std::string & message)144   void SendMouseClickWithListener(ui_controls::MouseButton button,
145                                   const std::string& message) {
146     ExtensionTestMessageListener listener(message, false);
147     SendMouseClick(button);
148     ASSERT_TRUE(listener.WaitUntilSatisfied());
149   }
150 
SendMouseClick(ui_controls::MouseButton button)151   void SendMouseClick(ui_controls::MouseButton button) {
152     SendMouseEvent(button, ui_controls::DOWN);
153     SendMouseEvent(button, ui_controls::UP);
154   }
155 
MoveMouseInsideWindow(const gfx::Point & point)156   void MoveMouseInsideWindow(const gfx::Point& point) {
157     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
158         gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
159   }
160 
GetPlatformAppWindow()161   gfx::NativeWindow GetPlatformAppWindow() {
162     const extensions::AppWindowRegistry::AppWindowList& app_windows =
163         extensions::AppWindowRegistry::Get(browser()->profile())->app_windows();
164     return (*app_windows.begin())->GetNativeWindow();
165   }
166 
SendKeyPressToPlatformApp(ui::KeyboardCode key)167   void SendKeyPressToPlatformApp(ui::KeyboardCode key) {
168     ASSERT_EQ(1U, GetAppWindowCount());
169     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
170         GetPlatformAppWindow(), key, false, false, false, false));
171   }
172 
SendCopyKeyPressToPlatformApp()173   void SendCopyKeyPressToPlatformApp() {
174     ASSERT_EQ(1U, GetAppWindowCount());
175 #if defined(OS_MACOSX)
176     // Send Cmd+C on MacOSX.
177     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
178         GetPlatformAppWindow(), ui::VKEY_C, false, false, false, true));
179 #else
180     // Send Ctrl+C on Windows and Linux/ChromeOS.
181     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
182         GetPlatformAppWindow(), ui::VKEY_C, true, false, false, false));
183 #endif
184   }
185 
SendStartOfLineKeyPressToPlatformApp()186   void SendStartOfLineKeyPressToPlatformApp() {
187 #if defined(OS_MACOSX)
188     // Send Cmd+Left on MacOSX.
189     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
190         GetPlatformAppWindow(), ui::VKEY_LEFT, false, false, false, true));
191 #else
192     // Send Ctrl+Left on Windows and Linux/ChromeOS.
193     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
194         GetPlatformAppWindow(), ui::VKEY_LEFT, true, false, false, false));
195 #endif
196   }
197 
SendBackShortcutToPlatformApp()198   void SendBackShortcutToPlatformApp() {
199 #if defined(OS_MACOSX)
200     // Send Cmd+[ on MacOSX.
201     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
202         GetPlatformAppWindow(), ui::VKEY_OEM_4, false, false, false, true));
203 #else
204     // Send browser back key on Linux/Windows.
205     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
206         GetPlatformAppWindow(), ui::VKEY_BROWSER_BACK,
207         false, false, false, false));
208 #endif
209   }
210 
SendForwardShortcutToPlatformApp()211   void SendForwardShortcutToPlatformApp() {
212 #if defined(OS_MACOSX)
213     // Send Cmd+] on MacOSX.
214     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
215         GetPlatformAppWindow(), ui::VKEY_OEM_6, false, false, false, true));
216 #else
217     // Send browser back key on Linux/Windows.
218     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
219         GetPlatformAppWindow(), ui::VKEY_BROWSER_FORWARD,
220         false, false, false, false));
221 #endif
222   }
223 
SendMouseEvent(ui_controls::MouseButton button,ui_controls::MouseButtonState state)224   void SendMouseEvent(ui_controls::MouseButton button,
225                       ui_controls::MouseButtonState state) {
226     if (first_click_) {
227       mouse_click_result_ = ui_test_utils::SendMouseEventsSync(button,
228                                                                 state);
229       first_click_ = false;
230     } else {
231       ASSERT_EQ(mouse_click_result_, ui_test_utils::SendMouseEventsSync(
232           button, state));
233     }
234   }
235 
236   enum TestServer {
237     NEEDS_TEST_SERVER,
238     NO_TEST_SERVER
239   };
240 
RunAppHelper(const std::string & test_name,const std::string & app_location,TestServer test_server,content::WebContents ** embedder_web_contents)241   scoped_ptr<ExtensionTestMessageListener> RunAppHelper(
242       const std::string& test_name,
243       const std::string& app_location,
244       TestServer test_server,
245       content::WebContents** embedder_web_contents) {
246     // For serving guest pages.
247     if ((test_server == NEEDS_TEST_SERVER) && !StartEmbeddedTestServer()) {
248       LOG(ERROR) << "FAILED TO START TEST SERVER.";
249       return scoped_ptr<ExtensionTestMessageListener>();
250     }
251 
252     LoadAndLaunchPlatformApp(app_location.c_str(), "Launched");
253     if (!ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow())) {
254       LOG(ERROR) << "UNABLE TO FOCUS TEST WINDOW.";
255       return scoped_ptr<ExtensionTestMessageListener>();
256     }
257 
258     // Flush any pending events to make sure we start with a clean slate.
259     content::RunAllPendingInMessageLoop();
260 
261     *embedder_web_contents = GetFirstAppWindowWebContents();
262 
263     scoped_ptr<ExtensionTestMessageListener> done_listener(
264         new ExtensionTestMessageListener("TEST_PASSED", false));
265     done_listener->set_failure_message("TEST_FAILED");
266     if (!content::ExecuteScript(
267             *embedder_web_contents,
268             base::StringPrintf("runTest('%s')", test_name.c_str()))) {
269       LOG(ERROR) << "UNABLE TO START TEST";
270       return scoped_ptr<ExtensionTestMessageListener>();
271     }
272 
273     return done_listener.Pass();
274   }
275 
TestHelper(const std::string & test_name,const std::string & app_location,TestServer test_server)276   void TestHelper(const std::string& test_name,
277                   const std::string& app_location,
278                   TestServer test_server) {
279     content::WebContents* embedder_web_contents = NULL;
280     scoped_ptr<ExtensionTestMessageListener> done_listener(
281         RunAppHelper(
282             test_name, app_location, test_server, &embedder_web_contents));
283 
284     ASSERT_TRUE(done_listener);
285     ASSERT_TRUE(done_listener->WaitUntilSatisfied());
286 
287     guest_web_contents_ = GetGuestViewManager()->WaitForGuestAdded();
288   }
289 
RunTest(const std::string & app_name)290   void RunTest(const std::string& app_name) {
291   }
SetupTest(const std::string & app_name,const std::string & guest_url_spec)292   void SetupTest(const std::string& app_name,
293                  const std::string& guest_url_spec) {
294     ASSERT_TRUE(StartEmbeddedTestServer());
295     GURL::Replacements replace_host;
296     std::string host_str("localhost");  // Must stay in scope with replace_host.
297     replace_host.SetHostStr(host_str);
298 
299     GURL guest_url = embedded_test_server()->GetURL(guest_url_spec);
300     guest_url = guest_url.ReplaceComponents(replace_host);
301 
302     ui_test_utils::UrlLoadObserver guest_observer(
303         guest_url, content::NotificationService::AllSources());
304 
305     LoadAndLaunchPlatformApp(app_name.c_str(), "connected");
306 
307     guest_observer.Wait();
308     content::Source<content::NavigationController> source =
309         guest_observer.source();
310     EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->
311         IsIsolatedGuest());
312 
313     guest_web_contents_ = source->GetWebContents();
314     embedder_web_contents_ =
315         extensions::GuestViewBase::FromWebContents(guest_web_contents_)->
316             embedder_web_contents();
317 
318     gfx::Rect offset = embedder_web_contents_->GetContainerBounds();
319     corner_ = gfx::Point(offset.x(), offset.y());
320 
321     const testing::TestInfo* const test_info =
322             testing::UnitTest::GetInstance()->current_test_info();
323     const char* prefix = "DragDropWithinWebView";
324     if (!strncmp(test_info->name(), prefix, strlen(prefix))) {
325       // In the drag drop test we add 20px padding to the page body because on
326       // windows if we get too close to the edge of the window the resize cursor
327       // appears and we start dragging the window edge.
328       corner_.Offset(20, 20);
329     }
330   }
331 
guest_web_contents()332   content::WebContents* guest_web_contents() {
333     return guest_web_contents_;
334   }
335 
embedder_web_contents()336   content::WebContents* embedder_web_contents() {
337     return embedder_web_contents_;
338   }
339 
corner()340   gfx::Point corner() {
341     return corner_;
342   }
343 
SimulateRWHMouseClick(content::RenderWidgetHost * rwh,blink::WebMouseEvent::Button button,int x,int y)344   void SimulateRWHMouseClick(content::RenderWidgetHost* rwh,
345                              blink::WebMouseEvent::Button button,
346                              int x,
347                              int y) {
348     blink::WebMouseEvent mouse_event;
349     mouse_event.button = button;
350     mouse_event.x = mouse_event.windowX = x;
351     mouse_event.y = mouse_event.windowY = y;
352     mouse_event.modifiers = 0;
353 
354     mouse_event.type = blink::WebInputEvent::MouseDown;
355     rwh->ForwardMouseEvent(mouse_event);
356     mouse_event.type = blink::WebInputEvent::MouseUp;
357     rwh->ForwardMouseEvent(mouse_event);
358   }
359 
360   class PopupCreatedObserver {
361    public:
PopupCreatedObserver()362     PopupCreatedObserver()
363         : initial_widget_count_(0),
364           last_render_widget_host_(NULL),
365           seen_new_widget_(false) {}
366 
~PopupCreatedObserver()367     ~PopupCreatedObserver() {}
368 
Wait()369     void Wait() {
370       size_t current_widget_count = CountWidgets();
371       if (!seen_new_widget_ &&
372           current_widget_count == initial_widget_count_ + 1) {
373         seen_new_widget_ = true;
374       }
375 
376       // If we haven't seen any new widget or we get 0 size widget, we need to
377       // schedule waiting.
378       bool needs_to_schedule_wait = true;
379 
380       if (seen_new_widget_) {
381         gfx::Rect popup_bounds =
382             last_render_widget_host_->GetView()->GetViewBounds();
383         if (!popup_bounds.size().IsEmpty())
384           needs_to_schedule_wait = false;
385       }
386 
387       if (needs_to_schedule_wait) {
388         ScheduleWait();
389       } else {
390         // We are done.
391         if (message_loop_.get())
392           message_loop_->Quit();
393       }
394 
395       if (!message_loop_.get()) {
396         message_loop_ = new content::MessageLoopRunner;
397         message_loop_->Run();
398       }
399     }
400 
Init()401     void Init() { initial_widget_count_ = CountWidgets(); }
402 
403     // Returns the last widget created.
last_render_widget_host()404     content::RenderWidgetHost* last_render_widget_host() {
405       return last_render_widget_host_;
406     }
407 
408    private:
ScheduleWait()409     void ScheduleWait() {
410       base::MessageLoop::current()->PostDelayedTask(
411           FROM_HERE,
412           base::Bind(&PopupCreatedObserver::Wait, base::Unretained(this)),
413           base::TimeDelta::FromMilliseconds(200));
414     }
415 
CountWidgets()416     size_t CountWidgets() {
417       scoped_ptr<content::RenderWidgetHostIterator> widgets(
418           content::RenderWidgetHost::GetRenderWidgetHosts());
419       size_t num_widgets = 0;
420       while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
421         if (widget->IsRenderView())
422           continue;
423         ++num_widgets;
424         last_render_widget_host_ = widget;
425       }
426       return num_widgets;
427     }
428 
429     size_t initial_widget_count_;
430     content::RenderWidgetHost* last_render_widget_host_;
431     scoped_refptr<content::MessageLoopRunner> message_loop_;
432     bool seen_new_widget_;
433 
434     DISALLOW_COPY_AND_ASSIGN(PopupCreatedObserver);
435   };
436 
WaitForTitle(const char * title)437   void WaitForTitle(const char* title) {
438     base::string16 expected_title(base::ASCIIToUTF16(title));
439     base::string16 error_title(base::ASCIIToUTF16("FAILED"));
440     content::TitleWatcher title_watcher(guest_web_contents(), expected_title);
441     title_watcher.AlsoWaitForTitle(error_title);
442     ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
443   }
444 
PopupTestHelper(const gfx::Point & padding)445   void PopupTestHelper(const gfx::Point& padding) {
446     PopupCreatedObserver popup_observer;
447     popup_observer.Init();
448     // Press alt+DOWN to open popup.
449     bool alt = true;
450     content::SimulateKeyPress(
451         guest_web_contents(), ui::VKEY_DOWN, false, false, alt, false);
452     popup_observer.Wait();
453 
454     content::RenderWidgetHost* popup_rwh =
455         popup_observer.last_render_widget_host();
456     gfx::Rect popup_bounds = popup_rwh->GetView()->GetViewBounds();
457 
458     content::RenderViewHost* embedder_rvh =
459         GetFirstAppWindowWebContents()->GetRenderViewHost();
460     gfx::Rect embedder_bounds = embedder_rvh->GetView()->GetViewBounds();
461     gfx::Vector2d diff = popup_bounds.origin() - embedder_bounds.origin();
462     LOG(INFO) << "DIFF: x = " << diff.x() << ", y = " << diff.y();
463 
464     const int left_spacing = 40 + padding.x();  // div.style.paddingLeft = 40px.
465     // div.style.paddingTop = 50px + (input box height = 26px).
466     const int top_spacing = 50 + 26 + padding.y();
467 
468     // If the popup is placed within |threshold_px| of the expected position,
469     // then we consider the test as a pass.
470     const int threshold_px = 10;
471 
472     EXPECT_LE(std::abs(diff.x() - left_spacing), threshold_px);
473     EXPECT_LE(std::abs(diff.y() - top_spacing), threshold_px);
474 
475     // Close the popup.
476     content::SimulateKeyPress(
477         guest_web_contents(), ui::VKEY_ESCAPE, false, false, false, false);
478   }
479 
DragTestStep1()480   void DragTestStep1() {
481     // Move mouse to start of text.
482     MoveMouseInsideWindow(gfx::Point(45, 8));
483     MoveMouseInsideWindow(gfx::Point(45, 9));
484     SendMouseEvent(ui_controls::LEFT, ui_controls::DOWN);
485 
486     MoveMouseInsideWindow(gfx::Point(74, 12));
487     MoveMouseInsideWindow(gfx::Point(78, 12));
488 
489     // Now wait a bit before moving mouse to initiate drag/drop.
490     base::MessageLoop::current()->PostDelayedTask(
491         FROM_HERE,
492         base::Bind(&WebViewInteractiveTest::DragTestStep2,
493                    base::Unretained(this)),
494         base::TimeDelta::FromMilliseconds(200));
495   }
496 
DragTestStep2()497   void DragTestStep2() {
498     // Drag source over target.
499     MoveMouseInsideWindow(gfx::Point(76, 76));
500 
501     // Create a second mouse over the source to trigger the drag over event.
502     MoveMouseInsideWindow(gfx::Point(76, 77));
503 
504     // Release mouse to drop.
505     SendMouseEvent(ui_controls::LEFT, ui_controls::UP);
506     SendMouseClick(ui_controls::LEFT);
507 
508     quit_closure_.Run();
509 
510     // Note that following ExtensionTestMessageListener and ExecuteScript*
511     // call must be after we quit |quit_closure_|. Otherwise the class
512     // here won't be able to receive messages sent by chrome.test.sendMessage.
513     // This is because of the nature of drag and drop code (esp. the
514     // MessageLoop) in it.
515 
516     // Now check if we got a drop and read the drop data.
517     embedder_web_contents_ = GetFirstAppWindowWebContents();
518     ExtensionTestMessageListener drop_listener("guest-got-drop", false);
519     EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
520                                        "window.checkIfGuestGotDrop()"));
521     EXPECT_TRUE(drop_listener.WaitUntilSatisfied());
522 
523     std::string last_drop_data;
524     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
525                     embedder_web_contents_,
526                     "window.domAutomationController.send(getLastDropData())",
527                     &last_drop_data));
528 
529     last_drop_data_ = last_drop_data;
530   }
531 
532  protected:
533   TestGuestViewManagerFactory factory_;
534   content::WebContents* guest_web_contents_;
535   content::WebContents* embedder_web_contents_;
536   gfx::Point corner_;
537   bool mouse_click_result_;
538   bool first_click_;
539   // Only used in drag/drop test.
540   base::Closure quit_closure_;
541   std::string last_drop_data_;
542 };
543 
544 // ui_test_utils::SendMouseMoveSync doesn't seem to work on OS_MACOSX, and
545 // likely won't work on many other platforms as well, so for now this test
546 // is for Windows and Linux only. As of Sept 17th, 2013 this test is disabled
547 // on Windows due to flakines, see http://crbug.com/293445.
548 
549 // Disabled on Linux Aura because pointer lock does not work on Linux Aura.
550 // crbug.com/341876
551 
552 #if defined(OS_LINUX)
553 // flaky http://crbug.com/412086
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,DISABLED_PointerLock)554 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PointerLock) {
555   SetupTest("web_view/pointer_lock",
556             "/extensions/platform_apps/web_view/pointer_lock/guest.html");
557 
558   // Move the mouse over the Lock Pointer button.
559   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
560       gfx::Point(corner().x() + 75, corner().y() + 25)));
561 
562   // Click the Lock Pointer button. The first two times the button is clicked
563   // the permission API will deny the request (intentional).
564   ExtensionTestMessageListener exception_listener("request exception", false);
565   SendMouseClickWithListener(ui_controls::LEFT, "lock error");
566   ASSERT_TRUE(exception_listener.WaitUntilSatisfied());
567   SendMouseClickWithListener(ui_controls::LEFT, "lock error");
568 
569   // Click the Lock Pointer button, locking the mouse to lockTarget1.
570   SendMouseClickWithListener(ui_controls::LEFT, "locked");
571 
572   // Attempt to move the mouse off of the lock target, and onto lockTarget2,
573   // (which would trigger a test failure).
574   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
575       gfx::Point(corner().x() + 74, corner().y() + 74)));
576   MoveMouseInsideWindowWithListener(gfx::Point(75, 75), "mouse-move");
577 
578 #if defined(OS_WIN)
579   // When the mouse is unlocked on win aura, sending a test mouse click clicks
580   // where the mouse moved to while locked. I was unable to figure out why, and
581   // since the issue only occurs with the test mouse events, just fix it with
582   // a simple workaround - moving the mouse back to where it should be.
583   // TODO(mthiesse): Fix Win Aura simulated mouse events while mouse locked.
584   MoveMouseInsideWindowWithListener(gfx::Point(75, 25), "mouse-move");
585 #endif
586 
587   ExtensionTestMessageListener unlocked_listener("unlocked", false);
588   // Send a key press to unlock the mouse.
589   SendKeyPressToPlatformApp(ui::VKEY_ESCAPE);
590 
591   // Wait for page to receive (successful) mouse unlock response.
592   ASSERT_TRUE(unlocked_listener.WaitUntilSatisfied());
593 
594   // After the second lock, guest.js sends a message to main.js to remove the
595   // webview object. main.js then removes the div containing the webview, which
596   // should unlock, and leave the mouse over the mousemove-capture-container
597   // div. We then move the mouse over that div to ensure the mouse was properly
598   // unlocked and that the div receieves the message.
599   ExtensionTestMessageListener move_captured_listener("move-captured", false);
600   move_captured_listener.set_failure_message("timeout");
601 
602   // Mouse should already be over lock button (since we just unlocked), so send
603   // click to re-lock the mouse.
604   SendMouseClickWithListener(ui_controls::LEFT, "deleted");
605 
606   // A mousemove event is triggered on the mousemove-capture-container element
607   // when we delete the webview container (since the mouse moves onto the
608   // element), but just in case, send an explicit mouse movement to be safe.
609   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
610       gfx::Point(corner().x() + 50, corner().y() + 10)));
611 
612   // Wait for page to receive second (successful) mouselock response.
613   bool success = move_captured_listener.WaitUntilSatisfied();
614   if (!success) {
615     fprintf(stderr, "TIMEOUT - retrying\n");
616     // About 1 in 40 tests fail to detect mouse moves at this point (why?).
617     // Sending a right click seems to fix this (why?).
618     ExtensionTestMessageListener move_listener2("move-captured", false);
619     SendMouseClick(ui_controls::RIGHT);
620     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
621         gfx::Point(corner().x() + 51, corner().y() + 11)));
622     ASSERT_TRUE(move_listener2.WaitUntilSatisfied());
623   }
624 }
625 
626 // flaky http://crbug.com/412086
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,DISABLED_PointerLockFocus)627 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PointerLockFocus) {
628   SetupTest("web_view/pointer_lock_focus",
629             "/extensions/platform_apps/web_view/pointer_lock_focus/guest.html");
630 
631   // Move the mouse over the Lock Pointer button.
632   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
633       gfx::Point(corner().x() + 75, corner().y() + 25)));
634 
635   // Click the Lock Pointer button, locking the mouse to lockTarget.
636   // This will also change focus to another element
637   SendMouseClickWithListener(ui_controls::LEFT, "locked");
638 
639   // Try to unlock the mouse now that the focus is outside of the BrowserPlugin
640   ExtensionTestMessageListener unlocked_listener("unlocked", false);
641   // Send a key press to unlock the mouse.
642   SendKeyPressToPlatformApp(ui::VKEY_ESCAPE);
643 
644   // Wait for page to receive (successful) mouse unlock response.
645   ASSERT_TRUE(unlocked_listener.WaitUntilSatisfied());
646 }
647 
648 #endif  // defined(OS_LINUX)
649 
650 // Tests that if a <webview> is focused before navigation then the guest starts
651 // off focused.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Focus_FocusBeforeNavigation)652 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusBeforeNavigation) {
653   TestHelper("testFocusBeforeNavigation", "web_view/focus", NO_TEST_SERVER);
654 }
655 
656 // Tests that setting focus on the <webview> sets focus on the guest.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Focus_FocusEvent)657 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusEvent) {
658   TestHelper("testFocusEvent", "web_view/focus", NO_TEST_SERVER);
659 }
660 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Focus_FocusTracksEmbedder)661 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusTracksEmbedder) {
662   content::WebContents* embedder_web_contents = NULL;
663 
664   scoped_ptr<ExtensionTestMessageListener> done_listener(
665       RunAppHelper("testFocusTracksEmbedder", "web_view/focus", NO_TEST_SERVER,
666                    &embedder_web_contents));
667   done_listener->WaitUntilSatisfied();
668 
669   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED", false);
670   next_step_listener.set_failure_message("TEST_STEP_FAILED");
671   EXPECT_TRUE(content::ExecuteScript(
672                   embedder_web_contents,
673                   "window.runCommand('testFocusTracksEmbedderRunNextStep');"));
674 
675   // Blur the embedder.
676   embedder_web_contents->GetRenderViewHost()->Blur();
677   // Ensure that the guest is also blurred.
678   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
679 }
680 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Focus_AdvanceFocus)681 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_AdvanceFocus) {
682   content::WebContents* embedder_web_contents = NULL;
683 
684   {
685     scoped_ptr<ExtensionTestMessageListener> done_listener(
686         RunAppHelper("testAdvanceFocus", "web_view/focus", NO_TEST_SERVER,
687                      &embedder_web_contents));
688     done_listener->WaitUntilSatisfied();
689   }
690 
691   {
692     ExtensionTestMessageListener listener("button1-focused", false);
693     listener.set_failure_message("TEST_FAILED");
694     SimulateRWHMouseClick(embedder_web_contents->GetRenderViewHost(),
695                           blink::WebMouseEvent::ButtonLeft, 200, 20);
696     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
697         false, false, false, false);
698     ASSERT_TRUE(listener.WaitUntilSatisfied());
699   }
700 
701   {
702     // Wait for button1 to be focused again, this means we were asked to
703     // move the focus to the next focusable element.
704     ExtensionTestMessageListener listener("button1-advance-focus", false);
705     listener.set_failure_message("TEST_FAILED");
706     // TODO(fsamuel): A third Tab key press should not be necessary.
707     // The <webview> will take keyboard focus but it will not focus an initial
708     // element. The initial element is dependent upon tab direction which blink
709     // does not propagate to the plugin.
710     // See http://crbug.com/147644.
711     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
712         false, false, false, false);
713     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
714         false, false, false, false);
715     content::SimulateKeyPress(embedder_web_contents, ui::VKEY_TAB,
716         false, false, false, false);
717     ASSERT_TRUE(listener.WaitUntilSatisfied());
718   }
719 }
720 
721 // Tests that blurring <webview> also blurs the guest.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Focus_BlurEvent)722 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_BlurEvent) {
723   TestHelper("testBlurEvent", "web_view/focus", NO_TEST_SERVER);
724 }
725 
726 // Tests that guests receive edit commands and respond appropriately.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,EditCommands)727 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommands) {
728   LoadAndLaunchPlatformApp("web_view/edit_commands", "connected");
729 
730   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
731       GetPlatformAppWindow()));
732 
733   // Flush any pending events to make sure we start with a clean slate.
734   content::RunAllPendingInMessageLoop();
735 
736   ExtensionTestMessageListener copy_listener("copy", false);
737   SendCopyKeyPressToPlatformApp();
738 
739   // Wait for the guest to receive a 'copy' edit command.
740   ASSERT_TRUE(copy_listener.WaitUntilSatisfied());
741 }
742 
743 // Tests that guests receive edit commands and respond appropriately.
744 // http://crbug.com/417892
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,DISABLED_EditCommandsNoMenu)745 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_EditCommandsNoMenu) {
746   SetupTest("web_view/edit_commands_no_menu",
747       "/extensions/platform_apps/web_view/edit_commands_no_menu/"
748       "guest.html");
749 
750   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
751       GetPlatformAppWindow()));
752 
753   // Flush any pending events to make sure we start with a clean slate.
754   content::RunAllPendingInMessageLoop();
755 
756   ExtensionTestMessageListener start_of_line_listener("StartOfLine", false);
757   SendStartOfLineKeyPressToPlatformApp();
758   // Wait for the guest to receive a 'copy' edit command.
759   ASSERT_TRUE(start_of_line_listener.WaitUntilSatisfied());
760 }
761 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_AttachAfterOpenerDestroyed)762 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
763                        NewWindow_AttachAfterOpenerDestroyed) {
764   TestHelper("testNewWindowAttachAfterOpenerDestroyed",
765              "web_view/newwindow",
766              NEEDS_TEST_SERVER);
767 }
768 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_NewWindowNameTakesPrecedence)769 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
770                        NewWindow_NewWindowNameTakesPrecedence) {
771   TestHelper("testNewWindowNameTakesPrecedence",
772              "web_view/newwindow",
773              NEEDS_TEST_SERVER);
774 }
775 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_WebViewNameTakesPrecedence)776 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
777                        NewWindow_WebViewNameTakesPrecedence) {
778   TestHelper("testNewWindowWebViewNameTakesPrecedence",
779              "web_view/newwindow",
780              NEEDS_TEST_SERVER);
781 }
782 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_NoName)783 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_NoName) {
784   TestHelper("testNewWindowNoName",
785              "web_view/newwindow",
786              NEEDS_TEST_SERVER);
787 }
788 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_Redirect)789 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Redirect) {
790   TestHelper("testNewWindowRedirect",
791              "web_view/newwindow",
792              NEEDS_TEST_SERVER);
793 }
794 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_Close)795 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Close) {
796   TestHelper("testNewWindowClose",
797              "web_view/newwindow",
798              NEEDS_TEST_SERVER);
799 }
800 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_DeferredAttachment)801 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_DeferredAttachment) {
802   TestHelper("testNewWindowDeferredAttachment",
803              "web_view/newwindow",
804              NEEDS_TEST_SERVER);
805 }
806 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_ExecuteScript)807 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_ExecuteScript) {
808   TestHelper("testNewWindowExecuteScript",
809              "web_view/newwindow",
810              NEEDS_TEST_SERVER);
811 }
812 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_DeclarativeWebRequest)813 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
814                        NewWindow_DeclarativeWebRequest) {
815   TestHelper("testNewWindowDeclarativeWebRequest",
816              "web_view/newwindow",
817              NEEDS_TEST_SERVER);
818 }
819 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_DiscardAfterOpenerDestroyed)820 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
821                        NewWindow_DiscardAfterOpenerDestroyed) {
822   TestHelper("testNewWindowDiscardAfterOpenerDestroyed",
823              "web_view/newwindow",
824              NEEDS_TEST_SERVER);
825 }
826 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_WebRequest)827 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_WebRequest) {
828   TestHelper("testNewWindowWebRequest",
829              "web_view/newwindow",
830              NEEDS_TEST_SERVER);
831 }
832 
833 // A custom elements bug needs to be addressed to enable this test:
834 // See http://crbug.com/282477 for more information.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,DISABLED_NewWindow_WebRequestCloseWindow)835 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
836                        DISABLED_NewWindow_WebRequestCloseWindow) {
837   TestHelper("testNewWindowWebRequestCloseWindow",
838              "web_view/newwindow",
839              NEEDS_TEST_SERVER);
840 }
841 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_WebRequestRemoveElement)842 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
843                        NewWindow_WebRequestRemoveElement) {
844   TestHelper("testNewWindowWebRequestRemoveElement",
845              "web_view/newwindow",
846              NEEDS_TEST_SERVER);
847 }
848 
849 // Tests that Ctrl+Click/Cmd+Click on a link fires up the newwindow API.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_OpenInNewTab)850 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_OpenInNewTab) {
851   content::WebContents* embedder_web_contents = NULL;
852 
853   ExtensionTestMessageListener loaded_listener("Loaded", false);
854   scoped_ptr<ExtensionTestMessageListener> done_listener(
855     RunAppHelper("testNewWindowOpenInNewTab",
856                  "web_view/newwindow",
857                  NEEDS_TEST_SERVER,
858                  &embedder_web_contents));
859 
860   loaded_listener.WaitUntilSatisfied();
861 #if defined(OS_MACOSX)
862   ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
863       GetPlatformAppWindow(), ui::VKEY_RETURN,
864       false, false, false, true /* cmd */));
865 #else
866   ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
867       GetPlatformAppWindow(), ui::VKEY_RETURN,
868       true /* ctrl */, false, false, false));
869 #endif
870 
871   // Wait for the embedder to receive a 'newwindow' event.
872   ASSERT_TRUE(done_listener->WaitUntilSatisfied());
873 }
874 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,NewWindow_OpenerDestroyedWhileUnattached)875 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
876                        NewWindow_OpenerDestroyedWhileUnattached) {
877   TestHelper("testNewWindowOpenerDestroyedWhileUnattached",
878              "web_view/newwindow",
879              NEEDS_TEST_SERVER);
880   ASSERT_EQ(2u, GetGuestViewManager()->guest_add_count());
881 
882   // We have two guests in this test, one is the intial one, the other
883   // is the newwindow one.
884   // Before the embedder goes away, both the guests should go away.
885   // This ensures that unattached guests are gone if opener is gone.
886   GetGuestViewManager()->WaitForGuestRemoved(2u);
887 }
888 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,ExecuteCode)889 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, ExecuteCode) {
890   ASSERT_TRUE(RunPlatformAppTestWithArg(
891       "platform_apps/web_view/common", "execute_code")) << message_;
892 }
893 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,PopupPositioningBasic)894 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioningBasic) {
895   TestHelper("testBasic", "web_view/popup_positioning", NO_TEST_SERVER);
896   ASSERT_TRUE(guest_web_contents());
897   PopupTestHelper(gfx::Point());
898 
899   // TODO(lazyboy): Move the embedder window to a random location and
900   // make sure we keep rendering popups correct in webview.
901 }
902 
903 // Tests that moving browser plugin (without resize/UpdateRects) correctly
904 // repositions popup.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,PopupPositioningMoved)905 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioningMoved) {
906   TestHelper("testMoved", "web_view/popup_positioning", NO_TEST_SERVER);
907   ASSERT_TRUE(guest_web_contents());
908   PopupTestHelper(gfx::Point(20, 0));
909 }
910 
911 // Drag and drop inside a webview is currently only enabled for linux and mac,
912 // but the tests don't work on anything except chromeos for now. This is because
913 // of simulating mouse drag code's dependency on platforms.
914 #if defined(OS_CHROMEOS) && !defined(USE_OZONE)
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,DragDropWithinWebView)915 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DragDropWithinWebView) {
916   LoadAndLaunchPlatformApp("web_view/dnd_within_webview", "connected");
917   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
918 
919   embedder_web_contents_ = GetFirstAppWindowWebContents();
920   gfx::Rect offset = embedder_web_contents_->GetContainerBounds();
921   corner_ = gfx::Point(offset.x(), offset.y());
922 
923   // In the drag drop test we add 20px padding to the page body because on
924   // windows if we get too close to the edge of the window the resize cursor
925   // appears and we start dragging the window edge.
926   corner_.Offset(20, 20);
927 
928   // Flush any pending events to make sure we start with a clean slate.
929   content::RunAllPendingInMessageLoop();
930   for (;;) {
931     base::RunLoop run_loop;
932     quit_closure_ = run_loop.QuitClosure();
933     base::MessageLoop::current()->PostTask(
934         FROM_HERE,
935         base::Bind(&WebViewInteractiveTest::DragTestStep1,
936                    base::Unretained(this)));
937     run_loop.Run();
938 
939     if (last_drop_data_ == "Drop me")
940       break;
941 
942     LOG(INFO) << "Drag was cancelled in interactive_test, restarting drag";
943 
944     // Reset state for next try.
945     ExtensionTestMessageListener reset_listener("resetStateReply", false);
946     EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
947                                        "window.resetState()"));
948     ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
949   }
950   ASSERT_EQ("Drop me", last_drop_data_);
951 }
952 #endif  // (defined(OS_CHROMEOS))
953 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Navigation)954 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation) {
955   TestHelper("testNavigation", "web_view/navigation", NO_TEST_SERVER);
956 }
957 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Navigation_BackForwardKeys)958 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation_BackForwardKeys) {
959   LoadAndLaunchPlatformApp("web_view/navigation", "Launched");
960   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
961       GetPlatformAppWindow()));
962   // Flush any pending events to make sure we start with a clean slate.
963   content::RunAllPendingInMessageLoop();
964 
965   content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
966   ASSERT_TRUE(embedder_web_contents);
967 
968   ExtensionTestMessageListener done_listener(
969       "TEST_PASSED", false);
970   done_listener.set_failure_message("TEST_FAILED");
971   ExtensionTestMessageListener ready_back_key_listener(
972       "ReadyForBackKey", false);
973   ExtensionTestMessageListener ready_forward_key_listener(
974       "ReadyForForwardKey", false);
975 
976   EXPECT_TRUE(content::ExecuteScript(
977                   embedder_web_contents,
978                   "runTest('testBackForwardKeys')"));
979 
980   ASSERT_TRUE(ready_back_key_listener.WaitUntilSatisfied());
981   SendBackShortcutToPlatformApp();
982 
983   ASSERT_TRUE(ready_forward_key_listener.WaitUntilSatisfied());
984   SendForwardShortcutToPlatformApp();
985 
986   ASSERT_TRUE(done_listener.WaitUntilSatisfied());
987 }
988 
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,PointerLock_PointerLockLostWithFocus)989 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
990                        PointerLock_PointerLockLostWithFocus) {
991   TestHelper("testPointerLockLostWithFocus",
992              "web_view/pointerlock",
993              NO_TEST_SERVER);
994 }
995 
996 // This test exercies the following scenario:
997 // 1. An <input> in guest has focus.
998 // 2. User takes focus to embedder by clicking e.g. an <input> in embedder.
999 // 3. User brings back the focus directly to the <input> in #1.
1000 //
1001 // Now we need to make sure TextInputTypeChanged fires properly for the guest's
1002 // view upon step #3. We simply read the input type's state after #3 to
1003 // make sure it's not TEXT_INPUT_TYPE_NONE.
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,Focus_FocusRestored)1004 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusRestored) {
1005   TestHelper("testFocusRestored", "web_view/focus", NO_TEST_SERVER);
1006   content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
1007   ASSERT_TRUE(embedder_web_contents);
1008   ASSERT_TRUE(guest_web_contents());
1009 
1010   // 1) We click on the guest so that we get a focus event.
1011   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED", false);
1012   next_step_listener.set_failure_message("TEST_STEP_FAILED");
1013   {
1014     content::SimulateMouseClickAt(guest_web_contents(),
1015                                   0,
1016                                   blink::WebMouseEvent::ButtonLeft,
1017                                   gfx::Point(10, 10));
1018     EXPECT_TRUE(content::ExecuteScript(
1019                     embedder_web_contents,
1020                     "window.runCommand('testFocusRestoredRunNextStep', 1);"));
1021   }
1022   // Wait for the next step to complete.
1023   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
1024 
1025   // 2) We click on the embedder so the guest's focus goes away and it observes
1026   // a blur event.
1027   next_step_listener.Reset();
1028   {
1029     content::SimulateMouseClickAt(embedder_web_contents,
1030                                   0,
1031                                   blink::WebMouseEvent::ButtonLeft,
1032                                   gfx::Point(200, 20));
1033     EXPECT_TRUE(content::ExecuteScript(
1034                     embedder_web_contents,
1035                     "window.runCommand('testFocusRestoredRunNextStep', 2);"));
1036   }
1037   // Wait for the next step to complete.
1038   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
1039 
1040   // 3) We click on the guest again to bring back focus directly to the previous
1041   // input element, then we ensure text_input_type is properly set.
1042   next_step_listener.Reset();
1043   {
1044     content::SimulateMouseClickAt(guest_web_contents(),
1045                                   0,
1046                                   blink::WebMouseEvent::ButtonLeft,
1047                                   gfx::Point(10, 10));
1048     EXPECT_TRUE(content::ExecuteScript(
1049                     embedder_web_contents,
1050                     "window.runCommand('testFocusRestoredRunNextStep', 3)"));
1051   }
1052   // Wait for the next step to complete.
1053   ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
1054 
1055   // |text_input_client| is not available for mac and android.
1056 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
1057   ui::TextInputClient* text_input_client =
1058       embedder_web_contents->GetRenderViewHost()->GetView()
1059           ->GetTextInputClient();
1060   ASSERT_TRUE(text_input_client);
1061   ASSERT_TRUE(text_input_client->GetTextInputType() !=
1062               ui::TEXT_INPUT_TYPE_NONE);
1063 #endif
1064 }
1065 
1066 // ui::TextInputClient is NULL for mac and android.
1067 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,DISABLED_Focus_InputMethod)1068 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_Focus_InputMethod) {
1069   content::WebContents* embedder_web_contents = NULL;
1070   scoped_ptr<ExtensionTestMessageListener> done_listener(
1071       RunAppHelper("testInputMethod", "web_view/focus", NO_TEST_SERVER,
1072                    &embedder_web_contents));
1073   ASSERT_TRUE(done_listener->WaitUntilSatisfied());
1074 
1075   ui::TextInputClient* text_input_client =
1076       embedder_web_contents->GetRenderViewHost()->GetView()
1077           ->GetTextInputClient();
1078   ASSERT_TRUE(text_input_client);
1079 
1080   ExtensionTestMessageListener next_step_listener("TEST_STEP_PASSED", false);
1081   next_step_listener.set_failure_message("TEST_STEP_FAILED");
1082 
1083   // An input element inside the <webview> gets focus and is given some
1084   // user input via IME.
1085   {
1086     ui::CompositionText composition;
1087     composition.text = base::UTF8ToUTF16("InputTest123");
1088     text_input_client->SetCompositionText(composition);
1089     EXPECT_TRUE(content::ExecuteScript(
1090                     embedder_web_contents,
1091                     "window.runCommand('testInputMethodRunNextStep', 1);"));
1092 
1093     // Wait for the next step to complete.
1094     ASSERT_TRUE(next_step_listener.WaitUntilSatisfied());
1095   }
1096 
1097   // A composition is committed via IME.
1098   {
1099     next_step_listener.Reset();
1100 
1101     ui::CompositionText composition;
1102     composition.text = base::UTF8ToUTF16("InputTest456");
1103     text_input_client->SetCompositionText(composition);
1104     text_input_client->ConfirmCompositionText();
1105     EXPECT_TRUE(content::ExecuteScript(
1106                   embedder_web_contents,
1107                   "window.runCommand('testInputMethodRunNextStep', 2);"));
1108 
1109     // Wait for the next step to complete.
1110     EXPECT_TRUE(next_step_listener.WaitUntilSatisfied());
1111   }
1112 
1113   // Moving focus causes IME cancel, and the composition will be committed
1114   // in first <input> in the <webview>, not in the second <input>.
1115   {
1116     next_step_listener.Reset();
1117     ui::CompositionText composition;
1118     composition.text = base::UTF8ToUTF16("InputTest789");
1119     text_input_client->SetCompositionText(composition);
1120     EXPECT_TRUE(content::ExecuteScript(
1121                     embedder_web_contents,
1122                     "window.runCommand('testInputMethodRunNextStep', 3);"));
1123 
1124     // Wait for the next step to complete.
1125     EXPECT_TRUE(next_step_listener.WaitUntilSatisfied());
1126   }
1127 
1128   // Tests ExtendSelectionAndDelete message works in <webview>.
1129   {
1130     next_step_listener.Reset();
1131 
1132     // At this point we have set focus on first <input> in the <webview>,
1133     // and the value it contains is 'InputTestABC' with caret set after 'T'.
1134     // Now we delete 'Test' in 'InputTestABC', as the caret is after 'T':
1135     // delete before 1 character ('T') and after 3 characters ('est').
1136     text_input_client->ExtendSelectionAndDelete(1, 3);
1137     EXPECT_TRUE(content::ExecuteScript(
1138                     embedder_web_contents,
1139                     "window.runCommand('testInputMethodRunNextStep', 4);"));
1140 
1141     // Wait for the next step to complete.
1142     EXPECT_TRUE(next_step_listener.WaitUntilSatisfied());
1143   }
1144 }
1145 #endif
1146 
1147 #if defined(OS_MACOSX)
IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,TextSelection)1148 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, TextSelection) {
1149   SetupTest("web_view/text_selection",
1150             "/extensions/platform_apps/web_view/text_selection/guest.html");
1151   ASSERT_TRUE(guest_web_contents());
1152   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
1153       GetPlatformAppWindow()));
1154 
1155   // Wait until guest sees a context menu, select an arbitrary item (copy).
1156   ExtensionTestMessageListener ctx_listener("MSG_CONTEXTMENU", false);
1157   ContextMenuNotificationObserver menu_observer(IDC_CONTENT_CONTEXT_COPY);
1158   SimulateRWHMouseClick(guest_web_contents()->GetRenderViewHost(),
1159                         blink::WebMouseEvent::ButtonRight, 20, 20);
1160   ASSERT_TRUE(ctx_listener.WaitUntilSatisfied());
1161 
1162   // Now verify that the selection text propagates properly to RWHV.
1163   content::RenderWidgetHostView* guest_rwhv =
1164       guest_web_contents()->GetRenderWidgetHostView();
1165   ASSERT_TRUE(guest_rwhv);
1166   std::string selected_text = base::UTF16ToUTF8(guest_rwhv->GetSelectedText());
1167   ASSERT_TRUE(selected_text.size() >= 10u);
1168   ASSERT_EQ("AAAAAAAAAA", selected_text.substr(0, 10));
1169 }
1170 #endif
1171