| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/keyboard_codes.h" | 5 #include "base/keyboard_codes.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "base/ref_counted.h" | 7 #include "base/ref_counted.h" |
| 8 #include "chrome/browser/automation/ui_controls.h" | 8 #include "chrome/browser/automation/ui_controls.h" |
| 9 #include "chrome/browser/browser.h" | 9 #include "chrome/browser/browser.h" |
| 10 #include "chrome/browser/browser_window.h" | 10 #include "chrome/browser/browser_window.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 | 140 |
| 141 return false; | 141 return false; |
| 142 } | 142 } |
| 143 #endif | 143 #endif |
| 144 }; | 144 }; |
| 145 | 145 |
| 146 class TestInterstitialPage : public InterstitialPage { | 146 class TestInterstitialPage : public InterstitialPage { |
| 147 public: | 147 public: |
| 148 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url) | 148 TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url) |
| 149 : InterstitialPage(tab, new_navigation, url), | 149 : InterstitialPage(tab, new_navigation, url), |
| 150 waiting_for_dom_response_(false) { | 150 waiting_for_dom_response_(false), |
| 151 waiting_for_focus_change_(false) { |
| 151 FilePath file_path; | 152 FilePath file_path; |
| 152 bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path); | 153 bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path); |
| 153 EXPECT_TRUE(r); | 154 EXPECT_TRUE(r); |
| 154 file_path = file_path.AppendASCII("focus"); | 155 file_path = file_path.AppendASCII("focus"); |
| 155 file_path = file_path.AppendASCII(kTypicalPageName); | 156 file_path = file_path.AppendASCII(kTypicalPageName); |
| 156 r = file_util::ReadFileToString(file_path, &html_contents_); | 157 r = file_util::ReadFileToString(file_path, &html_contents_); |
| 157 EXPECT_TRUE(r); | 158 EXPECT_TRUE(r); |
| 158 } | 159 } |
| 159 | 160 |
| 160 virtual std::string GetHTMLContents() { | 161 virtual std::string GetHTMLContents() { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 185 dom_response_[dom_response_.size() - 1] == '"') { | 186 dom_response_[dom_response_.size() - 1] == '"') { |
| 186 dom_response_ = dom_response_.substr(1, dom_response_.size() - 2); | 187 dom_response_ = dom_response_.substr(1, dom_response_.size() - 2); |
| 187 } | 188 } |
| 188 return dom_response_; | 189 return dom_response_; |
| 189 } | 190 } |
| 190 | 191 |
| 191 bool HasFocus() { | 192 bool HasFocus() { |
| 192 return render_view_host()->view()->HasFocus(); | 193 return render_view_host()->view()->HasFocus(); |
| 193 } | 194 } |
| 194 | 195 |
| 196 void WaitForFocusChange() { |
| 197 waiting_for_focus_change_ = true; |
| 198 ui_test_utils::RunMessageLoop(); |
| 199 } |
| 200 |
| 201 protected: |
| 202 virtual void FocusedNodeChanged() { |
| 203 if (!waiting_for_focus_change_) |
| 204 return; |
| 205 |
| 206 waiting_for_focus_change_= false; |
| 207 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 208 } |
| 209 |
| 195 private: | 210 private: |
| 196 std::string html_contents_; | 211 std::string html_contents_; |
| 197 | 212 |
| 198 bool waiting_for_dom_response_; | 213 bool waiting_for_dom_response_; |
| 214 bool waiting_for_focus_change_; |
| 199 std::string dom_response_; | 215 std::string dom_response_; |
| 200 | 216 |
| 201 }; | 217 }; |
| 202 | 218 |
| 203 } // namespace | 219 } // namespace |
| 204 | 220 |
| 205 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) { | 221 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) { |
| 206 #if defined(OS_LINUX) | 222 #if defined(OS_LINUX) |
| 207 // It seems we have to wait a little bit for the widgets to spin up before | 223 // It seems we have to wait a little bit for the widgets to spin up before |
| 208 // we can start clicking on them. | 224 // we can start clicking on them. |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 browser()->FocusLocationBar(); | 405 browser()->FocusLocationBar(); |
| 390 | 406 |
| 391 // Wait for the page to steal focus. | 407 // Wait for the page to steal focus. |
| 392 PlatformThread::Sleep(2000); | 408 PlatformThread::Sleep(2000); |
| 393 | 409 |
| 394 // Make sure the location bar is still focused. | 410 // Make sure the location bar is still focused. |
| 395 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); | 411 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); |
| 396 } | 412 } |
| 397 | 413 |
| 398 // Focus traversal on a regular page. | 414 // Focus traversal on a regular page. |
| 415 // Note that this test relies on a notification from the renderer that the |
| 416 // focus has changed in the page. The notification in the renderer may change |
| 417 // at which point this test would fail (see comment in |
| 418 // RenderWidget::didFocus()). |
| 399 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { | 419 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { |
| 400 HTTPTestServer* server = StartHTTPServer(); | 420 HTTPTestServer* server = StartHTTPServer(); |
| 401 | 421 |
| 402 // First we navigate to our test page. | 422 // First we navigate to our test page. |
| 403 GURL url = server->TestServerPageW(kTypicalPage); | 423 GURL url = server->TestServerPageW(kTypicalPage); |
| 404 ui_test_utils::NavigateToURL(browser(), url); | 424 ui_test_utils::NavigateToURL(browser(), url); |
| 405 | 425 |
| 406 browser()->FocusLocationBar(); | 426 browser()->FocusLocationBar(); |
| 407 | 427 |
| 408 const char* kExpElementIDs[] = { | 428 const char* kExpElementIDs[] = { |
| 409 "", // Initially no element in the page should be focused | 429 "", // Initially no element in the page should be focused |
| 410 // (the location bar is focused). | 430 // (the location bar is focused). |
| 411 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink", | 431 "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink", |
| 412 "gmapLink" | 432 "gmapLink" |
| 413 }; | 433 }; |
| 414 | 434 |
| 415 gfx::NativeWindow window = browser()->window()->GetNativeHandle(); | 435 gfx::NativeWindow window = browser()->window()->GetNativeHandle(); |
| 416 | 436 |
| 417 // Test forward focus traversal. | 437 // Test forward focus traversal. |
| 418 for (int i = 0; i < 3; ++i) { | 438 for (int i = 0; i < 3; ++i) { |
| 419 // Location bar should be focused. | 439 // Location bar should be focused. |
| 420 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); | 440 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); |
| 421 | 441 |
| 422 // Now let's press tab to move the focus. | 442 // Now let's press tab to move the focus. |
| 423 for (int j = 0; j < 7; ++j) { | 443 for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) { |
| 424 // Let's make sure the focus is on the expected element in the page. | 444 // Let's make sure the focus is on the expected element in the page. |
| 425 std::string actual; | 445 std::string actual; |
| 426 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( | 446 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( |
| 427 browser()->GetSelectedTabContents()->render_view_host(), | 447 browser()->GetSelectedTabContents()->render_view_host(), |
| 428 L"", | 448 L"", |
| 429 L"window.domAutomationController.send(getFocusedElement());", | 449 L"window.domAutomationController.send(getFocusedElement());", |
| 430 &actual)); | 450 &actual)); |
| 431 ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); | 451 ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); |
| 432 | 452 |
| 433 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, | 453 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, |
| 434 false, false, | 454 false, false, false)); |
| 435 new MessageLoop::QuitTask()); | 455 |
| 436 ui_test_utils::RunMessageLoop(); | 456 if (j < arraysize(kExpElementIDs) - 1) { |
| 437 // Ideally, we wouldn't sleep here and instead would use the event | 457 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()-> |
| 438 // processed ack notification from the renderer. I am reluctant to create | 458 render_view_host()); |
| 439 // a new notification/callback for that purpose just for this test. | 459 } else { |
| 440 PlatformThread::Sleep(kActionDelayMs); | 460 // On the last tab key press, the focus returns to the browser. |
| 461 ui_test_utils::WaitForFocusInBrowser(browser()); |
| 462 } |
| 441 } | 463 } |
| 442 | 464 |
| 443 // At this point the renderer has sent us a message asking to advance the | 465 // At this point the renderer has sent us a message asking to advance the |
| 444 // focus (as the end of the focus loop was reached in the renderer). | 466 // focus (as the end of the focus loop was reached in the renderer). |
| 445 // We need to run the message loop to process it. | 467 // We need to run the message loop to process it. |
| 446 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 468 MessageLoop::current()->RunAllPending(); |
| 447 ui_test_utils::RunMessageLoop(); | |
| 448 } | 469 } |
| 449 | 470 |
| 450 // Now let's try reverse focus traversal. | 471 // Now let's try reverse focus traversal. |
| 451 for (int i = 0; i < 3; ++i) { | 472 for (int i = 0; i < 3; ++i) { |
| 452 // Location bar should be focused. | 473 // Location bar should be focused. |
| 453 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); | 474 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); |
| 454 | 475 |
| 455 // Now let's press shift-tab to move the focus in reverse. | 476 // Now let's press shift-tab to move the focus in reverse. |
| 456 for (int j = 0; j < 7; ++j) { | 477 for (size_t j = 0; j < 7; ++j) { |
| 457 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, | 478 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, |
| 458 true, false, | 479 false, true, false)); |
| 459 new MessageLoop::QuitTask()); | 480 |
| 460 ui_test_utils::RunMessageLoop(); | 481 if (j < arraysize(kExpElementIDs) - 1) { |
| 461 PlatformThread::Sleep(kActionDelayMs); | 482 ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()-> |
| 483 render_view_host()); |
| 484 } else { |
| 485 // On the last tab key press, the focus returns to the browser. |
| 486 ui_test_utils::WaitForFocusInBrowser(browser()); |
| 487 } |
| 462 | 488 |
| 463 // Let's make sure the focus is on the expected element in the page. | 489 // Let's make sure the focus is on the expected element in the page. |
| 464 std::string actual; | 490 std::string actual; |
| 465 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( | 491 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( |
| 466 browser()->GetSelectedTabContents()->render_view_host(), | 492 browser()->GetSelectedTabContents()->render_view_host(), |
| 467 L"", | 493 L"", |
| 468 L"window.domAutomationController.send(getFocusedElement());", | 494 L"window.domAutomationController.send(getFocusedElement());", |
| 469 &actual)); | 495 &actual)); |
| 470 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); | 496 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); |
| 471 } | 497 } |
| 472 | 498 |
| 473 // At this point the renderer has sent us a message asking to advance the | 499 // At this point the renderer has sent us a message asking to advance the |
| 474 // focus (as the end of the focus loop was reached in the renderer). | 500 // focus (as the end of the focus loop was reached in the renderer). |
| 475 // We need to run the message loop to process it. | 501 // We need to run the message loop to process it. |
| 476 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 502 MessageLoop::current()->RunAllPending(); |
| 477 ui_test_utils::RunMessageLoop(); | |
| 478 } | 503 } |
| 479 } | 504 } |
| 480 | 505 |
| 481 // Focus traversal while an interstitial is showing. | 506 // Focus traversal while an interstitial is showing. |
| 482 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) { | 507 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) { |
| 483 HTTPTestServer* server = StartHTTPServer(); | 508 HTTPTestServer* server = StartHTTPServer(); |
| 484 | 509 |
| 485 // First we navigate to our test page. | 510 // First we navigate to our test page. |
| 486 GURL url = server->TestServerPageW(kSimplePage); | 511 GURL url = server->TestServerPageW(kSimplePage); |
| 487 ui_test_utils::NavigateToURL(browser(), url); | 512 ui_test_utils::NavigateToURL(browser(), url); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 510 }; | 535 }; |
| 511 | 536 |
| 512 gfx::NativeWindow window = browser()->window()->GetNativeHandle(); | 537 gfx::NativeWindow window = browser()->window()->GetNativeHandle(); |
| 513 | 538 |
| 514 // Test forward focus traversal. | 539 // Test forward focus traversal. |
| 515 for (int i = 0; i < 2; ++i) { | 540 for (int i = 0; i < 2; ++i) { |
| 516 // Location bar should be focused. | 541 // Location bar should be focused. |
| 517 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); | 542 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); |
| 518 | 543 |
| 519 // Now let's press tab to move the focus. | 544 // Now let's press tab to move the focus. |
| 520 for (int j = 0; j < 7; ++j) { | 545 for (size_t j = 0; j < 7; ++j) { |
| 521 // Let's make sure the focus is on the expected element in the page. | 546 // Let's make sure the focus is on the expected element in the page. |
| 522 std::string actual = interstitial_page->GetFocusedElement(); | 547 std::string actual = interstitial_page->GetFocusedElement(); |
| 523 ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); | 548 ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); |
| 524 | 549 |
| 525 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, | 550 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, |
| 526 false, false, | 551 false, false, false)); |
| 527 new MessageLoop::QuitTask()); | 552 |
| 528 ui_test_utils::RunMessageLoop(); | 553 if (j < arraysize(kExpElementIDs) - 1) { |
| 529 // Ideally, we wouldn't sleep here and instead would use the event | 554 interstitial_page->WaitForFocusChange(); |
| 530 // processed ack notification from the renderer. I am reluctant to create | 555 } else { |
| 531 // a new notification/callback for that purpose just for this test. | 556 // On the last tab key press, the focus returns to the browser. |
| 532 PlatformThread::Sleep(kActionDelayMs); | 557 ui_test_utils::WaitForFocusInBrowser(browser()); |
| 558 } |
| 533 } | 559 } |
| 534 | 560 |
| 535 // At this point the renderer has sent us a message asking to advance the | 561 // At this point the renderer has sent us a message asking to advance the |
| 536 // focus (as the end of the focus loop was reached in the renderer). | 562 // focus (as the end of the focus loop was reached in the renderer). |
| 537 // We need to run the message loop to process it. | 563 // We need to run the message loop to process it. |
| 538 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 564 MessageLoop::current()->RunAllPending(); |
| 539 ui_test_utils::RunMessageLoop(); | |
| 540 } | 565 } |
| 541 | 566 |
| 542 // Now let's try reverse focus traversal. | 567 // Now let's try reverse focus traversal. |
| 543 for (int i = 0; i < 2; ++i) { | 568 for (int i = 0; i < 2; ++i) { |
| 544 // Location bar should be focused. | 569 // Location bar should be focused. |
| 545 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); | 570 CheckViewHasFocus(VIEW_ID_LOCATION_BAR); |
| 546 | 571 |
| 547 // Now let's press shift-tab to move the focus in reverse. | 572 // Now let's press shift-tab to move the focus in reverse. |
| 548 for (int j = 0; j < 7; ++j) { | 573 for (size_t j = 0; j < 7; ++j) { |
| 549 ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, | 574 ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, |
| 550 true, false, | 575 false, true, false)); |
| 551 new MessageLoop::QuitTask()); | 576 |
| 552 ui_test_utils::RunMessageLoop(); | 577 if (j < arraysize(kExpElementIDs) - 1) { |
| 553 PlatformThread::Sleep(kActionDelayMs); | 578 interstitial_page->WaitForFocusChange(); |
| 579 } else { |
| 580 // On the last tab key press, the focus returns to the browser. |
| 581 ui_test_utils::WaitForFocusInBrowser(browser()); |
| 582 } |
| 554 | 583 |
| 555 // Let's make sure the focus is on the expected element in the page. | 584 // Let's make sure the focus is on the expected element in the page. |
| 556 std::string actual = interstitial_page->GetFocusedElement(); | 585 std::string actual = interstitial_page->GetFocusedElement(); |
| 557 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); | 586 ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); |
| 558 } | 587 } |
| 559 | 588 |
| 560 // At this point the renderer has sent us a message asking to advance the | 589 // At this point the renderer has sent us a message asking to advance the |
| 561 // focus (as the end of the focus loop was reached in the renderer). | 590 // focus (as the end of the focus loop was reached in the renderer). |
| 562 // We need to run the message loop to process it. | 591 // We need to run the message loop to process it. |
| 563 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 592 MessageLoop::current()->RunAllPending(); |
| 564 ui_test_utils::RunMessageLoop(); | |
| 565 } | 593 } |
| 566 } | 594 } |
| 567 | 595 |
| 568 // Focus stays on page with interstitials. | 596 // Focus stays on page with interstitials. |
| 569 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) { | 597 IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) { |
| 570 HTTPTestServer* server = StartHTTPServer(); | 598 HTTPTestServer* server = StartHTTPServer(); |
| 571 | 599 |
| 572 // First we navigate to our test page. | 600 // First we navigate to our test page. |
| 573 GURL url = server->TestServerPageW(kSimplePage); | 601 GURL url = server->TestServerPageW(kSimplePage); |
| 574 ui_test_utils::NavigateToURL(browser(), url); | 602 ui_test_utils::NavigateToURL(browser(), url); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 | 730 |
| 703 // Open a regular page, crash, reload. | 731 // Open a regular page, crash, reload. |
| 704 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage)); | 732 ui_test_utils::NavigateToURL(browser(), server->TestServerPageW(kSimplePage)); |
| 705 ui_test_utils::CrashTab(browser()->GetSelectedTabContents()); | 733 ui_test_utils::CrashTab(browser()->GetSelectedTabContents()); |
| 706 browser()->Reload(); | 734 browser()->Reload(); |
| 707 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser())); | 735 ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser())); |
| 708 // Focus should now be on the tab contents. | 736 // Focus should now be on the tab contents. |
| 709 browser()->ShowDownloadsTab(); | 737 browser()->ShowDownloadsTab(); |
| 710 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); | 738 CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); |
| 711 } | 739 } |
| OLD | NEW |