1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "base/file_path.h"
8 #include "base/path_service.h"
9 #include "base/stringprintf.h"
10 #include "chrome/browser/automation/automation_tab_helper.h"
11 #include "chrome/browser/automation/mock_tab_event_observer.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "chrome/common/url_constants.h"
16 #include "chrome/test/in_process_browser_test.h"
17 #include "chrome/test/ui_test_utils.h"
18 #include "content/browser/renderer_host/render_view_host.h"
19 #include "content/browser/tab_contents/tab_contents.h"
20 #include "content/common/notification_details.h"
21 #include "content/common/notification_observer.h"
22 #include "content/common/notification_registrar.h"
23 #include "content/common/notification_service.h"
24 #include "content/common/notification_source.h"
25 #include "content/common/notification_type.h"
26 #include "net/base/net_util.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 using testing::_;
31
32 class MockNotificationObserver : public NotificationObserver {
33 public:
MockNotificationObserver()34 MockNotificationObserver() { }
~MockNotificationObserver()35 virtual ~MockNotificationObserver() { }
36
37 MOCK_METHOD3(Observe, void(NotificationType type,
38 const NotificationSource& source,
39 const NotificationDetails& details));
40
Register(NotificationType type,const NotificationSource & source)41 void Register(NotificationType type, const NotificationSource& source) {
42 registrar_.Add(this, type, source);
43 }
44
45 private:
46 NotificationRegistrar registrar_;
47
48 DISALLOW_COPY_AND_ASSIGN(MockNotificationObserver);
49 };
50
51 class AutomationTabHelperBrowserTest : public InProcessBrowserTest {
52 public:
AutomationTabHelperBrowserTest()53 AutomationTabHelperBrowserTest() {
54 EnableDOMAutomation();
55 }
~AutomationTabHelperBrowserTest()56 virtual ~AutomationTabHelperBrowserTest() { }
57
SetUpInProcessBrowserTestFixture()58 void SetUpInProcessBrowserTestFixture() {
59 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
60 test_data_dir_ = test_data_dir_.AppendASCII("automation");
61 }
62
63 // Add default expectations for a client redirection initiated by script,
64 // and quit the message loop when the redirect has completed. This expects
65 // that the tab receives news of the redirect before the script returns.
ExpectClientRedirectAndBreak(MockTabEventObserver * mock_tab_observer,MockNotificationObserver * mock_notification_observer)66 void ExpectClientRedirectAndBreak(
67 MockTabEventObserver* mock_tab_observer,
68 MockNotificationObserver* mock_notification_observer) {
69 mock_notification_observer->Register(
70 NotificationType::DOM_OPERATION_RESPONSE,
71 NotificationService::AllSources());
72
73 testing::InSequence expect_in_sequence;
74 EXPECT_CALL(*mock_tab_observer, OnFirstPendingLoad(_));
75 EXPECT_CALL(*mock_notification_observer, Observe(
76 testing::Eq(NotificationType::DOM_OPERATION_RESPONSE), _, _));
77 EXPECT_CALL(*mock_tab_observer, OnNoMorePendingLoads(_))
78 .WillOnce(testing::InvokeWithoutArgs(
79 MessageLoopForUI::current(), &MessageLoop::Quit));
80 }
81
82 // Executes javascript to execute a given test case found in the current
83 // page's script. If |wait_for_response| is true, this method will not
84 // return until the javascript has been executed.
85 // Use with [ASSERT|EXPECT]_NO_FATAL_FAILURE.
RunTestCaseInJavaScript(int test_case_number,bool wait_for_response)86 void RunTestCaseInJavaScript(int test_case_number, bool wait_for_response) {
87 std::string script = base::StringPrintf("runTestCase(%d);",
88 test_case_number);
89 RenderViewHost* host =
90 browser()->GetSelectedTabContents()->render_view_host();
91 if (wait_for_response) {
92 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
93 host, L"", ASCIIToWide(script)));
94 } else {
95 script += "window.domAutomationController.setAutomationId(0);"
96 "window.domAutomationController.send(0);";
97 host->ExecuteJavascriptInWebFrame(ASCIIToUTF16(""), ASCIIToUTF16(script));
98 }
99 }
100
101 // Returns the |AutomationTabHelper| for the first browser's first tab.
tab_helper()102 AutomationTabHelper* tab_helper() {
103 return browser()->GetTabContentsWrapperAt(0)->automation_tab_helper();
104 }
105
106 protected:
107 FilePath test_data_dir_;
108 };
109
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,FormSubmission)110 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, FormSubmission) {
111 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(
112 test_data_dir_.AppendASCII("client_redirects.html")));
113
114 MockNotificationObserver mock_notification_observer;
115 MockTabEventObserver mock_observer(tab_helper());
116
117 ExpectClientRedirectAndBreak(&mock_observer, &mock_notification_observer);
118
119 ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(1, false));
120 ui_test_utils::RunMessageLoop();
121 }
122
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,CancelFormSubmission)123 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,
124 CancelFormSubmission) {
125 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(
126 test_data_dir_.AppendASCII("client_redirects.html")));
127
128 MockNotificationObserver mock_notification_observer;
129 MockTabEventObserver mock_observer(tab_helper());
130
131 testing::InSequence expect_in_sequence;
132 EXPECT_CALL(mock_observer, OnFirstPendingLoad(_)).Times(0);
133
134 ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(2, true));
135 }
136
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,JsRedirectToSite)137 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,
138 JsRedirectToSite) {
139 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(
140 test_data_dir_.AppendASCII("client_redirects.html")));
141
142 MockNotificationObserver mock_notification_observer;
143 MockTabEventObserver mock_observer(tab_helper());
144
145 ExpectClientRedirectAndBreak(&mock_observer, &mock_notification_observer);
146
147 ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(3, false));
148 ui_test_utils::RunMessageLoop();
149 }
150
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,JsRedirectToUnknownSite)151 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,
152 JsRedirectToUnknownSite) {
153 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(
154 test_data_dir_.AppendASCII("client_redirects.html")));
155
156 MockNotificationObserver mock_notification_observer;
157 MockTabEventObserver mock_observer(tab_helper());
158
159 ExpectClientRedirectAndBreak(&mock_observer, &mock_notification_observer);
160
161 ASSERT_NO_FATAL_FAILURE(RunTestCaseInJavaScript(4, false));
162 ui_test_utils::RunMessageLoop();
163 }
164
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,MetaTagRedirect)165 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,
166 MetaTagRedirect) {
167 MockTabEventObserver mock_observer(tab_helper());
168
169 testing::InSequence expect_in_sequence;
170 EXPECT_CALL(mock_observer, OnFirstPendingLoad(_));
171 EXPECT_CALL(mock_observer, OnNoMorePendingLoads(_));
172
173 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
174 browser(),
175 net::FilePathToFileURL(test_data_dir_.AppendASCII("meta_redirect.html")),
176 2);
177 }
178
179 // Tests that the load stop event occurs after the window onload handler.
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,LoadStopComesAfterOnLoad)180 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,
181 LoadStopComesAfterOnLoad) {
182 MockNotificationObserver mock_notification_observer;
183 mock_notification_observer.Register(NotificationType::DOM_OPERATION_RESPONSE,
184 NotificationService::AllSources());
185 MockTabEventObserver mock_tab_observer(tab_helper());
186
187 EXPECT_CALL(mock_tab_observer, OnFirstPendingLoad(_));
188 {
189 testing::InSequence expect_in_sequence;
190 EXPECT_CALL(mock_notification_observer, Observe(
191 testing::Eq(NotificationType::DOM_OPERATION_RESPONSE), _, _));
192 EXPECT_CALL(mock_tab_observer, OnNoMorePendingLoads(_));
193 }
194
195 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(
196 test_data_dir_.AppendASCII("sends_message_on_load.html")));
197 }
198
199 // Tests that a crashed tab reports that it has stopped loading.
IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,CrashedTabStopsLoading)200 IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest,
201 CrashedTabStopsLoading) {
202 MockTabEventObserver mock_tab_observer(tab_helper());
203
204 testing::InSequence expect_in_sequence;
205 EXPECT_CALL(mock_tab_observer, OnFirstPendingLoad(_));
206 EXPECT_CALL(mock_tab_observer, OnNoMorePendingLoads(_));
207
208 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutCrashURL));
209 }
210