| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/message_loop.h" |
| 6 #include "chrome/browser/automation/ui_controls.h" |
| 7 #include "chrome/browser/browser.h" |
| 8 #include "chrome/browser/dom_operation_notification_details.h" |
| 9 #include "chrome/browser/tab_contents/web_contents.h" |
| 5 #include "chrome/browser/view_ids.h" | 10 #include "chrome/browser/view_ids.h" |
| 11 #include "chrome/browser/views/frame/browser_view.h" |
| 12 #include "chrome/browser/views/location_bar_view.h" |
| 13 #include "chrome/common/notification_details.h" |
| 14 #include "chrome/common/notification_observer.h" |
| 15 #include "chrome/common/notification_service.h" |
| 16 #include "chrome/common/notification_source.h" |
| 17 #include "chrome/common/notification_type.h" |
| 18 #include "chrome/views/focus_manager.h" |
| 6 #include "chrome/views/view.h" | 19 #include "chrome/views/view.h" |
| 7 #include "chrome/test/automation/browser_proxy.h" | 20 #include "chrome/views/window.h" |
| 8 #include "chrome/test/automation/window_proxy.h" | 21 #include "chrome/test/in_process_browser_test.h" |
| 9 #include "chrome/test/automation/tab_proxy.h" | 22 #include "chrome/test/ui_test_utils.h" |
| 10 #include "chrome/test/ui/ui_test.h" | 23 |
| 11 #include "net/url_request/url_request_unittest.h" | |
| 12 | 24 |
| 13 namespace { | 25 namespace { |
| 14 | 26 |
| 15 // The delay waited after sending an OS simulated event. | 27 // The delay waited in some cases where we don't have a notifications for an |
| 28 // action we take. |
| 16 const int kActionDelayMs = 500; | 29 const int kActionDelayMs = 500; |
| 17 | 30 |
| 18 const wchar_t kDocRoot[] = L"chrome/test/data"; | |
| 19 | |
| 20 const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html"; | 31 const wchar_t kSimplePage[] = L"files/focus/page_with_focus.html"; |
| 21 const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html"; | 32 const wchar_t kStealFocusPage[] = L"files/focus/page_steals_focus.html"; |
| 22 const wchar_t kTypicalPage[] = L"files/focus/typical_page.html"; | 33 const wchar_t kTypicalPage[] = L"files/focus/typical_page.html"; |
| 23 | 34 |
| 24 class BrowserFocusTest : public UITest { | 35 class BrowserFocusTest : public InProcessBrowserTest { |
| 25 public: | 36 public: |
| 26 BrowserFocusTest() { | 37 BrowserFocusTest() { |
| 27 show_window_ = true; | 38 set_show_window(true); |
| 28 dom_automation_enabled_ = true; | 39 EnableDOMAutomation(); |
| 29 } | 40 } |
| 30 }; | 41 }; |
| 31 | 42 |
| 32 // Activate a tab by clicking on it. Returns true if the call was successful | 43 class JavaScriptRunner : public NotificationObserver { |
| 33 // (meaning the messages were correctly sent, but does not guarantee the tab | 44 public: |
| 34 // has been changed). | 45 JavaScriptRunner(WebContents* web_contents, |
| 35 bool ActivateTabByClick(AutomationProxy* automation, | 46 const std::wstring& frame_xpath, |
| 36 WindowProxy* browser_window, | 47 const std::wstring& jscript) |
| 37 int tab_index) { | 48 : web_contents_(web_contents), |
| 38 // Click on the tab. | 49 frame_xpath_(frame_xpath), |
| 39 gfx::Rect bounds; | 50 jscript_(jscript) { |
| 51 NotificationService::current()-> |
| 52 AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE, |
| 53 Source<WebContents>(web_contents)); |
| 54 } |
| 40 | 55 |
| 41 if (!browser_window->GetViewBounds(VIEW_ID_TAB_0 + tab_index, &bounds, true)) | 56 virtual void Observe(NotificationType type, |
| 42 return false; | 57 const NotificationSource& source, |
| 58 const NotificationDetails& details) { |
| 59 Details<DomOperationNotificationDetails> dom_op_details(details); |
| 60 result_ = dom_op_details->json(); |
| 61 // The Jasonified response has quotes, remove them. |
| 62 if (result_.length() > 1 && result_[0] == '"') |
| 63 result_ = result_.substr(1, result_.length() - 2); |
| 43 | 64 |
| 44 POINT click(bounds.CenterPoint().ToPOINT()); | 65 NotificationService::current()-> |
| 45 if (!browser_window->SimulateOSClick(click, | 66 RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE, |
| 46 views::Event::EF_LEFT_BUTTON_DOWN)) | 67 Source<WebContents>(web_contents_)); |
| 47 return false; | 68 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 69 } |
| 48 | 70 |
| 49 // Wait a bit to let the click be processed. | 71 std::string Run() { |
| 50 ::Sleep(kActionDelayMs); | 72 // The DOMAutomationController requires an automation ID, eventhough we are |
| 73 // not using it in this case. |
| 74 web_contents_->render_view_host()->ExecuteJavascriptInWebFrame( |
| 75 frame_xpath_, L"window.domAutomationController.setAutomationId(0);"); |
| 51 | 76 |
| 52 return true; | 77 web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath_, |
| 53 } | 78 jscript_); |
| 79 ui_test_utils::RunMessageLoop(); |
| 80 return result_; |
| 81 } |
| 82 |
| 83 private: |
| 84 WebContents* web_contents_; |
| 85 std::wstring frame_xpath_; |
| 86 std::wstring jscript_; |
| 87 std::string result_; |
| 88 |
| 89 DISALLOW_COPY_AND_ASSIGN(JavaScriptRunner); |
| 90 }; |
| 54 | 91 |
| 55 } // namespace | 92 } // namespace |
| 56 | 93 |
| 57 TEST_F(BrowserFocusTest, BrowsersRememberFocus) { | 94 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) { |
| 58 scoped_refptr<HTTPTestServer> server = | 95 HTTPTestServer* server = StartHTTPServer(); |
| 59 HTTPTestServer::CreateServer(kDocRoot, NULL); | |
| 60 ASSERT_TRUE(NULL != server.get()); | |
| 61 | 96 |
| 62 // First we navigate to our test page. | 97 // First we navigate to our test page. |
| 63 GURL url = server->TestServerPageW(kSimplePage); | 98 GURL url = server->TestServerPageW(kSimplePage); |
| 64 scoped_ptr<TabProxy> tab(GetActiveTab()); | 99 ui_test_utils::NavigateToURL(browser(), url); |
| 65 EXPECT_NE(AUTOMATION_MSG_NAVIGATION_ERROR, tab->NavigateToURL(url)); | |
| 66 | 100 |
| 67 // The focus should be on the Tab contents. | 101 // The focus should be on the Tab contents. |
| 68 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow()); | 102 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); |
| 69 ASSERT_TRUE(window.get() != NULL); | 103 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd); |
| 104 ASSERT_TRUE(browser_view); |
| 105 views::FocusManager* focus_manager = |
| 106 views::FocusManager::GetFocusManager(hwnd); |
| 107 ASSERT_TRUE(focus_manager); |
| 70 | 108 |
| 71 scoped_ptr<BrowserProxy> browser(window->GetBrowser()); | 109 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView()); |
| 72 ASSERT_TRUE(browser.get() != NULL); | |
| 73 | |
| 74 int focused_view_id; | |
| 75 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | |
| 76 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id); | |
| 77 | 110 |
| 78 // Now hide the window, show it again, the focus should not have changed. | 111 // Now hide the window, show it again, the focus should not have changed. |
| 79 EXPECT_TRUE(window->SetVisible(false)); | 112 // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of |
| 80 EXPECT_TRUE(window->SetVisible(true)); | 113 // using Windows API. |
| 81 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 114 ::ShowWindow(hwnd, SW_HIDE); |
| 82 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id); | 115 ::ShowWindow(hwnd, SW_SHOW); |
| 116 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView()); |
| 83 | 117 |
| 84 // Click on the location bar. | 118 // Click on the location bar. |
| 85 gfx::Rect bounds; | 119 LocationBarView* location_bar = browser_view->GetLocationBarView(); |
| 86 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, false)); | 120 ui_controls::MoveMouseToCenterAndPress(location_bar, |
| 87 POINT click(bounds.CenterPoint().ToPOINT()); | 121 ui_controls::LEFT, |
| 88 | 122 ui_controls::DOWN | ui_controls::UP, |
| 89 EXPECT_TRUE(window->SimulateOSClick(click, | 123 new MessageLoop::QuitTask()); |
| 90 views::Event::EF_LEFT_BUTTON_DOWN)); | 124 ui_test_utils::RunMessageLoop(); |
| 91 ::Sleep(kActionDelayMs); | 125 // Location bar should have focus. |
| 92 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 126 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 93 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | |
| 94 | 127 |
| 95 // Hide the window, show it again, the focus should not have changed. | 128 // Hide the window, show it again, the focus should not have changed. |
| 96 EXPECT_TRUE(window->SetVisible(false)); | 129 ::ShowWindow(hwnd, SW_HIDE); |
| 97 EXPECT_TRUE(window->SetVisible(true)); | 130 ::ShowWindow(hwnd, SW_SHOW); |
| 98 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 131 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 99 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | |
| 100 | 132 |
| 101 // Open a new browser window. | 133 // Open a new browser window. |
| 102 EXPECT_TRUE(automation()->OpenNewBrowserWindow(SW_SHOWNORMAL)); | 134 Browser* browser2 = Browser::Create(browser()->profile()); |
| 103 scoped_ptr<WindowProxy> new_window(automation()->GetActiveWindow()); | 135 ASSERT_TRUE(browser2); |
| 104 ASSERT_TRUE(new_window.get() != NULL); | 136 browser2->AddBlankTab(true); |
| 105 scoped_ptr<BrowserProxy> new_browser(new_window->GetBrowser()); | 137 browser2->window()->Show(); |
| 106 ASSERT_TRUE(new_browser.get() != NULL); | 138 ui_test_utils::NavigateToURL(browser2, url); |
| 107 | 139 |
| 108 // Let's make sure we have 2 different browser windows. | 140 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle()); |
| 109 EXPECT_TRUE(browser->handle() != new_browser->handle()); | 141 BrowserView* browser_view2 = BrowserView::GetBrowserViewForHWND(hwnd2); |
| 110 | 142 ASSERT_TRUE(browser_view2); |
| 111 tab.reset(new_browser->GetActiveTab()); | 143 views::FocusManager* focus_manager2 = |
| 112 EXPECT_TRUE(tab.get()); | 144 views::FocusManager::GetFocusManager(hwnd2); |
| 113 tab->NavigateToURL(url); | 145 ASSERT_TRUE(focus_manager2); |
| 146 EXPECT_EQ(browser_view2->GetContentsView(), focus_manager2->GetFocusedView()); |
| 114 | 147 |
| 115 // Switch to the 1st browser window, focus should still be on the location | 148 // Switch to the 1st browser window, focus should still be on the location |
| 116 // bar and the second browser should have nothing focused. | 149 // bar and the second browser should have nothing focused. |
| 117 EXPECT_TRUE(window->Activate()); | 150 browser()->window()->Activate(); |
| 118 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 151 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 119 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | 152 EXPECT_EQ(NULL, focus_manager2->GetFocusedView()); |
| 120 EXPECT_TRUE(new_window->GetFocusedViewID(&focused_view_id)); | |
| 121 EXPECT_EQ(-1, focused_view_id); | |
| 122 | 153 |
| 123 // Switch back to the second browser, focus should still be on the page. | 154 // Switch back to the second browser, focus should still be on the page. |
| 124 EXPECT_TRUE(new_window->Activate()); | 155 browser2->window()->Activate(); |
| 125 EXPECT_TRUE(new_window->GetFocusedViewID(&focused_view_id)); | 156 EXPECT_EQ(NULL, focus_manager->GetFocusedView()); |
| 126 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id); | 157 EXPECT_EQ(browser_view2->GetContentsView(), focus_manager2->GetFocusedView()); |
| 127 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 158 |
| 128 EXPECT_EQ(-1, focused_view_id); | 159 // Close the 2nd browser to avoid a DCHECK(). |
| 160 browser_view2->Close(); |
| 129 } | 161 } |
| 130 | 162 |
| 131 // Tabs remember focus. | 163 // Tabs remember focus. |
| 132 TEST_F(BrowserFocusTest, TabsRememberFocus) { | 164 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) { |
| 133 scoped_refptr<HTTPTestServer> server = | 165 HTTPTestServer* server = StartHTTPServer(); |
| 134 HTTPTestServer::CreateServer(kDocRoot, NULL); | |
| 135 ASSERT_TRUE(NULL != server.get()); | |
| 136 | |
| 137 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow()); | |
| 138 ASSERT_TRUE(window.get() != NULL); | |
| 139 scoped_ptr<BrowserProxy> browser(window->GetBrowser()); | |
| 140 ASSERT_TRUE(browser.get() != NULL); | |
| 141 | 166 |
| 142 // First we navigate to our test page. | 167 // First we navigate to our test page. |
| 143 GURL url = server->TestServerPageW(kSimplePage); | 168 GURL url = server->TestServerPageW(kSimplePage); |
| 144 scoped_ptr<TabProxy> tab(GetActiveTab()); | 169 ui_test_utils::NavigateToURL(browser(), url); |
| 145 tab->NavigateToURL(url); | 170 |
| 171 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); |
| 172 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd); |
| 173 ASSERT_TRUE(browser_view); |
| 174 |
| 175 views::FocusManager* focus_manager = |
| 176 views::FocusManager::GetFocusManager(hwnd); |
| 177 ASSERT_TRUE(focus_manager); |
| 146 | 178 |
| 147 // Create several tabs. | 179 // Create several tabs. |
| 148 EXPECT_TRUE(browser->AppendTab(url)); | 180 for (int i = 0; i < 4; ++i) |
| 149 EXPECT_TRUE(browser->AppendTab(url)); | 181 browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, NULL); |
| 150 EXPECT_TRUE(browser->AppendTab(url)); | |
| 151 EXPECT_TRUE(browser->AppendTab(url)); | |
| 152 | |
| 153 int tab_count; | |
| 154 EXPECT_TRUE(browser->GetTabCount(&tab_count)); | |
| 155 ASSERT_EQ(5, tab_count); | |
| 156 | 182 |
| 157 // Alternate focus for the tab. | 183 // Alternate focus for the tab. |
| 158 const bool kFocusPage[3][5] = { | 184 const bool kFocusPage[3][5] = { |
| 159 { true, true, true, true, false }, | 185 { true, true, true, true, false }, |
| 160 { false, false, false, false, false }, | 186 { false, false, false, false, false }, |
| 161 { false, true, false, true, false } | 187 { false, true, false, true, false } |
| 162 }; | 188 }; |
| 163 | 189 |
| 164 for (int i = 1; i < 3; i++) { | 190 for (int i = 1; i < 3; i++) { |
| 165 for (int j = 0; j < 5; j++) { | 191 for (int j = 0; j < 5; j++) { |
| 166 // Click on the tab. | 192 // Activate the tab. |
| 167 ActivateTabByClick(automation(), window.get(), j); | 193 browser()->SelectTabContentsAt(j, true); |
| 168 | 194 |
| 169 // Activate the location bar or the page. | 195 // Activate the location bar or the page. |
| 170 int view_id = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER : | 196 views::View* view_to_focus = kFocusPage[i][j] ? |
| 171 VIEW_ID_LOCATION_BAR; | 197 browser_view->GetContentsView() : |
| 172 | 198 browser_view->GetLocationBarView(); |
| 173 gfx::Rect bounds; | 199 |
| 174 EXPECT_TRUE(window->GetViewBounds(view_id, &bounds, true)); | 200 ui_controls::MoveMouseToCenterAndPress(view_to_focus, |
| 175 POINT click(bounds.CenterPoint().ToPOINT()); | 201 ui_controls::LEFT, |
| 176 EXPECT_TRUE(window->SimulateOSClick(click, | 202 ui_controls::DOWN | |
| 177 views::Event::EF_LEFT_BUTTON_DOWN)); | 203 ui_controls::UP, |
| 178 ::Sleep(kActionDelayMs); | 204 new MessageLoop::QuitTask()); |
| 205 ui_test_utils::RunMessageLoop(); |
| 179 } | 206 } |
| 180 | 207 |
| 181 // Now come back to the tab and check the right view is focused. | 208 // Now come back to the tab and check the right view is focused. |
| 182 for (int j = 0; j < 5; j++) { | 209 for (int j = 0; j < 5; j++) { |
| 183 // Click on the tab. | 210 // Activate the tab. |
| 184 ActivateTabByClick(automation(), window.get(), j); | 211 browser()->SelectTabContentsAt(j, true); |
| 185 | 212 |
| 186 // Activate the location bar or the page. | 213 // Activate the location bar or the page. |
| 187 int exp_view_id = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER : | 214 views::View* view = kFocusPage[i][j] ? |
| 188 VIEW_ID_LOCATION_BAR; | 215 browser_view->GetContentsView() : |
| 189 int focused_view_id; | 216 browser_view->GetLocationBarView(); |
| 190 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 217 EXPECT_EQ(view, focus_manager->GetFocusedView()); |
| 191 EXPECT_EQ(exp_view_id, focused_view_id); | |
| 192 } | 218 } |
| 193 } | 219 } |
| 194 } | 220 } |
| 195 | 221 |
| 196 // Background window does not steal focus. | 222 // Background window does not steal focus. |
| 197 TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) { | 223 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) { |
| 198 scoped_refptr<HTTPTestServer> server = | 224 HTTPTestServer* server = StartHTTPServer(); |
| 199 HTTPTestServer::CreateServer(kDocRoot, NULL); | |
| 200 ASSERT_TRUE(NULL != server.get()); | |
| 201 | 225 |
| 202 // First we navigate to our test page. | 226 // First we navigate to our test page. |
| 203 GURL simple_page_url = server->TestServerPageW(kSimplePage); | 227 GURL url = server->TestServerPageW(kSimplePage); |
| 204 scoped_ptr<TabProxy> tab(GetActiveTab()); | 228 ui_test_utils::NavigateToURL(browser(), url); |
| 205 tab->NavigateToURL(simple_page_url); | |
| 206 | |
| 207 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow()); | |
| 208 ASSERT_TRUE(window.get() != NULL); | |
| 209 scoped_ptr<BrowserProxy> browser(window->GetBrowser()); | |
| 210 ASSERT_TRUE(browser.get() != NULL); | |
| 211 | 229 |
| 212 // Open a new browser window. | 230 // Open a new browser window. |
| 213 EXPECT_TRUE(automation()->OpenNewBrowserWindow(SW_SHOWNORMAL)); | 231 Browser* browser2 = Browser::Create(browser()->profile()); |
| 214 scoped_ptr<WindowProxy> new_window(automation()->GetActiveWindow()); | 232 ASSERT_TRUE(browser2); |
| 215 ASSERT_TRUE(window.get() != NULL); | 233 browser2->AddBlankTab(true); |
| 216 scoped_ptr<BrowserProxy> new_browser(new_window->GetBrowser()); | 234 browser2->window()->Show(); |
| 217 ASSERT_TRUE(new_browser.get() != NULL); | |
| 218 | |
| 219 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage); | 235 GURL steal_focus_url = server->TestServerPageW(kStealFocusPage); |
| 220 new_browser->AppendTab(steal_focus_url); | 236 ui_test_utils::NavigateToURL(browser2, steal_focus_url); |
| 221 | 237 |
| 222 // Make the first browser active | 238 // Activate the first browser. |
| 223 EXPECT_TRUE(window->Activate()); | 239 browser()->window()->Activate(); |
| 224 | 240 |
| 225 // Wait for the focus to be stolen by the other browser. | 241 // Wait for the focus to be stolen by the other browser. |
| 226 ::Sleep(2000); | 242 ::Sleep(2000); |
| 227 | 243 |
| 228 // Make sure the 1st browser window is still active. | 244 // Make sure the first browser is still active. |
| 229 bool is_active = false; | 245 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); |
| 230 EXPECT_TRUE(window->IsActive(&is_active)); | 246 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd); |
| 231 EXPECT_TRUE(is_active); | 247 ASSERT_TRUE(browser_view); |
| 248 EXPECT_TRUE(browser_view->frame()->GetWindow()->IsActive()); |
| 249 |
| 250 // Close the 2nd browser to avoid a DCHECK(). |
| 251 HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle()); |
| 252 BrowserView* browser_view2 = BrowserView::GetBrowserViewForHWND(hwnd2); |
| 253 browser_view2->Close(); |
| 232 } | 254 } |
| 233 | 255 |
| 234 // Page cannot steal focus when focus is on location bar. | 256 // Page cannot steal focus when focus is on location bar. |
| 235 TEST_F(BrowserFocusTest, LocationBarLockFocus) { | 257 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) { |
| 236 scoped_refptr<HTTPTestServer> server = | 258 HTTPTestServer* server = StartHTTPServer(); |
| 237 HTTPTestServer::CreateServer(kDocRoot, NULL); | |
| 238 ASSERT_TRUE(NULL != server.get()); | |
| 239 | 259 |
| 240 // Open the page that steals focus. | 260 // Open the page that steals focus. |
| 241 GURL url = server->TestServerPageW(kStealFocusPage); | 261 GURL url = server->TestServerPageW(kStealFocusPage); |
| 242 scoped_ptr<TabProxy> tab(GetActiveTab()); | 262 ui_test_utils::NavigateToURL(browser(), url); |
| 243 tab->NavigateToURL(url); | 263 |
| 244 | 264 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); |
| 245 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow()); | 265 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd); |
| 246 ASSERT_TRUE(window.get() != NULL); | 266 views::FocusManager* focus_manager = |
| 247 scoped_ptr<BrowserProxy> browser(window->GetBrowser()); | 267 views::FocusManager::GetFocusManager(hwnd); |
| 248 ASSERT_TRUE(browser.get() != NULL); | |
| 249 | 268 |
| 250 // Click on the location bar. | 269 // Click on the location bar. |
| 251 gfx::Rect bounds; | 270 LocationBarView* location_bar = browser_view->GetLocationBarView(); |
| 252 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, true)); | 271 ui_controls::MoveMouseToCenterAndPress(location_bar, |
| 253 POINT click(bounds.CenterPoint().ToPOINT()); | 272 ui_controls::LEFT, |
| 254 EXPECT_TRUE(window->SimulateOSClick(click, | 273 ui_controls::DOWN | ui_controls::UP, |
| 255 views::Event::EF_LEFT_BUTTON_DOWN)); | 274 new MessageLoop::QuitTask()); |
| 256 ::Sleep(kActionDelayMs); | 275 ui_test_utils::RunMessageLoop(); |
| 257 | 276 |
| 258 // Wait for the page to steal focus. | 277 // Wait for the page to steal focus. |
| 259 ::Sleep(2000); | 278 ::Sleep(2000); |
| 260 | 279 |
| 261 // Make sure the location bar is still focused. | 280 // Make sure the location bar is still focused. |
| 262 int focused_view_id; | 281 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 263 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | |
| 264 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | |
| 265 } | 282 } |
| 266 | 283 |
| 267 // Focus traversal | 284 // Focus traversal |
| 268 TEST_F(BrowserFocusTest, FocusTraversal) { | 285 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { |
| 269 scoped_refptr<HTTPTestServer> server = | 286 HTTPTestServer* server = StartHTTPServer(); |
| 270 HTTPTestServer::CreateServer(kDocRoot, NULL); | 287 |
| 271 ASSERT_TRUE(NULL != server.get()); | 288 // First we navigate to our test page. |
| 272 | |
| 273 // Open the page the test page. | |
| 274 GURL url = server->TestServerPageW(kTypicalPage); | 289 GURL url = server->TestServerPageW(kTypicalPage); |
| 275 scoped_ptr<TabProxy> tab(GetActiveTab()); | 290 ui_test_utils::NavigateToURL(browser(), url); |
| 276 tab->NavigateToURL(url); | 291 |
| 277 | 292 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); |
| 278 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow()); | 293 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd); |
| 279 ASSERT_TRUE(window.get() != NULL); | 294 views::FocusManager* focus_manager = |
| 280 scoped_ptr<BrowserProxy> browser(window->GetBrowser()); | 295 views::FocusManager::GetFocusManager(hwnd); |
| 281 ASSERT_TRUE(browser.get() != NULL); | |
| 282 | 296 |
| 283 // Click on the location bar. | 297 // Click on the location bar. |
| 284 gfx::Rect bounds; | 298 LocationBarView* location_bar = browser_view->GetLocationBarView(); |
| 285 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, true)); | 299 ui_controls::MoveMouseToCenterAndPress(location_bar, |
| 286 POINT click(bounds.CenterPoint().ToPOINT()); | 300 ui_controls::LEFT, |
| 287 EXPECT_TRUE(window->SimulateOSClick(click, | 301 ui_controls::DOWN | ui_controls::UP, |
| 288 views::Event::EF_LEFT_BUTTON_DOWN)); | 302 new MessageLoop::QuitTask()); |
| 289 ::Sleep(kActionDelayMs); | 303 ui_test_utils::RunMessageLoop(); |
| 290 | 304 |
| 291 const wchar_t* kExpElementIDs[] = { | 305 const char* kExpElementIDs[] = { |
| 292 L"", // Initially no element in the page should be focused | 306 "", // Initially no element in the page should be focused |
| 293 // (the location bar is focused). | 307 // (the location bar is focused). |
| 294 L"textEdit", L"searchButton", L"luckyButton", L"googleLink", L"gmailLink", | 308 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink", |
| 295 L"gmapLink" | 309 "gmapLink" |
| 296 }; | 310 }; |
| 297 | 311 |
| 298 // Test forward focus traversal. | 312 // Test forward focus traversal. |
| 299 for (int i = 0; i < 3; ++i) { | 313 for (int i = 0; i < 3; ++i) { |
| 300 // Location bar should be focused. | 314 // Location bar should be focused. |
| 301 int focused_view_id; | 315 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 302 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | |
| 303 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | |
| 304 | 316 |
| 305 // Now let's press tab to move the focus. | 317 // Now let's press tab to move the focus. |
| 306 for (int j = 0; j < 7; ++j) { | 318 for (int j = 0; j < 7; ++j) { |
| 307 // Let's make sure the focus is on the expected element in the page. | 319 // Let's make sure the focus is on the expected element in the page. |
| 308 std::wstring actual; | 320 JavaScriptRunner js_runner( |
| 309 ASSERT_TRUE(tab->ExecuteAndExtractString(L"", | 321 browser()->GetSelectedTabContents()->AsWebContents(), |
| 310 L"window.domAutomationController.send(getFocusedElement());", | 322 L"", |
| 311 &actual)); | 323 L"window.domAutomationController.send(getFocusedElement());"); |
| 324 std::string actual = js_runner.Run(); |
| 312 ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); | 325 ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); |
| 313 | 326 |
| 314 window->SimulateOSKeyPress(L'\t', 0); | 327 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, false, false, |
| 328 new MessageLoop::QuitTask()); |
| 329 ui_test_utils::RunMessageLoop(); |
| 330 // Ideally, we wouldn't sleep here and instead would use the event |
| 331 // processed ack nofification from the renderer. I am reluctant to create |
| 332 // a new notification/callback for that purpose just for this test. |
| 315 ::Sleep(kActionDelayMs); | 333 ::Sleep(kActionDelayMs); |
| 316 } | 334 } |
| 335 |
| 336 // At this point the renderer has sent us a message asking to advance the |
| 337 // focus (as the end of the focus loop was reached in the renderer). |
| 338 // We need to run the message loop to process it. |
| 339 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 340 ui_test_utils::RunMessageLoop(); |
| 317 } | 341 } |
| 318 | 342 |
| 319 // Now let's try reverse focus traversal. | 343 // Now let's try reverse focus traversal. |
| 320 for (int i = 0; i < 3; ++i) { | 344 for (int i = 0; i < 3; ++i) { |
| 321 // Location bar should be focused. | 345 // Location bar should be focused. |
| 322 int focused_view_id; | 346 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 323 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 347 |
| 324 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | 348 // Now let's press shift-tab to move the focus in reverse. |
| 325 | |
| 326 // Now let's press tab to move the focus. | |
| 327 for (int j = 0; j < 7; ++j) { | 349 for (int j = 0; j < 7; ++j) { |
| 328 window->SimulateOSKeyPress(L'\t', views::Event::EF_SHIFT_DOWN); | 350 ui_controls::SendKeyPressNotifyWhenDone(L'\t', false, true, false, |
| 351 new MessageLoop::QuitTask()); |
| 352 ui_test_utils::RunMessageLoop(); |
| 329 ::Sleep(kActionDelayMs); | 353 ::Sleep(kActionDelayMs); |
| 330 | 354 |
| 331 // Let's make sure the focus is on the expected element in the page. | 355 // Let's make sure the focus is on the expected element in the page. |
| 332 std::wstring actual; | 356 JavaScriptRunner js_runner( |
| 333 ASSERT_TRUE(tab->ExecuteAndExtractString(L"", | 357 browser()->GetSelectedTabContents()->AsWebContents(), |
| 334 L"window.domAutomationController.send(getFocusedElement());", | 358 L"", |
| 335 &actual)); | 359 L"window.domAutomationController.send(getFocusedElement());"); |
| 360 std::string actual = js_runner.Run(); |
| 336 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); | 361 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); |
| 337 } | 362 } |
| 363 |
| 364 // At this point the renderer has sent us a message asking to advance the |
| 365 // focus (as the end of the focus loop was reached in the renderer). |
| 366 // We need to run the message loop to process it. |
| 367 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 368 ui_test_utils::RunMessageLoop(); |
| 338 } | 369 } |
| 339 } | 370 } |
| 340 | 371 |
| 341 // Make sure Find box can request focus, even when it is already open. | 372 // Make sure Find box can request focus, even when it is already open. |
| 342 TEST_F(BrowserFocusTest, FindFocusTest) { | 373 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) { |
| 343 scoped_refptr<HTTPTestServer> server = | 374 HTTPTestServer* server = StartHTTPServer(); |
| 344 HTTPTestServer::CreateServer(kDocRoot, NULL); | |
| 345 ASSERT_TRUE(NULL != server.get()); | |
| 346 | 375 |
| 347 // Open some page (any page that doesn't steal focus). | 376 // Open some page (any page that doesn't steal focus). |
| 348 GURL url = server->TestServerPageW(kTypicalPage); | 377 GURL url = server->TestServerPageW(kTypicalPage); |
| 349 scoped_ptr<TabProxy> tab(GetActiveTab()); | 378 ui_test_utils::NavigateToURL(browser(), url); |
| 350 tab->NavigateToURL(url); | 379 |
| 351 | 380 HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); |
| 352 scoped_ptr<WindowProxy> window(automation()->GetActiveWindow()); | 381 BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd); |
| 353 ASSERT_TRUE(window.get() != NULL); | 382 views::FocusManager* focus_manager = |
| 354 scoped_ptr<BrowserProxy> browser(window->GetBrowser()); | 383 views::FocusManager::GetFocusManager(hwnd); |
| 355 ASSERT_TRUE(browser.get() != NULL); | 384 LocationBarView* location_bar = browser_view->GetLocationBarView(); |
| 356 | 385 |
| 357 // Press Ctrl+F, which will make the Find box open and request focus. | 386 // Press Ctrl+F, which will make the Find box open and request focus. |
| 358 static const int VK_F = 0x46; | 387 static const int VK_F = 0x46; |
| 359 EXPECT_TRUE(window->SimulateOSKeyPress(VK_F, views::Event::EF_CONTROL_DOWN)); | 388 ui_controls::SendKeyPressNotifyWhenDone(L'F', true, false, false, |
| 389 new MessageLoop::QuitTask()); |
| 390 ui_test_utils::RunMessageLoop(); |
| 391 |
| 392 // Ideally, we wouldn't sleep here and instead would intercept the |
| 393 // RenderViewHostDelegate::HandleKeyboardEvent() callback. To do that, we |
| 394 // could create a RenderViewHostDelegate wrapper and hook-it up by either: |
| 395 // - creating a factory used to create the delegate |
| 396 // - making the test a private and overwriting the delegate member directly. |
| 360 ::Sleep(kActionDelayMs); | 397 ::Sleep(kActionDelayMs); |
| 361 int focused_view_id; | 398 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 362 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 399 ui_test_utils::RunMessageLoop(); |
| 363 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view_id); | 400 |
| 401 views::View* focused_view = focus_manager->GetFocusedView(); |
| 402 ASSERT_TRUE(focused_view != NULL); |
| 403 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID()); |
| 364 | 404 |
| 365 // Click on the location bar. | 405 // Click on the location bar. |
| 366 gfx::Rect bounds; | 406 ui_controls::MoveMouseToCenterAndPress(location_bar, |
| 367 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &bounds, true)); | 407 ui_controls::LEFT, |
| 368 POINT click(bounds.CenterPoint().ToPOINT()); | 408 ui_controls::DOWN | ui_controls::UP, |
| 369 EXPECT_TRUE(window->SimulateOSClick(click, | 409 new MessageLoop::QuitTask()); |
| 370 views::Event::EF_LEFT_BUTTON_DOWN)); | 410 ui_test_utils::RunMessageLoop(); |
| 411 |
| 412 // Make sure the location bar is focused. |
| 413 EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); |
| 414 |
| 415 // Now press Ctrl+F again and focus should move to the Find box. |
| 416 ui_controls::SendKeyPressNotifyWhenDone(L'F', true, false, false, |
| 417 new MessageLoop::QuitTask()); |
| 418 ui_test_utils::RunMessageLoop(); |
| 419 focused_view = focus_manager->GetFocusedView(); |
| 420 ASSERT_TRUE(focused_view != NULL); |
| 421 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID()); |
| 422 |
| 423 // Set focus to the page. |
| 424 ui_controls::MoveMouseToCenterAndPress(browser_view->GetContentsView(), |
| 425 ui_controls::LEFT, |
| 426 ui_controls::DOWN | ui_controls::UP, |
| 427 new MessageLoop::QuitTask()); |
| 428 ui_test_utils::RunMessageLoop(); |
| 429 EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView()); |
| 430 |
| 431 // Now press Ctrl+F again and focus should move to the Find box. |
| 432 ui_controls::SendKeyPressNotifyWhenDone(VK_F, true, false, false, |
| 433 new MessageLoop::QuitTask()); |
| 434 ui_test_utils::RunMessageLoop(); |
| 435 |
| 436 // See remark above on why we wait. |
| 371 ::Sleep(kActionDelayMs); | 437 ::Sleep(kActionDelayMs); |
| 372 // Make sure the location bar is focused. | 438 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 373 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | 439 ui_test_utils::RunMessageLoop(); |
| 374 EXPECT_EQ(VIEW_ID_LOCATION_BAR, focused_view_id); | 440 |
| 375 | 441 focused_view = focus_manager->GetFocusedView(); |
| 376 // Now press Ctrl+F again and focus should move to the Find box. | 442 ASSERT_TRUE(focused_view != NULL); |
| 377 EXPECT_TRUE(window->SimulateOSKeyPress(VK_F, views::Event::EF_CONTROL_DOWN)); | 443 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID()); |
| 378 ::Sleep(kActionDelayMs); | 444 } |
| 379 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | |
| 380 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view_id); | |
| 381 | |
| 382 // Set focus to the page. | |
| 383 EXPECT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER, &bounds, true)); | |
| 384 click = bounds.CenterPoint().ToPOINT(); | |
| 385 EXPECT_TRUE(window->SimulateOSClick(click, | |
| 386 views::Event::EF_LEFT_BUTTON_DOWN)); | |
| 387 ::Sleep(kActionDelayMs); | |
| 388 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | |
| 389 EXPECT_EQ(VIEW_ID_TAB_CONTAINER, focused_view_id); | |
| 390 | |
| 391 // Now press Ctrl+F again and focus should move to the Find box. | |
| 392 EXPECT_TRUE(window->SimulateOSKeyPress(VK_F, views::Event::EF_CONTROL_DOWN)); | |
| 393 ::Sleep(kActionDelayMs); | |
| 394 EXPECT_TRUE(window->GetFocusedViewID(&focused_view_id)); | |
| 395 EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view_id); | |
| 396 } | |
| OLD | NEW |