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 |