blob: 160c3ab5a6598087af52eb76930efd57fe7237cf [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// 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
5#include "chrome/browser/view_ids.h"
6#include "chrome/views/view.h"
7#include "chrome/test/automation/browser_proxy.h"
8#include "chrome/test/automation/window_proxy.h"
9#include "chrome/test/automation/tab_proxy.h"
10#include "chrome/test/ui/ui_test.h"
11#include "net/url_request/url_request_unittest.h"
12
13namespace {
14
15// The delay waited after sending an OS simulated event.
16const int kActionDelayMs = 500;
17
18const wchar_t kDocRoot[] = L"chrome/test/data";
19
20const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html";
21const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html";
22const wchar_t kTypicalPage[] = L"files/focus/typical_page.html";
23
24class BrowserFocusTest : public UITest {
25 public:
26 BrowserFocusTest() {
27 show_window_ = true;
28 dom_automation_enabled_ = true;
29 }
30};
31
32// Activate a tab by clicking on it. Returns true if the call was successful
33// (meaning the messages were correctly sent, but does not guarantee the tab
34// has been changed).
35bool ActivateTabByClick(AutomationProxy* automation,
36 WindowProxy* browser_window,
37 int tab_index) {
38 // Click on the tab.
39 gfx::Rect bounds;
40
41 if (!browser_window->GetViewBounds(VIEW_ID_TAB_0 + tab_index, &bounds, true))
42 return false;
43
44 POINT click(bounds.CenterPoint().ToPOINT());
45 if (!browser_window->SimulateOSClick(click,
[email protected]c2dacc92008-10-16 23:51:3846 views::Event::EF_LEFT_BUTTON_DOWN))
initial.commit09911bf2008-07-26 23:55:2947 return false;
48
49 // Wait a bit to let the click be processed.
50 ::Sleep(kActionDelayMs);
51
52 return true;
53}
54
55} // namespace
56
57TEST_F(BrowserFocusTest, BrowsersRememberFocus) {
[email protected]dd265012009-01-08 20:45:2758 scoped_refptr<HTTPTestServer> server =
59 HTTPTestServer::CreateServer(kDocRoot);
60 ASSERT_TRUE(NULL != server.get());
initial.commit09911bf2008-07-26 23:55:2961
62 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:2763 GURL url = server->TestServerPageW(kSimplePage);
initial.commit09911bf2008-07-26 23:55:2964 scoped_ptr<TabProxy> tab(GetActiveTab());
65 EXPECT_NE(AUTOMATION_MSG_NAVIGATION_ERROR, tab->NavigateToURL(url));
66
67 // The focus should be on the Tab contents.
68 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:1369 ASSERT_TRUE(window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:2970
71 scoped_ptr<BrowserProxy> browser(automation()->
72 GetBrowserForWindow(window.get()));
[email protected]969ff7902008-08-28 22:11:1373 ASSERT_TRUE(browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:2974
75 int focused_view_id;
76 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
77 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id);
78
79 // Now hide the window, show it again, the focus should not have changed.
80 EXPECT_TRUE(window->SetVisible(false));
81 EXPECT_TRUE(window->SetVisible(true));
82 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
83 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id);
84
85 // Click on the location bar.
86 gfx::Rect bounds;
87 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, false));
88 POINT click(bounds.CenterPoint().ToPOINT());
89
90 EXPECT_TRUE(window->SimulateOSClick(click,
[email protected]c2dacc92008-10-16 23:51:3891 views::Event::EF_LEFT_BUTTON_DOWN));
initial.commit09911bf2008-07-26 23:55:2992 ::Sleep(kActionDelayMs);
93 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
94 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
95
96 // Hide the window, show it again, the focus should not have changed.
97 EXPECT_TRUE(window->SetVisible(false));
98 EXPECT_TRUE(window->SetVisible(true));
99 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
100 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
101
102 // Open a new browser window.
103 EXPECT_TRUE(automation()->OpenNewBrowserWindow(SW_SHOWNORMAL));
104 scoped_ptr<WindowProxy> new_window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:13105 ASSERT_TRUE(new_window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29106 scoped_ptr<BrowserProxy> new_browser(automation()->
107 GetBrowserForWindow(new_window.get()));
[email protected]969ff7902008-08-28 22:11:13108 ASSERT_TRUE(new_browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29109
110 // Let's make sure we have 2 different browser windows.
111 EXPECT_TRUE(browser->handle() != new_browser->handle());
112
113 tab.reset(new_browser->GetActiveTab());
114 EXPECT_TRUE(tab.get());
115 tab->NavigateToURL(url);
116
117 // Switch to the 1st browser window, focus should still be on the location
118 // bar and the second browser should have nothing focused.
119 EXPECT_TRUE(window->Activate());
120 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
121 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
122 EXPECT_TRUE(new_window->GetFocusedViewID(&focused_view_id));
123 EXPECT_EQ(-1, focused_view_id);
124
125 // Switch back to the second browser, focus should still be on the page.
126 EXPECT_TRUE(new_window->Activate());
127 EXPECT_TRUE(new_window->GetFocusedViewID(&focused_view_id));
128 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id);
129 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
130 EXPECT_EQ(-1, focused_view_id);
131}
132
133// Tabs remember focus.
134TEST_F(BrowserFocusTest, TabsRememberFocus) {
[email protected]dd265012009-01-08 20:45:27135 scoped_refptr<HTTPTestServer> server =
136 HTTPTestServer::CreateServer(kDocRoot);
137 ASSERT_TRUE(NULL != server.get());
initial.commit09911bf2008-07-26 23:55:29138
139 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:13140 ASSERT_TRUE(window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29141 scoped_ptr<BrowserProxy> browser(
142 automation()->GetBrowserForWindow(window.get()));
[email protected]969ff7902008-08-28 22:11:13143 ASSERT_TRUE(browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29144
145 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27146 GURL url = server->TestServerPageW(kSimplePage);
initial.commit09911bf2008-07-26 23:55:29147 scoped_ptr<TabProxy> tab(GetActiveTab());
148 tab->NavigateToURL(url);
149
150 // Create several tabs.
151 EXPECT_TRUE(browser->AppendTab(url));
152 EXPECT_TRUE(browser->AppendTab(url));
153 EXPECT_TRUE(browser->AppendTab(url));
154 EXPECT_TRUE(browser->AppendTab(url));
155
156 int tab_count;
157 EXPECT_TRUE(browser->GetTabCount(&tab_count));
158 ASSERT_EQ(5, tab_count);
159
160 // Alternate focus for the tab.
161 const bool kFocusPage[3][5] = {
162 { true, true, true, true, false },
163 { false, false, false, false, false },
164 { false, true, false, true, false }
165 };
166
167 for (int i = 1; i < 3; i++) {
168 for (int j = 0; j < 5; j++) {
169 // Click on the tab.
170 ActivateTabByClick(automation(), window.get(), j);
171
172 // Activate the location bar or the page.
173 int view_id = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER :
174 VIEW_ID_LOCATION_BAR;
175
176 gfx::Rect bounds;
177 EXPECT_TRUE(window->GetViewBounds(view_id, &bounds, true));
178 POINT click(bounds.CenterPoint().ToPOINT());
179 EXPECT_TRUE(window->SimulateOSClick(click,
[email protected]c2dacc92008-10-16 23:51:38180 views::Event::EF_LEFT_BUTTON_DOWN));
initial.commit09911bf2008-07-26 23:55:29181 ::Sleep(kActionDelayMs);
182 }
183
184 // Now come back to the tab and check the right view is focused.
185 for (int j = 0; j < 5; j++) {
186 // Click on the tab.
187 ActivateTabByClick(automation(), window.get(), j);
188
189 // Activate the location bar or the page.
190 int exp_view_id = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER :
191 VIEW_ID_LOCATION_BAR;
192 int focused_view_id;
193 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
194 EXPECT_EQ(exp_view_id, focused_view_id);
195 }
196 }
197}
198
199// Background window does not steal focus.
200TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) {
[email protected]dd265012009-01-08 20:45:27201 scoped_refptr<HTTPTestServer> server =
202 HTTPTestServer::CreateServer(kDocRoot);
203 ASSERT_TRUE(NULL != server.get());
initial.commit09911bf2008-07-26 23:55:29204
205 // First we navigate to our test page.
[email protected]dd265012009-01-08 20:45:27206 GURL simple_page_url = server->TestServerPageW(kSimplePage);
initial.commit09911bf2008-07-26 23:55:29207 scoped_ptr<TabProxy> tab(GetActiveTab());
208 tab->NavigateToURL(simple_page_url);
209
210 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:13211 ASSERT_TRUE(window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29212 scoped_ptr<BrowserProxy> browser(
213 automation()->GetBrowserForWindow(window.get()));
[email protected]969ff7902008-08-28 22:11:13214 ASSERT_TRUE(browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29215
216 // Open a new browser window.
217 EXPECT_TRUE(automation()->OpenNewBrowserWindow(SW_SHOWNORMAL));
218 scoped_ptr<WindowProxy> new_window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:13219 ASSERT_TRUE(window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29220 scoped_ptr<BrowserProxy> new_browser(
221 automation()->GetBrowserForWindow(new_window.get()));
[email protected]969ff7902008-08-28 22:11:13222 ASSERT_TRUE(new_browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29223
[email protected]dd265012009-01-08 20:45:27224 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage);
initial.commit09911bf2008-07-26 23:55:29225 new_browser->AppendTab(steal_focus_url);
226
227 // Make the first browser active
228 EXPECT_TRUE(window->Activate());
229
230 // Wait for the focus to be stolen by the other browser.
231 ::Sleep(2000);
232
233 // Make sure the 1st browser window is still active.
234 bool is_active = false;
235 EXPECT_TRUE(window->IsActive(&is_active));
236 EXPECT_TRUE(is_active);
237}
238
239// Page cannot steal focus when focus is on location bar.
240TEST_F(BrowserFocusTest, LocationBarLockFocus) {
[email protected]dd265012009-01-08 20:45:27241 scoped_refptr<HTTPTestServer> server =
242 HTTPTestServer::CreateServer(kDocRoot);
243 ASSERT_TRUE(NULL != server.get());
initial.commit09911bf2008-07-26 23:55:29244
245 // Open the page that steals focus.
[email protected]dd265012009-01-08 20:45:27246 GURL url = server->TestServerPageW(kStealFocusPage);
initial.commit09911bf2008-07-26 23:55:29247 scoped_ptr<TabProxy> tab(GetActiveTab());
248 tab->NavigateToURL(url);
249
250 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:13251 ASSERT_TRUE(window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29252 scoped_ptr<BrowserProxy> browser(
253 automation()->GetBrowserForWindow(window.get()));
[email protected]969ff7902008-08-28 22:11:13254 ASSERT_TRUE(browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29255
[email protected]9bd491ee2008-12-10 22:31:07256 // Click on the location bar.
initial.commit09911bf2008-07-26 23:55:29257 gfx::Rect bounds;
258 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, true));
259 POINT click(bounds.CenterPoint().ToPOINT());
260 EXPECT_TRUE(window->SimulateOSClick(click,
[email protected]c2dacc92008-10-16 23:51:38261 views::Event::EF_LEFT_BUTTON_DOWN));
initial.commit09911bf2008-07-26 23:55:29262 ::Sleep(kActionDelayMs);
263
264 // Wait for the page to steal focus.
265 ::Sleep(2000);
266
267 // Make sure the location bar is still focused.
268 int focused_view_id;
269 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
270 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
271}
272
273// Focus traversal
274TEST_F(BrowserFocusTest, FocusTraversal) {
[email protected]dd265012009-01-08 20:45:27275 scoped_refptr<HTTPTestServer> server =
276 HTTPTestServer::CreateServer(kDocRoot);
277 ASSERT_TRUE(NULL != server.get());
initial.commit09911bf2008-07-26 23:55:29278
279 // Open the page the test page.
[email protected]dd265012009-01-08 20:45:27280 GURL url = server->TestServerPageW(kTypicalPage);
initial.commit09911bf2008-07-26 23:55:29281 scoped_ptr<TabProxy> tab(GetActiveTab());
282 tab->NavigateToURL(url);
283
284 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow());
[email protected]969ff7902008-08-28 22:11:13285 ASSERT_TRUE(window.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29286 scoped_ptr<BrowserProxy> browser(
287 automation()->GetBrowserForWindow(window.get()));
[email protected]969ff7902008-08-28 22:11:13288 ASSERT_TRUE(browser.get() != NULL);
initial.commit09911bf2008-07-26 23:55:29289
290 // Click on the location bar.
291 gfx::Rect bounds;
292 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, true));
293 POINT click(bounds.CenterPoint().ToPOINT());
294 EXPECT_TRUE(window->SimulateOSClick(click,
[email protected]c2dacc92008-10-16 23:51:38295 views::Event::EF_LEFT_BUTTON_DOWN));
initial.commit09911bf2008-07-26 23:55:29296 ::Sleep(kActionDelayMs);
297
298 const wchar_t* kExpElementIDs[] = {
299 L"", // Initially no element in the page should be focused
300 // (the location bar is focused).
301 L"textEdit", L"searchButton", L"luckyButton", L"googleLink", L"gmailLink",
302 L"gmapLink"
303 };
304
305 // Test forward focus traversal.
306 for (int i = 0; i < 3; ++i) {
307 // Location bar should be focused.
308 int focused_view_id;
309 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
310 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
311
312 // Now let's press tab to move the focus.
313 for (int j = 0; j < 7; ++j) {
314 // Let's make sure the focus is on the expected element in the page.
315 std::wstring actual;
316 ASSERT_TRUE(tab->ExecuteAndExtractString(L"",
[email protected]f29acf52008-11-03 20:08:33317 L"window.domAutomationController.send(getFocusedElement());",
initial.commit09911bf2008-07-26 23:55:29318 &actual));
319 ASSERT_STREQ(kExpElementIDs[j], actual.c_str());
320
321 window->SimulateOSKeyPress(L'\t', 0);
322 ::Sleep(kActionDelayMs);
323 }
324 }
325
326 // Now let's try reverse focus traversal.
327 for (int i = 0; i < 3; ++i) {
328 // Location bar should be focused.
329 int focused_view_id;
330 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
331 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
332
333 // Now let's press tab to move the focus.
334 for (int j = 0; j < 7; ++j) {
[email protected]c2dacc92008-10-16 23:51:38335 window->SimulateOSKeyPress(L'\t', views::Event::EF_SHIFT_DOWN);
initial.commit09911bf2008-07-26 23:55:29336 ::Sleep(kActionDelayMs);
337
338 // Let's make sure the focus is on the expected element in the page.
339 std::wstring actual;
340 ASSERT_TRUE(tab->ExecuteAndExtractString(L"",
[email protected]f29acf52008-11-03 20:08:33341 L"window.domAutomationController.send(getFocusedElement());",
initial.commit09911bf2008-07-26 23:55:29342 &actual));
343 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
344 }
345 }
346}
347
[email protected]9bd491ee2008-12-10 22:31:07348// Make sure Find box can request focus, even when it is already open.
349TEST_F(BrowserFocusTest, FindFocusTest) {
[email protected]dd265012009-01-08 20:45:27350 scoped_refptr<HTTPTestServer> server =
351 HTTPTestServer::CreateServer(kDocRoot);
352 ASSERT_TRUE(NULL != server.get());
license.botbf09a502008-08-24 00:55:55353
[email protected]9bd491ee2008-12-10 22:31:07354 // Open some page (any page that doesn't steal focus).
[email protected]dd265012009-01-08 20:45:27355 GURL url = server->TestServerPageW(kTypicalPage);
[email protected]9bd491ee2008-12-10 22:31:07356 scoped_ptr<TabProxy> tab(GetActiveTab());
357 tab->NavigateToURL(url);
358
359 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow());
360 ASSERT_TRUE(window.get() != NULL);
361 scoped_ptr<BrowserProxy> browser(
362 automation()->GetBrowserForWindow(window.get()));
363 ASSERT_TRUE(browser.get() != NULL);
364
365 // Press Ctrl+F, which will make the Find box open and request focus.
366 static const int VK_F = 0x46;
367 EXPECT_TRUE(window->SimulateOSKeyPress(VK_F, views::Event::EF_CONTROL_DOWN));
368 ::Sleep(kActionDelayMs);
369 int focused_view_id;
370 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
371 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view_id);
372
373 // Click on the location bar.
374 gfx::Rect bounds;
375 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, true));
376 POINT click(bounds.CenterPoint().ToPOINT());
377 EXPECT_TRUE(window->SimulateOSClick(click,
378 views::Event::EF_LEFT_BUTTON_DOWN));
379 ::Sleep(kActionDelayMs);
380 // Make sure the location bar is focused.
381 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
382 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id);
383
384 // Now press Ctrl+F again and focus should move to the Find box.
385 EXPECT_TRUE(window->SimulateOSKeyPress(VK_F, views::Event::EF_CONTROL_DOWN));
386 ::Sleep(kActionDelayMs);
387 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
388 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view_id);
389
390 // Set focus to the page.
391 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER, &bounds, true));
392 click = bounds.CenterPoint().ToPOINT();
393 EXPECT_TRUE(window->SimulateOSClick(click,
394 views::Event::EF_LEFT_BUTTON_DOWN));
395 ::Sleep(kActionDelayMs);
396 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
397 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id);
398
399 // Now press Ctrl+F again and focus should move to the Find box.
400 EXPECT_TRUE(window->SimulateOSKeyPress(VK_F, views::Event::EF_CONTROL_DOWN));
401 ::Sleep(kActionDelayMs);
402 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id));
403 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view_id);
404}