blob: 673b578aa893867a378457b5dba2d1d71cb53551 [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.
[email protected]d6b3b4e2009-10-02 21:56:53348// TODO(jcampan): http://crbug.com/23683 Disabled because it fails on Linux.
349IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabsRememberFocusFindInPage) {
[email protected]ae40b572009-10-02 21:17:45350 HTTPTestServer* server = StartHTTPServer();
351
352 // First we navigate to our test page.
353 GURL url = server->TestServerPageW(kSimplePage);
354 ui_test_utils::NavigateToURL(browser(), url);
355
356 browser()->Find();
357 ui_test_utils::FindInPage(browser()->GetSelectedTabContents(),
358 ASCIIToUTF16("a"), true, false, NULL);
359 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
360
361 // Focus the location bar.
362 browser()->FocusLocationBar();
363
364 // Create a 2nd tab.
365 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
366 false, NULL);
367
368 // Focus should be on the recently opened tab page.
369 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
370
371 // Select 1st tab, focus should still be on the location-bar.
372 // (bug http://crbug.com/23296)
373 browser()->SelectTabContentsAt(0, true);
374 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
375
376 // Now open the find box again, switch to another tab and come back, the focus
377 // should return to the find box.
378 browser()->Find();
379 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
380 browser()->SelectTabContentsAt(1, true);
381 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
382 browser()->SelectTabContentsAt(0, true);
383 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
384}
385
initial.commit09911bf2008-07-26 23:55:29386// Background window does not steal focus.
[email protected]042d43e2009-07-23 16:31:45387IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
[email protected]8bcdec92009-02-25 16:15:18388 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29389
390 // First we navigate to our test page.
[email protected]8bcdec92009-02-25 16:15:18391 GURL url = server->TestServerPageW(kSimplePage);
392 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29393
394 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18395 Browser* browser2 = Browser::Create(browser()->profile());
396 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43397 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18398 browser2->window()->Show();
[email protected]186f13f2009-08-19 20:34:00399
[email protected]ed179ee2009-10-03 21:02:51400 Browser* focused_browser = NULL;
401 Browser* unfocused_browser = NULL;
[email protected]186f13f2009-08-19 20:34:00402#if defined(OS_LINUX)
403 // On Linux, calling Activate() is not guaranteed to move focus, so we have
404 // to figure out which browser does have focus.
405 if (browser2->window()->IsActive()) {
406 focused_browser = browser2;
407 unfocused_browser = browser();
408 } else if (browser()->window()->IsActive()) {
409 focused_browser = browser();
410 unfocused_browser = browser2;
411 } else {
412 ASSERT_TRUE(false);
413 }
414#elif defined(OS_WIN)
415 focused_browser = browser();
416 unfocused_browser = browser2;
417#endif
418
[email protected]1e187af2009-02-25 02:02:46419 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
[email protected]186f13f2009-08-19 20:34:00420 ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url);
[email protected]1e187af2009-02-25 02:02:46421
[email protected]8bcdec92009-02-25 16:15:18422 // Activate the first browser.
[email protected]186f13f2009-08-19 20:34:00423 focused_browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:29424
425 // Wait for the focus to be stolen by the other browser.
[email protected]186f13f2009-08-19 20:34:00426 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29427
[email protected]8bcdec92009-02-25 16:15:18428 // Make sure the first browser is still active.
[email protected]186f13f2009-08-19 20:34:00429 EXPECT_TRUE(focused_browser->window()->IsActive());
[email protected]8bcdec92009-02-25 16:15:18430
431 // Close the 2nd browser to avoid a DCHECK().
[email protected]186f13f2009-08-19 20:34:00432 browser2->window()->Close();
initial.commit09911bf2008-07-26 23:55:29433}
434
435// Page cannot steal focus when focus is on location bar.
[email protected]8bcdec92009-02-25 16:15:18436IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
437 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29438
439 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27440 GURL url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18441 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29442
[email protected]186f13f2009-08-19 20:34:00443 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29444
445 // Wait for the page to steal focus.
[email protected]186f13f2009-08-19 20:34:00446 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29447
448 // Make sure the location bar is still focused.
[email protected]186f13f2009-08-19 20:34:00449 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29450}
451
[email protected]9e0c83a2009-05-06 19:44:37452// Focus traversal on a regular page.
[email protected]130efb02009-09-18 18:54:35453// Note that this test relies on a notification from the renderer that the
454// focus has changed in the page. The notification in the renderer may change
455// at which point this test would fail (see comment in
456// RenderWidget::didFocus()).
[email protected]8bcdec92009-02-25 16:15:18457IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
458 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29459
[email protected]8bcdec92009-02-25 16:15:18460 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27461 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18462 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29463
[email protected]186f13f2009-08-19 20:34:00464 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29465
[email protected]8bcdec92009-02-25 16:15:18466 const char* kExpElementIDs[] = {
467 "", // Initially no element in the page should be focused
468 // (the location bar is focused).
469 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
470 "gmapLink"
initial.commit09911bf2008-07-26 23:55:29471 };
472
[email protected]186f13f2009-08-19 20:34:00473 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
474
initial.commit09911bf2008-07-26 23:55:29475 // Test forward focus traversal.
476 for (int i = 0; i < 3; ++i) {
477 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00478 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29479
480 // Now let's press tab to move the focus.
[email protected]130efb02009-09-18 18:54:35481 for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) {
initial.commit09911bf2008-07-26 23:55:29482 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01483 std::string actual;
484 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25485 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18486 L"",
[email protected]45671612009-04-29 22:24:01487 L"window.domAutomationController.send(getFocusedElement());",
488 &actual));
initial.commit09911bf2008-07-26 23:55:29489 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
490
[email protected]130efb02009-09-18 18:54:35491 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
492 false, false, false));
493
494 if (j < arraysize(kExpElementIDs) - 1) {
495 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
496 render_view_host());
497 } else {
498 // On the last tab key press, the focus returns to the browser.
499 ui_test_utils::WaitForFocusInBrowser(browser());
500 }
initial.commit09911bf2008-07-26 23:55:29501 }
[email protected]8bcdec92009-02-25 16:15:18502
503 // At this point the renderer has sent us a message asking to advance the
504 // focus (as the end of the focus loop was reached in the renderer).
505 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35506 MessageLoop::current()->RunAllPending();
initial.commit09911bf2008-07-26 23:55:29507 }
508
509 // Now let's try reverse focus traversal.
510 for (int i = 0; i < 3; ++i) {
511 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00512 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29513
[email protected]8bcdec92009-02-25 16:15:18514 // Now let's press shift-tab to move the focus in reverse.
[email protected]130efb02009-09-18 18:54:35515 for (size_t j = 0; j < 7; ++j) {
516 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
517 false, true, false));
518
519 if (j < arraysize(kExpElementIDs) - 1) {
520 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
521 render_view_host());
522 } else {
523 // On the last tab key press, the focus returns to the browser.
524 ui_test_utils::WaitForFocusInBrowser(browser());
525 }
initial.commit09911bf2008-07-26 23:55:29526
527 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01528 std::string actual;
529 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25530 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18531 L"",
[email protected]45671612009-04-29 22:24:01532 L"window.domAutomationController.send(getFocusedElement());",
533 &actual));
initial.commit09911bf2008-07-26 23:55:29534 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
535 }
[email protected]8bcdec92009-02-25 16:15:18536
537 // At this point the renderer has sent us a message asking to advance the
538 // focus (as the end of the focus loop was reached in the renderer).
539 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35540 MessageLoop::current()->RunAllPending();
initial.commit09911bf2008-07-26 23:55:29541 }
542}
543
[email protected]9e0c83a2009-05-06 19:44:37544// Focus traversal while an interstitial is showing.
[email protected]fc2e0872009-08-21 22:14:41545IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) {
[email protected]9e0c83a2009-05-06 19:44:37546 HTTPTestServer* server = StartHTTPServer();
547
548 // First we navigate to our test page.
549 GURL url = server->TestServerPageW(kSimplePage);
550 ui_test_utils::NavigateToURL(browser(), url);
551
[email protected]9e0c83a2009-05-06 19:44:37552 // Focus should be on the page.
[email protected]fc2e0872009-08-21 22:14:41553 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37554
555 // Let's show an interstitial.
556 TestInterstitialPage* interstitial_page =
557 new TestInterstitialPage(browser()->GetSelectedTabContents(),
558 true, GURL("http://interstitial.com"));
559 interstitial_page->Show();
560 // Give some time for the interstitial to show.
561 MessageLoop::current()->PostDelayedTask(FROM_HERE,
562 new MessageLoop::QuitTask(),
563 1000);
564 ui_test_utils::RunMessageLoop();
565
[email protected]fc2e0872009-08-21 22:14:41566 browser()->FocusLocationBar();
[email protected]9e0c83a2009-05-06 19:44:37567
568 const char* kExpElementIDs[] = {
569 "", // Initially no element in the page should be focused
570 // (the location bar is focused).
571 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
572 "gmapLink"
573 };
574
[email protected]fc2e0872009-08-21 22:14:41575 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
576
[email protected]9e0c83a2009-05-06 19:44:37577 // Test forward focus traversal.
578 for (int i = 0; i < 2; ++i) {
579 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41580 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37581
582 // Now let's press tab to move the focus.
[email protected]130efb02009-09-18 18:54:35583 for (size_t j = 0; j < 7; ++j) {
[email protected]9e0c83a2009-05-06 19:44:37584 // Let's make sure the focus is on the expected element in the page.
585 std::string actual = interstitial_page->GetFocusedElement();
586 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
587
[email protected]130efb02009-09-18 18:54:35588 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
589 false, false, false));
590
591 if (j < arraysize(kExpElementIDs) - 1) {
592 interstitial_page->WaitForFocusChange();
593 } else {
594 // On the last tab key press, the focus returns to the browser.
595 ui_test_utils::WaitForFocusInBrowser(browser());
596 }
[email protected]9e0c83a2009-05-06 19:44:37597 }
598
599 // At this point the renderer has sent us a message asking to advance the
600 // focus (as the end of the focus loop was reached in the renderer).
601 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35602 MessageLoop::current()->RunAllPending();
[email protected]9e0c83a2009-05-06 19:44:37603 }
604
605 // Now let's try reverse focus traversal.
606 for (int i = 0; i < 2; ++i) {
607 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41608 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37609
610 // Now let's press shift-tab to move the focus in reverse.
[email protected]130efb02009-09-18 18:54:35611 for (size_t j = 0; j < 7; ++j) {
612 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
613 false, true, false));
614
615 if (j < arraysize(kExpElementIDs) - 1) {
616 interstitial_page->WaitForFocusChange();
617 } else {
618 // On the last tab key press, the focus returns to the browser.
619 ui_test_utils::WaitForFocusInBrowser(browser());
620 }
[email protected]9e0c83a2009-05-06 19:44:37621
622 // Let's make sure the focus is on the expected element in the page.
623 std::string actual = interstitial_page->GetFocusedElement();
624 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
625 }
626
627 // At this point the renderer has sent us a message asking to advance the
628 // focus (as the end of the focus loop was reached in the renderer).
629 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35630 MessageLoop::current()->RunAllPending();
[email protected]9e0c83a2009-05-06 19:44:37631 }
632}
633
634// Focus stays on page with interstitials.
635IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
636 HTTPTestServer* server = StartHTTPServer();
637
638 // First we navigate to our test page.
639 GURL url = server->TestServerPageW(kSimplePage);
640 ui_test_utils::NavigateToURL(browser(), url);
641
[email protected]9e0c83a2009-05-06 19:44:37642 // Page should have focus.
[email protected]fc2e0872009-08-21 22:14:41643 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37644 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
645 HasFocus());
646
[email protected]9d8a4642009-07-29 17:25:30647 // Let's show an interstitial.
[email protected]9e0c83a2009-05-06 19:44:37648 TestInterstitialPage* interstitial_page =
649 new TestInterstitialPage(browser()->GetSelectedTabContents(),
650 true, GURL("http://interstitial.com"));
651 interstitial_page->Show();
652 // Give some time for the interstitial to show.
653 MessageLoop::current()->PostDelayedTask(FROM_HERE,
654 new MessageLoop::QuitTask(),
655 1000);
656 ui_test_utils::RunMessageLoop();
657
658 // The interstitial should have focus now.
[email protected]fc2e0872009-08-21 22:14:41659 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37660 EXPECT_TRUE(interstitial_page->HasFocus());
661
662 // Hide the interstitial.
663 interstitial_page->DontProceed();
664
665 // Focus should be back on the original page.
[email protected]fc2e0872009-08-21 22:14:41666 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37667}
668
[email protected]9bd491ee2008-12-10 22:31:07669// Make sure Find box can request focus, even when it is already open.
[email protected]8bcdec92009-02-25 16:15:18670IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
671 HTTPTestServer* server = StartHTTPServer();
license.botbf09a502008-08-24 00:55:55672
[email protected]9bd491ee2008-12-10 22:31:07673 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27674 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18675 ui_test_utils::NavigateToURL(browser(), url);
[email protected]9bd491ee2008-12-10 22:31:07676
[email protected]fc2e0872009-08-21 22:14:41677 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
[email protected]9bd491ee2008-12-10 22:31:07678
679 // Press Ctrl+F, which will make the Find box open and request focus.
[email protected]fc2e0872009-08-21 22:14:41680 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21681 false, false,
[email protected]8bcdec92009-02-25 16:15:18682 new MessageLoop::QuitTask());
683 ui_test_utils::RunMessageLoop();
684
685 // Ideally, we wouldn't sleep here and instead would intercept the
686 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we
687 // could create a RenderViewHostDelegate wrapper and hook-it up by either:
688 // - creating a factory used to create the delegate
689 // - making the test a private and overwriting the delegate member directly.
[email protected]fc2e0872009-08-21 22:14:41690 MessageLoop::current()->PostDelayedTask(
691 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18692 ui_test_utils::RunMessageLoop();
693
[email protected]fc2e0872009-08-21 22:14:41694 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07695
[email protected]fc2e0872009-08-21 22:14:41696 browser()->FocusLocationBar();
697 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9bd491ee2008-12-10 22:31:07698
699 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41700 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21701 false, false,
[email protected]8bcdec92009-02-25 16:15:18702 new MessageLoop::QuitTask());
703 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41704 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07705
706 // Set focus to the page.
[email protected]fc2e0872009-08-21 22:14:41707 ClickOnView(VIEW_ID_TAB_CONTAINER);
708 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9bd491ee2008-12-10 22:31:07709
710 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41711 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true, false,
[email protected]22cdd932009-08-18 02:16:21712 false, new MessageLoop::QuitTask());
[email protected]8bcdec92009-02-25 16:15:18713 ui_test_utils::RunMessageLoop();
714
715 // See remark above on why we wait.
[email protected]fc2e0872009-08-21 22:14:41716 MessageLoop::current()->PostDelayedTask(
717 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18718 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41719 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07720}
[email protected]401513c2009-03-12 00:21:28721
722// Makes sure the focus is in the right location when opening the different
723// types of tabs.
[email protected]186f13f2009-08-19 20:34:00724IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
[email protected]401513c2009-03-12 00:21:28725 // Open the history tab, focus should be on the tab contents.
726 browser()->ShowHistoryTab();
[email protected]186f13f2009-08-19 20:34:00727 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]401513c2009-03-12 00:21:28728
729 // Open the new tab, focus should be on the location bar.
730 browser()->NewTab();
[email protected]b9821882009-08-17 22:25:17731 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28732
733 // Open the download tab, focus should be on the tab contents.
734 browser()->ShowDownloadsTab();
[email protected]186f13f2009-08-19 20:34:00735 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]3e3f0eb2009-06-22 18:33:43736
737 // Open about:blank, focus should be on the location bar.
738 browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK,
739 true, -1, false, NULL);
[email protected]b9821882009-08-17 22:25:17740 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28741}
[email protected]9d8a4642009-07-29 17:25:30742
743// Tests that focus goes where expected when using reload.
744IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {
745 HTTPTestServer* server = StartHTTPServer();
746
[email protected]9d8a4642009-07-29 17:25:30747 // Open the new tab, reload.
748 browser()->NewTab();
[email protected]b7a20d32009-08-15 00:02:40749 browser()->Reload();
750 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30751 // Focus should stay on the location bar.
[email protected]fc2e0872009-08-21 22:14:41752 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9d8a4642009-07-29 17:25:30753
754 // Open a regular page, focus the location bar, reload.
755 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
[email protected]fc2e0872009-08-21 22:14:41756 browser()->FocusLocationBar();
757 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]b7a20d32009-08-15 00:02:40758 browser()->Reload();
759 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30760 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41761 browser()->ShowDownloadsTab();
762 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30763}
764
765// Tests that focus goes where expected when using reload on a crashed tab.
766IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReloadCrashedTab) {
767 HTTPTestServer* server = StartHTTPServer();
768
[email protected]9d8a4642009-07-29 17:25:30769 // Open a regular page, crash, reload.
770 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
771 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]b7a20d32009-08-15 00:02:40772 browser()->Reload();
773 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30774 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41775 browser()->ShowDownloadsTab();
776 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30777}