blob: ca3de5e4c546f0c8232e33706a2e813e36803d2a [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]8bcdec92009-02-25 16:15:185#include "base/message_loop.h"
[email protected]ece3c8b2009-03-27 16:55:396#include "base/ref_counted.h"
[email protected]8bcdec92009-02-25 16:15:187#include "chrome/browser/automation/ui_controls.h"
8#include "chrome/browser/browser.h"
[email protected]134c47b92009-08-19 03:33:449#include "chrome/browser/browser_window.h"
10#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]9e0c83a2009-05-06 19:44:3711#include "chrome/browser/renderer_host/render_widget_host_view.h"
12#include "chrome/browser/tab_contents/interstitial_page.h"
[email protected]186f13f2009-08-19 20:34:0013#include "chrome/browser/tab_contents/tab_contents.h"
14#include "chrome/browser/tab_contents/tab_contents_view.h"
initial.commit09911bf2008-07-26 23:55:2915#include "chrome/browser/view_ids.h"
[email protected]9e0c83a2009-05-06 19:44:3716#include "chrome/common/chrome_paths.h"
[email protected]8bcdec92009-02-25 16:15:1817#include "chrome/test/in_process_browser_test.h"
18#include "chrome/test/ui_test_utils.h"
[email protected]2362e4f2009-05-08 00:34:0519#include "views/focus/focus_manager.h"
20#include "views/view.h"
21#include "views/window/window.h"
initial.commit09911bf2008-07-26 23:55:2922
[email protected]134c47b92009-08-19 03:33:4423#if defined(TOOLKIT_VIEWS)
24#include "chrome/browser/views/frame/browser_view.h"
25#include "chrome/browser/views/location_bar_view.h"
26#include "chrome/browser/views/tab_contents/tab_contents_container.h"
27#endif
28
[email protected]b9821882009-08-17 22:25:1729#if defined(OS_LINUX)
30#include "chrome/browser/gtk/view_id_util.h"
31#endif
32
[email protected]fc2e0872009-08-21 22:14:4133#if defined(OS_LINUX)
34// For some reason we hit an external DNS lookup in this test in Linux but not
35// on Windows. TODO(estade): investigate.
36#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial
37#else
38#define MAYBE_FocusTraversalOnInterstitial FocusTraversalOnInterstitial
39#endif
40
initial.commit09911bf2008-07-26 23:55:2941namespace {
42
[email protected]8bcdec92009-02-25 16:15:1843// The delay waited in some cases where we don't have a notifications for an
44// action we take.
initial.commit09911bf2008-07-26 23:55:2945const int kActionDelayMs = 500;
46
initial.commit09911bf2008-07-26 23:55:2947const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html";
48const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html";
49const wchar_t kTypicalPage[] = L"files/focus/typical_page.html";
[email protected]b65de8b92009-09-14 19:36:3150const char kTypicalPageName[] = "typical_page.html";
initial.commit09911bf2008-07-26 23:55:2951
[email protected]8bcdec92009-02-25 16:15:1852class BrowserFocusTest : public InProcessBrowserTest {
initial.commit09911bf2008-07-26 23:55:2953 public:
54 BrowserFocusTest() {
[email protected]8bcdec92009-02-25 16:15:1855 set_show_window(true);
56 EnableDOMAutomation();
initial.commit09911bf2008-07-26 23:55:2957 }
[email protected]b9821882009-08-17 22:25:1758
59 void CheckViewHasFocus(ViewID vid) {
60 BrowserWindow* browser_window = browser()->window();
61 ASSERT_TRUE(browser_window);
62 gfx::NativeWindow window = browser_window->GetNativeHandle();
63 ASSERT_TRUE(window);
64#if defined(OS_WIN)
65 views::FocusManager* focus_manager =
66 views::FocusManager::GetFocusManagerForNativeView(window);
67 ASSERT_TRUE(focus_manager);
[email protected]fc2e0872009-08-21 22:14:4168 EXPECT_EQ(vid, focus_manager->GetFocusedView()->GetID()) <<
69 "For view id " << vid;
[email protected]b9821882009-08-17 22:25:1770#elif defined(OS_LINUX)
71 GtkWidget* widget = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid);
72 ASSERT_TRUE(widget);
[email protected]fc2e0872009-08-21 22:14:4173 EXPECT_TRUE(WidgetInFocusChain(GTK_WIDGET(window), widget)) <<
74 "For view id " << vid;
[email protected]b9821882009-08-17 22:25:1775#else
76 NOTIMPLEMENTED();
77#endif
78 }
79
[email protected]fc2e0872009-08-21 22:14:4180 void ClickOnView(ViewID vid) {
81 BrowserWindow* browser_window = browser()->window();
82 ASSERT_TRUE(browser_window);
[email protected]c0cbacb2009-08-26 03:27:2983#if defined(TOOLKIT_VIEWS)
[email protected]fc2e0872009-08-21 22:14:4184 views::View* view =
85 reinterpret_cast<BrowserView*>(browser_window)->GetViewByID(vid);
86#elif defined(OS_LINUX)
87 gfx::NativeWindow window = browser_window->GetNativeHandle();
88 ASSERT_TRUE(window);
89 GtkWidget* view = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid);
90#endif
91 ASSERT_TRUE(view);
92 ui_controls::MoveMouseToCenterAndPress(
93 view,
94 ui_controls::LEFT,
95 ui_controls::DOWN | ui_controls::UP,
96 new MessageLoop::QuitTask());
97 ui_test_utils::RunMessageLoop();
98 }
99
[email protected]186f13f2009-08-19 20:34:00100 static void HideNativeWindow(gfx::NativeWindow window) {
101#if defined(OS_WIN)
102 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
103 // using Windows API.
104 ::ShowWindow(window, SW_HIDE);
105#elif defined(OS_LINUX)
106 gtk_widget_hide(GTK_WIDGET(window));
107#else
108 NOTIMPLEMENTED();
109#endif
110 }
111
112 static void ShowNativeWindow(gfx::NativeWindow window) {
113#if defined(OS_WIN)
114 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
115 // using Windows API.
116 ::ShowWindow(window, SW_SHOW);
117#elif defined(OS_LINUX)
118 gtk_widget_hide(GTK_WIDGET(window));
119#else
120 NOTIMPLEMENTED();
121#endif
122 }
123
[email protected]b9821882009-08-17 22:25:17124 private:
125#if defined(OS_LINUX)
126 // Check if the focused widget for |root| is |target| or a child of |target|.
127 static bool WidgetInFocusChain(GtkWidget* root, GtkWidget* target) {
128 GtkWidget* iter = root;
129
130 while (iter) {
131 if (iter == target)
132 return true;
133
134 if (!GTK_IS_CONTAINER(iter))
135 return false;
136
137 iter = GTK_CONTAINER(iter)->focus_child;
138 }
139
140 return false;
141 }
142#endif
initial.commit09911bf2008-07-26 23:55:29143};
144
[email protected]9e0c83a2009-05-06 19:44:37145class TestInterstitialPage : public InterstitialPage {
146 public:
147 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
148 : InterstitialPage(tab, new_navigation, url),
[email protected]130efb02009-09-18 18:54:35149 waiting_for_dom_response_(false),
150 waiting_for_focus_change_(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
[email protected]130efb02009-09-18 18:54:35195 void WaitForFocusChange() {
196 waiting_for_focus_change_ = true;
197 ui_test_utils::RunMessageLoop();
198 }
199
200 protected:
201 virtual void FocusedNodeChanged() {
202 if (!waiting_for_focus_change_)
203 return;
204
205 waiting_for_focus_change_= false;
206 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
207 }
208
[email protected]9e0c83a2009-05-06 19:44:37209 private:
210 std::string html_contents_;
211
212 bool waiting_for_dom_response_;
[email protected]130efb02009-09-18 18:54:35213 bool waiting_for_focus_change_;
[email protected]9e0c83a2009-05-06 19:44:37214 std::string dom_response_;
215
216};
[email protected]b9821882009-08-17 22:25:17217
initial.commit09911bf2008-07-26 23:55:29218} // namespace
219
[email protected]186f13f2009-08-19 20:34:00220IN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) {
[email protected]fc2e0872009-08-21 22:14:41221#if defined(OS_LINUX)
222 // It seems we have to wait a little bit for the widgets to spin up before
223 // we can start clicking on them.
224 MessageLoop::current()->PostDelayedTask(FROM_HERE,
225 new MessageLoop::QuitTask(),
226 kActionDelayMs);
227 ui_test_utils::RunMessageLoop();
228#endif
229
[email protected]186f13f2009-08-19 20:34:00230 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
231
[email protected]fc2e0872009-08-21 22:14:41232 ClickOnView(VIEW_ID_TAB_CONTAINER);
[email protected]186f13f2009-08-19 20:34:00233 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
234
[email protected]fc2e0872009-08-21 22:14:41235 ClickOnView(VIEW_ID_LOCATION_BAR);
[email protected]186f13f2009-08-19 20:34:00236 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
237}
[email protected]186f13f2009-08-19 20:34:00238
[email protected]7e383692009-06-12 19:14:54239IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) {
[email protected]8bcdec92009-02-25 16:15:18240 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29241
242 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27243 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18244 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29245
[email protected]186f13f2009-08-19 20:34:00246 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
247
initial.commit09911bf2008-07-26 23:55:29248 // The focus should be on the Tab contents.
[email protected]186f13f2009-08-19 20:34:00249 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
initial.commit09911bf2008-07-26 23:55:29250 // Now hide the window, show it again, the focus should not have changed.
[email protected]186f13f2009-08-19 20:34:00251 HideNativeWindow(window);
252 ShowNativeWindow(window);
253 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
initial.commit09911bf2008-07-26 23:55:29254
[email protected]186f13f2009-08-19 20:34:00255 browser()->FocusLocationBar();
256 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29257 // Hide the window, show it again, the focus should not have changed.
[email protected]186f13f2009-08-19 20:34:00258 HideNativeWindow(window);
259 ShowNativeWindow(window);
260 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29261
[email protected]186f13f2009-08-19 20:34:00262 // The rest of this test does not make sense on Linux because the behavior
263 // of Activate() is not well defined and can vary by window manager.
264#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29265 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18266 Browser* browser2 = Browser::Create(browser()->profile());
267 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43268 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18269 browser2->window()->Show();
270 ui_test_utils::NavigateToURL(browser2, url);
initial.commit09911bf2008-07-26 23:55:29271
[email protected]8bcdec92009-02-25 16:15:18272 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00273 BrowserView* browser_view2 =
274 BrowserView::GetBrowserViewForNativeWindow(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18275 ASSERT_TRUE(browser_view2);
276 views::FocusManager* focus_manager2 =
[email protected]82166b62009-06-30 18:48:00277 views::FocusManager::GetFocusManagerForNativeView(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18278 ASSERT_TRUE(focus_manager2);
[email protected]7e383692009-06-12 19:14:54279 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38280 focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29281
282 // Switch to the 1st browser window, focus should still be on the location
283 // bar and the second browser should have nothing focused.
[email protected]8bcdec92009-02-25 16:15:18284 browser()->window()->Activate();
[email protected]186f13f2009-08-19 20:34:00285 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]8bcdec92009-02-25 16:15:18286 EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29287
288 // Switch back to the second browser, focus should still be on the page.
[email protected]8bcdec92009-02-25 16:15:18289 browser2->window()->Activate();
[email protected]186f13f2009-08-19 20:34:00290 EXPECT_EQ(NULL,
291 views::FocusManager::GetFocusManagerForNativeView(
292 browser()->window()->GetNativeHandle())->GetFocusedView());
[email protected]7e383692009-06-12 19:14:54293 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38294 focus_manager2->GetFocusedView());
[email protected]8bcdec92009-02-25 16:15:18295
296 // Close the 2nd browser to avoid a DCHECK().
297 browser_view2->Close();
[email protected]186f13f2009-08-19 20:34:00298#endif
initial.commit09911bf2008-07-26 23:55:29299}
300
301// Tabs remember focus.
[email protected]8bcdec92009-02-25 16:15:18302IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
303 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29304
305 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27306 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18307 ui_test_utils::NavigateToURL(browser(), url);
308
initial.commit09911bf2008-07-26 23:55:29309 // Create several tabs.
[email protected]22735af62009-04-07 21:09:58310 for (int i = 0; i < 4; ++i) {
[email protected]82166b62009-06-30 18:48:00311 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
312 false, NULL);
[email protected]22735af62009-04-07 21:09:58313 }
initial.commit09911bf2008-07-26 23:55:29314
315 // Alternate focus for the tab.
316 const bool kFocusPage[3][5] = {
317 { true, true, true, true, false },
318 { false, false, false, false, false },
319 { false, true, false, true, false }
320 };
321
322 for (int i = 1; i < 3; i++) {
323 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18324 // Activate the tab.
325 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29326
327 // Activate the location bar or the page.
[email protected]7e383692009-06-12 19:14:54328 if (kFocusPage[i][j]) {
[email protected]186f13f2009-08-19 20:34:00329 browser()->GetTabContentsAt(j)->view()->Focus();
[email protected]7e383692009-06-12 19:14:54330 } else {
[email protected]186f13f2009-08-19 20:34:00331 browser()->FocusLocationBar();
[email protected]7e383692009-06-12 19:14:54332 }
initial.commit09911bf2008-07-26 23:55:29333 }
334
335 // Now come back to the tab and check the right view is focused.
336 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18337 // Activate the tab.
338 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29339
[email protected]186f13f2009-08-19 20:34:00340 ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
341 VIEW_ID_LOCATION_BAR;
342 CheckViewHasFocus(vid);
initial.commit09911bf2008-07-26 23:55:29343 }
344 }
345}
346
[email protected]ae40b572009-10-02 21:17:45347// Tabs remember focus with find-in-page box.
348IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocusFindInPage) {
349 HTTPTestServer* server = StartHTTPServer();
350
351 // First we navigate to our test page.
352 GURL url = server->TestServerPageW(kSimplePage);
353 ui_test_utils::NavigateToURL(browser(), url);
354
355 browser()->Find();
356 ui_test_utils::FindInPage(browser()->GetSelectedTabContents(),
357 ASCIIToUTF16("a"), true, false, NULL);
358 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
359
360 // Focus the location bar.
361 browser()->FocusLocationBar();
362
363 // Create a 2nd tab.
364 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
365 false, NULL);
366
367 // Focus should be on the recently opened tab page.
368 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
369
370 // Select 1st tab, focus should still be on the location-bar.
371 // (bug http://crbug.com/23296)
372 browser()->SelectTabContentsAt(0, true);
373 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
374
375 // Now open the find box again, switch to another tab and come back, the focus
376 // should return to the find box.
377 browser()->Find();
378 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
379 browser()->SelectTabContentsAt(1, true);
380 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
381 browser()->SelectTabContentsAt(0, true);
382 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
383}
384
initial.commit09911bf2008-07-26 23:55:29385// Background window does not steal focus.
[email protected]042d43e2009-07-23 16:31:45386IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
[email protected]8bcdec92009-02-25 16:15:18387 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29388
389 // First we navigate to our test page.
[email protected]8bcdec92009-02-25 16:15:18390 GURL url = server->TestServerPageW(kSimplePage);
391 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29392
393 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18394 Browser* browser2 = Browser::Create(browser()->profile());
395 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43396 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18397 browser2->window()->Show();
[email protected]186f13f2009-08-19 20:34:00398
399 Browser* focused_browser;
400 Browser* unfocused_browser;
401#if defined(OS_LINUX)
402 // On Linux, calling Activate() is not guaranteed to move focus, so we have
403 // to figure out which browser does have focus.
404 if (browser2->window()->IsActive()) {
405 focused_browser = browser2;
406 unfocused_browser = browser();
407 } else if (browser()->window()->IsActive()) {
408 focused_browser = browser();
409 unfocused_browser = browser2;
410 } else {
411 ASSERT_TRUE(false);
412 }
413#elif defined(OS_WIN)
414 focused_browser = browser();
415 unfocused_browser = browser2;
416#endif
417
[email protected]1e187af2009-02-25 02:02:46418 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
[email protected]186f13f2009-08-19 20:34:00419 ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url);
[email protected]1e187af2009-02-25 02:02:46420
[email protected]8bcdec92009-02-25 16:15:18421 // Activate the first browser.
[email protected]186f13f2009-08-19 20:34:00422 focused_browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:29423
424 // Wait for the focus to be stolen by the other browser.
[email protected]186f13f2009-08-19 20:34:00425 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29426
[email protected]8bcdec92009-02-25 16:15:18427 // Make sure the first browser is still active.
[email protected]186f13f2009-08-19 20:34:00428 EXPECT_TRUE(focused_browser->window()->IsActive());
[email protected]8bcdec92009-02-25 16:15:18429
430 // Close the 2nd browser to avoid a DCHECK().
[email protected]186f13f2009-08-19 20:34:00431 browser2->window()->Close();
initial.commit09911bf2008-07-26 23:55:29432}
433
434// Page cannot steal focus when focus is on location bar.
[email protected]8bcdec92009-02-25 16:15:18435IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
436 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29437
438 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27439 GURL url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18440 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29441
[email protected]186f13f2009-08-19 20:34:00442 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29443
444 // Wait for the page to steal focus.
[email protected]186f13f2009-08-19 20:34:00445 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29446
447 // Make sure the location bar is still focused.
[email protected]186f13f2009-08-19 20:34:00448 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29449}
450
[email protected]9e0c83a2009-05-06 19:44:37451// Focus traversal on a regular page.
[email protected]130efb02009-09-18 18:54:35452// Note that this test relies on a notification from the renderer that the
453// focus has changed in the page. The notification in the renderer may change
454// at which point this test would fail (see comment in
455// RenderWidget::didFocus()).
[email protected]8bcdec92009-02-25 16:15:18456IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
457 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29458
[email protected]8bcdec92009-02-25 16:15:18459 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27460 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18461 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29462
[email protected]186f13f2009-08-19 20:34:00463 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29464
[email protected]8bcdec92009-02-25 16:15:18465 const char* kExpElementIDs[] = {
466 "", // Initially no element in the page should be focused
467 // (the location bar is focused).
468 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
469 "gmapLink"
initial.commit09911bf2008-07-26 23:55:29470 };
471
[email protected]186f13f2009-08-19 20:34:00472 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
473
initial.commit09911bf2008-07-26 23:55:29474 // Test forward focus traversal.
475 for (int i = 0; i < 3; ++i) {
476 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00477 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29478
479 // Now let's press tab to move the focus.
[email protected]130efb02009-09-18 18:54:35480 for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) {
initial.commit09911bf2008-07-26 23:55:29481 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01482 std::string actual;
483 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25484 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18485 L"",
[email protected]45671612009-04-29 22:24:01486 L"window.domAutomationController.send(getFocusedElement());",
487 &actual));
initial.commit09911bf2008-07-26 23:55:29488 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
489
[email protected]130efb02009-09-18 18:54:35490 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
491 false, false, false));
492
493 if (j < arraysize(kExpElementIDs) - 1) {
494 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
495 render_view_host());
496 } else {
497 // On the last tab key press, the focus returns to the browser.
498 ui_test_utils::WaitForFocusInBrowser(browser());
499 }
initial.commit09911bf2008-07-26 23:55:29500 }
[email protected]8bcdec92009-02-25 16:15:18501
502 // At this point the renderer has sent us a message asking to advance the
503 // focus (as the end of the focus loop was reached in the renderer).
504 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35505 MessageLoop::current()->RunAllPending();
initial.commit09911bf2008-07-26 23:55:29506 }
507
508 // Now let's try reverse focus traversal.
509 for (int i = 0; i < 3; ++i) {
510 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00511 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29512
[email protected]8bcdec92009-02-25 16:15:18513 // Now let's press shift-tab to move the focus in reverse.
[email protected]130efb02009-09-18 18:54:35514 for (size_t j = 0; j < 7; ++j) {
515 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
516 false, true, false));
517
518 if (j < arraysize(kExpElementIDs) - 1) {
519 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
520 render_view_host());
521 } else {
522 // On the last tab key press, the focus returns to the browser.
523 ui_test_utils::WaitForFocusInBrowser(browser());
524 }
initial.commit09911bf2008-07-26 23:55:29525
526 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01527 std::string actual;
528 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25529 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18530 L"",
[email protected]45671612009-04-29 22:24:01531 L"window.domAutomationController.send(getFocusedElement());",
532 &actual));
initial.commit09911bf2008-07-26 23:55:29533 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
534 }
[email protected]8bcdec92009-02-25 16:15:18535
536 // At this point the renderer has sent us a message asking to advance the
537 // focus (as the end of the focus loop was reached in the renderer).
538 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35539 MessageLoop::current()->RunAllPending();
initial.commit09911bf2008-07-26 23:55:29540 }
541}
542
[email protected]9e0c83a2009-05-06 19:44:37543// Focus traversal while an interstitial is showing.
[email protected]fc2e0872009-08-21 22:14:41544IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) {
[email protected]9e0c83a2009-05-06 19:44:37545 HTTPTestServer* server = StartHTTPServer();
546
547 // First we navigate to our test page.
548 GURL url = server->TestServerPageW(kSimplePage);
549 ui_test_utils::NavigateToURL(browser(), url);
550
[email protected]9e0c83a2009-05-06 19:44:37551 // Focus should be on the page.
[email protected]fc2e0872009-08-21 22:14:41552 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37553
554 // Let's show an interstitial.
555 TestInterstitialPage* interstitial_page =
556 new TestInterstitialPage(browser()->GetSelectedTabContents(),
557 true, GURL("http://interstitial.com"));
558 interstitial_page->Show();
559 // Give some time for the interstitial to show.
560 MessageLoop::current()->PostDelayedTask(FROM_HERE,
561 new MessageLoop::QuitTask(),
562 1000);
563 ui_test_utils::RunMessageLoop();
564
[email protected]fc2e0872009-08-21 22:14:41565 browser()->FocusLocationBar();
[email protected]9e0c83a2009-05-06 19:44:37566
567 const char* kExpElementIDs[] = {
568 "", // Initially no element in the page should be focused
569 // (the location bar is focused).
570 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
571 "gmapLink"
572 };
573
[email protected]fc2e0872009-08-21 22:14:41574 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
575
[email protected]9e0c83a2009-05-06 19:44:37576 // Test forward focus traversal.
577 for (int i = 0; i < 2; ++i) {
578 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41579 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37580
581 // Now let's press tab to move the focus.
[email protected]130efb02009-09-18 18:54:35582 for (size_t j = 0; j < 7; ++j) {
[email protected]9e0c83a2009-05-06 19:44:37583 // Let's make sure the focus is on the expected element in the page.
584 std::string actual = interstitial_page->GetFocusedElement();
585 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
586
[email protected]130efb02009-09-18 18:54:35587 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
588 false, false, false));
589
590 if (j < arraysize(kExpElementIDs) - 1) {
591 interstitial_page->WaitForFocusChange();
592 } else {
593 // On the last tab key press, the focus returns to the browser.
594 ui_test_utils::WaitForFocusInBrowser(browser());
595 }
[email protected]9e0c83a2009-05-06 19:44:37596 }
597
598 // At this point the renderer has sent us a message asking to advance the
599 // focus (as the end of the focus loop was reached in the renderer).
600 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35601 MessageLoop::current()->RunAllPending();
[email protected]9e0c83a2009-05-06 19:44:37602 }
603
604 // Now let's try reverse focus traversal.
605 for (int i = 0; i < 2; ++i) {
606 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41607 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37608
609 // Now let's press shift-tab to move the focus in reverse.
[email protected]130efb02009-09-18 18:54:35610 for (size_t j = 0; j < 7; ++j) {
611 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
612 false, true, false));
613
614 if (j < arraysize(kExpElementIDs) - 1) {
615 interstitial_page->WaitForFocusChange();
616 } else {
617 // On the last tab key press, the focus returns to the browser.
618 ui_test_utils::WaitForFocusInBrowser(browser());
619 }
[email protected]9e0c83a2009-05-06 19:44:37620
621 // Let's make sure the focus is on the expected element in the page.
622 std::string actual = interstitial_page->GetFocusedElement();
623 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
624 }
625
626 // At this point the renderer has sent us a message asking to advance the
627 // focus (as the end of the focus loop was reached in the renderer).
628 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35629 MessageLoop::current()->RunAllPending();
[email protected]9e0c83a2009-05-06 19:44:37630 }
631}
632
633// Focus stays on page with interstitials.
634IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
635 HTTPTestServer* server = StartHTTPServer();
636
637 // First we navigate to our test page.
638 GURL url = server->TestServerPageW(kSimplePage);
639 ui_test_utils::NavigateToURL(browser(), url);
640
[email protected]9e0c83a2009-05-06 19:44:37641 // Page should have focus.
[email protected]fc2e0872009-08-21 22:14:41642 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37643 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
644 HasFocus());
645
[email protected]9d8a4642009-07-29 17:25:30646 // Let's show an interstitial.
[email protected]9e0c83a2009-05-06 19:44:37647 TestInterstitialPage* interstitial_page =
648 new TestInterstitialPage(browser()->GetSelectedTabContents(),
649 true, GURL("http://interstitial.com"));
650 interstitial_page->Show();
651 // Give some time for the interstitial to show.
652 MessageLoop::current()->PostDelayedTask(FROM_HERE,
653 new MessageLoop::QuitTask(),
654 1000);
655 ui_test_utils::RunMessageLoop();
656
657 // The interstitial should have focus now.
[email protected]fc2e0872009-08-21 22:14:41658 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37659 EXPECT_TRUE(interstitial_page->HasFocus());
660
661 // Hide the interstitial.
662 interstitial_page->DontProceed();
663
664 // Focus should be back on the original page.
[email protected]fc2e0872009-08-21 22:14:41665 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37666}
667
[email protected]9bd491ee2008-12-10 22:31:07668// Make sure Find box can request focus, even when it is already open.
[email protected]8bcdec92009-02-25 16:15:18669IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
670 HTTPTestServer* server = StartHTTPServer();
license.botbf09a502008-08-24 00:55:55671
[email protected]9bd491ee2008-12-10 22:31:07672 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27673 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18674 ui_test_utils::NavigateToURL(browser(), url);
[email protected]9bd491ee2008-12-10 22:31:07675
[email protected]fc2e0872009-08-21 22:14:41676 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
[email protected]9bd491ee2008-12-10 22:31:07677
678 // Press Ctrl+F, which will make the Find box open and request focus.
[email protected]fc2e0872009-08-21 22:14:41679 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21680 false, false,
[email protected]8bcdec92009-02-25 16:15:18681 new MessageLoop::QuitTask());
682 ui_test_utils::RunMessageLoop();
683
684 // Ideally, we wouldn't sleep here and instead would intercept the
685 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we
686 // could create a RenderViewHostDelegate wrapper and hook-it up by either:
687 // - creating a factory used to create the delegate
688 // - making the test a private and overwriting the delegate member directly.
[email protected]fc2e0872009-08-21 22:14:41689 MessageLoop::current()->PostDelayedTask(
690 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18691 ui_test_utils::RunMessageLoop();
692
[email protected]fc2e0872009-08-21 22:14:41693 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07694
[email protected]fc2e0872009-08-21 22:14:41695 browser()->FocusLocationBar();
696 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9bd491ee2008-12-10 22:31:07697
698 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41699 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21700 false, false,
[email protected]8bcdec92009-02-25 16:15:18701 new MessageLoop::QuitTask());
702 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41703 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07704
705 // Set focus to the page.
[email protected]fc2e0872009-08-21 22:14:41706 ClickOnView(VIEW_ID_TAB_CONTAINER);
707 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9bd491ee2008-12-10 22:31:07708
709 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41710 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true, false,
[email protected]22cdd932009-08-18 02:16:21711 false, new MessageLoop::QuitTask());
[email protected]8bcdec92009-02-25 16:15:18712 ui_test_utils::RunMessageLoop();
713
714 // See remark above on why we wait.
[email protected]fc2e0872009-08-21 22:14:41715 MessageLoop::current()->PostDelayedTask(
716 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18717 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41718 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07719}
[email protected]401513c2009-03-12 00:21:28720
721// Makes sure the focus is in the right location when opening the different
722// types of tabs.
[email protected]186f13f2009-08-19 20:34:00723IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
[email protected]401513c2009-03-12 00:21:28724 // Open the history tab, focus should be on the tab contents.
725 browser()->ShowHistoryTab();
[email protected]186f13f2009-08-19 20:34:00726 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]401513c2009-03-12 00:21:28727
728 // Open the new tab, focus should be on the location bar.
729 browser()->NewTab();
[email protected]b9821882009-08-17 22:25:17730 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28731
732 // Open the download tab, focus should be on the tab contents.
733 browser()->ShowDownloadsTab();
[email protected]186f13f2009-08-19 20:34:00734 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]3e3f0eb2009-06-22 18:33:43735
736 // Open about:blank, focus should be on the location bar.
737 browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK,
738 true, -1, false, NULL);
[email protected]b9821882009-08-17 22:25:17739 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28740}
[email protected]9d8a4642009-07-29 17:25:30741
742// Tests that focus goes where expected when using reload.
743IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {
744 HTTPTestServer* server = StartHTTPServer();
745
[email protected]9d8a4642009-07-29 17:25:30746 // Open the new tab, reload.
747 browser()->NewTab();
[email protected]b7a20d32009-08-15 00:02:40748 browser()->Reload();
749 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30750 // Focus should stay on the location bar.
[email protected]fc2e0872009-08-21 22:14:41751 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9d8a4642009-07-29 17:25:30752
753 // Open a regular page, focus the location bar, reload.
754 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
[email protected]fc2e0872009-08-21 22:14:41755 browser()->FocusLocationBar();
756 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]b7a20d32009-08-15 00:02:40757 browser()->Reload();
758 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30759 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41760 browser()->ShowDownloadsTab();
761 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30762}
763
764// Tests that focus goes where expected when using reload on a crashed tab.
765IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReloadCrashedTab) {
766 HTTPTestServer* server = StartHTTPServer();
767
[email protected]9d8a4642009-07-29 17:25:30768 // Open a regular page, crash, reload.
769 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
770 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]b7a20d32009-08-15 00:02:40771 browser()->Reload();
772 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30773 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41774 browser()->ShowDownloadsTab();
775 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30776}