12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/interactive_test_utils.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ui_test_utils {
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetNativeWindow(const Browser* browser, gfx::NativeWindow* native_window) {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserWindow* window = browser->window();
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *native_window = window->GetNativeWindow();
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return *native_window;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BringBrowserWindowToFront(const Browser* browser) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::NativeWindow window = NULL;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetNativeWindow(browser, &window))
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ui_test_utils::ShowAndFocusNativeWindow(window);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SendKeyPressSync(const Browser* browser,
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      ui::KeyboardCode key,
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      bool control,
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      bool shift,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      bool alt,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      bool command) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::NativeWindow window = NULL;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetNativeWindow(browser, &window))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SendKeyPressToWindowSync(window, key, control, shift, alt, command);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SendKeyPressToWindowSync(const gfx::NativeWindow window,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              ui::KeyboardCode key,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool control,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool shift,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool alt,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool command) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner =
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new content::MessageLoopRunner;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result = ui_controls::SendKeyPressNotifyWhenDone(
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window, key, control, shift, alt, command, runner->QuitClosure());
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!result && ui_test_utils::ShowAndFocusNativeWindow(window)) {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result = ui_controls::SendKeyPressNotifyWhenDone(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        window, key, control, shift, alt, command, runner->QuitClosure());
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!result) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "ui_controls::SendKeyPressNotifyWhenDone failed";
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Run the message loop. It'll stop running when either the key was received
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or the test timed out (in which case testing::Test::HasFatalFailure should
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be set).
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  runner->Run();
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !testing::Test::HasFatalFailure();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SendKeyPressAndWait(const Browser* browser,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ui::KeyboardCode key,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool control,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool shift,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool alt,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool command,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         int type,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const content::NotificationSource& source) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WindowedNotificationObserver observer(type, source);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!SendKeyPressSync(browser, key, control, shift, alt, command))
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer.Wait();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !testing::Test::HasFatalFailure();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SendMouseMoveSync(const gfx::Point& location) {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner =
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new content::MessageLoopRunner;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ui_controls::SendMouseMoveNotifyWhenDone(
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          location.x(), location.y(), runner->QuitClosure())) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  runner->Run();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !testing::Test::HasFatalFailure();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SendMouseEventsSync(ui_controls::MouseButton type, int state) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner =
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new content::MessageLoopRunner;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ui_controls::SendMouseEventsNotifyWhenDone(
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          type, state, runner->QuitClosure())) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  runner->Run();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !testing::Test::HasFatalFailure();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ClickTask(ui_controls::MouseButton button,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               int state,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               const base::Closure& followup) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!followup.is_null())
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_controls::SendMouseEventsNotifyWhenDone(button, state, followup);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui_controls::SendMouseEvents(button, state);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace internal
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ui_test_utils
127