diff options
-rw-r--r-- | chrome/browser/browser_focus_uitest.cc | 63 | ||||
-rw-r--r-- | chrome/browser/views/find_bar_win_unittest.cc | 63 | ||||
-rw-r--r-- | chrome/test/data/find_in_page/end_state.html | 45 | ||||
-rw-r--r-- | chrome/test/ui_test_utils.cc | 41 | ||||
-rw-r--r-- | chrome/test/ui_test_utils.h | 40 | ||||
-rw-r--r-- | webkit/glue/webframe_impl.cc | 6 |
6 files changed, 191 insertions, 67 deletions
diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc index 77d67b5..a19e072 100644 --- a/chrome/browser/browser_focus_uitest.cc +++ b/chrome/browser/browser_focus_uitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,16 +6,10 @@ #include "base/ref_counted.h" #include "chrome/browser/automation/ui_controls.h" #include "chrome/browser/browser.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/location_bar_view.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_source.h" -#include "chrome/common/notification_type.h" #include "chrome/views/focus/focus_manager.h" #include "chrome/views/view.h" #include "chrome/views/window/window.h" @@ -40,55 +34,6 @@ class BrowserFocusTest : public InProcessBrowserTest { } }; -class JavaScriptRunner : public NotificationObserver { - public: - JavaScriptRunner(WebContents* web_contents, - const std::wstring& frame_xpath, - const std::wstring& jscript) - : web_contents_(web_contents), - frame_xpath_(frame_xpath), - jscript_(jscript) { - NotificationService::current()-> - AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE, - Source<WebContents>(web_contents)); - } - - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - Details<DomOperationNotificationDetails> dom_op_details(details); - result_ = dom_op_details->json(); - // The Jasonified response has quotes, remove them. - if (result_.length() > 1 && result_[0] == '"') - result_ = result_.substr(1, result_.length() - 2); - - NotificationService::current()-> - RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE, - Source<WebContents>(web_contents_)); - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); - } - - std::string Run() { - // The DOMAutomationController requires an automation ID, eventhough we are - // not using it in this case. - web_contents_->render_view_host()->ExecuteJavascriptInWebFrame( - frame_xpath_, L"window.domAutomationController.setAutomationId(0);"); - - web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath_, - jscript_); - ui_test_utils::RunMessageLoop(); - return result_; - } - - private: - WebContents* web_contents_; - std::wstring frame_xpath_; - std::wstring jscript_; - std::string result_; - - DISALLOW_COPY_AND_ASSIGN(JavaScriptRunner); -}; - } // namespace IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BrowsersRememberFocus) { @@ -319,7 +264,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { // Now let's press tab to move the focus. for (int j = 0; j < 7; ++j) { // Let's make sure the focus is on the expected element in the page. - JavaScriptRunner js_runner( + ui_test_utils::JavaScriptRunner js_runner( browser()->GetSelectedTabContents()->AsWebContents(), L"", L"window.domAutomationController.send(getFocusedElement());"); @@ -330,7 +275,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { new MessageLoop::QuitTask()); ui_test_utils::RunMessageLoop(); // Ideally, we wouldn't sleep here and instead would use the event - // processed ack nofification from the renderer. I am reluctant to create + // processed ack notification from the renderer. I am reluctant to create // a new notification/callback for that purpose just for this test. ::Sleep(kActionDelayMs); } @@ -355,7 +300,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { ::Sleep(kActionDelayMs); // Let's make sure the focus is on the expected element in the page. - JavaScriptRunner js_runner( + ui_test_utils::JavaScriptRunner js_runner( browser()->GetSelectedTabContents()->AsWebContents(), L"", L"window.domAutomationController.send(getFocusedElement());"); diff --git a/chrome/browser/views/find_bar_win_unittest.cc b/chrome/browser/views/find_bar_win_unittest.cc index 097e4f3..4d30d7c 100644 --- a/chrome/browser/views/find_bar_win_unittest.cc +++ b/chrome/browser/views/find_bar_win_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -19,6 +19,7 @@ const std::wstring kFrameData = L"files/find_in_page/framedata_general.html"; const std::wstring kUserSelectPage = L"files/find_in_page/user-select.html"; const std::wstring kCrashPage = L"files/find_in_page/crash_1341577.html"; const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html"; +const std::wstring kEndState = L"files/find_in_page/end_state.html"; class FindInPageNotificationObserver : public NotificationObserver { public: @@ -78,6 +79,11 @@ typedef enum FindInPageDirection { BACK = 0, FWD = 1 }; typedef enum FindInPageCase { IGNORE_CASE = 0, CASE_SENSITIVE = 1 }; class FindInPageControllerTest : public InProcessBrowserTest { + public: + FindInPageControllerTest() { + EnableDOMAutomation(); + } + protected: int FindInPage(const std::wstring& search_string, FindInPageDirection forward, @@ -98,7 +104,7 @@ class FindInPageControllerTest : public InProcessBrowserTest { } }; -// This test loads a page with frames and starts FindInPage requests +// This test loads a page with frames and starts FindInPage requests. IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) { HTTPTestServer* server = StartHTTPServer(); @@ -141,3 +147,56 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) { EXPECT_EQ(1, FindInPage(L"Hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false)); EXPECT_EQ(0, FindInPage(L"hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false)); } + +std::string FocusedOnPage(WebContents* web_contents) { + ui_test_utils::JavaScriptRunner js_runner( + web_contents, + L"", + L"window.domAutomationController.send(getFocusedElement());"); + return js_runner.Run(); +} + +// This tests the FindInPage end-state, in other words: what is focused when you +// close the Find box (ie. if you find within a link the link should be +// focused). +// TODO(jcampan): This test needs to be enabled once Jay fixes the issues with +// running two InProc browser tests that both start a web server (crashes). +IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, DISABLED_FindInPageEndState) { + HTTPTestServer* server = StartHTTPServer(); + + // First we navigate to our special focus tracking page. + GURL url = server->TestServerPageW(kEndState); + ui_test_utils::NavigateToURL(browser(), url); + + WebContents* web_contents = + browser()->GetSelectedTabContents()->AsWebContents(); + ASSERT_TRUE(NULL != web_contents); + + // Verify that nothing has focus. + ASSERT_STREQ("{nothing focused}", FocusedOnPage(web_contents).c_str()); + + // Search for a text that exists within a link on the page. + EXPECT_EQ(1, FindInPage(L"nk", FWD, IGNORE_CASE, false)); + + // End the find session, which should set focus to the link. + web_contents->StopFinding(false); + + // Verify that the link is focused. + EXPECT_STREQ("link1", FocusedOnPage(web_contents).c_str()); + + // Search for a text that exists within a link on the page. + EXPECT_EQ(1, FindInPage(L"Google", FWD, IGNORE_CASE, false)); + + // Move the selection to link 1, after searching. + ui_test_utils::JavaScriptRunner js_runner( + web_contents, + L"", + L"window.domAutomationController.send(selectLink1());"); + js_runner.Run(); + + // End the find session. + web_contents->StopFinding(false); + + // Verify that link2 is not focused. + EXPECT_STREQ("", FocusedOnPage(web_contents).c_str()); +} diff --git a/chrome/test/data/find_in_page/end_state.html b/chrome/test/data/find_in_page/end_state.html new file mode 100644 index 0000000..bf8332c --- /dev/null +++ b/chrome/test/data/find_in_page/end_state.html @@ -0,0 +1,45 @@ +<html>
+<head>
+<script>
+ var focused_elem = "{nothing focused}";
+
+ function setFocusedElem(id) {
+ focused_elem = id;
+ updateLog();
+ }
+
+ function clearFocus() {
+ focused_elem = "";
+ updateLog();
+ }
+
+ function getFocusedElement() {
+ return focused_elem;
+ }
+
+ function updateLog() {
+ document.getElementById("log").innerHTML = "Focused element: " + focused_elem;
+ }
+
+ function selectLink1() {
+ clearFocus();
+ var sel = window.getSelection();
+ var range = document.createRange();
+ range.setStartBefore(document.getElementById('link1'));
+ range.setEndAfter(document.getElementById('link1'));
+ sel.addRange(range);
+ return "";
+ }
+
+</script>
+</head>
+
+<body>
+ This is
+ a <a id="link1" href="http://www.google.com" onfocus="setFocusedElem(this.id)" onblur="clearFocus()">link</a>
+ to <a id="link2" href="http://www.google.com" onfocus="setFocusedElem(this.id)" onblur="clearFocus()">Google</a>.
+
+ <br><br><br>
+ <div id="log"><div>
+</body>
+</html>
\ No newline at end of file diff --git a/chrome/test/ui_test_utils.cc b/chrome/test/ui_test_utils.cc index 6af1091..be86d17 100644 --- a/chrome/test/ui_test_utils.cc +++ b/chrome/test/ui_test_utils.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,7 @@ #include "base/message_loop.h" #include "chrome/browser/browser.h" +#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/web_contents.h" #include "chrome/common/notification_registrar.h" @@ -98,4 +99,42 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser, WaitForNavigations(controller, number_of_navigations); } +JavaScriptRunner::JavaScriptRunner(WebContents* web_contents, + const std::wstring& frame_xpath, + const std::wstring& jscript) + : web_contents_(web_contents), + frame_xpath_(frame_xpath), + jscript_(jscript) { + NotificationService::current()-> + AddObserver(this, NotificationType::DOM_OPERATION_RESPONSE, + Source<WebContents>(web_contents)); +} + +void JavaScriptRunner::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + Details<DomOperationNotificationDetails> dom_op_details(details); + result_ = dom_op_details->json(); + // The Jasonified response has quotes, remove them. + if (result_.length() > 1 && result_[0] == '"') + result_ = result_.substr(1, result_.length() - 2); + + NotificationService::current()-> + RemoveObserver(this, NotificationType::DOM_OPERATION_RESPONSE, + Source<WebContents>(web_contents_)); + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); +} + +std::string JavaScriptRunner::Run() { + // The DOMAutomationController requires an automation ID, even though we are + // not using it in this case. + web_contents_->render_view_host()->ExecuteJavascriptInWebFrame( + frame_xpath_, L"window.domAutomationController.setAutomationId(0);"); + + web_contents_->render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath_, + jscript_); + ui_test_utils::RunMessageLoop(); + return result_; +} + } // namespace ui_test_utils diff --git a/chrome/test/ui_test_utils.h b/chrome/test/ui_test_utils.h index ced32d2..2ac73f9 100644 --- a/chrome/test/ui_test_utils.h +++ b/chrome/test/ui_test_utils.h @@ -1,13 +1,17 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_TEST_UI_TEST_UTILS_H_ #define CHROME_TEST_UI_TEST_UTILS_H_ +#include "base/basictypes.h" +#include "chrome/common/notification_observer.h" + class Browser; class GURL; class NavigationController; +class WebContents; // A collections of functions designed for use with InProcessBrowserTest. namespace ui_test_utils { @@ -35,6 +39,40 @@ void NavigateToURL(Browser* browser, const GURL& url); void NavigateToURLBlockUntilNavigationsComplete(Browser* browser, const GURL& url, int number_of_navigations); + + +// This class enables you to send JavaScript as a string from the browser to the +// renderer for execution in a frame of your choice. +class JavaScriptRunner : public NotificationObserver { + public: + // Constructor. |web_contents| is a pointer to the WebContents you want to run + // the JavaScript code in. |frame_xpath| is a path to the frame to run it in. + // |jscript| is a string containing the JavaScript code to run, for example: + // "window.domAutomationController.send(alert('hello world'));". The + // JavaScript code will execute when Run is called. Note: In order for the + // domAutomationController to work, you must call EnableDOMAutomation() in + // your test class first. + JavaScriptRunner(WebContents* web_contents, + const std::wstring& frame_xpath, + const std::wstring& jscript); + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Executes the JavaScript code passed in to the constructor. See also comment + // about EnableDOMAutomation in the constructor. + std::string Run(); + + private: + WebContents* web_contents_; + std::wstring frame_xpath_; + std::wstring jscript_; + std::string result_; + + DISALLOW_COPY_AND_ASSIGN(JavaScriptRunner); +}; + } #endif // CHROME_TEST_UI_TEST_UTILS_H_ diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc index 62202a0..aeb01d5 100644 --- a/webkit/glue/webframe_impl.cc +++ b/webkit/glue/webframe_impl.cc @@ -1370,12 +1370,10 @@ void WebFrameImpl::SetFindEndstateFocusAndSelection() { if (this == main_frame_impl->active_match_frame() && active_match_.get()) { - // If the user has changed the selection since the match was found, we + // If the user has set the selection since the match was found, we // don't focus anything. VisibleSelection selection(frame()->selection()->selection()); - if (selection.isNone() || (selection.start() == selection.end()) || - active_match_->boundingBox() != - selection.toNormalizedRange()->boundingBox()) + if (!selection.isNone()) return; // We will be setting focus ourselves, so we want the view to forget its |