| // Copyright (c) 2011 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. |
| |
| #include <string> |
| |
| #include "base/file_path.h" |
| #include "base/path_service.h" |
| #include "base/stringprintf.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/automation/automation_tab_helper.h" |
| #include "chrome/browser/automation/mock_tab_event_observer.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| #include "chrome/common/chrome_notification_types.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/in_process_browser_test.h" |
| #include "chrome/test/ui_test_utils.h" |
| #include "content/browser/renderer_host/render_view_host.h" |
| #include "content/browser/tab_contents/tab_contents.h" |
| #include "content/common/notification_details.h" |
| #include "content/common/notification_observer.h" |
| #include "content/common/notification_registrar.h" |
| #include "content/common/notification_service.h" |
| #include "content/common/notification_source.h" |
| #include "net/base/net_util.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::_; |
| |
| class MockNotificationObserver : public NotificationObserver { |
| public: |
| MockNotificationObserver() { } |
| virtual ~MockNotificationObserver() { } |
| |
| MOCK_METHOD3(Observe, void(int type, |
| const NotificationSource& source, |
| const NotificationDetails& details)); |
| |
| void Register(int type, const NotificationSource& source) { |
| registrar_.Add(this, type, source); |
| } |
| |
| private: |
| NotificationRegistrar registrar_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MockNotificationObserver); |
| }; |
| |
| class AutomationTabHelperBrowserTest : public InProcessBrowserTest { |
| public: |
| AutomationTabHelperBrowserTest() { |
| EnableDOMAutomation(); |
| } |
| virtual ~AutomationTabHelperBrowserTest() { } |
| |
| void SetUpInProcessBrowserTestFixture() { |
| EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_)); |
| test_data_dir_ = test_data_dir_.AppendASCII("automation"); |
| } |
| |
| // Add default expectations for a client redirection initiated by script, |
| // and quit the message loop when the redirect has completed. This expects |
| // that the tab receives news of the redirect before the script returns. |
| void ExpectClientRedirectAndBreak( |
| MockTabEventObserver* mock_tab_observer, |
| MockNotificationObserver* mock_notification_observer) { |
| mock_notification_observer->Register( |
| chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, |
| NotificationService::AllSources()); |
| |
| testing::InSequence expect_in_sequence; |
| EXPECT_CALL(*mock_tab_observer, OnFirstPendingLoad(_)); |
| EXPECT_CALL(*mock_notification_observer, Observe( |
| testing::Eq( |
| static_cast<int>(chrome::NOTIFICATION_DOM_OPERATION_RESPONSE)), |
| _, _)); |
| EXPECT_CALL(*mock_tab_observer, OnNoMorePendingLoads(_)) |
| .WillOnce(testing::InvokeWithoutArgs( |
| MessageLoopForUI::current(), &MessageLoop::Quit)); |
| } |
| |
| // Executes javascript to execute a given test case found in the current |
| // page's script. If |wait_for_response| is true, this method will not |
| // return until the javascript has been executed. |
| // Use with [ASSERT|EXPECT]_NO_FATAL_FAILURE. |
| void RunTestCaseInJavaScript(int test_case_number, bool wait_for_response) { |
| std::string script = base::StringPrintf("runTestCase(%d);", |
| test_case_number); |
| RenderViewHost* host = |
| browser()->GetSelectedTabContents()->render_view_host(); |
| if (wait_for_response) { |
| ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( |
| host, L"", ASCIIToWide(script))); |
| } else { |
| script += "window.domAutomationController.setAutomationId(0);" |
| "window.domAutomationController.send(0);"; |
| host->ExecuteJavascriptInWebFrame(ASCIIToUTF16(""), ASCIIToUTF16(script)); |
| } |
| } |
| |
| // Returns the |AutomationTabHelper| for the first browser's first tab. |
| AutomationTabHelper* tab_helper() { |
| return browser()->GetTabContentsWrapperAt(0)->automation_tab_helper(); |
| } |
| |
| protected: |
| FilePath test_data_dir_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, FormSubmission) { |
| ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL( |
| test_data_dir_.AppendASCII("client_redirects.html"))); |
| |
| MockNotificationObserver mock_notification_observer; |
| MockTabEventObserver mock_observer(tab_helper()); |
| |
| ExpectClientRedirectAndBreak(&mock_observer, &mock_notification_observer); |
| |
| ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(1, false)); |
| ui_test_utils::RunMessageLoop(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, |
| CancelFormSubmission) { |
| ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL( |
| test_data_dir_.AppendASCII("client_redirects.html"))); |
| |
| MockNotificationObserver mock_notification_observer; |
| MockTabEventObserver mock_observer(tab_helper()); |
| |
| testing::InSequence expect_in_sequence; |
| EXPECT_CALL(mock_observer, OnFirstPendingLoad(_)).Times(0); |
| |
| ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(2, true)); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, |
| JsRedirectToSite) { |
| ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL( |
| test_data_dir_.AppendASCII("client_redirects.html"))); |
| |
| MockNotificationObserver mock_notification_observer; |
| MockTabEventObserver mock_observer(tab_helper()); |
| |
| ExpectClientRedirectAndBreak(&mock_observer, &mock_notification_observer); |
| |
| ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(3, false)); |
| ui_test_utils::RunMessageLoop(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, |
| JsRedirectToUnknownSite) { |
| ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL( |
| test_data_dir_.AppendASCII("client_redirects.html"))); |
| |
| MockNotificationObserver mock_notification_observer; |
| MockTabEventObserver mock_observer(tab_helper()); |
| |
| ExpectClientRedirectAndBreak(&mock_observer, &mock_notification_observer); |
| |
| ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(4, false)); |
| ui_test_utils::RunMessageLoop(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, |
| MetaTagRedirect) { |
| MockTabEventObserver mock_observer(tab_helper()); |
| |
| testing::InSequence expect_in_sequence; |
| EXPECT_CALL(mock_observer, OnFirstPendingLoad(_)); |
| EXPECT_CALL(mock_observer, OnNoMorePendingLoads(_)); |
| |
| ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| browser(), |
| net::FilePathToFileURL(test_data_dir_.AppendASCII("meta_redirect.html")), |
| 2); |
| } |
| |
| // Tests that the load stop event occurs after the window onload handler. |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, |
| LoadStopComesAfterOnLoad) { |
| MockNotificationObserver mock_notification_observer; |
| mock_notification_observer.Register( |
| chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, |
| NotificationService::AllSources()); |
| MockTabEventObserver mock_tab_observer(tab_helper()); |
| |
| EXPECT_CALL(mock_tab_observer, OnFirstPendingLoad(_)); |
| { |
| testing::InSequence expect_in_sequence; |
| EXPECT_CALL(mock_notification_observer, Observe( |
| testing::Eq( |
| static_cast<int>(chrome::NOTIFICATION_DOM_OPERATION_RESPONSE)), |
| _, _)); |
| EXPECT_CALL(mock_tab_observer, OnNoMorePendingLoads(_)); |
| } |
| |
| ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL( |
| test_data_dir_.AppendASCII("sends_message_on_load.html"))); |
| } |
| |
| // Tests that a crashed tab reports that it has stopped loading. |
| IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, |
| CrashedTabStopsLoading) { |
| MockTabEventObserver mock_tab_observer(tab_helper()); |
| |
| testing::InSequence expect_in_sequence; |
| EXPECT_CALL(mock_tab_observer, OnFirstPendingLoad(_)); |
| EXPECT_CALL(mock_tab_observer, OnNoMorePendingLoads(_)); |
| |
| ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUICrashURL)); |
| } |