• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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