blob: 01603ac5f4509b3b7fe88fc092dd641f05a87b07 [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]9e0c83a2009-05-06 19:44:379#include "chrome/browser/renderer_host/render_widget_host_view.h"
10#include "chrome/browser/tab_contents/interstitial_page.h"
initial.commit09911bf2008-07-26 23:55:2911#include "chrome/browser/view_ids.h"
[email protected]8bcdec92009-02-25 16:15:1812#include "chrome/browser/views/frame/browser_view.h"
13#include "chrome/browser/views/location_bar_view.h"
[email protected]9e0c83a2009-05-06 19:44:3714#include "chrome/common/chrome_paths.h"
[email protected]8bcdec92009-02-25 16:15:1815#include "chrome/test/in_process_browser_test.h"
16#include "chrome/test/ui_test_utils.h"
[email protected]2362e4f2009-05-08 00:34:0517#include "views/focus/focus_manager.h"
18#include "views/view.h"
19#include "views/window/window.h"
initial.commit09911bf2008-07-26 23:55:2920
21namespace {
22
[email protected]8bcdec92009-02-25 16:15:1823// The delay waited in some cases where we don't have a notifications for an
24// action we take.
initial.commit09911bf2008-07-26 23:55:2925const int kActionDelayMs = 500;
26
initial.commit09911bf2008-07-26 23:55:2927const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html";
28const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html";
29const wchar_t kTypicalPage[] = L"files/focus/typical_page.html";
[email protected]9e0c83a2009-05-06 19:44:3730const wchar_t kTypicalPageName[] = L"typical_page.html";
initial.commit09911bf2008-07-26 23:55:2931
[email protected]8bcdec92009-02-25 16:15:1832class BrowserFocusTest : public InProcessBrowserTest {
initial.commit09911bf2008-07-26 23:55:2933 public:
34 BrowserFocusTest() {
[email protected]8bcdec92009-02-25 16:15:1835 set_show_window(true);
36 EnableDOMAutomation();
initial.commit09911bf2008-07-26 23:55:2937 }
38};
39
[email protected]9e0c83a2009-05-06 19:44:3740class TestInterstitialPage : public InterstitialPage {
41 public:
42 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
43 : InterstitialPage(tab, new_navigation, url),
44 waiting_for_dom_response_(false) {
45 std::wstring file_path;
46 bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path);
47 EXPECT_TRUE(r);
48 file_util::AppendToPath(&file_path, L"focus");
49 file_util::AppendToPath(&file_path, kTypicalPageName);
50 r = file_util::ReadFileToString(file_path, &html_contents_);
51 EXPECT_TRUE(r);
52 }
53
54 virtual std::string GetHTMLContents() {
55 return html_contents_;
56 }
57
58 virtual void DomOperationResponse(const std::string& json_string,
59 int automation_id) {
60 if (waiting_for_dom_response_) {
61 dom_response_ = json_string;
62 waiting_for_dom_response_ = false;
63 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
64 return;
65 }
66 InterstitialPage::DomOperationResponse(json_string, automation_id);
67 }
68
69 std::string GetFocusedElement() {
70 std::wstring script = L"window.domAutomationController.setAutomationId(0);"
71 L"window.domAutomationController.send(getFocusedElement());";
72
73 render_view_host()->ExecuteJavascriptInWebFrame(L"", script);
74 DCHECK(!waiting_for_dom_response_);
75 waiting_for_dom_response_ = true;
76 ui_test_utils::RunMessageLoop();
77 // Remove the JSON extra quotes.
78 if (dom_response_.size() >= 2 && dom_response_[0] == '"' &&
79 dom_response_[dom_response_.size() - 1] == '"') {
80 dom_response_ = dom_response_.substr(1, dom_response_.size() - 2);
81 }
82 return dom_response_;
83 }
84
85 bool HasFocus() {
86 return render_view_host()->view()->HasFocus();
87 }
88
89 private:
90 std::string html_contents_;
91
92 bool waiting_for_dom_response_;
93 std::string dom_response_;
94
95};
initial.commit09911bf2008-07-26 23:55:2996} // namespace
97
[email protected]6a9f16e2009-04-15 06:02:2698IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BrowsersRememberFocus) {
[email protected]8bcdec92009-02-25 16:15:1899 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29100
101 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27102 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18103 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29104
105 // The focus should be on the Tab contents.
[email protected]8bcdec92009-02-25 16:15:18106 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
107 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
108 ASSERT_TRUE(browser_view);
109 views::FocusManager* focus_manager =
110 views::FocusManager::GetFocusManager(hwnd);
111 ASSERT_TRUE(focus_manager);
initial.commit09911bf2008-07-26 23:55:29112
[email protected]8bcdec92009-02-25 16:15:18113 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29114
115 // Now hide the window, show it again, the focus should not have changed.
[email protected]8bcdec92009-02-25 16:15:18116 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
117 // using Windows API.
118 ::ShowWindow(hwnd, SW_HIDE);
119 ::ShowWindow(hwnd, SW_SHOW);
120 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29121
122 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18123 LocationBarView* location_bar = browser_view->GetLocationBarView();
124 ui_controls::MoveMouseToCenterAndPress(location_bar,
125 ui_controls::LEFT,
126 ui_controls::DOWN | ui_controls::UP,
127 new MessageLoop::QuitTask());
128 ui_test_utils::RunMessageLoop();
129 // Location bar should have focus.
130 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29131
132 // Hide the window, show it again, the focus should not have changed.
[email protected]8bcdec92009-02-25 16:15:18133 ::ShowWindow(hwnd, SW_HIDE);
134 ::ShowWindow(hwnd, SW_SHOW);
135 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29136
137 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18138 Browser* browser2 = Browser::Create(browser()->profile());
139 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43140 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18141 browser2->window()->Show();
142 ui_test_utils::NavigateToURL(browser2, url);
initial.commit09911bf2008-07-26 23:55:29143
[email protected]8bcdec92009-02-25 16:15:18144 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
145 BrowserView* browser_view2 = BrowserView::GetBrowserViewForHWND(hwnd2);
146 ASSERT_TRUE(browser_view2);
147 views::FocusManager* focus_manager2 =
148 views::FocusManager::GetFocusManager(hwnd2);
149 ASSERT_TRUE(focus_manager2);
150 EXPECT_EQ(browser_view2->GetContentsView(), focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29151
152 // Switch to the 1st browser window, focus should still be on the location
153 // bar and the second browser should have nothing focused.
[email protected]8bcdec92009-02-25 16:15:18154 browser()->window()->Activate();
155 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
156 EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29157
158 // Switch back to the second browser, focus should still be on the page.
[email protected]8bcdec92009-02-25 16:15:18159 browser2->window()->Activate();
160 EXPECT_EQ(NULL, focus_manager->GetFocusedView());
161 EXPECT_EQ(browser_view2->GetContentsView(), focus_manager2->GetFocusedView());
162
163 // Close the 2nd browser to avoid a DCHECK().
164 browser_view2->Close();
initial.commit09911bf2008-07-26 23:55:29165}
166
167// Tabs remember focus.
[email protected]8bcdec92009-02-25 16:15:18168IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
169 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29170
171 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27172 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18173 ui_test_utils::NavigateToURL(browser(), url);
174
175 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
176 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
177 ASSERT_TRUE(browser_view);
178
179 views::FocusManager* focus_manager =
180 views::FocusManager::GetFocusManager(hwnd);
181 ASSERT_TRUE(focus_manager);
initial.commit09911bf2008-07-26 23:55:29182
183 // Create several tabs.
[email protected]22735af62009-04-07 21:09:58184 for (int i = 0; i < 4; ++i) {
[email protected]5a4940be2009-05-06 06:44:39185 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1, false,
[email protected]22735af62009-04-07 21:09:58186 NULL);
187 }
initial.commit09911bf2008-07-26 23:55:29188
189 // Alternate focus for the tab.
190 const bool kFocusPage[3][5] = {
191 { true, true, true, true, false },
192 { false, false, false, false, false },
193 { false, true, false, true, false }
194 };
195
196 for (int i = 1; i < 3; i++) {
197 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18198 // Activate the tab.
199 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29200
201 // Activate the location bar or the page.
[email protected]8bcdec92009-02-25 16:15:18202 views::View* view_to_focus = kFocusPage[i][j] ?
203 browser_view->GetContentsView() :
204 browser_view->GetLocationBarView();
initial.commit09911bf2008-07-26 23:55:29205
[email protected]8bcdec92009-02-25 16:15:18206 ui_controls::MoveMouseToCenterAndPress(view_to_focus,
207 ui_controls::LEFT,
208 ui_controls::DOWN |
209 ui_controls::UP,
210 new MessageLoop::QuitTask());
211 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29212 }
213
214 // Now come back to the tab and check the right view is focused.
215 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18216 // Activate the tab.
217 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29218
219 // Activate the location bar or the page.
[email protected]8bcdec92009-02-25 16:15:18220 views::View* view = kFocusPage[i][j] ?
221 browser_view->GetContentsView() :
222 browser_view->GetLocationBarView();
223 EXPECT_EQ(view, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29224 }
225 }
226}
227
228// Background window does not steal focus.
[email protected]8bcdec92009-02-25 16:15:18229IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
230 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29231
232 // First we navigate to our test page.
[email protected]8bcdec92009-02-25 16:15:18233 GURL url = server->TestServerPageW(kSimplePage);
234 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29235
236 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18237 Browser* browser2 = Browser::Create(browser()->profile());
238 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43239 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18240 browser2->window()->Show();
[email protected]1e187af2009-02-25 02:02:46241 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18242 ui_test_utils::NavigateToURL(browser2, steal_focus_url);
[email protected]1e187af2009-02-25 02:02:46243
[email protected]8bcdec92009-02-25 16:15:18244 // Activate the first browser.
245 browser()->window()->Activate();
initial.commit09911bf2008-07-26 23:55:29246
247 // Wait for the focus to be stolen by the other browser.
248 ::Sleep(2000);
249
[email protected]8bcdec92009-02-25 16:15:18250 // Make sure the first browser is still active.
251 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
252 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
253 ASSERT_TRUE(browser_view);
[email protected]6c8c80e2009-05-19 14:51:36254 EXPECT_TRUE(browser_view->frame()->GetWindow()->IsActive());
[email protected]8bcdec92009-02-25 16:15:18255
256 // Close the 2nd browser to avoid a DCHECK().
257 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
258 BrowserView* browser_view2 = BrowserView::GetBrowserViewForHWND(hwnd2);
259 browser_view2->Close();
initial.commit09911bf2008-07-26 23:55:29260}
261
262// Page cannot steal focus when focus is on location bar.
[email protected]8bcdec92009-02-25 16:15:18263IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
264 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29265
266 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27267 GURL url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18268 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29269
[email protected]8bcdec92009-02-25 16:15:18270 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
271 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
272 views::FocusManager* focus_manager =
273 views::FocusManager::GetFocusManager(hwnd);
initial.commit09911bf2008-07-26 23:55:29274
[email protected]9bd491ee2008-12-10 22:31:07275 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18276 LocationBarView* location_bar = browser_view->GetLocationBarView();
277 ui_controls::MoveMouseToCenterAndPress(location_bar,
278 ui_controls::LEFT,
279 ui_controls::DOWN | ui_controls::UP,
280 new MessageLoop::QuitTask());
281 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29282
283 // Wait for the page to steal focus.
284 ::Sleep(2000);
285
286 // Make sure the location bar is still focused.
[email protected]8bcdec92009-02-25 16:15:18287 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29288}
289
[email protected]9e0c83a2009-05-06 19:44:37290// Focus traversal on a regular page.
[email protected]8bcdec92009-02-25 16:15:18291IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
292 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29293
[email protected]8bcdec92009-02-25 16:15:18294 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27295 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18296 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29297
[email protected]8bcdec92009-02-25 16:15:18298 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
299 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
300 views::FocusManager* focus_manager =
301 views::FocusManager::GetFocusManager(hwnd);
initial.commit09911bf2008-07-26 23:55:29302
303 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18304 LocationBarView* location_bar = browser_view->GetLocationBarView();
305 ui_controls::MoveMouseToCenterAndPress(location_bar,
306 ui_controls::LEFT,
307 ui_controls::DOWN | ui_controls::UP,
308 new MessageLoop::QuitTask());
309 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29310
[email protected]8bcdec92009-02-25 16:15:18311 const char* kExpElementIDs[] = {
312 "", // Initially no element in the page should be focused
313 // (the location bar is focused).
314 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
315 "gmapLink"
initial.commit09911bf2008-07-26 23:55:29316 };
317
318 // Test forward focus traversal.
319 for (int i = 0; i < 3; ++i) {
320 // Location bar should be focused.
[email protected]8bcdec92009-02-25 16:15:18321 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29322
323 // Now let's press tab to move the focus.
324 for (int j = 0; j < 7; ++j) {
325 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01326 std::string actual;
327 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]57c6a652009-05-04 07:58:34328 browser()->GetSelectedTabContents(),
[email protected]8bcdec92009-02-25 16:15:18329 L"",
[email protected]45671612009-04-29 22:24:01330 L"window.domAutomationController.send(getFocusedElement());",
331 &actual));
initial.commit09911bf2008-07-26 23:55:29332 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
333
[email protected]8bcdec92009-02-25 16:15:18334 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false,
335 new MessageLoop::QuitTask());
336 ui_test_utils::RunMessageLoop();
337 // Ideally, we wouldn't sleep here and instead would use the event
[email protected]b54649012009-04-17 17:00:12338 // processed ack notification from the renderer. I am reluctant to create
[email protected]8bcdec92009-02-25 16:15:18339 // a new notification/callback for that purpose just for this test.
initial.commit09911bf2008-07-26 23:55:29340 ::Sleep(kActionDelayMs);
341 }
[email protected]8bcdec92009-02-25 16:15:18342
343 // At this point the renderer has sent us a message asking to advance the
344 // focus (as the end of the focus loop was reached in the renderer).
345 // We need to run the message loop to process it.
346 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
347 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29348 }
349
350 // Now let's try reverse focus traversal.
351 for (int i = 0; i < 3; ++i) {
352 // Location bar should be focused.
[email protected]8bcdec92009-02-25 16:15:18353 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29354
[email protected]8bcdec92009-02-25 16:15:18355 // Now let's press shift-tab to move the focus in reverse.
initial.commit09911bf2008-07-26 23:55:29356 for (int j = 0; j < 7; ++j) {
[email protected]8bcdec92009-02-25 16:15:18357 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, true, false,
358 new MessageLoop::QuitTask());
359 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29360 ::Sleep(kActionDelayMs);
361
362 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01363 std::string actual;
364 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]57c6a652009-05-04 07:58:34365 browser()->GetSelectedTabContents(),
[email protected]8bcdec92009-02-25 16:15:18366 L"",
[email protected]45671612009-04-29 22:24:01367 L"window.domAutomationController.send(getFocusedElement());",
368 &actual));
initial.commit09911bf2008-07-26 23:55:29369 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
370 }
[email protected]8bcdec92009-02-25 16:15:18371
372 // At this point the renderer has sent us a message asking to advance the
373 // focus (as the end of the focus loop was reached in the renderer).
374 // We need to run the message loop to process it.
375 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
376 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29377 }
378}
379
[email protected]9e0c83a2009-05-06 19:44:37380// Focus traversal while an interstitial is showing.
381IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversalOnInterstitial) {
382 HTTPTestServer* server = StartHTTPServer();
383
384 // First we navigate to our test page.
385 GURL url = server->TestServerPageW(kSimplePage);
386 ui_test_utils::NavigateToURL(browser(), url);
387
388 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
389 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
390 views::FocusManager* focus_manager =
391 views::FocusManager::GetFocusManager(hwnd);
392
393 // Focus should be on the page.
394 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
395
396 // Let's show an interstitial.
397 TestInterstitialPage* interstitial_page =
398 new TestInterstitialPage(browser()->GetSelectedTabContents(),
399 true, GURL("http://interstitial.com"));
400 interstitial_page->Show();
401 // Give some time for the interstitial to show.
402 MessageLoop::current()->PostDelayedTask(FROM_HERE,
403 new MessageLoop::QuitTask(),
404 1000);
405 ui_test_utils::RunMessageLoop();
406
407 // Click on the location bar.
408 LocationBarView* location_bar = browser_view->GetLocationBarView();
409 ui_controls::MoveMouseToCenterAndPress(location_bar,
410 ui_controls::LEFT,
411 ui_controls::DOWN | ui_controls::UP,
412 new MessageLoop::QuitTask());
413 ui_test_utils::RunMessageLoop();
414
415 const char* kExpElementIDs[] = {
416 "", // Initially no element in the page should be focused
417 // (the location bar is focused).
418 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
419 "gmapLink"
420 };
421
422 // Test forward focus traversal.
423 for (int i = 0; i < 2; ++i) {
424 // Location bar should be focused.
425 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
426
427 // Now let's press tab to move the focus.
428 for (int j = 0; j < 7; ++j) {
429 // Let's make sure the focus is on the expected element in the page.
430 std::string actual = interstitial_page->GetFocusedElement();
431 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
432
433 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false,
434 new MessageLoop::QuitTask());
435 ui_test_utils::RunMessageLoop();
436 // Ideally, we wouldn't sleep here and instead would use the event
437 // processed ack notification from the renderer. I am reluctant to create
438 // a new notification/callback for that purpose just for this test.
439 ::Sleep(kActionDelayMs);
440 }
441
442 // At this point the renderer has sent us a message asking to advance the
443 // focus (as the end of the focus loop was reached in the renderer).
444 // We need to run the message loop to process it.
445 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
446 ui_test_utils::RunMessageLoop();
447 }
448
449 // Now let's try reverse focus traversal.
450 for (int i = 0; i < 2; ++i) {
451 // Location bar should be focused.
452 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
453
454 // Now let's press shift-tab to move the focus in reverse.
455 for (int j = 0; j < 7; ++j) {
456 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, true, false,
457 new MessageLoop::QuitTask());
458 ui_test_utils::RunMessageLoop();
459 ::Sleep(kActionDelayMs);
460
461 // Let's make sure the focus is on the expected element in the page.
462 std::string actual = interstitial_page->GetFocusedElement();
463 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
464 }
465
466 // At this point the renderer has sent us a message asking to advance the
467 // focus (as the end of the focus loop was reached in the renderer).
468 // We need to run the message loop to process it.
469 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
470 ui_test_utils::RunMessageLoop();
471 }
472}
473
474// Focus stays on page with interstitials.
475IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
476 HTTPTestServer* server = StartHTTPServer();
477
478 // First we navigate to our test page.
479 GURL url = server->TestServerPageW(kSimplePage);
480 ui_test_utils::NavigateToURL(browser(), url);
481
482 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
483 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
484 views::FocusManager* focus_manager =
485 views::FocusManager::GetFocusManager(hwnd);
486
487 // Page should have focus.
488 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
489 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
490 HasFocus());
491
492 // Let's show an interstitial.
493 TestInterstitialPage* interstitial_page =
494 new TestInterstitialPage(browser()->GetSelectedTabContents(),
495 true, GURL("http://interstitial.com"));
496 interstitial_page->Show();
497 // Give some time for the interstitial to show.
498 MessageLoop::current()->PostDelayedTask(FROM_HERE,
499 new MessageLoop::QuitTask(),
500 1000);
501 ui_test_utils::RunMessageLoop();
502
503 // The interstitial should have focus now.
504 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
505 EXPECT_TRUE(interstitial_page->HasFocus());
506
507 // Hide the interstitial.
508 interstitial_page->DontProceed();
509
510 // Focus should be back on the original page.
511 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
512 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
513 HasFocus());
514}
515
[email protected]9bd491ee2008-12-10 22:31:07516// Make sure Find box can request focus, even when it is already open.
[email protected]8bcdec92009-02-25 16:15:18517IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
518 HTTPTestServer* server = StartHTTPServer();
license.botbf09a502008-08-24 00:55:55519
[email protected]9bd491ee2008-12-10 22:31:07520 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27521 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18522 ui_test_utils::NavigateToURL(browser(), url);
[email protected]9bd491ee2008-12-10 22:31:07523
[email protected]8bcdec92009-02-25 16:15:18524 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
525 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
526 views::FocusManager* focus_manager =
527 views::FocusManager::GetFocusManager(hwnd);
528 LocationBarView* location_bar = browser_view->GetLocationBarView();
[email protected]9bd491ee2008-12-10 22:31:07529
530 // Press Ctrl+F, which will make the Find box open and request focus.
531 static const int VK_F = 0x46;
[email protected]8bcdec92009-02-25 16:15:18532 ui_controls::SendKeyPressNotifyWhenDone(L'F', true, false, false,
533 new MessageLoop::QuitTask());
534 ui_test_utils::RunMessageLoop();
535
536 // Ideally, we wouldn't sleep here and instead would intercept the
537 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we
538 // could create a RenderViewHostDelegate wrapper and hook-it up by either:
539 // - creating a factory used to create the delegate
540 // - making the test a private and overwriting the delegate member directly.
[email protected]9bd491ee2008-12-10 22:31:07541 ::Sleep(kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18542 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
543 ui_test_utils::RunMessageLoop();
544
545 views::View* focused_view = focus_manager->GetFocusedView();
546 ASSERT_TRUE(focused_view != NULL);
547 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
[email protected]9bd491ee2008-12-10 22:31:07548
549 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18550 ui_controls::MoveMouseToCenterAndPress(location_bar,
551 ui_controls::LEFT,
552 ui_controls::DOWN | ui_controls::UP,
553 new MessageLoop::QuitTask());
554 ui_test_utils::RunMessageLoop();
555
[email protected]9bd491ee2008-12-10 22:31:07556 // Make sure the location bar is focused.
[email protected]8bcdec92009-02-25 16:15:18557 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
[email protected]9bd491ee2008-12-10 22:31:07558
559 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]8bcdec92009-02-25 16:15:18560 ui_controls::SendKeyPressNotifyWhenDone(L'F', true, false, false,
561 new MessageLoop::QuitTask());
562 ui_test_utils::RunMessageLoop();
563 focused_view = focus_manager->GetFocusedView();
564 ASSERT_TRUE(focused_view != NULL);
565 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
[email protected]9bd491ee2008-12-10 22:31:07566
567 // Set focus to the page.
[email protected]8bcdec92009-02-25 16:15:18568 ui_controls::MoveMouseToCenterAndPress(browser_view->GetContentsView(),
569 ui_controls::LEFT,
570 ui_controls::DOWN | ui_controls::UP,
571 new MessageLoop::QuitTask());
572 ui_test_utils::RunMessageLoop();
573 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
[email protected]9bd491ee2008-12-10 22:31:07574
575 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]8bcdec92009-02-25 16:15:18576 ui_controls::SendKeyPressNotifyWhenDone(VK_F, true, false, false,
577 new MessageLoop::QuitTask());
578 ui_test_utils::RunMessageLoop();
579
580 // See remark above on why we wait.
[email protected]9bd491ee2008-12-10 22:31:07581 ::Sleep(kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18582 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
583 ui_test_utils::RunMessageLoop();
584
585 focused_view = focus_manager->GetFocusedView();
586 ASSERT_TRUE(focused_view != NULL);
587 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
[email protected]9bd491ee2008-12-10 22:31:07588}
[email protected]401513c2009-03-12 00:21:28589
590// Makes sure the focus is in the right location when opening the different
591// types of tabs.
592IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
593 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
594 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
595 ASSERT_TRUE(browser_view);
596 views::FocusManager* focus_manager =
597 views::FocusManager::GetFocusManager(hwnd);
598 ASSERT_TRUE(focus_manager);
599
600 // Open the history tab, focus should be on the tab contents.
601 browser()->ShowHistoryTab();
602 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
603
604 // Open the new tab, focus should be on the location bar.
605 browser()->NewTab();
606 EXPECT_EQ(browser_view->GetLocationBarView(),
607 focus_manager->GetFocusedView());
608
609 // Open the download tab, focus should be on the tab contents.
610 browser()->ShowDownloadsTab();
611 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
612}