browser_focus_uitest.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "build/build_config.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/format_macros.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/ref_counted.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/automation/ui_controls.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_window.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_widget_host_view.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/interstitial_page.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents_view.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/view_ids.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/in_process_browser_test.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/ui_test_utils.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/focus_manager.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/view.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS)
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/frame/browser_view.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/location_bar/location_bar_view.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/tab_contents/tab_contents_container.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_USES_GTK)
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/gtk/view_id_util.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX)
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For some reason we hit an external DNS lookup in this test in Linux but not
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// on Windows. TODO(estade): investigate.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(jcampan): http://crbug.com/23683
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MAYBE_TabsRememberFocusFindInPage FAILS_TabsRememberFocusFindInPage
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MAYBE_FocusTraversalOnInterstitial FocusTraversalOnInterstitial
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define MAYBE_TabsRememberFocusFindInPage TabsRememberFocusFindInPage
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The delay waited in some cases where we don't have a notifications for an
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// action we take.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kActionDelayMs = 500;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kSimplePage[] = "files/focus/page_with_focus.html";
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kStealFocusPage[] = "files/focus/page_steals_focus.html";
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTypicalPage[] = "files/focus/typical_page.html";
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kTypicalPageName[] = "typical_page.html";
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BrowserFocusTest : public InProcessBrowserTest {
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserFocusTest() {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    set_show_window(true);
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EnableDOMAutomation();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool IsViewFocused(ViewID vid) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ui_test_utils::IsViewFocused(browser(), vid);
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ClickOnView(ViewID vid) {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::ClickOnView(browser(), vid);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void HideNativeWindow(gfx::NativeWindow window) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // using Windows API.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::ShowWindow(window, SW_HIDE);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK)
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_hide(GTK_WIDGET(window));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTIMPLEMENTED();
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void ShowNativeWindow(gfx::NativeWindow window) {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // using Windows API.
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::ShowWindow(window, SW_SHOW);
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK)
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_hide(GTK_WIDGET(window));
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTIMPLEMENTED();
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestInterstitialPage : public InterstitialPage {
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : InterstitialPage(tab, new_navigation, url),
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        waiting_for_dom_response_(false),
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        waiting_for_focus_change_(false) {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath file_path;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(r);
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_path = file_path.AppendASCII("focus");
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_path = file_path.AppendASCII(kTypicalPageName);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    r = file_util::ReadFileToString(file_path, &html_contents_);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(r);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::string GetHTMLContents() {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return html_contents_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void DomOperationResponse(const std::string& json_string,
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int automation_id) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (waiting_for_dom_response_) {
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      dom_response_ = json_string;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      waiting_for_dom_response_ = false;
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InterstitialPage::DomOperationResponse(json_string, automation_id);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string GetFocusedElement() {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::wstring script = L"window.domAutomationController.setAutomationId(0);"
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        L"window.domAutomationController.send(getFocusedElement());";
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_view_host()->ExecuteJavascriptInWebFrame(L"", script);
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!waiting_for_dom_response_);
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    waiting_for_dom_response_ = true;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::RunMessageLoop();
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Remove the JSON extra quotes.
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dom_response_.size() >= 2 && dom_response_[0] == '"' &&
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        dom_response_[dom_response_.size() - 1] == '"') {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      dom_response_ = dom_response_.substr(1, dom_response_.size() - 2);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return dom_response_;
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool HasFocus() {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return render_view_host()->view()->HasFocus();
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void WaitForFocusChange() {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    waiting_for_focus_change_ = true;
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::RunMessageLoop();
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void FocusedNodeChanged() {
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!waiting_for_focus_change_)
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    waiting_for_focus_change_= false;
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string html_contents_;
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool waiting_for_dom_response_;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool waiting_for_focus_change_;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string dom_response_;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_X11)
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // It seems we have to wait a little bit for the widgets to spin up before
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we can start clicking on them.
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostDelayedTask(FROM_HERE,
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          new MessageLoop::QuitTask(),
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          kActionDelayMs);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClickOnView(VIEW_ID_TAB_CONTAINER);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClickOnView(VIEW_ID_LOCATION_BAR);
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) {
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kSimplePage);
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeWindow window = browser()->window()->GetNativeHandle();
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The focus should be on the Tab contents.
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now hide the window, show it again, the focus should not have changed.
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HideNativeWindow(window);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowNativeWindow(window);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Hide the window, show it again, the focus should not have changed.
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HideNativeWindow(window);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowNativeWindow(window);
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The rest of this test does not make sense on Linux because the behavior
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of Activate() is not well defined and can vary by window manager.
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a new browser window.
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser2 = Browser::Create(browser()->profile());
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(browser2);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser2->tabstrip_model()->delegate()->AddBlankTab(true);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser2->window()->Show();
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser2, url);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserView* browser_view2 =
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BrowserView::GetBrowserViewForNativeWindow(hwnd2);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(browser_view2);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager* focus_manager2 =
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      views::FocusManager::GetFocusManagerForNativeView(hwnd2);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(focus_manager2);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            focus_manager2->GetFocusedView());
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Switch to the 1st browser window, focus should still be on the location
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bar and the second browser should have nothing focused.
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->window()->Activate();
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Switch back to the second browser, focus should still be on the page.
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser2->window()->Activate();
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(NULL,
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            views::FocusManager::GetFocusManagerForNativeView(
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                browser()->window()->GetNativeHandle())->GetFocusedView());
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            focus_manager2->GetFocusedView());
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close the 2nd browser to avoid a DCHECK().
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_view2->Close();
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tabs remember focus.
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kSimplePage);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create several tabs.
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < 4; ++i) {
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, -1,
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             TabStripModel::ADD_SELECTED, NULL, std::string());
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Alternate focus for the tab.
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool kFocusPage[3][5] = {
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { true, true, true, true, false },
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { false, false, false, false, false },
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { false, true, false, true, false }
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 1; i < 3; i++) {
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int j = 0; j < 5; j++) {
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Activate the tab.
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser()->SelectTabContentsAt(j, true);
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Activate the location bar or the page.
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (kFocusPage[i][j]) {
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        browser()->GetTabContentsAt(j)->view()->Focus();
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        browser()->FocusLocationBar();
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now come back to the tab and check the right view is focused.
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int j = 0; j < 5; j++) {
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Activate the tab.
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser()->SelectTabContentsAt(j, true);
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      VIEW_ID_LOCATION_BAR;
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(IsViewFocused(vid));
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeWindow window = browser()->window()->GetNativeHandle();
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser()->SelectTabContentsAt(0, true);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Try the above, but with ctrl+tab. Since tab normally changes focus,
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // this has regressed in the past. Loop through several times to be sure.
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int j = 0; j < 15; j++) {
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          VIEW_ID_LOCATION_BAR;
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(IsViewFocused(vid));
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, true,
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              false, false, false,
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              new MessageLoop::QuitTask());
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ui_test_utils::RunMessageLoop();
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // As above, but with ctrl+shift+tab.
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser()->SelectTabContentsAt(4, true);
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int j = 14; j >= 0; --j) {
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          VIEW_ID_LOCATION_BAR;
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(IsViewFocused(vid));
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, true,
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              true, false, false,
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              new MessageLoop::QuitTask());
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ui_test_utils::RunMessageLoop();
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tabs remember focus with find-in-page box.
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_TabsRememberFocusFindInPage) {
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kSimplePage);
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->Find();
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::FindInPage(browser()->GetSelectedTabContents(),
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            ASCIIToUTF16("a"), true, false, NULL);
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus the location bar.
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a 2nd tab.
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, -1,
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           TabStripModel::ADD_SELECTED, NULL, std::string());
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus should be on the recently opened tab page.
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Select 1st tab, focus should still be on the location-bar.
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (bug http://crbug.com/23296)
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->SelectTabContentsAt(0, true);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now open the find box again, switch to another tab and come back, the focus
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should return to the find box.
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->Find();
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->SelectTabContentsAt(1, true);
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->SelectTabContentsAt(0, true);
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Background window does not steal focus.
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kSimplePage);
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a new browser window.
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser2 = Browser::Create(browser()->profile());
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(browser2);
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser2->tabstrip_model()->delegate()->AddBlankTab(true);
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser2->window()->Show();
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* focused_browser = NULL;
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* unfocused_browser = NULL;
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_X11)
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On X11, calling Activate() is not guaranteed to move focus, so we have
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to figure out which browser does have focus.
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (browser2->window()->IsActive()) {
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focused_browser = browser2;
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unfocused_browser = browser();
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (browser()->window()->IsActive()) {
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focused_browser = browser();
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unfocused_browser = browser2;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(false);
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN)
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focused_browser = browser();
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unfocused_browser = browser2;
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL steal_focus_url = server->TestServerPage(kStealFocusPage);
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url);
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Activate the first browser.
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focused_browser->window()->Activate();
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the focus to be stolen by the other browser.
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostDelayedTask(
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FROM_HERE, new MessageLoop::QuitTask(), 2000);
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the first browser is still active.
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(focused_browser->window()->IsActive());
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close the 2nd browser to avoid a DCHECK().
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser2->window()->Close();
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Page cannot steal focus when focus is on location bar.
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the page that steals focus.
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kStealFocusPage);
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the page to steal focus.
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PlatformThread::Sleep(2000);
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the location bar is still focused.
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Focus traversal on a regular page.
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note that this test relies on a notification from the renderer that the
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// focus has changed in the page.  The notification in the renderer may change
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// at which point this test would fail (see comment in
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RenderWidget::didFocus()).
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kTypicalPage);
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* kExpElementIDs[] = {
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "",  // Initially no element in the page should be focused
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         // (the location bar is focused).
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "gmapLink"
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeWindow window = browser()->window()->GetNativeHandle();
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test forward focus traversal.
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < 3; ++i) {
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SCOPED_TRACE(StringPrintf("outer loop: %d", i));
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Location bar should be focused.
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now let's press tab to move the focus.
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) {
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SCOPED_TRACE(StringPrintf("inner loop %" PRIuS, j));
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Let's make sure the focus is on the expected element in the page.
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string actual;
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          browser()->GetSelectedTabContents()->render_view_host(),
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          L"",
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          L"window.domAutomationController.send(getFocusedElement());",
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &actual));
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            false, false, false, false));
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (j < arraysize(kExpElementIDs) - 1) {
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            render_view_host());
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // On the last tab key press, the focus returns to the browser.
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ui_test_utils::WaitForFocusInBrowser(browser());
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // At this point the renderer has sent us a message asking to advance the
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // focus (as the end of the focus loop was reached in the renderer).
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to run the message loop to process it.
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::RunAllPendingInMessageLoop();
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now let's try reverse focus traversal.
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < 3; ++i) {
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SCOPED_TRACE(StringPrintf("outer loop: %d", i));
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Location bar should be focused.
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now let's press shift-tab to move the focus in reverse.
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t j = 0; j < 7; ++j) {
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SCOPED_TRACE(StringPrintf("inner loop: %" PRIuS, j));
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            false, true, false, false));
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (j < arraysize(kExpElementIDs) - 1) {
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            render_view_host());
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // On the last tab key press, the focus returns to the browser.
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ui_test_utils::WaitForFocusInBrowser(browser());
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Let's make sure the focus is on the expected element in the page.
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string actual;
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          browser()->GetSelectedTabContents()->render_view_host(),
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          L"",
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          L"window.domAutomationController.send(getFocusedElement());",
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &actual));
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // At this point the renderer has sent us a message asking to advance the
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // focus (as the end of the focus loop was reached in the renderer).
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to run the message loop to process it.
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::RunAllPendingInMessageLoop();
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Focus traversal while an interstitial is showing.
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) {
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kSimplePage);
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus should be on the page.
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's show an interstitial.
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial_page =
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(browser()->GetSelectedTabContents(),
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               true, GURL("http://interstitial.com"));
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial_page->Show();
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Give some time for the interstitial to show.
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostDelayedTask(FROM_HERE,
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          new MessageLoop::QuitTask(),
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          1000);
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* kExpElementIDs[] = {
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "",  // Initially no element in the page should be focused
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         // (the location bar is focused).
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "gmapLink"
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeWindow window = browser()->window()->GetNativeHandle();
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test forward focus traversal.
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < 2; ++i) {
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Location bar should be focused.
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now let's press tab to move the focus.
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t j = 0; j < 7; ++j) {
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Let's make sure the focus is on the expected element in the page.
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string actual = interstitial_page->GetFocusedElement();
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            false, false, false, false));
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (j < arraysize(kExpElementIDs) - 1) {
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        interstitial_page->WaitForFocusChange();
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // On the last tab key press, the focus returns to the browser.
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ui_test_utils::WaitForFocusInBrowser(browser());
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // At this point the renderer has sent us a message asking to advance the
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // focus (as the end of the focus loop was reached in the renderer).
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to run the message loop to process it.
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::RunAllPendingInMessageLoop();
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now let's try reverse focus traversal.
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < 2; ++i) {
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Location bar should be focused.
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now let's press shift-tab to move the focus in reverse.
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t j = 0; j < 7; ++j) {
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            false, true, false, false));
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (j < arraysize(kExpElementIDs) - 1) {
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        interstitial_page->WaitForFocusChange();
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // On the last tab key press, the focus returns to the browser.
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ui_test_utils::WaitForFocusInBrowser(browser());
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Let's make sure the focus is on the expected element in the page.
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string actual = interstitial_page->GetFocusedElement();
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // At this point the renderer has sent us a message asking to advance the
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // focus (as the end of the focus loop was reached in the renderer).
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to run the message loop to process it.
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::RunAllPendingInMessageLoop();
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Focus stays on page with interstitials.
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First we navigate to our test page.
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kSimplePage);
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Page should have focus.
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HasFocus());
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's show an interstitial.
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestInterstitialPage* interstitial_page =
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new TestInterstitialPage(browser()->GetSelectedTabContents(),
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               true, GURL("http://interstitial.com"));
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial_page->Show();
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Give some time for the interstitial to show.
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostDelayedTask(FROM_HERE,
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          new MessageLoop::QuitTask(),
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          1000);
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The interstitial should have focus now.
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(interstitial_page->HasFocus());
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Hide the interstitial.
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interstitial_page->DontProceed();
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus should be back on the original page.
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure Find box can request focus, even when it is already open.
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some page (any page that doesn't steal focus).
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = server->TestServerPage(kTypicalPage);
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), url);
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeWindow window = browser()->window()->GetNativeHandle();
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Press Ctrl+F, which will make the Find box open and request focus.
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          false, false, false,
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          new MessageLoop::QuitTask());
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ideally, we wouldn't sleep here and instead would intercept the
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // RenderViewHostDelegate::HandleKeyboardEvent() callback.  To do that, we
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // could create a RenderViewHostDelegate wrapper and hook-it up by either:
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - creating a factory used to create the delegate
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - making the test a private and overwriting the delegate member directly.
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostDelayedTask(
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now press Ctrl+F again and focus should move to the Find box.
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          false, false, false,
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          new MessageLoop::QuitTask());
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set focus to the page.
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClickOnView(VIEW_ID_TAB_CONTAINER);
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now press Ctrl+F again and focus should move to the Find box.
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true, false,
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          false, false,
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          new MessageLoop::QuitTask());
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // See remark above on why we wait.
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostDelayedTask(
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunMessageLoop();
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure the focus is in the right location when opening the different
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// types of tabs.
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the history tab, focus should be on the tab contents.
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->ShowHistoryTab();
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunAllPendingInMessageLoop();
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the new tab, focus should be on the location bar.
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->NewTab();
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the download tab, focus should be on the tab contents.
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->ShowDownloadsTab();
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open about:blank, focus should be on the location bar.
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK,
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           -1, TabStripModel::ADD_SELECTED, NULL,
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           std::string());
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that focus goes where expected when using reload.
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the new tab, reload.
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->NewTab();
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::RunAllPendingInMessageLoop();
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->Reload(CURRENT_TAB);
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus should stay on the location bar.
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a regular page, focus the location bar, reload.
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), server->TestServerPage(kSimplePage));
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->FocusLocationBar();
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->Reload(CURRENT_TAB);
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus should now be on the tab contents.
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->ShowDownloadsTab();
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that focus goes where expected when using reload on a crashed tab.
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReloadCrashedTab) {
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HTTPTestServer* server = StartHTTPServer();
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a regular page, crash, reload.
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::NavigateToURL(browser(), server->TestServerPage(kSimplePage));
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->Reload(CURRENT_TAB);
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus should now be on the tab contents.
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser()->ShowDownloadsTab();
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
771