blob: 7fcc5997c9e68a99f77b6088ffa1ec210522a452 [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]610d36a2009-05-22 23:00:3814#include "chrome/browser/views/tab_contents/tab_contents_container.h"
[email protected]9e0c83a2009-05-06 19:44:3715#include "chrome/common/chrome_paths.h"
[email protected]8bcdec92009-02-25 16:15:1816#include "chrome/test/in_process_browser_test.h"
17#include "chrome/test/ui_test_utils.h"
[email protected]2362e4f2009-05-08 00:34:0518#include "views/focus/focus_manager.h"
19#include "views/view.h"
20#include "views/window/window.h"
initial.commit09911bf2008-07-26 23:55:2921
22namespace {
23
[email protected]8bcdec92009-02-25 16:15:1824// The delay waited in some cases where we don't have a notifications for an
25// action we take.
initial.commit09911bf2008-07-26 23:55:2926const int kActionDelayMs = 500;
27
initial.commit09911bf2008-07-26 23:55:2928const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html";
29const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html";
30const wchar_t kTypicalPage[] = L"files/focus/typical_page.html";
[email protected]9e0c83a2009-05-06 19:44:3731const wchar_t kTypicalPageName[] = L"typical_page.html";
initial.commit09911bf2008-07-26 23:55:2932
[email protected]8bcdec92009-02-25 16:15:1833class BrowserFocusTest : public InProcessBrowserTest {
initial.commit09911bf2008-07-26 23:55:2934 public:
35 BrowserFocusTest() {
[email protected]8bcdec92009-02-25 16:15:1836 set_show_window(true);
37 EnableDOMAutomation();
initial.commit09911bf2008-07-26 23:55:2938 }
39};
40
[email protected]9e0c83a2009-05-06 19:44:3741class TestInterstitialPage : public InterstitialPage {
42 public:
43 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
44 : InterstitialPage(tab, new_navigation, url),
45 waiting_for_dom_response_(false) {
46 std::wstring file_path;
47 bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path);
48 EXPECT_TRUE(r);
49 file_util::AppendToPath(&file_path, L"focus");
50 file_util::AppendToPath(&file_path, kTypicalPageName);
51 r = file_util::ReadFileToString(file_path, &html_contents_);
52 EXPECT_TRUE(r);
53 }
54
55 virtual std::string GetHTMLContents() {
56 return html_contents_;
57 }
58
59 virtual void DomOperationResponse(const std::string& json_string,
60 int automation_id) {
61 if (waiting_for_dom_response_) {
62 dom_response_ = json_string;
63 waiting_for_dom_response_ = false;
64 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
65 return;
66 }
67 InterstitialPage::DomOperationResponse(json_string, automation_id);
68 }
69
70 std::string GetFocusedElement() {
71 std::wstring script = L"window.domAutomationController.setAutomationId(0);"
72 L"window.domAutomationController.send(getFocusedElement());";
73
74 render_view_host()->ExecuteJavascriptInWebFrame(L"", script);
75 DCHECK(!waiting_for_dom_response_);
76 waiting_for_dom_response_ = true;
77 ui_test_utils::RunMessageLoop();
78 // Remove the JSON extra quotes.
79 if (dom_response_.size() >= 2 && dom_response_[0] == '"' &&
80 dom_response_[dom_response_.size() - 1] == '"') {
81 dom_response_ = dom_response_.substr(1, dom_response_.size() - 2);
82 }
83 return dom_response_;
84 }
85
86 bool HasFocus() {
87 return render_view_host()->view()->HasFocus();
88 }
89
90 private:
91 std::string html_contents_;
92
93 bool waiting_for_dom_response_;
94 std::string dom_response_;
95
96};
initial.commit09911bf2008-07-26 23:55:2997} // namespace
98
[email protected]7e383692009-06-12 19:14:5499IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) {
[email protected]8bcdec92009-02-25 16:15:18100 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29101
102 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27103 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18104 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29105
106 // The focus should be on the Tab contents.
[email protected]8bcdec92009-02-25 16:15:18107 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00108 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]8bcdec92009-02-25 16:15:18109 ASSERT_TRUE(browser_view);
110 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00111 views::FocusManager::GetFocusManagerForNativeView(hwnd);
[email protected]8bcdec92009-02-25 16:15:18112 ASSERT_TRUE(focus_manager);
initial.commit09911bf2008-07-26 23:55:29113
[email protected]7e383692009-06-12 19:14:54114 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38115 focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29116
117 // Now hide the window, show it again, the focus should not have changed.
[email protected]8bcdec92009-02-25 16:15:18118 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
119 // using Windows API.
120 ::ShowWindow(hwnd, SW_HIDE);
121 ::ShowWindow(hwnd, SW_SHOW);
[email protected]7e383692009-06-12 19:14:54122 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38123 focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29124
125 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18126 LocationBarView* location_bar = browser_view->GetLocationBarView();
127 ui_controls::MoveMouseToCenterAndPress(location_bar,
128 ui_controls::LEFT,
129 ui_controls::DOWN | ui_controls::UP,
130 new MessageLoop::QuitTask());
131 ui_test_utils::RunMessageLoop();
132 // Location bar should have focus.
133 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29134
135 // Hide the window, show it again, the focus should not have changed.
[email protected]8bcdec92009-02-25 16:15:18136 ::ShowWindow(hwnd, SW_HIDE);
137 ::ShowWindow(hwnd, SW_SHOW);
138 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29139
140 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18141 Browser* browser2 = Browser::Create(browser()->profile());
142 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43143 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18144 browser2->window()->Show();
145 ui_test_utils::NavigateToURL(browser2, url);
initial.commit09911bf2008-07-26 23:55:29146
[email protected]8bcdec92009-02-25 16:15:18147 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00148 BrowserView* browser_view2 =
149 BrowserView::GetBrowserViewForNativeWindow(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18150 ASSERT_TRUE(browser_view2);
151 views::FocusManager* focus_manager2 =
[email protected]82166b62009-06-30 18:48:00152 views::FocusManager::GetFocusManagerForNativeView(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18153 ASSERT_TRUE(focus_manager2);
[email protected]7e383692009-06-12 19:14:54154 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38155 focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29156
157 // Switch to the 1st browser window, focus should still be on the location
158 // bar and the second browser should have nothing focused.
[email protected]8bcdec92009-02-25 16:15:18159 browser()->window()->Activate();
160 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
161 EXPECT_EQ(NULL, focus_manager2->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29162
163 // Switch back to the second browser, focus should still be on the page.
[email protected]8bcdec92009-02-25 16:15:18164 browser2->window()->Activate();
165 EXPECT_EQ(NULL, focus_manager->GetFocusedView());
[email protected]7e383692009-06-12 19:14:54166 EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38167 focus_manager2->GetFocusedView());
[email protected]8bcdec92009-02-25 16:15:18168
169 // Close the 2nd browser to avoid a DCHECK().
170 browser_view2->Close();
initial.commit09911bf2008-07-26 23:55:29171}
172
173// Tabs remember focus.
[email protected]8bcdec92009-02-25 16:15:18174IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
175 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29176
177 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27178 GURL url = server->TestServerPageW(kSimplePage);
[email protected]8bcdec92009-02-25 16:15:18179 ui_test_utils::NavigateToURL(browser(), url);
180
181 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00182 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]8bcdec92009-02-25 16:15:18183 ASSERT_TRUE(browser_view);
184
185 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00186 views::FocusManager::GetFocusManagerForNativeView(hwnd);
[email protected]8bcdec92009-02-25 16:15:18187 ASSERT_TRUE(focus_manager);
initial.commit09911bf2008-07-26 23:55:29188
189 // Create several tabs.
[email protected]22735af62009-04-07 21:09:58190 for (int i = 0; i < 4; ++i) {
[email protected]82166b62009-06-30 18:48:00191 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1,
192 false, NULL);
[email protected]22735af62009-04-07 21:09:58193 }
initial.commit09911bf2008-07-26 23:55:29194
195 // Alternate focus for the tab.
196 const bool kFocusPage[3][5] = {
197 { true, true, true, true, false },
198 { false, false, false, false, false },
199 { false, true, false, true, false }
200 };
201
202 for (int i = 1; i < 3; i++) {
203 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18204 // Activate the tab.
205 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29206
207 // Activate the location bar or the page.
[email protected]7e383692009-06-12 19:14:54208 views::View* view_to_focus;
209 if (kFocusPage[i][j]) {
210 view_to_focus = browser_view->GetTabContentsContainerView();
211 } else {
212 view_to_focus = browser_view->GetLocationBarView();
213 }
initial.commit09911bf2008-07-26 23:55:29214
[email protected]8bcdec92009-02-25 16:15:18215 ui_controls::MoveMouseToCenterAndPress(view_to_focus,
216 ui_controls::LEFT,
217 ui_controls::DOWN |
218 ui_controls::UP,
219 new MessageLoop::QuitTask());
220 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29221 }
222
223 // Now come back to the tab and check the right view is focused.
224 for (int j = 0; j < 5; j++) {
[email protected]8bcdec92009-02-25 16:15:18225 // Activate the tab.
226 browser()->SelectTabContentsAt(j, true);
initial.commit09911bf2008-07-26 23:55:29227
228 // Activate the location bar or the page.
[email protected]7e383692009-06-12 19:14:54229 views::View* view;
230 if (kFocusPage[i][j]) {
231 view = browser_view->GetTabContentsContainerView();
232 } else {
233 view = browser_view->GetLocationBarView();
234 }
[email protected]8bcdec92009-02-25 16:15:18235 EXPECT_EQ(view, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29236 }
237 }
238}
239
240// Background window does not steal focus.
[email protected]bedb4a22009-06-25 00:47:50241// TODO(brettw) bug 15265 enable this test when it's fixed.
242IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BackgroundBrowserDontStealFocus) {
[email protected]8bcdec92009-02-25 16:15:18243 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29244
245 // First we navigate to our test page.
[email protected]8bcdec92009-02-25 16:15:18246 GURL url = server->TestServerPageW(kSimplePage);
247 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29248
249 // Open a new browser window.
[email protected]8bcdec92009-02-25 16:15:18250 Browser* browser2 = Browser::Create(browser()->profile());
251 ASSERT_TRUE(browser2);
[email protected]e0c7c262009-04-23 23:09:43252 browser2->tabstrip_model()->delegate()->AddBlankTab(true);
[email protected]8bcdec92009-02-25 16:15:18253 browser2->window()->Show();
[email protected]1e187af2009-02-25 02:02:46254 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18255 ui_test_utils::NavigateToURL(browser2, steal_focus_url);
[email protected]1e187af2009-02-25 02:02:46256
[email protected]8bcdec92009-02-25 16:15:18257 // Activate the first browser.
258 browser()->window()->Activate();
initial.commit09911bf2008-07-26 23:55:29259
260 // Wait for the focus to be stolen by the other browser.
261 ::Sleep(2000);
262
[email protected]8bcdec92009-02-25 16:15:18263 // Make sure the first browser is still active.
264 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00265 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]8bcdec92009-02-25 16:15:18266 ASSERT_TRUE(browser_view);
[email protected]6c8c80e2009-05-19 14:51:36267 EXPECT_TRUE(browser_view->frame()->GetWindow()->IsActive());
[email protected]8bcdec92009-02-25 16:15:18268
269 // Close the 2nd browser to avoid a DCHECK().
270 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00271 BrowserView* browser_view2 =
272 BrowserView::GetBrowserViewForNativeWindow(hwnd2);
[email protected]8bcdec92009-02-25 16:15:18273 browser_view2->Close();
initial.commit09911bf2008-07-26 23:55:29274}
275
276// Page cannot steal focus when focus is on location bar.
[email protected]8bcdec92009-02-25 16:15:18277IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
278 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29279
280 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27281 GURL url = server->TestServerPageW(kStealFocusPage);
[email protected]8bcdec92009-02-25 16:15:18282 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29283
[email protected]8bcdec92009-02-25 16:15:18284 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00285 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]8bcdec92009-02-25 16:15:18286 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00287 views::FocusManager::GetFocusManagerForNativeView(hwnd);
initial.commit09911bf2008-07-26 23:55:29288
[email protected]9bd491ee2008-12-10 22:31:07289 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18290 LocationBarView* location_bar = browser_view->GetLocationBarView();
291 ui_controls::MoveMouseToCenterAndPress(location_bar,
292 ui_controls::LEFT,
293 ui_controls::DOWN | ui_controls::UP,
294 new MessageLoop::QuitTask());
295 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29296
297 // Wait for the page to steal focus.
298 ::Sleep(2000);
299
300 // Make sure the location bar is still focused.
[email protected]8bcdec92009-02-25 16:15:18301 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29302}
303
[email protected]9e0c83a2009-05-06 19:44:37304// Focus traversal on a regular page.
[email protected]8bcdec92009-02-25 16:15:18305IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) {
306 HTTPTestServer* server = StartHTTPServer();
initial.commit09911bf2008-07-26 23:55:29307
[email protected]8bcdec92009-02-25 16:15:18308 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27309 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18310 ui_test_utils::NavigateToURL(browser(), url);
initial.commit09911bf2008-07-26 23:55:29311
[email protected]8bcdec92009-02-25 16:15:18312 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00313 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]8bcdec92009-02-25 16:15:18314 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00315 views::FocusManager::GetFocusManagerForNativeView(hwnd);
initial.commit09911bf2008-07-26 23:55:29316
317 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18318 LocationBarView* location_bar = browser_view->GetLocationBarView();
319 ui_controls::MoveMouseToCenterAndPress(location_bar,
320 ui_controls::LEFT,
321 ui_controls::DOWN | ui_controls::UP,
322 new MessageLoop::QuitTask());
323 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29324
[email protected]8bcdec92009-02-25 16:15:18325 const char* kExpElementIDs[] = {
326 "", // Initially no element in the page should be focused
327 // (the location bar is focused).
328 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
329 "gmapLink"
initial.commit09911bf2008-07-26 23:55:29330 };
331
332 // Test forward focus traversal.
333 for (int i = 0; i < 3; ++i) {
334 // Location bar should be focused.
[email protected]8bcdec92009-02-25 16:15:18335 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29336
337 // Now let's press tab to move the focus.
338 for (int j = 0; j < 7; ++j) {
339 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01340 std::string actual;
341 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]57c6a652009-05-04 07:58:34342 browser()->GetSelectedTabContents(),
[email protected]8bcdec92009-02-25 16:15:18343 L"",
[email protected]45671612009-04-29 22:24:01344 L"window.domAutomationController.send(getFocusedElement());",
345 &actual));
initial.commit09911bf2008-07-26 23:55:29346 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
347
[email protected]8bcdec92009-02-25 16:15:18348 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false,
349 new MessageLoop::QuitTask());
350 ui_test_utils::RunMessageLoop();
351 // Ideally, we wouldn't sleep here and instead would use the event
[email protected]b54649012009-04-17 17:00:12352 // processed ack notification from the renderer. I am reluctant to create
[email protected]8bcdec92009-02-25 16:15:18353 // a new notification/callback for that purpose just for this test.
initial.commit09911bf2008-07-26 23:55:29354 ::Sleep(kActionDelayMs);
355 }
[email protected]8bcdec92009-02-25 16:15:18356
357 // At this point the renderer has sent us a message asking to advance the
358 // focus (as the end of the focus loop was reached in the renderer).
359 // We need to run the message loop to process it.
360 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
361 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29362 }
363
364 // Now let's try reverse focus traversal.
365 for (int i = 0; i < 3; ++i) {
366 // Location bar should be focused.
[email protected]8bcdec92009-02-25 16:15:18367 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
initial.commit09911bf2008-07-26 23:55:29368
[email protected]8bcdec92009-02-25 16:15:18369 // Now let's press shift-tab to move the focus in reverse.
initial.commit09911bf2008-07-26 23:55:29370 for (int j = 0; j < 7; ++j) {
[email protected]8bcdec92009-02-25 16:15:18371 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, true, false,
372 new MessageLoop::QuitTask());
373 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29374 ::Sleep(kActionDelayMs);
375
376 // Let's make sure the focus is on the expected element in the page.
[email protected]45671612009-04-29 22:24:01377 std::string actual;
378 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
[email protected]57c6a652009-05-04 07:58:34379 browser()->GetSelectedTabContents(),
[email protected]8bcdec92009-02-25 16:15:18380 L"",
[email protected]45671612009-04-29 22:24:01381 L"window.domAutomationController.send(getFocusedElement());",
382 &actual));
initial.commit09911bf2008-07-26 23:55:29383 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
384 }
[email protected]8bcdec92009-02-25 16:15:18385
386 // At this point the renderer has sent us a message asking to advance the
387 // focus (as the end of the focus loop was reached in the renderer).
388 // We need to run the message loop to process it.
389 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
390 ui_test_utils::RunMessageLoop();
initial.commit09911bf2008-07-26 23:55:29391 }
392}
393
[email protected]9e0c83a2009-05-06 19:44:37394// Focus traversal while an interstitial is showing.
395IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversalOnInterstitial) {
396 HTTPTestServer* server = StartHTTPServer();
397
398 // First we navigate to our test page.
399 GURL url = server->TestServerPageW(kSimplePage);
400 ui_test_utils::NavigateToURL(browser(), url);
401
402 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00403 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]9e0c83a2009-05-06 19:44:37404 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00405 views::FocusManager::GetFocusManagerForNativeView(hwnd);
[email protected]9e0c83a2009-05-06 19:44:37406
407 // Focus should be on the page.
[email protected]7e383692009-06-12 19:14:54408 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38409 focus_manager->GetFocusedView());
[email protected]9e0c83a2009-05-06 19:44:37410
411 // Let's show an interstitial.
412 TestInterstitialPage* interstitial_page =
413 new TestInterstitialPage(browser()->GetSelectedTabContents(),
414 true, GURL("http://interstitial.com"));
415 interstitial_page->Show();
416 // Give some time for the interstitial to show.
417 MessageLoop::current()->PostDelayedTask(FROM_HERE,
418 new MessageLoop::QuitTask(),
419 1000);
420 ui_test_utils::RunMessageLoop();
421
422 // Click on the location bar.
423 LocationBarView* location_bar = browser_view->GetLocationBarView();
424 ui_controls::MoveMouseToCenterAndPress(location_bar,
425 ui_controls::LEFT,
426 ui_controls::DOWN | ui_controls::UP,
427 new MessageLoop::QuitTask());
428 ui_test_utils::RunMessageLoop();
429
430 const char* kExpElementIDs[] = {
431 "", // Initially no element in the page should be focused
432 // (the location bar is focused).
433 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
434 "gmapLink"
435 };
436
437 // Test forward focus traversal.
438 for (int i = 0; i < 2; ++i) {
439 // Location bar should be focused.
440 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
441
442 // Now let's press tab to move the focus.
443 for (int j = 0; j < 7; ++j) {
444 // Let's make sure the focus is on the expected element in the page.
445 std::string actual = interstitial_page->GetFocusedElement();
446 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
447
448 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false,
449 new MessageLoop::QuitTask());
450 ui_test_utils::RunMessageLoop();
451 // Ideally, we wouldn't sleep here and instead would use the event
452 // processed ack notification from the renderer. I am reluctant to create
453 // a new notification/callback for that purpose just for this test.
454 ::Sleep(kActionDelayMs);
455 }
456
457 // At this point the renderer has sent us a message asking to advance the
458 // focus (as the end of the focus loop was reached in the renderer).
459 // We need to run the message loop to process it.
460 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
461 ui_test_utils::RunMessageLoop();
462 }
463
464 // Now let's try reverse focus traversal.
465 for (int i = 0; i < 2; ++i) {
466 // Location bar should be focused.
467 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
468
469 // Now let's press shift-tab to move the focus in reverse.
470 for (int j = 0; j < 7; ++j) {
471 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, true, false,
472 new MessageLoop::QuitTask());
473 ui_test_utils::RunMessageLoop();
474 ::Sleep(kActionDelayMs);
475
476 // Let's make sure the focus is on the expected element in the page.
477 std::string actual = interstitial_page->GetFocusedElement();
478 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
479 }
480
481 // At this point the renderer has sent us a message asking to advance the
482 // focus (as the end of the focus loop was reached in the renderer).
483 // We need to run the message loop to process it.
484 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
485 ui_test_utils::RunMessageLoop();
486 }
487}
488
489// Focus stays on page with interstitials.
490IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
491 HTTPTestServer* server = StartHTTPServer();
492
493 // First we navigate to our test page.
494 GURL url = server->TestServerPageW(kSimplePage);
495 ui_test_utils::NavigateToURL(browser(), url);
496
497 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00498 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]9e0c83a2009-05-06 19:44:37499 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00500 views::FocusManager::GetFocusManagerForNativeView(hwnd);
[email protected]9e0c83a2009-05-06 19:44:37501
502 // Page should have focus.
[email protected]7e383692009-06-12 19:14:54503 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38504 focus_manager->GetFocusedView());
[email protected]9e0c83a2009-05-06 19:44:37505 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
506 HasFocus());
507
[email protected]7e383692009-06-12 19:14:54508 // Let's show an interstitial.erstitial
[email protected]9e0c83a2009-05-06 19:44:37509 TestInterstitialPage* interstitial_page =
510 new TestInterstitialPage(browser()->GetSelectedTabContents(),
511 true, GURL("http://interstitial.com"));
512 interstitial_page->Show();
513 // Give some time for the interstitial to show.
514 MessageLoop::current()->PostDelayedTask(FROM_HERE,
515 new MessageLoop::QuitTask(),
516 1000);
517 ui_test_utils::RunMessageLoop();
518
519 // The interstitial should have focus now.
[email protected]7e383692009-06-12 19:14:54520 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38521 focus_manager->GetFocusedView());
[email protected]9e0c83a2009-05-06 19:44:37522 EXPECT_TRUE(interstitial_page->HasFocus());
523
524 // Hide the interstitial.
525 interstitial_page->DontProceed();
526
527 // Focus should be back on the original page.
[email protected]7e383692009-06-12 19:14:54528 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38529 focus_manager->GetFocusedView());
[email protected]9e0c83a2009-05-06 19:44:37530 EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
531 HasFocus());
532}
533
[email protected]9bd491ee2008-12-10 22:31:07534// Make sure Find box can request focus, even when it is already open.
[email protected]8bcdec92009-02-25 16:15:18535IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
536 HTTPTestServer* server = StartHTTPServer();
license.botbf09a502008-08-24 00:55:55537
[email protected]9bd491ee2008-12-10 22:31:07538 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27539 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]8bcdec92009-02-25 16:15:18540 ui_test_utils::NavigateToURL(browser(), url);
[email protected]9bd491ee2008-12-10 22:31:07541
[email protected]8bcdec92009-02-25 16:15:18542 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00543 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]8bcdec92009-02-25 16:15:18544 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00545 views::FocusManager::GetFocusManagerForNativeView(hwnd);
[email protected]8bcdec92009-02-25 16:15:18546 LocationBarView* location_bar = browser_view->GetLocationBarView();
[email protected]9bd491ee2008-12-10 22:31:07547
548 // Press Ctrl+F, which will make the Find box open and request focus.
549 static const int VK_F = 0x46;
[email protected]8bcdec92009-02-25 16:15:18550 ui_controls::SendKeyPressNotifyWhenDone(L'F', true, false, false,
551 new MessageLoop::QuitTask());
552 ui_test_utils::RunMessageLoop();
553
554 // Ideally, we wouldn't sleep here and instead would intercept the
555 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we
556 // could create a RenderViewHostDelegate wrapper and hook-it up by either:
557 // - creating a factory used to create the delegate
558 // - making the test a private and overwriting the delegate member directly.
[email protected]9bd491ee2008-12-10 22:31:07559 ::Sleep(kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18560 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
561 ui_test_utils::RunMessageLoop();
562
563 views::View* 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 // Click on the location bar.
[email protected]8bcdec92009-02-25 16:15:18568 ui_controls::MoveMouseToCenterAndPress(location_bar,
569 ui_controls::LEFT,
570 ui_controls::DOWN | ui_controls::UP,
571 new MessageLoop::QuitTask());
572 ui_test_utils::RunMessageLoop();
573
[email protected]9bd491ee2008-12-10 22:31:07574 // Make sure the location bar is focused.
[email protected]8bcdec92009-02-25 16:15:18575 EXPECT_EQ(location_bar, focus_manager->GetFocusedView());
[email protected]9bd491ee2008-12-10 22:31:07576
577 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]8bcdec92009-02-25 16:15:18578 ui_controls::SendKeyPressNotifyWhenDone(L'F', true, false, false,
579 new MessageLoop::QuitTask());
580 ui_test_utils::RunMessageLoop();
581 focused_view = focus_manager->GetFocusedView();
582 ASSERT_TRUE(focused_view != NULL);
583 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
[email protected]9bd491ee2008-12-10 22:31:07584
585 // Set focus to the page.
[email protected]610d36a2009-05-22 23:00:38586 ui_controls::MoveMouseToCenterAndPress(
[email protected]7e383692009-06-12 19:14:54587 browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38588 ui_controls::LEFT,
589 ui_controls::DOWN | ui_controls::UP,
590 new MessageLoop::QuitTask());
[email protected]8bcdec92009-02-25 16:15:18591 ui_test_utils::RunMessageLoop();
[email protected]7e383692009-06-12 19:14:54592 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38593 focus_manager->GetFocusedView());
[email protected]9bd491ee2008-12-10 22:31:07594
595 // Now press Ctrl+F again and focus should move to the Find box.
[email protected]8bcdec92009-02-25 16:15:18596 ui_controls::SendKeyPressNotifyWhenDone(VK_F, true, false, false,
597 new MessageLoop::QuitTask());
598 ui_test_utils::RunMessageLoop();
599
600 // See remark above on why we wait.
[email protected]9bd491ee2008-12-10 22:31:07601 ::Sleep(kActionDelayMs);
[email protected]8bcdec92009-02-25 16:15:18602 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
603 ui_test_utils::RunMessageLoop();
604
605 focused_view = focus_manager->GetFocusedView();
606 ASSERT_TRUE(focused_view != NULL);
607 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
[email protected]9bd491ee2008-12-10 22:31:07608}
[email protected]401513c2009-03-12 00:21:28609
610// Makes sure the focus is in the right location when opening the different
611// types of tabs.
[email protected]bedb4a22009-06-25 00:47:50612// TODO(brettw) bug 15265 enable this test when it's fixed.
613IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabInitialFocus) {
[email protected]401513c2009-03-12 00:21:28614 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
[email protected]4a507a62009-05-28 00:10:00615 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd);
[email protected]401513c2009-03-12 00:21:28616 ASSERT_TRUE(browser_view);
617 views::FocusManager* focus_manager =
[email protected]82166b62009-06-30 18:48:00618 views::FocusManager::GetFocusManagerForNativeView(hwnd);
[email protected]401513c2009-03-12 00:21:28619 ASSERT_TRUE(focus_manager);
620
621 // Open the history tab, focus should be on the tab contents.
622 browser()->ShowHistoryTab();
[email protected]7e383692009-06-12 19:14:54623 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38624 focus_manager->GetFocusedView());
[email protected]401513c2009-03-12 00:21:28625
626 // Open the new tab, focus should be on the location bar.
627 browser()->NewTab();
628 EXPECT_EQ(browser_view->GetLocationBarView(),
629 focus_manager->GetFocusedView());
630
631 // Open the download tab, focus should be on the tab contents.
632 browser()->ShowDownloadsTab();
[email protected]7e383692009-06-12 19:14:54633 EXPECT_EQ(browser_view->GetTabContentsContainerView(),
[email protected]610d36a2009-05-22 23:00:38634 focus_manager->GetFocusedView());
[email protected]3e3f0eb2009-06-22 18:33:43635
636 // Open about:blank, focus should be on the location bar.
637 browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK,
638 true, -1, false, NULL);
639 EXPECT_EQ(browser_view->GetLocationBarView(),
640 focus_manager->GetFocusedView());
[email protected]401513c2009-03-12 00:21:28641}