blob: df25ba457a9d7e5547dc726028850bd7a306438f [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]d9fde8d2009-10-08 19:59:305#include "build/build_config.h"
6
[email protected]8bcdec92009-02-25 16:15:187#include "base/message_loop.h"
[email protected]ece3c8b2009-03-27 16:55:398#include "base/ref_counted.h"
[email protected]8bcdec92009-02-25 16:15:189#include "chrome/browser/automation/ui_controls.h"
10#include "chrome/browser/browser.h"
[email protected]134c47b92009-08-19 03:33:4411#include "chrome/browser/browser_window.h"
12#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]9e0c83a2009-05-06 19:44:3713#include "chrome/browser/renderer_host/render_widget_host_view.h"
14#include "chrome/browser/tab_contents/interstitial_page.h"
[email protected]186f13f2009-08-19 20:34:0015#include "chrome/browser/tab_contents/tab_contents.h"
16#include "chrome/browser/tab_contents/tab_contents_view.h"
initial.commit09911bf2008-07-26 23:55:2917#include "chrome/browser/view_ids.h"
[email protected]9e0c83a2009-05-06 19:44:3718#include "chrome/common/chrome_paths.h"
[email protected]8bcdec92009-02-25 16:15:1819#include "chrome/test/in_process_browser_test.h"
20#include "chrome/test/ui_test_utils.h"
[email protected]2362e4f2009-05-08 00:34:0521#include "views/focus/focus_manager.h"
22#include "views/view.h"
23#include "views/window/window.h"
initial.commit09911bf2008-07-26 23:55:2924
[email protected]134c47b92009-08-19 03:33:4425#if defined(TOOLKIT_VIEWS)
26#include "chrome/browser/views/frame/browser_view.h"
27#include "chrome/browser/views/location_bar_view.h"
28#include "chrome/browser/views/tab_contents/tab_contents_container.h"
29#endif
30
[email protected]b9821882009-08-17 22:25:1731#if defined(OS_LINUX)
32#include "chrome/browser/gtk/view_id_util.h"
33#endif
34
[email protected]fc2e0872009-08-21 22:14:4135#if defined(OS_LINUX)
36// For some reason we hit an external DNS lookup in this test in Linux but not
37// on Windows. TODO(estade): investigate.
38#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial
39#else
40#define MAYBE_FocusTraversalOnInterstitial FocusTraversalOnInterstitial
41#endif
42
initial.commit09911bf2008-07-26 23:55:2943namespace {
44
[email protected]8bcdec92009-02-25 16:15:1845// The delay waited in some cases where we don't have a notifications for an
46// action we take.
initial.commit09911bf2008-07-26 23:55:2947const int kActionDelayMs = 500;
48
initial.commit09911bf2008-07-26 23:55:2949const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html";
50const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html";
51const wchar_t kTypicalPage[] = L"files/focus/typical_page.html";
[email protected]b65de8b92009-09-14 19:36:3152const char kTypicalPageName[] = "typical_page.html";
initial.commit09911bf2008-07-26 23:55:2953
[email protected]8bcdec92009-02-25 16:15:1854class BrowserFocusTest : public InProcessBrowserTest {
initial.commit09911bf2008-07-26 23:55:2955 public:
56 BrowserFocusTest() {
[email protected]8bcdec92009-02-25 16:15:1857 set_show_window(true);
58 EnableDOMAutomation();
initial.commit09911bf2008-07-26 23:55:2959 }
[email protected]b9821882009-08-17 22:25:1760
61 void CheckViewHasFocus(ViewID vid) {
62 BrowserWindow* browser_window = browser()->window();
63 ASSERT_TRUE(browser_window);
64 gfx::NativeWindow window = browser_window->GetNativeHandle();
65 ASSERT_TRUE(window);
66#if defined(OS_WIN)
67 views::FocusManager* focus_manager =
68 views::FocusManager::GetFocusManagerForNativeView(window);
69 ASSERT_TRUE(focus_manager);
[email protected]fc2e0872009-08-21 22:14:4170 EXPECT_EQ(vid, focus_manager->GetFocusedView()->GetID()) <<
71 "For view id " << vid;
[email protected]b9821882009-08-17 22:25:1772#elif defined(OS_LINUX)
73 GtkWidget* widget = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid);
74 ASSERT_TRUE(widget);
[email protected]fc2e0872009-08-21 22:14:4175 EXPECT_TRUE(WidgetInFocusChain(GTK_WIDGET(window), widget)) <<
76 "For view id " << vid;
[email protected]b9821882009-08-17 22:25:1777#else
78 NOTIMPLEMENTED();
79#endif
80 }
81
[email protected]fc2e0872009-08-21 22:14:4182 void ClickOnView(ViewID vid) {
83 BrowserWindow* browser_window = browser()->window();
84 ASSERT_TRUE(browser_window);
[email protected]c0cbacb2009-08-26 03:27:2985#if defined(TOOLKIT_VIEWS)
[email protected]fc2e0872009-08-21 22:14:4186 views::View* view =
87 reinterpret_cast<BrowserView*>(browser_window)->GetViewByID(vid);
88#elif defined(OS_LINUX)
89 gfx::NativeWindow window = browser_window->GetNativeHandle();
90 ASSERT_TRUE(window);
91 GtkWidget* view = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid);
92#endif
93 ASSERT_TRUE(view);
94 ui_controls::MoveMouseToCenterAndPress(
95 view,
96 ui_controls::LEFT,
97 ui_controls::DOWN | ui_controls::UP,
98 new MessageLoop::QuitTask());
99 ui_test_utils::RunMessageLoop();
100 }
101
[email protected]186f13f2009-08-19 20:34:00102 static void HideNativeWindow(gfx::NativeWindow window) {
103#if defined(OS_WIN)
104 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
105 // using Windows API.
106 ::ShowWindow(window, SW_HIDE);
107#elif defined(OS_LINUX)
108 gtk_widget_hide(GTK_WIDGET(window));
109#else
110 NOTIMPLEMENTED();
111#endif
112 }
113
114 static void ShowNativeWindow(gfx::NativeWindow window) {
115#if defined(OS_WIN)
116 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
117 // using Windows API.
118 ::ShowWindow(window, SW_SHOW);
119#elif defined(OS_LINUX)
120 gtk_widget_hide(GTK_WIDGET(window));
121#else
122 NOTIMPLEMENTED();
123#endif
124 }
125
[email protected]b9821882009-08-17 22:25:17126 private:
127#if defined(OS_LINUX)
128 // Check if the focused widget for |root| is |target| or a child of |target|.
129 static bool WidgetInFocusChain(GtkWidget* root, GtkWidget* target) {
130 GtkWidget* iter = root;
131
132 while (iter) {
133 if (iter == target)
134 return true;
135
136 if (!GTK_IS_CONTAINER(iter))
137 return false;
138
139 iter = GTK_CONTAINER(iter)->focus_child;
140 }
141
142 return false;
143 }
144#endif
initial.commit09911bf2008-07-26 23:55:29145};
146
[email protected]9e0c83a2009-05-06 19:44:37147class TestInterstitialPage : public InterstitialPage {
148 public:
149 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
150 : InterstitialPage(tab, new_navigation, url),
[email protected]130efb02009-09-18 18:54:35151 waiting_for_dom_response_(false),
152 waiting_for_focus_change_(false) {
[email protected]b65de8b92009-09-14 19:36:31153 FilePath file_path;
[email protected]9e0c83a2009-05-06 19:44:37154 bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path);
155 EXPECT_TRUE(r);
[email protected]b65de8b92009-09-14 19:36:31156 file_path = file_path.AppendASCII("focus");
157 file_path = file_path.AppendASCII(kTypicalPageName);
[email protected]9e0c83a2009-05-06 19:44:37158 r = file_util::ReadFileToString(file_path, &html_contents_);
159 EXPECT_TRUE(r);
160 }
161
162 virtual std::string GetHTMLContents() {
163 return html_contents_;
164 }
165
166 virtual void DomOperationResponse(const std::string& json_string,
167 int automation_id) {
168 if (waiting_for_dom_response_) {
169 dom_response_ = json_string;
170 waiting_for_dom_response_ = false;
171 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
172 return;
173 }
174 InterstitialPage::DomOperationResponse(json_string, automation_id);
175 }
176
177 std::string GetFocusedElement() {
178 std::wstring script = L"window.domAutomationController.setAutomationId(0);"
179 L"window.domAutomationController.send(getFocusedElement());";
180
181 render_view_host()->ExecuteJavascriptInWebFrame(L"", script);
182 DCHECK(!waiting_for_dom_response_);
183 waiting_for_dom_response_ = true;
184 ui_test_utils::RunMessageLoop();
185 // Remove the JSON extra quotes.
186 if (dom_response_.size() >= 2 && dom_response_[0] == '"' &&
187 dom_response_[dom_response_.size() - 1] == '"') {
188 dom_response_ = dom_response_.substr(1, dom_response_.size() - 2);
189 }
190 return dom_response_;
191 }
192
193 bool HasFocus() {
194 return render_view_host()->view()->HasFocus();
195 }
196
[email protected]130efb02009-09-18 18:54:35197 void WaitForFocusChange() {
198 waiting_for_focus_change_ = true;
199 ui_test_utils::RunMessageLoop();
200 }
201
202 protected:
203 virtual void FocusedNodeChanged() {
204 if (!waiting_for_focus_change_)
205 return;
206
207 waiting_for_focus_change_= false;
208 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
209 }
210
[email protected]9e0c83a2009-05-06 19:44:37211 private:
212 std::string html_contents_;
213
214 bool waiting_for_dom_response_;
[email protected]130efb02009-09-18 18:54:35215 bool waiting_for_focus_change_;
[email protected]9e0c83a2009-05-06 19:44:37216 std::string dom_response_;
217
218};
[email protected]b9821882009-08-17 22:25:17219
initial.commit09911bf2008-07-26 23:55:29220} // namespace
221
[email protected]d9fde8d2009-10-08 19:59:30222
223#if defined(OS_WIN)
224#define MAYBE_ClickingMovesFocus DISABLED_ClickingMovesFocus
225#else
226#define MAYBE_ClickingMovesFocus ClickingMovesFocus
227#endif // defined(OS_WIN)
228
229IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_ClickingMovesFocus) {
[email protected]fc2e0872009-08-21 22:14:41230#if defined(OS_LINUX)
231 // It seems we have to wait a little bit for the widgets to spin up before
232 // we can start clicking on them.
233 MessageLoop::current()->PostDelayedTask(FROM_HERE,
234 new MessageLoop::QuitTask(),
235 kActionDelayMs);
236 ui_test_utils::RunMessageLoop();
237#endif
238
[email protected]186f13f2009-08-19 20:34:00239 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
240
[email protected]fc2e0872009-08-21 22:14:41241 ClickOnView(VIEW_ID_TAB_CONTAINER);
[email protected]186f13f2009-08-19 20:34:00242 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
243
[email protected]fc2e0872009-08-21 22:14:41244 ClickOnView(VIEW_ID_LOCATION_BAR);
[email protected]186f13f2009-08-19 20:34:00245 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
246}
[email protected]186f13f2009-08-19 20:34:00247
[email protected]7e383692009-06-12 19:14:54248IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) {
[email protected]8bcdec92009-02-25 16:15:18249 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29250
251 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27252 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18253 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29254
[email protected]186f13f2009-08-19 20:34:00255 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
256
initial.commit09911bf2008-07-26 23:55:29257 // The focus should be on the Tab contents.
[email protected]186f13f2009-08-19 20:34:00258 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
initial.commit09911bf2008-07-26 23:55:29259 // Now hide the window, show it again, the focus should not have changed.
[email protected]186f13f2009-08-19 20:34:00260 HideNativeWindow(window);
261 ShowNativeWindow(window);
262 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
initial.commit09911bf2008-07-26 23:55:29263
[email protected]186f13f2009-08-19 20:34:00264 browser()->FocusLocationBar();
265 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29266 // Hide the window, show it again, the focus should not have changed.
[email protected]186f13f2009-08-19 20:34:00267 HideNativeWindow(window);
268 ShowNativeWindow(window);
269 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29270
[email protected]186f13f2009-08-19 20:34:00271 // The rest of this test does not make sense on Linux because the behavior
272 // of Activate() is not well defined and can vary by window manager.
273#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29274 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18275 Browser* browser2 = Browser::Create(browser()->profile());
276 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43277 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18278 browser2->window()->Show();
279 ui_test_utils::NavigateToURL(browser2, url);
initial.commit09911bf2008-07-26 23:55:29280
[email protected]8bcdec92009-02-25 16:15:18281 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00282 BrowserView* browser_view2 =
283 BrowserView::GetBrowserViewForNativeWindow(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18284 ASSERT_TRUE(browser_view2);
285 views::FocusManager* focus_manager2 =
[email protected]82166b62009-06-30 18:48:00286 views::FocusManager::GetFocusManagerForNativeView(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18287 ASSERT_TRUE(focus_manager2);
[email protected]7e383692009-06-12 19:14:54288 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38289 focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29290
291 // Switch to the 1st browser window, focus should still be on the location
292 // bar and the second browser should have nothing focused.
[email protected]8bcdec92009-02-25 16:15:18293 browser()->window()->Activate();
[email protected]186f13f2009-08-19 20:34:00294 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]8bcdec92009-02-25 16:15:18295 EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29296
297 // Switch back to the second browser, focus should still be on the page.
[email protected]8bcdec92009-02-25 16:15:18298 browser2->window()->Activate();
[email protected]186f13f2009-08-19 20:34:00299 EXPECT_EQ(NULL,
300 views::FocusManager::GetFocusManagerForNativeView(
301 browser()->window()->GetNativeHandle())->GetFocusedView());
[email protected]7e383692009-06-12 19:14:54302 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38303 focus_manager2->GetFocusedView());
[email protected]8bcdec92009-02-25 16:15:18304
305 // Close the 2nd browser to avoid a DCHECK().
306 browser_view2->Close();
[email protected]186f13f2009-08-19 20:34:00307#endif
initial.commit09911bf2008-07-26 23:55:29308}
309
310// Tabs remember focus.
[email protected]8bcdec92009-02-25 16:15:18311IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
312 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29313
314 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27315 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18316 ui_test_utils::NavigateToURL(browser(), url);
317
initial.commit09911bf2008-07-26 23:55:29318 // Create several tabs.
[email protected]22735af62009-04-07 21:09:58319 for (int i = 0; i < 4; ++i) {
[email protected]82166b62009-06-30 18:48:00320 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
321 false, NULL);
[email protected]22735af62009-04-07 21:09:58322 }
initial.commit09911bf2008-07-26 23:55:29323
324 // Alternate focus for the tab.
325 const bool kFocusPage[3][5] = {
326 { true, true, true, true, false },
327 { false, false, false, false, false },
328 { false, true, false, true, false }
329 };
330
331 for (int i = 1; i < 3; i++) {
332 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18333 // Activate the tab.
334 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29335
336 // Activate the location bar or the page.
[email protected]7e383692009-06-12 19:14:54337 if (kFocusPage[i][j]) {
[email protected]186f13f2009-08-19 20:34:00338 browser()->GetTabContentsAt(j)->view()->Focus();
[email protected]7e383692009-06-12 19:14:54339 } else {
[email protected]186f13f2009-08-19 20:34:00340 browser()->FocusLocationBar();
[email protected]7e383692009-06-12 19:14:54341 }
initial.commit09911bf2008-07-26 23:55:29342 }
343
344 // Now come back to the tab and check the right view is focused.
345 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18346 // Activate the tab.
347 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29348
[email protected]186f13f2009-08-19 20:34:00349 ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
350 VIEW_ID_LOCATION_BAR;
351 CheckViewHasFocus(vid);
initial.commit09911bf2008-07-26 23:55:29352 }
353 }
354}
355
[email protected]ae40b572009-10-02 21:17:45356// Tabs remember focus with find-in-page box.
[email protected]d6b3b4e2009-10-02 21:56:53357// TODO(jcampan): http://crbug.com/23683 Disabled because it fails on Linux.
358IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabsRememberFocusFindInPage) {
[email protected]ae40b572009-10-02 21:17:45359 HTTPTestServer* server = StartHTTPServer();
360
361 // First we navigate to our test page.
362 GURL url = server->TestServerPageW(kSimplePage);
363 ui_test_utils::NavigateToURL(browser(), url);
364
365 browser()->Find();
366 ui_test_utils::FindInPage(browser()->GetSelectedTabContents(),
367 ASCIIToUTF16("a"), true, false, NULL);
368 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
369
370 // Focus the location bar.
371 browser()->FocusLocationBar();
372
373 // Create a 2nd tab.
374 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
375 false, NULL);
376
377 // Focus should be on the recently opened tab page.
378 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
379
380 // Select 1st tab, focus should still be on the location-bar.
381 // (bug http://crbug.com/23296)
382 browser()->SelectTabContentsAt(0, true);
383 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
384
385 // Now open the find box again, switch to another tab and come back, the focus
386 // should return to the find box.
387 browser()->Find();
388 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
389 browser()->SelectTabContentsAt(1, true);
390 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
391 browser()->SelectTabContentsAt(0, true);
392 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
393}
394
initial.commit09911bf2008-07-26 23:55:29395// Background window does not steal focus.
[email protected]042d43e2009-07-23 16:31:45396IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
[email protected]8bcdec92009-02-25 16:15:18397 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29398
399 // First we navigate to our test page.
[email protected]8bcdec92009-02-25 16:15:18400 GURL url = server->TestServerPageW(kSimplePage);
401 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29402
403 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18404 Browser* browser2 = Browser::Create(browser()->profile());
405 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43406 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18407 browser2->window()->Show();
[email protected]186f13f2009-08-19 20:34:00408
[email protected]ed179ee2009-10-03 21:02:51409 Browser* focused_browser = NULL;
410 Browser* unfocused_browser = NULL;
[email protected]186f13f2009-08-19 20:34:00411#if defined(OS_LINUX)
412 // On Linux, calling Activate() is not guaranteed to move focus, so we have
413 // to figure out which browser does have focus.
414 if (browser2->window()->IsActive()) {
415 focused_browser = browser2;
416 unfocused_browser = browser();
417 } else if (browser()->window()->IsActive()) {
418 focused_browser = browser();
419 unfocused_browser = browser2;
420 } else {
421 ASSERT_TRUE(false);
422 }
423#elif defined(OS_WIN)
424 focused_browser = browser();
425 unfocused_browser = browser2;
426#endif
427
[email protected]1e187af2009-02-25 02:02:46428 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
[email protected]186f13f2009-08-19 20:34:00429 ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url);
[email protected]1e187af2009-02-25 02:02:46430
[email protected]8bcdec92009-02-25 16:15:18431 // Activate the first browser.
[email protected]186f13f2009-08-19 20:34:00432 focused_browser->window()->Activate();
initial.commit09911bf2008-07-26 23:55:29433
434 // Wait for the focus to be stolen by the other browser.
[email protected]186f13f2009-08-19 20:34:00435 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29436
[email protected]8bcdec92009-02-25 16:15:18437 // Make sure the first browser is still active.
[email protected]186f13f2009-08-19 20:34:00438 EXPECT_TRUE(focused_browser->window()->IsActive());
[email protected]8bcdec92009-02-25 16:15:18439
440 // Close the 2nd browser to avoid a DCHECK().
[email protected]186f13f2009-08-19 20:34:00441 browser2->window()->Close();
initial.commit09911bf2008-07-26 23:55:29442}
443
444// Page cannot steal focus when focus is on location bar.
[email protected]8bcdec92009-02-25 16:15:18445IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
446 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29447
448 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27449 GURL url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18450 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29451
[email protected]186f13f2009-08-19 20:34:00452 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29453
454 // Wait for the page to steal focus.
[email protected]186f13f2009-08-19 20:34:00455 PlatformThread::Sleep(2000);
initial.commit09911bf2008-07-26 23:55:29456
457 // Make sure the location bar is still focused.
[email protected]186f13f2009-08-19 20:34:00458 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29459}
460
[email protected]9e0c83a2009-05-06 19:44:37461// Focus traversal on a regular page.
[email protected]130efb02009-09-18 18:54:35462// Note that this test relies on a notification from the renderer that the
463// focus has changed in the page. The notification in the renderer may change
464// at which point this test would fail (see comment in
465// RenderWidget::didFocus()).
[email protected]8bcdec92009-02-25 16:15:18466IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
467 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29468
[email protected]8bcdec92009-02-25 16:15:18469 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27470 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18471 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29472
[email protected]186f13f2009-08-19 20:34:00473 browser()->FocusLocationBar();
initial.commit09911bf2008-07-26 23:55:29474
[email protected]8bcdec92009-02-25 16:15:18475 const char* kExpElementIDs[] = {
476 "", // Initially no element in the page should be focused
477 // (the location bar is focused).
478 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
479 "gmapLink"
initial.commit09911bf2008-07-26 23:55:29480 };
481
[email protected]186f13f2009-08-19 20:34:00482 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
483
initial.commit09911bf2008-07-26 23:55:29484 // Test forward focus traversal.
485 for (int i = 0; i < 3; ++i) {
486 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00487 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29488
489 // Now let's press tab to move the focus.
[email protected]130efb02009-09-18 18:54:35490 for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) {
initial.commit09911bf2008-07-26 23:55:29491 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01492 std::string actual;
493 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25494 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18495 L"",
[email protected]45671612009-04-29 22:24:01496 L"window.domAutomationController.send(getFocusedElement());",
497 &actual));
initial.commit09911bf2008-07-26 23:55:29498 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
499
[email protected]130efb02009-09-18 18:54:35500 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
501 false, false, false));
502
503 if (j < arraysize(kExpElementIDs) - 1) {
504 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
505 render_view_host());
506 } else {
507 // On the last tab key press, the focus returns to the browser.
508 ui_test_utils::WaitForFocusInBrowser(browser());
509 }
initial.commit09911bf2008-07-26 23:55:29510 }
[email protected]8bcdec92009-02-25 16:15:18511
512 // At this point the renderer has sent us a message asking to advance the
513 // focus (as the end of the focus loop was reached in the renderer).
514 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35515 MessageLoop::current()->RunAllPending();
initial.commit09911bf2008-07-26 23:55:29516 }
517
518 // Now let's try reverse focus traversal.
519 for (int i = 0; i < 3; ++i) {
520 // Location bar should be focused.
[email protected]186f13f2009-08-19 20:34:00521 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
initial.commit09911bf2008-07-26 23:55:29522
[email protected]8bcdec92009-02-25 16:15:18523 // Now let's press shift-tab to move the focus in reverse.
[email protected]130efb02009-09-18 18:54:35524 for (size_t j = 0; j < 7; ++j) {
525 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
526 false, true, false));
527
528 if (j < arraysize(kExpElementIDs) - 1) {
529 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()->
530 render_view_host());
531 } else {
532 // On the last tab key press, the focus returns to the browser.
533 ui_test_utils::WaitForFocusInBrowser(browser());
534 }
initial.commit09911bf2008-07-26 23:55:29535
536 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01537 std::string actual;
538 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]17c4f3c2009-07-04 16:36:25539 browser()->GetSelectedTabContents()->render_view_host(),
[email protected]8bcdec92009-02-25 16:15:18540 L"",
[email protected]45671612009-04-29 22:24:01541 L"window.domAutomationController.send(getFocusedElement());",
542 &actual));
initial.commit09911bf2008-07-26 23:55:29543 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
544 }
[email protected]8bcdec92009-02-25 16:15:18545
546 // At this point the renderer has sent us a message asking to advance the
547 // focus (as the end of the focus loop was reached in the renderer).
548 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35549 MessageLoop::current()->RunAllPending();
initial.commit09911bf2008-07-26 23:55:29550 }
551}
552
[email protected]9e0c83a2009-05-06 19:44:37553// Focus traversal while an interstitial is showing.
[email protected]fc2e0872009-08-21 22:14:41554IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) {
[email protected]9e0c83a2009-05-06 19:44:37555 HTTPTestServer* server = StartHTTPServer();
556
557 // First we navigate to our test page.
558 GURL url = server->TestServerPageW(kSimplePage);
559 ui_test_utils::NavigateToURL(browser(), url);
560
[email protected]9e0c83a2009-05-06 19:44:37561 // Focus should be on the page.
[email protected]fc2e0872009-08-21 22:14:41562 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37563
564 // Let's show an interstitial.
565 TestInterstitialPage* interstitial_page =
566 new TestInterstitialPage(browser()->GetSelectedTabContents(),
567 true, GURL("http://interstitial.com"));
568 interstitial_page->Show();
569 // Give some time for the interstitial to show.
570 MessageLoop::current()->PostDelayedTask(FROM_HERE,
571 new MessageLoop::QuitTask(),
572 1000);
573 ui_test_utils::RunMessageLoop();
574
[email protected]fc2e0872009-08-21 22:14:41575 browser()->FocusLocationBar();
[email protected]9e0c83a2009-05-06 19:44:37576
577 const char* kExpElementIDs[] = {
578 "", // Initially no element in the page should be focused
579 // (the location bar is focused).
580 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
581 "gmapLink"
582 };
583
[email protected]fc2e0872009-08-21 22:14:41584 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
585
[email protected]9e0c83a2009-05-06 19:44:37586 // Test forward focus traversal.
587 for (int i = 0; i < 2; ++i) {
588 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41589 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37590
591 // Now let's press tab to move the focus.
[email protected]130efb02009-09-18 18:54:35592 for (size_t j = 0; j < 7; ++j) {
[email protected]9e0c83a2009-05-06 19:44:37593 // Let's make sure the focus is on the expected element in the page.
594 std::string actual = interstitial_page->GetFocusedElement();
595 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
596
[email protected]130efb02009-09-18 18:54:35597 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
598 false, false, false));
599
600 if (j < arraysize(kExpElementIDs) - 1) {
601 interstitial_page->WaitForFocusChange();
602 } else {
603 // On the last tab key press, the focus returns to the browser.
604 ui_test_utils::WaitForFocusInBrowser(browser());
605 }
[email protected]9e0c83a2009-05-06 19:44:37606 }
607
608 // At this point the renderer has sent us a message asking to advance the
609 // focus (as the end of the focus loop was reached in the renderer).
610 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35611 MessageLoop::current()->RunAllPending();
[email protected]9e0c83a2009-05-06 19:44:37612 }
613
614 // Now let's try reverse focus traversal.
615 for (int i = 0; i < 2; ++i) {
616 // Location bar should be focused.
[email protected]fc2e0872009-08-21 22:14:41617 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9e0c83a2009-05-06 19:44:37618
619 // Now let's press shift-tab to move the focus in reverse.
[email protected]130efb02009-09-18 18:54:35620 for (size_t j = 0; j < 7; ++j) {
621 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB,
622 false, true, false));
623
624 if (j < arraysize(kExpElementIDs) - 1) {
625 interstitial_page->WaitForFocusChange();
626 } else {
627 // On the last tab key press, the focus returns to the browser.
628 ui_test_utils::WaitForFocusInBrowser(browser());
629 }
[email protected]9e0c83a2009-05-06 19:44:37630
631 // Let's make sure the focus is on the expected element in the page.
632 std::string actual = interstitial_page->GetFocusedElement();
633 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
634 }
635
636 // At this point the renderer has sent us a message asking to advance the
637 // focus (as the end of the focus loop was reached in the renderer).
638 // We need to run the message loop to process it.
[email protected]130efb02009-09-18 18:54:35639 MessageLoop::current()->RunAllPending();
[email protected]9e0c83a2009-05-06 19:44:37640 }
641}
642
643// Focus stays on page with interstitials.
644IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
645 HTTPTestServer* server = StartHTTPServer();
646
647 // First we navigate to our test page.
648 GURL url = server->TestServerPageW(kSimplePage);
649 ui_test_utils::NavigateToURL(browser(), url);
650
[email protected]9e0c83a2009-05-06 19:44:37651 // Page should have focus.
[email protected]fc2e0872009-08-21 22:14:41652 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37653 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
654 HasFocus());
655
[email protected]9d8a4642009-07-29 17:25:30656 // Let's show an interstitial.
[email protected]9e0c83a2009-05-06 19:44:37657 TestInterstitialPage* interstitial_page =
658 new TestInterstitialPage(browser()->GetSelectedTabContents(),
659 true, GURL("http://interstitial.com"));
660 interstitial_page->Show();
661 // Give some time for the interstitial to show.
662 MessageLoop::current()->PostDelayedTask(FROM_HERE,
663 new MessageLoop::QuitTask(),
664 1000);
665 ui_test_utils::RunMessageLoop();
666
667 // The interstitial should have focus now.
[email protected]fc2e0872009-08-21 22:14:41668 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37669 EXPECT_TRUE(interstitial_page->HasFocus());
670
671 // Hide the interstitial.
672 interstitial_page->DontProceed();
673
674 // Focus should be back on the original page.
[email protected]fc2e0872009-08-21 22:14:41675 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9e0c83a2009-05-06 19:44:37676}
677
[email protected]9bd491ee2008-12-10 22:31:07678// Make sure Find box can request focus, even when it is already open.
[email protected]8bcdec92009-02-25 16:15:18679IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
680 HTTPTestServer* server = StartHTTPServer();
license.botbf09a502008-08-24 00:55:55681
[email protected]9bd491ee2008-12-10 22:31:07682 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27683 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18684 ui_test_utils::NavigateToURL(browser(), url);
[email protected]9bd491ee2008-12-10 22:31:07685
[email protected]fc2e0872009-08-21 22:14:41686 gfx::NativeWindow window = browser()->window()->GetNativeHandle();
[email protected]9bd491ee2008-12-10 22:31:07687
688 // Press Ctrl+F, which will make the Find box open and request focus.
[email protected]fc2e0872009-08-21 22:14:41689 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21690 false, false,
[email protected]8bcdec92009-02-25 16:15:18691 new MessageLoop::QuitTask());
692 ui_test_utils::RunMessageLoop();
693
694 // Ideally, we wouldn't sleep here and instead would intercept the
695 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we
696 // could create a RenderViewHostDelegate wrapper and hook-it up by either:
697 // - creating a factory used to create the delegate
698 // - making the test a private and overwriting the delegate member directly.
[email protected]fc2e0872009-08-21 22:14:41699 MessageLoop::current()->PostDelayedTask(
700 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18701 ui_test_utils::RunMessageLoop();
702
[email protected]fc2e0872009-08-21 22:14:41703 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07704
[email protected]fc2e0872009-08-21 22:14:41705 browser()->FocusLocationBar();
706 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9bd491ee2008-12-10 22:31:07707
708 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41709 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true,
[email protected]22cdd932009-08-18 02:16:21710 false, false,
[email protected]8bcdec92009-02-25 16:15:18711 new MessageLoop::QuitTask());
712 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41713 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07714
715 // Set focus to the page.
[email protected]fc2e0872009-08-21 22:14:41716 ClickOnView(VIEW_ID_TAB_CONTAINER);
717 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9bd491ee2008-12-10 22:31:07718
719 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]fc2e0872009-08-21 22:14:41720 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_F, true, false,
[email protected]22cdd932009-08-18 02:16:21721 false, new MessageLoop::QuitTask());
[email protected]8bcdec92009-02-25 16:15:18722 ui_test_utils::RunMessageLoop();
723
724 // See remark above on why we wait.
[email protected]fc2e0872009-08-21 22:14:41725 MessageLoop::current()->PostDelayedTask(
726 FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18727 ui_test_utils::RunMessageLoop();
[email protected]fc2e0872009-08-21 22:14:41728 CheckViewHasFocus(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
[email protected]9bd491ee2008-12-10 22:31:07729}
[email protected]401513c2009-03-12 00:21:28730
731// Makes sure the focus is in the right location when opening the different
732// types of tabs.
[email protected]186f13f2009-08-19 20:34:00733IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
[email protected]401513c2009-03-12 00:21:28734 // Open the history tab, focus should be on the tab contents.
735 browser()->ShowHistoryTab();
[email protected]186f13f2009-08-19 20:34:00736 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]401513c2009-03-12 00:21:28737
738 // Open the new tab, focus should be on the location bar.
739 browser()->NewTab();
[email protected]b9821882009-08-17 22:25:17740 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28741
742 // Open the download tab, focus should be on the tab contents.
743 browser()->ShowDownloadsTab();
[email protected]186f13f2009-08-19 20:34:00744 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]3e3f0eb2009-06-22 18:33:43745
746 // Open about:blank, focus should be on the location bar.
747 browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK,
748 true, -1, false, NULL);
[email protected]b9821882009-08-17 22:25:17749 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]401513c2009-03-12 00:21:28750}
[email protected]9d8a4642009-07-29 17:25:30751
752// Tests that focus goes where expected when using reload.
753IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {
754 HTTPTestServer* server = StartHTTPServer();
755
[email protected]9d8a4642009-07-29 17:25:30756 // Open the new tab, reload.
757 browser()->NewTab();
[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 stay on the location bar.
[email protected]fc2e0872009-08-21 22:14:41761 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]9d8a4642009-07-29 17:25:30762
763 // Open a regular page, focus the location bar, reload.
764 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
[email protected]fc2e0872009-08-21 22:14:41765 browser()->FocusLocationBar();
766 CheckViewHasFocus(VIEW_ID_LOCATION_BAR);
[email protected]b7a20d32009-08-15 00:02:40767 browser()->Reload();
768 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30769 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41770 browser()->ShowDownloadsTab();
771 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30772}
773
774// Tests that focus goes where expected when using reload on a crashed tab.
775IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReloadCrashedTab) {
776 HTTPTestServer* server = StartHTTPServer();
777
[email protected]9d8a4642009-07-29 17:25:30778 // Open a regular page, crash, reload.
779 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage));
780 ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
[email protected]b7a20d32009-08-15 00:02:40781 browser()->Reload();
782 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
[email protected]9d8a4642009-07-29 17:25:30783 // Focus should now be on the tab contents.
[email protected]fc2e0872009-08-21 22:14:41784 browser()->ShowDownloadsTab();
785 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
[email protected]9d8a4642009-07-29 17:25:30786}