- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / apps / web_view_interactive_browsertest.cc
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 "apps/shell_window.h"
6 #include "apps/shell_window_registry.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/apps/app_browsertest_util.h"
10 #include "chrome/browser/extensions/extension_test_message_listener.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/test/base/interactive_test_utils.h"
13 #include "chrome/test/base/test_launcher_utils.h"
14 #include "chrome/test/base/ui_test_utils.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_view.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "ui/base/test/ui_controls.h"
25 #include "ui/events/keycodes/keyboard_codes.h"
26
27 using apps::ShellWindow;
28
29 class WebViewInteractiveTest
30     : public extensions::PlatformAppBrowserTest {
31  public:
32   WebViewInteractiveTest()
33       : corner_(gfx::Point()),
34         mouse_click_result_(false),
35         first_click_(true) {}
36
37   virtual void SetUp() OVERRIDE {
38     // We need real contexts, otherwise the embedder doesn't composite, but the
39     // guest does, and that isn't an expected configuration.
40     UseRealGLContexts();
41     extensions::PlatformAppBrowserTest::SetUp();
42   }
43
44   void MoveMouseInsideWindowWithListener(gfx::Point point,
45                                          const std::string& message) {
46     ExtensionTestMessageListener move_listener(message, false);
47     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
48         gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
49     ASSERT_TRUE(move_listener.WaitUntilSatisfied());
50   }
51
52   void SendMouseClickWithListener(ui_controls::MouseButton button,
53                                   const std::string& message) {
54     ExtensionTestMessageListener listener(message, false);
55     SendMouseClick(button);
56     ASSERT_TRUE(listener.WaitUntilSatisfied());
57   }
58
59   void SendMouseClick(ui_controls::MouseButton button) {
60     SendMouseEvent(button, ui_controls::DOWN);
61     SendMouseEvent(button, ui_controls::UP);
62   }
63
64   void MoveMouseInsideWindow(const gfx::Point& point) {
65     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
66         gfx::Point(corner_.x() + point.x(), corner_.y() + point.y())));
67   }
68
69   gfx::NativeWindow GetPlatformAppWindow() {
70     const apps::ShellWindowRegistry::ShellWindowList& shell_windows =
71         apps::ShellWindowRegistry::Get(
72             browser()->profile())->shell_windows();
73     return (*shell_windows.begin())->GetNativeWindow();
74   }
75
76   void SendKeyPressToPlatformApp(ui::KeyboardCode key) {
77     ASSERT_EQ(1U, GetShellWindowCount());
78     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
79         GetPlatformAppWindow(), key, false, false, false, false));
80   }
81
82   void SendCopyKeyPressToPlatformApp() {
83     ASSERT_EQ(1U, GetShellWindowCount());
84 #if defined(OS_MACOSX)
85     // Send Cmd+C on MacOSX.
86     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
87         GetPlatformAppWindow(), ui::VKEY_C, false, false, false, true));
88 #else
89     // Send Ctrl+C on Windows and Linux/ChromeOS.
90     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
91         GetPlatformAppWindow(), ui::VKEY_C, true, false, false, false));
92 #endif
93   }
94
95   void SendStartOfLineKeyPressToPlatformApp() {
96 #if defined(OS_MACOSX)
97     // Send Cmd+Left on MacOSX.
98     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
99         GetPlatformAppWindow(), ui::VKEY_LEFT, false, false, false, true));
100 #else
101     // Send Ctrl+Left on Windows and Linux/ChromeOS.
102     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
103         GetPlatformAppWindow(), ui::VKEY_LEFT, true, false, false, false));
104 #endif
105   }
106
107   void SendBackShortcutToPlatformApp() {
108 #if defined(OS_MACOSX)
109     // Send Cmd+[ on MacOSX.
110     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
111         GetPlatformAppWindow(), ui::VKEY_OEM_4, false, false, false, true));
112 #else
113     // Send browser back key on Linux/Windows.
114     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
115         GetPlatformAppWindow(), ui::VKEY_BROWSER_BACK,
116         false, false, false, false));
117 #endif
118   }
119
120   void SendForwardShortcutToPlatformApp() {
121 #if defined(OS_MACOSX)
122     // Send Cmd+] on MacOSX.
123     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
124         GetPlatformAppWindow(), ui::VKEY_OEM_6, false, false, false, true));
125 #else
126     // Send browser back key on Linux/Windows.
127     ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
128         GetPlatformAppWindow(), ui::VKEY_BROWSER_FORWARD,
129         false, false, false, false));
130 #endif
131   }
132
133   void SendMouseEvent(ui_controls::MouseButton button,
134                       ui_controls::MouseButtonState state) {
135     if (first_click_) {
136       mouse_click_result_ = ui_test_utils::SendMouseEventsSync(button,
137                                                                 state);
138       first_click_ = false;
139     } else {
140       ASSERT_EQ(mouse_click_result_, ui_test_utils::SendMouseEventsSync(
141           button, state));
142     }
143   }
144
145   enum TestServer {
146     NEEDS_TEST_SERVER,
147     NO_TEST_SERVER
148   };
149
150   scoped_ptr<ExtensionTestMessageListener> RunAppHelper(
151       const std::string& test_name,
152       const std::string& app_location,
153       TestServer test_server,
154       content::WebContents** embedder_web_contents) {
155     // For serving guest pages.
156     if ((test_server == NEEDS_TEST_SERVER) && !StartEmbeddedTestServer()) {
157       LOG(ERROR) << "FAILED TO START TEST SERVER.";
158       return scoped_ptr<ExtensionTestMessageListener>();
159     }
160
161     ExtensionTestMessageListener launched_listener("Launched", false);
162     LoadAndLaunchPlatformApp(app_location.c_str());
163     if (!launched_listener.WaitUntilSatisfied()) {
164       LOG(ERROR) << "TEST DID NOT LAUNCH.";
165       return scoped_ptr<ExtensionTestMessageListener>();
166     }
167
168     if (!ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow())) {
169       LOG(ERROR) << "UNABLE TO FOCUS TEST WINDOW.";
170       return scoped_ptr<ExtensionTestMessageListener>();
171     }
172
173     // Flush any pending events to make sure we start with a clean slate.
174     content::RunAllPendingInMessageLoop();
175
176     *embedder_web_contents = GetFirstShellWindowWebContents();
177
178     scoped_ptr<ExtensionTestMessageListener> done_listener(
179         new ExtensionTestMessageListener("TEST_PASSED", false));
180     done_listener->AlsoListenForFailureMessage("TEST_FAILED");
181     if (!content::ExecuteScript(
182             *embedder_web_contents,
183             base::StringPrintf("runTest('%s')", test_name.c_str()))) {
184       LOG(ERROR) << "UNABLE TO START TEST";
185       return scoped_ptr<ExtensionTestMessageListener>();
186     }
187
188     return done_listener.Pass();
189   }
190
191   void TestHelper(const std::string& test_name,
192                   const std::string& app_location,
193                   TestServer test_server) {
194     content::WebContents* embedder_web_contents = NULL;
195     scoped_ptr<ExtensionTestMessageListener> done_listener(
196         RunAppHelper(
197             test_name, app_location, test_server, &embedder_web_contents));
198
199     ASSERT_TRUE(done_listener);
200     ASSERT_TRUE(done_listener->WaitUntilSatisfied());
201   }
202
203   void RunTest(const std::string& app_name) {
204   }
205   void SetupTest(const std::string& app_name,
206                  const std::string& guest_url_spec) {
207     ASSERT_TRUE(StartEmbeddedTestServer());
208     GURL::Replacements replace_host;
209     std::string host_str("localhost");  // Must stay in scope with replace_host.
210     replace_host.SetHostStr(host_str);
211
212     GURL guest_url = embedded_test_server()->GetURL(guest_url_spec);
213     guest_url = guest_url.ReplaceComponents(replace_host);
214
215     ui_test_utils::UrlLoadObserver guest_observer(
216         guest_url, content::NotificationService::AllSources());
217
218     ExtensionTestMessageListener guest_connected_listener("connected", false);
219     LoadAndLaunchPlatformApp(app_name.c_str());
220
221     guest_observer.Wait();
222
223     // Wait until the guest process reports that it has established a message
224     // channel with the app.
225     ASSERT_TRUE(guest_connected_listener.WaitUntilSatisfied());
226     content::Source<content::NavigationController> source =
227         guest_observer.source();
228     EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest());
229
230     guest_web_contents_ = source->GetWebContents();
231     embedder_web_contents_ = guest_web_contents_->GetEmbedderWebContents();
232
233     gfx::Rect offset;
234     embedder_web_contents_->GetView()->GetContainerBounds(&offset);
235     corner_ = gfx::Point(offset.x(), offset.y());
236
237     const testing::TestInfo* const test_info =
238             testing::UnitTest::GetInstance()->current_test_info();
239     const char* prefix = "DragDropWithinWebView";
240     if (!strncmp(test_info->name(), prefix, strlen(prefix))) {
241       // In the drag drop test we add 20px padding to the page body because on
242       // windows if we get too close to the edge of the window the resize cursor
243       // appears and we start dragging the window edge.
244       corner_.Offset(20, 20);
245     }
246   }
247
248   content::WebContents* guest_web_contents() {
249     return guest_web_contents_;
250   }
251
252   content::WebContents* embedder_web_contents() {
253     return embedder_web_contents_;
254   }
255
256   gfx::Point corner() {
257     return corner_;
258   }
259
260   void SimulateRWHMouseClick(content::RenderWidgetHost* rwh, int x, int y) {
261     WebKit::WebMouseEvent mouse_event;
262     mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
263     mouse_event.x = mouse_event.windowX = x;
264     mouse_event.y = mouse_event.windowY = y;
265     mouse_event.modifiers = 0;
266
267     mouse_event.type = WebKit::WebInputEvent::MouseDown;
268     rwh->ForwardMouseEvent(mouse_event);
269     mouse_event.type = WebKit::WebInputEvent::MouseUp;
270     rwh->ForwardMouseEvent(mouse_event);
271   }
272
273   class PopupCreatedObserver {
274    public:
275     PopupCreatedObserver() : created_(false), last_render_widget_host_(NULL) {
276       created_callback_ = base::Bind(
277           &PopupCreatedObserver::CreatedCallback, base::Unretained(this));
278       content::RenderWidgetHost::AddCreatedCallback(created_callback_);
279     }
280     virtual ~PopupCreatedObserver() {
281       content::RenderWidgetHost::RemoveCreatedCallback(created_callback_);
282     }
283     void Reset() {
284       created_ = false;
285     }
286     void Start() {
287       if (created_)
288         return;
289       message_loop_ = new content::MessageLoopRunner;
290       message_loop_->Run();
291     }
292     content::RenderWidgetHost* last_render_widget_host() {
293       return last_render_widget_host_;
294     }
295
296    private:
297     void CreatedCallback(content::RenderWidgetHost* rwh) {
298       last_render_widget_host_ = rwh;
299       if (message_loop_.get())
300         message_loop_->Quit();
301       else
302         created_ = true;
303     }
304     content::RenderWidgetHost::CreatedCallback created_callback_;
305     scoped_refptr<content::MessageLoopRunner> message_loop_;
306     bool created_;
307     content::RenderWidgetHost* last_render_widget_host_;
308   };
309
310   void WaitForTitle(const char* title) {
311     string16 expected_title(ASCIIToUTF16(title));
312     string16 error_title(ASCIIToUTF16("FAILED"));
313     content::TitleWatcher title_watcher(guest_web_contents(), expected_title);
314     title_watcher.AlsoWaitForTitle(error_title);
315     ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
316   }
317
318   void PopupTestHelper(const gfx::Point& padding) {
319     PopupCreatedObserver popup_created_observer;
320     popup_created_observer.Reset();
321
322     content::SimulateKeyPress(
323         guest_web_contents(),
324         ui::VKEY_C,  // C to autocomplete.
325         false, false, false, false);
326
327     WaitForTitle("PASSED1");
328
329     popup_created_observer.Start();
330
331     content::RenderWidgetHost* popup_rwh = NULL;
332     popup_rwh = popup_created_observer.last_render_widget_host();
333     // Popup must be present.
334     ASSERT_TRUE(popup_rwh);
335     ASSERT_TRUE(!popup_rwh->IsRenderView());
336     ASSERT_TRUE(popup_rwh->GetView());
337
338     string16 expected_title = ASCIIToUTF16("PASSED2");
339     string16 error_title = ASCIIToUTF16("FAILED");
340     content::TitleWatcher title_watcher(guest_web_contents(), expected_title);
341     title_watcher.AlsoWaitForTitle(error_title);
342     EXPECT_TRUE(content::ExecuteScript(guest_web_contents(),
343                                        "changeTitle();"));
344     ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
345
346     gfx::Rect popup_bounds = popup_rwh->GetView()->GetViewBounds();
347     // (2, 2) is expected to lie on the first datalist element.
348     SimulateRWHMouseClick(popup_rwh, 2, 2);
349
350     content::RenderViewHost* embedder_rvh =
351         GetFirstShellWindowWebContents()->GetRenderViewHost();
352     gfx::Rect embedder_bounds = embedder_rvh->GetView()->GetViewBounds();
353     gfx::Vector2d diff = popup_bounds.origin() - embedder_bounds.origin();
354     LOG(INFO) << "DIFF: x = " << diff.x() << ", y = " << diff.y();
355
356     const int left_spacing = 40 + padding.x();  // div.style.paddingLeft = 40px.
357     // div.style.paddingTop = 50px + (input box height = 26px).
358     const int top_spacing = 50 + 26 + padding.y();
359
360     // If the popup is placed within |threshold_px| of the expected position,
361     // then we consider the test as a pass.
362     const int threshold_px = 10;
363
364     EXPECT_LE(std::abs(diff.x() - left_spacing), threshold_px);
365     EXPECT_LE(std::abs(diff.y() - top_spacing), threshold_px);
366
367     WaitForTitle("PASSED3");
368   }
369
370   void DragTestStep1() {
371     // Move mouse to start of text.
372     MoveMouseInsideWindow(gfx::Point(45, 8));
373     MoveMouseInsideWindow(gfx::Point(45, 9));
374     SendMouseEvent(ui_controls::LEFT, ui_controls::DOWN);
375
376     MoveMouseInsideWindow(gfx::Point(74, 12));
377     MoveMouseInsideWindow(gfx::Point(78, 12));
378
379     // Now wait a bit before moving mouse to initiate drag/drop.
380     base::MessageLoop::current()->PostDelayedTask(
381         FROM_HERE,
382         base::Bind(&WebViewInteractiveTest::DragTestStep2,
383                    base::Unretained(this)),
384         base::TimeDelta::FromMilliseconds(200));
385   }
386
387   void DragTestStep2() {
388     // Drag source over target.
389     MoveMouseInsideWindow(gfx::Point(76, 76));
390
391     // Create a second mouse over the source to trigger the drag over event.
392     MoveMouseInsideWindow(gfx::Point(76, 77));
393
394     // Release mouse to drop.
395     SendMouseEvent(ui_controls::LEFT, ui_controls::UP);
396     SendMouseClick(ui_controls::LEFT);
397
398     quit_closure_.Run();
399
400     // Note that following ExtensionTestMessageListener and ExecuteScript*
401     // call must be after we quit |quit_closure_|. Otherwise the class
402     // here won't be able to receive messages sent by chrome.test.sendMessage.
403     // This is because of the nature of drag and drop code (esp. the
404     // MessageLoop) in it.
405
406     // Now check if we got a drop and read the drop data.
407     embedder_web_contents_ = GetFirstShellWindowWebContents();
408     ExtensionTestMessageListener drop_listener("guest-got-drop", false);
409     EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
410                                        "window.checkIfGuestGotDrop()"));
411     EXPECT_TRUE(drop_listener.WaitUntilSatisfied());
412
413     std::string last_drop_data;
414     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
415                     embedder_web_contents_,
416                     "window.domAutomationController.send(getLastDropData())",
417                     &last_drop_data));
418
419     last_drop_data_ = last_drop_data;
420   }
421
422  protected:
423   content::WebContents* guest_web_contents_;
424   content::WebContents* embedder_web_contents_;
425   gfx::Point corner_;
426   bool mouse_click_result_;
427   bool first_click_;
428   // Only used in drag/drop test.
429   base::Closure quit_closure_;
430   std::string last_drop_data_;
431 };
432
433 // ui_test_utils::SendMouseMoveSync doesn't seem to work on OS_MACOSX, and
434 // likely won't work on many other platforms as well, so for now this test
435 // is for Windows and Linux only. As of Sept 17th, 2013 this test is disabled
436 // on Windows due to flakines, see http://crbug.com/293445.
437
438 #if defined(OS_LINUX)
439
440 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PointerLock) {
441   SetupTest("web_view/pointer_lock",
442             "/extensions/platform_apps/web_view/pointer_lock/guest.html");
443
444   // Move the mouse over the Lock Pointer button.
445   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
446       gfx::Point(corner().x() + 75, corner().y() + 25)));
447
448   // Click the Lock Pointer button. The first two times the button is clicked
449   // the permission API will deny the request (intentional).
450   ExtensionTestMessageListener exception_listener("request exception", false);
451   SendMouseClickWithListener(ui_controls::LEFT, "lock error");
452   ASSERT_TRUE(exception_listener.WaitUntilSatisfied());
453   SendMouseClickWithListener(ui_controls::LEFT, "lock error");
454
455   // Click the Lock Pointer button, locking the mouse to lockTarget1.
456   SendMouseClickWithListener(ui_controls::LEFT, "locked");
457
458   // Attempt to move the mouse off of the lock target, and onto lockTarget2,
459   // (which would trigger a test failure).
460   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
461       gfx::Point(corner().x() + 74, corner().y() + 74)));
462   MoveMouseInsideWindowWithListener(gfx::Point(75, 75), "mouse-move");
463
464 #if (defined(OS_WIN) && defined(USE_AURA))
465   // When the mouse is unlocked on win aura, sending a test mouse click clicks
466   // where the mouse moved to while locked. I was unable to figure out why, and
467   // since the issue only occurs with the test mouse events, just fix it with
468   // a simple workaround - moving the mouse back to where it should be.
469   // TODO(mthiesse): Fix Win Aura simulated mouse events while mouse locked.
470   MoveMouseInsideWindowWithListener(gfx::Point(75, 25), "mouse-move");
471 #endif
472
473   ExtensionTestMessageListener unlocked_listener("unlocked", false);
474   // Send a key press to unlock the mouse.
475   SendKeyPressToPlatformApp(ui::VKEY_ESCAPE);
476
477   // Wait for page to receive (successful) mouse unlock response.
478   ASSERT_TRUE(unlocked_listener.WaitUntilSatisfied());
479
480   // After the second lock, guest.js sends a message to main.js to remove the
481   // webview object. main.js then removes the div containing the webview, which
482   // should unlock, and leave the mouse over the mousemove-capture-container
483   // div. We then move the mouse over that div to ensure the mouse was properly
484   // unlocked and that the div receieves the message.
485   ExtensionTestMessageListener move_captured_listener("move-captured", false);
486   move_captured_listener.AlsoListenForFailureMessage("timeout");
487
488   // Mouse should already be over lock button (since we just unlocked), so send
489   // click to re-lock the mouse.
490   SendMouseClickWithListener(ui_controls::LEFT, "deleted");
491
492   // A mousemove event is triggered on the mousemove-capture-container element
493   // when we delete the webview container (since the mouse moves onto the
494   // element), but just in case, send an explicit mouse movement to be safe.
495   ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
496       gfx::Point(corner().x() + 50, corner().y() + 10)));
497
498   // Wait for page to receive second (successful) mouselock response.
499   bool success = move_captured_listener.WaitUntilSatisfied();
500   if (!success) {
501     fprintf(stderr, "TIMEOUT - retrying\n");
502     // About 1 in 40 tests fail to detect mouse moves at this point (why?).
503     // Sending a right click seems to fix this (why?).
504     ExtensionTestMessageListener move_listener2("move-captured", false);
505     SendMouseClick(ui_controls::RIGHT);
506     ASSERT_TRUE(ui_test_utils::SendMouseMoveSync(
507         gfx::Point(corner().x() + 51, corner().y() + 11)));
508     ASSERT_TRUE(move_listener2.WaitUntilSatisfied());
509   }
510 }
511
512 #endif  // (defined(OS_WIN) || defined(OS_LINUX))
513
514 // Tests that setting focus on the <webview> sets focus on the guest.
515 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_FocusEvent) {
516   TestHelper("testFocusEvent", "web_view/focus", NO_TEST_SERVER);
517 }
518
519 // Tests that setting focus on the <webview> sets focus on the guest.
520 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Focus_BlurEvent) {
521   TestHelper("testBlurEvent", "web_view/focus", NO_TEST_SERVER);
522 }
523
524 // Tests that guests receive edit commands and respond appropriately.
525 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommands) {
526   ExtensionTestMessageListener guest_connected_listener("connected", false);
527   LoadAndLaunchPlatformApp("web_view/edit_commands");
528   // Wait until the guest process reports that it has established a message
529   // channel with the app.
530   ASSERT_TRUE(guest_connected_listener.WaitUntilSatisfied());
531
532   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
533       GetPlatformAppWindow()));
534
535   // Flush any pending events to make sure we start with a clean slate.
536   content::RunAllPendingInMessageLoop();
537
538   ExtensionTestMessageListener copy_listener("copy", false);
539   SendCopyKeyPressToPlatformApp();
540
541   // Wait for the guest to receive a 'copy' edit command.
542   ASSERT_TRUE(copy_listener.WaitUntilSatisfied());
543 }
544
545 // Tests that guests receive edit commands and respond appropriately.
546 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, EditCommandsNoMenu) {
547   SetupTest("web_view/edit_commands_no_menu",
548       "/extensions/platform_apps/web_view/edit_commands_no_menu/"
549       "guest.html");
550
551   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
552       GetPlatformAppWindow()));
553
554   // Flush any pending events to make sure we start with a clean slate.
555   content::RunAllPendingInMessageLoop();
556
557   ExtensionTestMessageListener start_of_line_listener("StartOfLine", false);
558   SendStartOfLineKeyPressToPlatformApp();
559   // Wait for the guest to receive a 'copy' edit command.
560   ASSERT_TRUE(start_of_line_listener.WaitUntilSatisfied());
561 }
562
563 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
564                        NewWindow_NewWindowNameTakesPrecedence) {
565   TestHelper("testNewWindowNameTakesPrecedence",
566              "web_view/newwindow",
567              NEEDS_TEST_SERVER);
568 }
569
570 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
571                        NewWindow_WebViewNameTakesPrecedence) {
572   TestHelper("testWebViewNameTakesPrecedence",
573              "web_view/newwindow",
574              NEEDS_TEST_SERVER);
575 }
576
577 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_NoName) {
578   TestHelper("testNoName",
579              "web_view/newwindow",
580              NEEDS_TEST_SERVER);
581 }
582
583 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Redirect) {
584   TestHelper("testNewWindowRedirect",
585              "web_view/newwindow",
586              NEEDS_TEST_SERVER);
587 }
588
589 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_Close) {
590   TestHelper("testNewWindowClose",
591              "web_view/newwindow",
592              NEEDS_TEST_SERVER);
593 }
594
595 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_ExecuteScript) {
596   TestHelper("testNewWindowExecuteScript",
597              "web_view/newwindow",
598              NEEDS_TEST_SERVER);
599 }
600
601 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_WebRequest) {
602   TestHelper("testNewWindowWebRequest",
603              "web_view/newwindow",
604              NEEDS_TEST_SERVER);
605 }
606
607 // A custom elements bug needs to be addressed to enable this test:
608 // See http://crbug.com/282477 for more information.
609 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
610                        DISABLED_NewWindow_WebRequestCloseWindow) {
611   TestHelper("testNewWindowWebRequestCloseWindow",
612              "web_view/newwindow",
613              NEEDS_TEST_SERVER);
614 }
615
616 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
617                        NewWindow_WebRequestRemoveElement) {
618   TestHelper("testNewWindowWebRequestRemoveElement",
619              "web_view/newwindow",
620              NEEDS_TEST_SERVER);
621 }
622
623 // Tests that Ctrl+Click/Cmd+Click on a link fires up the newwindow API.
624 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, NewWindow_OpenInNewTab) {
625   content::WebContents* embedder_web_contents = NULL;
626
627   ExtensionTestMessageListener loaded_listener("Loaded", false);
628   scoped_ptr<ExtensionTestMessageListener> done_listener(
629     RunAppHelper("testNewWindowOpenInNewTab",
630                  "web_view/newwindow",
631                  NEEDS_TEST_SERVER,
632                  &embedder_web_contents));
633
634   loaded_listener.WaitUntilSatisfied();
635 #if defined(OS_MACOSX)
636   ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
637       GetPlatformAppWindow(), ui::VKEY_RETURN,
638       false, false, false, true /* cmd */));
639 #else
640   ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
641       GetPlatformAppWindow(), ui::VKEY_RETURN,
642       true /* ctrl */, false, false, false));
643 #endif
644
645   // Wait for the embedder to receive a 'newwindow' event.
646   ASSERT_TRUE(done_listener->WaitUntilSatisfied());
647 }
648
649
650 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, ExecuteCode) {
651   ASSERT_TRUE(RunPlatformAppTestWithArg(
652       "platform_apps/web_view/common", "execute_code")) << message_;
653 }
654
655 // This test used the old Autofill UI, which has been removed.
656 // See crbug.com/259438
657 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PopupPositioning) {
658   SetupTest(
659       "web_view/popup_positioning",
660       "/extensions/platform_apps/web_view/popup_positioning/guest.html");
661   ASSERT_TRUE(guest_web_contents());
662
663   PopupTestHelper(gfx::Point());
664
665   // moveTo a random location and run the steps again.
666   EXPECT_TRUE(content::ExecuteScript(embedder_web_contents(),
667                                      "window.moveTo(16, 20);"));
668   PopupTestHelper(gfx::Point());
669 }
670
671 // Tests that moving browser plugin (without resize/UpdateRects) correctly
672 // repositions popup.
673 // Started flakily failing after a Blink roll: http://crbug.com/245332
674 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_PopupPositioningMoved) {
675   SetupTest(
676       "web_view/popup_positioning_moved",
677       "/extensions/platform_apps/web_view/popup_positioning_moved"
678       "/guest.html");
679   ASSERT_TRUE(guest_web_contents());
680
681   PopupTestHelper(gfx::Point(20, 0));
682 }
683
684 // Drag and drop inside a webview is currently only enabled for linux and mac,
685 // but the tests don't work on anything except chromeos for now. This is because
686 // of simulating mouse drag code's dependency on platforms.
687 #if defined(OS_CHROMEOS)
688 // This test is flaky. See crbug.com/309032
689 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, DISABLED_DragDropWithinWebView) {
690   ExtensionTestMessageListener guest_connected_listener("connected", false);
691   LoadAndLaunchPlatformApp("web_view/dnd_within_webview");
692   ASSERT_TRUE(guest_connected_listener.WaitUntilSatisfied());
693
694   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
695
696   gfx::Rect offset;
697   embedder_web_contents_ = GetFirstShellWindowWebContents();
698   embedder_web_contents_->GetView()->GetContainerBounds(&offset);
699   corner_ = gfx::Point(offset.x(), offset.y());
700
701   // In the drag drop test we add 20px padding to the page body because on
702   // windows if we get too close to the edge of the window the resize cursor
703   // appears and we start dragging the window edge.
704   corner_.Offset(20, 20);
705
706   // Flush any pending events to make sure we start with a clean slate.
707   content::RunAllPendingInMessageLoop();
708   for (;;) {
709     base::RunLoop run_loop;
710     quit_closure_ = run_loop.QuitClosure();
711     base::MessageLoop::current()->PostTask(
712         FROM_HERE,
713         base::Bind(&WebViewInteractiveTest::DragTestStep1,
714                    base::Unretained(this)));
715     run_loop.Run();
716
717     if (last_drop_data_ == "Drop me")
718       break;
719
720     LOG(INFO) << "Drag was cancelled in interactive_test, restarting drag";
721
722     // Reset state for next try.
723     ExtensionTestMessageListener reset_listener("resetStateReply", false);
724     EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
725                                        "window.resetState()"));
726     ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
727   }
728   ASSERT_EQ("Drop me", last_drop_data_);
729 }
730 #endif  // (defined(OS_CHROMEOS))
731
732 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation) {
733   TestHelper("testNavigation", "web_view/navigation", NO_TEST_SERVER);
734 }
735
736 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, Navigation_BackForwardKeys) {
737   ExtensionTestMessageListener launched_listener("Launched", false);
738   LoadAndLaunchPlatformApp("web_view/navigation");
739   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
740
741   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
742       GetPlatformAppWindow()));
743   // Flush any pending events to make sure we start with a clean slate.
744   content::RunAllPendingInMessageLoop();
745
746   content::WebContents* embedder_web_contents =
747       GetFirstShellWindowWebContents();
748   ASSERT_TRUE(embedder_web_contents);
749
750   ExtensionTestMessageListener done_listener(
751       "TEST_PASSED", false);
752   done_listener.AlsoListenForFailureMessage("TEST_FAILED");
753   ExtensionTestMessageListener ready_back_key_listener(
754       "ReadyForBackKey", false);
755   ExtensionTestMessageListener ready_forward_key_listener(
756       "ReadyForForwardKey", false);
757
758   EXPECT_TRUE(content::ExecuteScript(
759                   embedder_web_contents,
760                   "runTest('testBackForwardKeys')"));
761
762   ASSERT_TRUE(ready_back_key_listener.WaitUntilSatisfied());
763   SendBackShortcutToPlatformApp();
764
765   ASSERT_TRUE(ready_forward_key_listener.WaitUntilSatisfied());
766   SendForwardShortcutToPlatformApp();
767
768   ASSERT_TRUE(done_listener.WaitUntilSatisfied());
769 }
770
771 IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
772                        PointerLock_PointerLockLostWithFocus) {
773   TestHelper("testPointerLockLostWithFocus",
774              "web_view/pointerlock",
775              NO_TEST_SERVER);
776 }