blob: d2cab010b15ae38ae35ff3ef8b7bc0cafffda70b [file] [log] [blame]
[email protected]b54649012009-04-17 17:00:121// Copyright (c) 2009 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]22cdd932009-08-18 02:16:215#include "base/keyboard_codes.h"
[email protected]8bcdec92009-02-25 16:15:186#include "base/message_loop.h"
[email protected]ece3c8b2009-03-27 16:55:397#include "base/ref_counted.h"
[email protected]8bcdec92009-02-25 16:15:188#include "chrome/browser/automation/ui_controls.h"
9#include "chrome/browser/browser.h"
[email protected]134c47b92009-08-19 03:33:4410#include "chrome/browser/browser_window.h"
11#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]9e0c83a2009-05-06 19:44:3712#include "chrome/browser/renderer_host/render_widget_host_view.h"
13#include "chrome/browser/tab_contents/interstitial_page.h"
[email protected]186f13f2009-08-19 20:34:0014#include "chrome/browser/tab_contents/tab_contents.h"
15#include "chrome/browser/tab_contents/tab_contents_view.h"
initial.commit09911bf2008-07-26 23:55:2916#include "chrome/browser/view_ids.h"
[email protected]9e0c83a2009-05-06 19:44:3717#include "chrome/common/chrome_paths.h"
[email protected]8bcdec92009-02-25 16:15:1818#include "chrome/test/in_process_browser_test.h"
19#include "chrome/test/ui_test_utils.h"
[email protected]2362e4f2009-05-08 00:34:0520#include "views/focus/focus_manager.h"
21#include "views/view.h"
22#include "views/window/window.h"
initial.commit09911bf2008-07-26 23:55:2923
[email protected]134c47b92009-08-19 03:33:4424#if defined(TOOLKIT_VIEWS)
25#include "chrome/browser/views/frame/browser_view.h"
26#include "chrome/browser/views/location_bar_view.h"
27#include "chrome/browser/views/tab_contents/tab_contents_container.h"
28#endif
29
[email protected]b9821882009-08-17 22:25:1730#if defined(OS_LINUX)
31#include "chrome/browser/gtk/view_id_util.h"
32#endif
33
[email protected]fc2e0872009-08-21 22:14:4134#if defined(OS_LINUX)
35// For some reason we hit an external DNS lookup in this test in Linux but not
36// on Windows. TODO(estade): investigate.
37#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial
38#else
39#define MAYBE_FocusTraversalOnInterstitial FocusTraversalOnInterstitial
40#endif
41
initial.commit09911bf2008-07-26 23:55:2942namespace {
43
[email protected]8bcdec92009-02-25 16:15:1844// The delay waited in some cases where we don't have a notifications for an
45// action we take.
initial.commit09911bf2008-07-26 23:55:2946const int kActionDelayMs = 500;
47
initial.commit09911bf2008-07-26 23:55:2948const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html";
49const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html";
50const wchar_t kTypicalPage[] = L"files/focus/typical_page.html";
[email protected]b65de8b92009-09-14 19:36:3151const char kTypicalPageName[] = "typical_page.html";
initial.commit09911bf2008-07-26 23:55:2952
[email protected]8bcdec92009-02-25 16:15:1853class BrowserFocusTest : public InProcessBrowserTest {
initial.commit09911bf2008-07-26 23:55:2954 public:
55 BrowserFocusTest() {
[email protected]8bcdec92009-02-25 16:15:1856 set_show_window(true);
57 EnableDOMAutomation();
initial.commit09911bf2008-07-26 23:55:2958 }
[email protected]b9821882009-08-17 22:25:1759
60 void CheckViewHasFocus(ViewID vid) {
61 BrowserWindow* browser_window = browser()->window();
62 ASSERT_TRUE(browser_window);
63 gfx::NativeWindow window = browser_window->GetNativeHandle();
64 ASSERT_TRUE(window);
65#if defined(OS_WIN)
66 views::FocusManager* focus_manager =
67 views::FocusManager::GetFocusManagerForNativeView(window);
68 ASSERT_TRUE(focus_manager);
[email protected]fc2e0872009-08-21 22:14:4169 EXPECT_EQ(vid, focus_manager->GetFocusedView()->GetID()) <<
70 "For view id " << vid;
[email protected]b9821882009-08-17 22:25:1771#elif defined(OS_LINUX)
72 GtkWidget* widget = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid);
73 ASSERT_TRUE(widget);
[email protected]fc2e0872009-08-21 22:14:4174 EXPECT_TRUE(WidgetInFocusChain(GTK_WIDGET(window), widget)) <<
75 "For view id " << vid;
[email protected]b9821882009-08-17 22:25:1776#else
77 NOTIMPLEMENTED();
78#endif
79 }
80
[email protected]fc2e0872009-08-21 22:14:4181 void ClickOnView(ViewID vid) {
82 BrowserWindow* browser_window = browser()->window();
83 ASSERT_TRUE(browser_window);
[email protected]c0cbacb2009-08-26 03:27:2984#if defined(TOOLKIT_VIEWS)
[email protected]fc2e0872009-08-21 22:14:4185 views::View* view =
86 reinterpret_cast<BrowserView*>(browser_window)->GetViewByID(vid);
87#elif defined(OS_LINUX)
88 gfx::NativeWindow window = browser_window->GetNativeHandle();
89 ASSERT_TRUE(window);
90 GtkWidget* view = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid);
91#endif
92 ASSERT_TRUE(view);
93 ui_controls::MoveMouseToCenterAndPress(
94 view,
95 ui_controls::LEFT,
96 ui_controls::DOWN | ui_controls::UP,
97 new MessageLoop::QuitTask());
98 ui_test_utils::RunMessageLoop();
99 }
100
[email protected]186f13f2009-08-19 20:34:00101 static void HideNativeWindow(gfx::NativeWindow window) {
102#if defined(OS_WIN)
103 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
104 // using Windows API.
105 ::ShowWindow(window, SW_HIDE);
106#elif defined(OS_LINUX)
107 gtk_widget_hide(GTK_WIDGET(window));
108#else
109 NOTIMPLEMENTED();
110#endif
111 }
112
113 static void ShowNativeWindow(gfx::NativeWindow window) {
114#if defined(OS_WIN)
115 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
116 // using Windows API.
117 ::ShowWindow(window, SW_SHOW);
118#elif defined(OS_LINUX)
119 gtk_widget_hide(GTK_WIDGET(window));
120#else
121 NOTIMPLEMENTED();
122#endif
123 }
124
[email protected]b9821882009-08-17 22:25:17125 private:
126#if defined(OS_LINUX)
127 // Check if the focused widget for |root| is |target| or a child of |target|.
128 static bool WidgetInFocusChain(GtkWidget* root, GtkWidget* target) {
129 GtkWidget* iter = root;
130
131 while (iter) {
132 if (iter == target)
133 return true;
134
135 if (!GTK_IS_CONTAINER(iter))
136 return false;
137
138 iter = GTK_CONTAINER(iter)->focus_child;
139 }
140
141 return false;
142 }
143#endif
initial.commit09911bf2008-07-26 23:55:29144};
145
[email protected]9e0c83a2009-05-06 19:44:37146class TestInterstitialPage : public InterstitialPage {
147 public:
148 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
149 : InterstitialPage(tab, new_navigation, url),
150 waiting_for_dom_response_(false) {
[email protected]b65de8b92009-09-14 19:36:31151 FilePath file_path;
[email protected]9e0c83a2009-05-06 19:44:37152 bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path);
153 EXPECT_TRUE(r);
[email protected]b65de8b92009-09-14 19:36:31154 file_path = file_path.AppendASCII("focus");
155 file_path = file_path.AppendASCII(kTypicalPageName);
[email protected]9e0c83a2009-05-06 19:44:37156 r = file_util::ReadFileToString(file_path, &html_contents_);
157 EXPECT_TRUE(r);
158 }
159
160 virtual std::string GetHTMLContents() {
161 return html_contents_;
162 }
163
164 virtual void DomOperationResponse(const std::string& json_string,
165 int automation_id) {
166 if (waiting_for_dom_response_) {
167 dom_response_ = json_string;
168 waiting_for_dom_response_ = false;
169 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
170 return;
171 }
172 InterstitialPage::DomOperationResponse(json_string, automation_id);
173 }
174
175 std::string GetFocusedElement() {
176 std::wstring script = L"window.domAutomationController.setAutomationId(0);"
177 L"window.domAutomationController.send(getFocusedElement());";
178
179 render_view_host()->ExecuteJavascriptInWebFrame(L"", script);
180 DCHECK(!waiting_for_dom_response_);
181 waiting_for_dom_response_ = true;
182 ui_test_utils::RunMessageLoop();
183 // Remove the JSON extra quotes.
184 if (dom_response_.size() >= 2 && dom_response_[0] == '"' &&
185 dom_response_[dom_response_.size() - 1] == '"') {
186 dom_response_ = dom_response_.substr(1, dom_response_.size() - 2);
187 }
188 return dom_response_;
189 }
190
191 bool HasFocus() {
192 return render_view_host()->view()->HasFocus();
193 }
194
195 private:
196 std::string html_contents_;
197
198 bool waiting_for_dom_response_;
199 std::string dom_response_;
200
201};
[email protected]b9821882009-08-17 22:25:17202
initial.commit09911bf2008-07-26 23:55:29203} // namespace
204
[email protected]186f13f2009-08-19 20:34:00205IN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) {
[email protected]fc2e0872009-08-21 22:14:41206#if defined(OS_LINUX)
207 // It seems we have to wait a little bit for the widgets to spin up before
208 // we can start clicking on them.
209 MessageLoop::current()->PostDelayedTask(FROM_HERE,
210 new MessageLoop::QuitTask(),
211 kActionDelayMs);
212 ui_test_utils::RunMessageLoop();
213#endif
214
[email protected]186f13f2009-08-19 20:34:00215 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
216
[email protected]fc2e0872009-08-21 22:14:41217 ClickOnView(VIEW_ID_TAB_CONTAINER);
[email protected]186f13f2009-08-19 20:34:00218 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
219
[email protected]fc2e0872009-08-21 22:14:41220 ClickOnView(VIEW_ID_LOCATION_BAR);
[email protected]186f13f2009-08-19 20:34:00221 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
222}
[email protected]186f13f2009-08-19 20:34:00223
[email protected]7e383692009-06-12 19:14:54224IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) {
[email protected]8bcdec92009-02-25 16:15:18225 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29226
227 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27228 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18229 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29230
[email protected]186f13f2009-08-19 20:34:00231 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
232
initial.commit09911bf2008-07-26 23:55:29233 // The focus should be on the Tab contents.
[email protected]186f13f2009-08-19 20:34:00234 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
initial.commit09911bf2008-07-26 23:55:29235 // Now hide the window, show it again, the focus should not have changed.
[email protected]186f13f2009-08-19 20:34:00236 HideNativeWindow(window);
237 ShowNativeWindow(window);
238 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
initial.commit09911bf2008-07-26 23:55:29239
[email protected]186f13f2009-08-19 20:34:00240 browser()->FocusLocationBar();
241 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29242 // Hide the window, show it again, the focus should not have changed.
[email protected]186f13f2009-08-19 20:34:00243 HideNativeWindow(window);
244 ShowNativeWindow(window);
245 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29246
[email protected]186f13f2009-08-19 20:34:00247 // The rest of this test does not make sense on Linux because the behavior
248 // of Activate() is not well defined and can vary by window manager.
249#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29250 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18251 Browser* browser2 = Browser::Create(browser()->profile());
252 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43253 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18254 browser2->window()->Show();
255 ui_test_utils::NavigateToURL(browser2, url);
initial.commit09911bf2008-07-26 23:55:29256
[email protected]8bcdec92009-02-25 16:15:18257 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00258 BrowserView* browser_view2 =
259 BrowserView::GetBrowserViewForNativeWindow(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18260 ASSERT_TRUE(browser_view2);
261 views::FocusManager* focus_manager2 =
[email protected]82166b62009-06-30 18:48:00262 views::FocusManager::GetFocusManagerForNativeView(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18263 ASSERT_TRUE(focus_manager2);
[email protected]7e383692009-06-12 19:14:54264 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38265 focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29266
267 // Switch to the 1st browser window, focus should still be on the location
268 // bar and the second browser should have nothing focused.
[email protected]8bcdec92009-02-25 16:15:18269 browser()->window()->Activate();
[email protected]186f13f2009-08-19 20:34:00270 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]8bcdec92009-02-25 16:15:18271 EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29272
273 // Switch back to the second browser, focus should still be on the page.
[email protected]8bcdec92009-02-25 16:15:18274 browser2->window()->Activate();
[email protected]186f13f2009-08-19 20:34:00275 EXPECT_EQ(NULL,
276 views::FocusManager::GetFocusManagerForNativeView(
277 browser()->window()->GetNativeHandle())->GetFocusedView());
[email protected]7e383692009-06-12 19:14:54278 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38279 focus_manager2->GetFocusedView());
[email protected]8bcdec92009-02-25 16:15:18280
281 // Close the 2nd browser to avoid a DCHECK().
282 browser_view2->Close();
[email protected]186f13f2009-08-19 20:34:00283#endif
initial.commit09911bf2008-07-26 23:55:29284}
285
286// Tabs remember focus.
[email protected]8bcdec92009-02-25 16:15:18287IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
288 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29289
290 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27291 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18292 ui_test_utils::NavigateToURL(browser(), url);
293
initial.commit09911bf2008-07-26 23:55:29294 // Create several tabs.
[email protected]22735af62009-04-07 21:09:58295 for (int i = 0; i < 4; ++i) {
[email protected]82166b62009-06-30 18:48:00296 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
297 false, NULL);
[email protected]22735af62009-04-07 21:09:58298 }
initial.commit09911bf2008-07-26 23:55:29299
300 // Alternate focus for the tab.
301 const bool kFocusPage[3][5] = {
302 { true, true, true, true, false },
303 { false, false, false, false, false },
304 { false, true, false, true, false }
305 };
306
307 for (int i = 1; i < 3; i++) {
308 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18309 // Activate the tab.
310 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29311
312 // Activate the location bar or the page.
[email protected]7e383692009-06-12 19:14:54313 if (kFocusPage[i][j]) {
[email protected]186f13f2009-08-19 20:34:00314 browser()->GetTabContentsAt(j)->view()->Focus();
[email protected]7e383692009-06-12 19:14:54315 } else {
[email protected]186f13f2009-08-19 20:34:00316 browser()->FocusLocationBar();
[email protected]7e383692009-06-12 19:14:54317 }
initial.commit09911bf2008-07-26 23:55:29318 }
319
320 // Now come back to the tab and check the right view is focused.
321 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18322 // Activate the tab.
323 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29324
[email protected]186f13f2009-08-19 20:34:00325 ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
326 VIEW_ID_LOCATION_BAR;
327 CheckViewHasFocus(vid);
initial.commit09911bf2008-07-26 23:55:29328 }
329 }
330}
331
332// Background window does not steal focus.
[email protected]042d43e2009-07-23 16:31:45333IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
[email protected]8bcdec92009-02-25 16:15:18334 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29335
336 // First we navigate to our test page.
[email protected]8bcdec92009-02-25 16:15:18337 GURL url = server->TestServerPageW(kSimplePage);
338 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29339
340 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18341 Browser* browser2 = Browser::Create(browser()->profile());
342 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43343 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18344 browser2->window()->Show();
[email protected]186f13f2009-08-19 20:34:00345
346 Browser* focused_browser;
347 Browser* unfocused_browser;
348#if defined(OS_LINUX)
349 // On Linux, calling Activate() is not guaranteed to move focus, so we have
350 // to figure out which browser does have focus.
351 if (browser2->window()->IsActive()) {
352 focused_browser = browser2;
353 unfocused_browser = browser();
354 } else if (browser()->window()->IsActive()) {
355 focused_browser = browser();
356 unfocused_browser = browser2;
357 } else {
358 ASSERT_TRUE(false);
359 }
360#elif defined(OS_WIN)
361 focused_browser = browser();
362 unfocused_browser = browser2;
363#endif
364
[email protected]1e187af2009-02-25 02:02:46365 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
[email protected]186f13f2009-08-19 20:34:00366 ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url);
[email protected]1e187af2009-02-25 02:02:46367
[email protected]8bcdec92009-02-25 16:15:18368 // Activate the first browser.
[email protected]186f13f2009-08-19 20:34:00369 focused_browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:29370
371 // Wait for the focus to be stolen by the other browser.
[email protected]186f13f2009-08-19 20:34:00372 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29373
[email protected]8bcdec92009-02-25 16:15:18374 // Make sure the first browser is still active.
[email protected]186f13f2009-08-19 20:34:00375 EXPECT_TRUE(focused_browser->window()->IsActive());
[email protected]8bcdec92009-02-25 16:15:18376
377 // Close the 2nd browser to avoid a DCHECK().
[email protected]186f13f2009-08-19 20:34:00378 browser2->window()->Close();
initial.commit09911bf2008-07-26 23:55:29379}
380
381// Page cannot steal focus when focus is on location bar.
[email protected]8bcdec92009-02-25 16:15:18382IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
383 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29384
385 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27386 GURL url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18387 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29388
[email protected]186f13f2009-08-19 20:34:00389 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29390
391 // Wait for the page to steal focus.
[email protected]186f13f2009-08-19 20:34:00392 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29393
394 // Make sure the location bar is still focused.
[email protected]186f13f2009-08-19 20:34:00395 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29396}
397
[email protected]9e0c83a2009-05-06 19:44:37398// Focus traversal on a regular page.
[email protected]8bcdec92009-02-25 16:15:18399IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
400 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29401
[email protected]8bcdec92009-02-25 16:15:18402 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27403 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18404 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29405
[email protected]186f13f2009-08-19 20:34:00406 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29407
[email protected]8bcdec92009-02-25 16:15:18408 const char* kExpElementIDs[] = {
409 "", // Initially no element in the page should be focused
410 // (the location bar is focused).
411 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
412 "gmapLink"
initial.commit09911bf2008-07-26 23:55:29413 };
414
[email protected]186f13f2009-08-19 20:34:00415 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
416
initial.commit09911bf2008-07-26 23:55:29417 // Test forward focus traversal.
418 for (int i = 0; i < 3; ++i) {
419 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00420 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29421
422 // Now let's press tab to move the focus.
423 for (int j = 0; j < 7; ++j) {
424 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01425 std::string actual;
426 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25427 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18428 L"",
[email protected]45671612009-04-29 22:24:01429 L"window.domAutomationController.send(getFocusedElement());",
430 &actual));
initial.commit09911bf2008-07-26 23:55:29431 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
432
[email protected]186f13f2009-08-19 20:34:00433 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false,
[email protected]22cdd932009-08-18 02:16:21434 false, false,
[email protected]8bcdec92009-02-25 16:15:18435 new MessageLoop::QuitTask());
436 ui_test_utils::RunMessageLoop();
437 // Ideally, we wouldn't sleep here and instead would use the event
[email protected]b54649012009-04-17 17:00:12438 // processed ack notification from the renderer. I am reluctant to create
[email protected]8bcdec92009-02-25 16:15:18439 // a new notification/callback for that purpose just for this test.
[email protected]186f13f2009-08-19 20:34:00440 PlatformThread::Sleep(kActionDelayMs);
initial.commit09911bf2008-07-26 23:55:29441 }
[email protected]8bcdec92009-02-25 16:15:18442
443 // At this point the renderer has sent us a message asking to advance the
444 // focus (as the end of the focus loop was reached in the renderer).
445 // We need to run the message loop to process it.
446 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
447 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29448 }
449
450 // Now let's try reverse focus traversal.
451 for (int i = 0; i < 3; ++i) {
452 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00453 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29454
[email protected]8bcdec92009-02-25 16:15:18455 // Now let's press shift-tab to move the focus in reverse.
initial.commit09911bf2008-07-26 23:55:29456 for (int j = 0; j < 7; ++j) {
[email protected]186f13f2009-08-19 20:34:00457 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false,
[email protected]22cdd932009-08-18 02:16:21458 true, false,
[email protected]8bcdec92009-02-25 16:15:18459 new MessageLoop::QuitTask());
460 ui_test_utils::RunMessageLoop();
[email protected]186f13f2009-08-19 20:34:00461 PlatformThread::Sleep(kActionDelayMs);
initial.commit09911bf2008-07-26 23:55:29462
463 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01464 std::string actual;
465 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25466 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18467 L"",
[email protected]45671612009-04-29 22:24:01468 L"window.domAutomationController.send(getFocusedElement());",
469 &actual));
initial.commit09911bf2008-07-26 23:55:29470 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
471 }
[email protected]8bcdec92009-02-25 16:15:18472
473 // At this point the renderer has sent us a message asking to advance the
474 // focus (as the end of the focus loop was reached in the renderer).
475 // We need to run the message loop to process it.
476 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
477 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29478 }
479}
480
[email protected]9e0c83a2009-05-06 19:44:37481// Focus traversal while an interstitial is showing.
[email protected]fc2e0872009-08-21 22:14:41482IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) {
[email protected]9e0c83a2009-05-06 19:44:37483 HTTPTestServer* server = StartHTTPServer();
484
485 // First we navigate to our test page.
486 GURL url = server->TestServerPageW(kSimplePage);
487 ui_test_utils::NavigateToURL(browser(), url);
488
[email protected]9e0c83a2009-05-06 19:44:37489 // Focus should be on the page.
[email protected]fc2e0872009-08-21 22:14:41490 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37491
492 // Let's show an interstitial.
493 TestInterstitialPage* interstitial_page =
494 new TestInterstitialPage(browser()->GetSelectedTabContents(),
495 true, GURL("http://interstitial.com"));
496 interstitial_page->Show();
497 // Give some time for the interstitial to show.
498 MessageLoop::current()->PostDelayedTask(FROM_HERE,
499 new MessageLoop::QuitTask(),
500 1000);
501 ui_test_utils::RunMessageLoop();
502
[email protected]fc2e0872009-08-21 22:14:41503 browser()->FocusLocationBar();
[email protected]9e0c83a2009-05-06 19:44:37504
505 const char* kExpElementIDs[] = {
506 "", // Initially no element in the page should be focused
507 // (the location bar is focused).
508 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
509 "gmapLink"
510 };
511
[email protected]fc2e0872009-08-21 22:14:41512 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
513
[email protected]9e0c83a2009-05-06 19:44:37514 // Test forward focus traversal.
515 for (int i = 0; i < 2; ++i) {
516 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41517 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37518
519 // Now let's press tab to move the focus.
520 for (int j = 0; j < 7; ++j) {
521 // Let's make sure the focus is on the expected element in the page.
522 std::string actual = interstitial_page->GetFocusedElement();
523 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
524
[email protected]fc2e0872009-08-21 22:14:41525 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false,
[email protected]22cdd932009-08-18 02:16:21526 false, false,
[email protected]9e0c83a2009-05-06 19:44:37527 new MessageLoop::QuitTask());
528 ui_test_utils::RunMessageLoop();
529 // Ideally, we wouldn't sleep here and instead would use the event
530 // processed ack notification from the renderer. I am reluctant to create
531 // a new notification/callback for that purpose just for this test.
[email protected]fc2e0872009-08-21 22:14:41532 PlatformThread::Sleep(kActionDelayMs);
[email protected]9e0c83a2009-05-06 19:44:37533 }
534
535 // At this point the renderer has sent us a message asking to advance the
536 // focus (as the end of the focus loop was reached in the renderer).
537 // We need to run the message loop to process it.
538 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
539 ui_test_utils::RunMessageLoop();
540 }
541
542 // Now let's try reverse focus traversal.
543 for (int i = 0; i < 2; ++i) {
544 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41545 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37546
547 // Now let's press shift-tab to move the focus in reverse.
548 for (int j = 0; j < 7; ++j) {
[email protected]fc2e0872009-08-21 22:14:41549 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false,
[email protected]22cdd932009-08-18 02:16:21550 true, false,
[email protected]9e0c83a2009-05-06 19:44:37551 new MessageLoop::QuitTask());
552 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41553 PlatformThread::Sleep(kActionDelayMs);
[email protected]9e0c83a2009-05-06 19:44:37554
555 // Let's make sure the focus is on the expected element in the page.
556 std::string actual = interstitial_page->GetFocusedElement();
557 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
558 }
559
560 // At this point the renderer has sent us a message asking to advance the
561 // focus (as the end of the focus loop was reached in the renderer).
562 // We need to run the message loop to process it.
563 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
564 ui_test_utils::RunMessageLoop();
565 }
566}
567
568// Focus stays on page with interstitials.
569IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
570 HTTPTestServer* server = StartHTTPServer();
571
572 // First we navigate to our test page.
573 GURL url = server->TestServerPageW(kSimplePage);
574 ui_test_utils::NavigateToURL(browser(), url);
575
[email protected]9e0c83a2009-05-06 19:44:37576 // Page should have focus.
[email protected]fc2e0872009-08-21 22:14:41577 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37578 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
579 HasFocus());
580
[email protected]9d8a4642009-07-29 17:25:30581 // Let's show an interstitial.
[email protected]9e0c83a2009-05-06 19:44:37582 TestInterstitialPage* interstitial_page =
583 new TestInterstitialPage(browser()->GetSelectedTabContents(),
584 true, GURL("http://interstitial.com"));
585 interstitial_page->Show();
586 // Give some time for the interstitial to show.
587 MessageLoop::current()->PostDelayedTask(FROM_HERE,
588 new MessageLoop::QuitTask(),
589 1000);
590 ui_test_utils::RunMessageLoop();
591
592 // The interstitial should have focus now.
[email protected]fc2e0872009-08-21 22:14:41593 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37594 EXPECT_TRUE(interstitial_page->HasFocus());
595
596 // Hide the interstitial.
597 interstitial_page->DontProceed();
598
599 // Focus should be back on the original page.
[email protected]fc2e0872009-08-21 22:14:41600 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37601}
602
[email protected]9bd491ee2008-12-10 22:31:07603// Make sure Find box can request focus, even when it is already open.
[email protected]8bcdec92009-02-25 16:15:18604IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
605 HTTPTestServer* server = StartHTTPServer();
license.botbf09a502008-08-24 00:55:55606
[email protected]9bd491ee2008-12-10 22:31:07607 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27608 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18609 ui_test_utils::NavigateToURL(browser(), url);
[email protected]9bd491ee2008-12-10 22:31:07610
[email protected]fc2e0872009-08-21 22:14:41611 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
[email protected]9bd491ee2008-12-10 22:31:07612
613 // Press Ctrl+F, which will make the Find box open and request focus.
[email protected]fc2e0872009-08-21 22:14:41614 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21615 false, false,
[email protected]8bcdec92009-02-25 16:15:18616 new MessageLoop::QuitTask());
617 ui_test_utils::RunMessageLoop();
618
619 // Ideally, we wouldn't sleep here and instead would intercept the
620 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we
621 // could create a RenderViewHostDelegate wrapper and hook-it up by either:
622 // - creating a factory used to create the delegate
623 // - making the test a private and overwriting the delegate member directly.
[email protected]fc2e0872009-08-21 22:14:41624 MessageLoop::current()->PostDelayedTask(
625 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18626 ui_test_utils::RunMessageLoop();
627
[email protected]fc2e0872009-08-21 22:14:41628 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07629
[email protected]fc2e0872009-08-21 22:14:41630 browser()->FocusLocationBar();
631 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9bd491ee2008-12-10 22:31:07632
633 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41634 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21635 false, false,
[email protected]8bcdec92009-02-25 16:15:18636 new MessageLoop::QuitTask());
637 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41638 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07639
640 // Set focus to the page.
[email protected]fc2e0872009-08-21 22:14:41641 ClickOnView(VIEW_ID_TAB_CONTAINER);
642 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9bd491ee2008-12-10 22:31:07643
644 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41645 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true, false,
[email protected]22cdd932009-08-18 02:16:21646 false, new MessageLoop::QuitTask());
[email protected]8bcdec92009-02-25 16:15:18647 ui_test_utils::RunMessageLoop();
648
649 // See remark above on why we wait.
[email protected]fc2e0872009-08-21 22:14:41650 MessageLoop::current()->PostDelayedTask(
651 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18652 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41653 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07654}
[email protected]401513c2009-03-12 00:21:28655
656// Makes sure the focus is in the right location when opening the different
657// types of tabs.
[email protected]186f13f2009-08-19 20:34:00658IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
[email protected]401513c2009-03-12 00:21:28659 // Open the history tab, focus should be on the tab contents.
660 browser()->ShowHistoryTab();
[email protected]186f13f2009-08-19 20:34:00661 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]401513c2009-03-12 00:21:28662
663 // Open the new tab, focus should be on the location bar.
664 browser()->NewTab();
[email protected]b9821882009-08-17 22:25:17665 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28666
667 // Open the download tab, focus should be on the tab contents.
668 browser()->ShowDownloadsTab();
[email protected]186f13f2009-08-19 20:34:00669 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]3e3f0eb2009-06-22 18:33:43670
671 // Open about:blank, focus should be on the location bar.
672 browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK,
673 true, -1, false, NULL);
[email protected]b9821882009-08-17 22:25:17674 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28675}
[email protected]9d8a4642009-07-29 17:25:30676
[email protected]9d8a4642009-07-29 17:25:30677// Tests that focus goes where expected when using reload.
678IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {
679 HTTPTestServer* server = StartHTTPServer();
680
[email protected]9d8a4642009-07-29 17:25:30681 // Open the new tab, reload.
682 browser()->NewTab();
[email protected]b7a20d32009-08-15 00:02:40683 browser()->Reload();
684 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30685 // Focus should stay on the location bar.
[email protected]fc2e0872009-08-21 22:14:41686 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9d8a4642009-07-29 17:25:30687
688 // Open a regular page, focus the location bar, reload.
689 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
[email protected]fc2e0872009-08-21 22:14:41690 browser()->FocusLocationBar();
691 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]b7a20d32009-08-15 00:02:40692 browser()->Reload();
693 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30694 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41695 browser()->ShowDownloadsTab();
696 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30697}
698
699// Tests that focus goes where expected when using reload on a crashed tab.
700IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReloadCrashedTab) {
701 HTTPTestServer* server = StartHTTPServer();
702
[email protected]9d8a4642009-07-29 17:25:30703 // Open a regular page, crash, reload.
704 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
705 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]b7a20d32009-08-15 00:02:40706 browser()->Reload();
707 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30708 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41709 browser()->ShowDownloadsTab();
710 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30711}