1 // Copyright 2013 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 "base/command_line.h"
6 #include "base/files/file_path.h"
7 #include "base/strings/string_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/translate/translate_service.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chrome/test/base/test_switches.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "components/infobars/core/infobar.h"
18 #include "components/translate/core/browser/translate_infobar_delegate.h"
19 #include "components/translate/core/browser/translate_manager.h"
20 #include "components/translate/core/browser/translate_script.h"
21 #include "components/translate/core/common/translate_switches.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "net/http/http_status_code.h"
25 #include "net/test/embedded_test_server/embedded_test_server.h"
26 #include "net/test/spawned_test_server/spawned_test_server.h"
27 #include "net/url_request/test_url_fetcher_factory.h"
28 #include "net/url_request/url_fetcher_delegate.h"
29
30 namespace {
31
32 const base::FilePath::CharType kTranslateRoot[] =
33 FILE_PATH_LITERAL("chrome/test/data/translate");
34 const char kNonSecurePrefix[] = "/translate/";
35 const char kSecurePrefix[] = "files/";
36 const char kFrenchTestPath[] = "fr_test.html";
37 const char kRefreshMetaTagTestPath[] = "refresh_meta_tag.html";
38 const char kRefreshMetaTagCaseInsensitiveTestPath[] =
39 "refresh_meta_tag_casei.html";
40 const char kRefreshMetaTagAtOnloadTestPath[] =
41 "refresh_meta_tag_at_onload.html";
42 const char kUpdateLocationTestPath[] = "update_location.html";
43 const char kUpdateLocationAtOnloadTestPath[] = "update_location_at_onload.html";
44 const char kMainScriptPath[] = "pseudo_main.js";
45 const char kElementMainScriptPath[] = "pseudo_element_main.js";
46
47 }; // namespace
48
49 class TranslateBrowserTest : public InProcessBrowserTest {
50 public:
TranslateBrowserTest()51 TranslateBrowserTest()
52 : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
53 SSLOptions(SSLOptions::CERT_OK),
54 base::FilePath(kTranslateRoot)),
55 infobar_service_(NULL) {}
56
SetUpCommandLine(CommandLine * command_line)57 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
58 ASSERT_TRUE(https_server_.Start());
59 // Setup alternate security origin for testing in order to allow XHR against
60 // local test server. Note that this flag shows a confirm infobar in tests.
61 GURL base_url = GetSecureURL("");
62 command_line->AppendSwitchASCII(
63 translate::switches::kTranslateSecurityOrigin,
64 base_url.GetOrigin().spec());
65 }
66
67 protected:
GetNonSecureURL(const std::string & path) const68 GURL GetNonSecureURL(const std::string& path) const {
69 std::string prefix(kNonSecurePrefix);
70 return embedded_test_server()->GetURL(prefix + path);
71 }
72
GetSecureURL(const std::string & path) const73 GURL GetSecureURL(const std::string& path) const {
74 std::string prefix(kSecurePrefix);
75 return https_server_.GetURL(prefix + path);
76 }
77
GetExistingTranslateInfoBarDelegate()78 TranslateInfoBarDelegate* GetExistingTranslateInfoBarDelegate() {
79 if (!infobar_service_) {
80 content::WebContents* web_contents =
81 browser()->tab_strip_model()->GetActiveWebContents();
82 if (web_contents)
83 infobar_service_ = InfoBarService::FromWebContents(web_contents);
84 }
85 if (!infobar_service_) {
86 ADD_FAILURE() << "infobar service is not available";
87 return NULL;
88 }
89
90 TranslateInfoBarDelegate* delegate = NULL;
91 for (size_t i = 0; i < infobar_service_->infobar_count(); ++i) {
92 // Check if the shown infobar is a confirm infobar coming from the
93 // |kTranslateSecurityOrigin| flag specified in SetUpCommandLine().
94 // This infobar appears in all tests of TranslateBrowserTest and can be
95 // ignored here.
96 if (infobar_service_->infobar_at(i)->delegate()->
97 AsConfirmInfoBarDelegate()) {
98 continue;
99 }
100
101 TranslateInfoBarDelegate* translate =
102 infobar_service_->infobar_at(i)->delegate()->
103 AsTranslateInfoBarDelegate();
104 if (translate) {
105 EXPECT_FALSE(delegate) << "multiple infobars are shown unexpectedly";
106 delegate = translate;
107 continue;
108 }
109
110 // Other infobar should not be shown.
111 EXPECT_TRUE(delegate);
112 }
113 return delegate;
114 }
115
116 private:
117 net::SpawnedTestServer https_server_;
118 InfoBarService* infobar_service_;
119
120 typedef net::SpawnedTestServer::SSLOptions SSLOptions;
121
122 DISALLOW_COPY_AND_ASSIGN(TranslateBrowserTest);
123 };
124
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,TranslateInIsolatedWorld)125 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, TranslateInIsolatedWorld) {
126 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235
127 if (TranslateService::IsTranslateBubbleEnabled())
128 return;
129
130 net::TestURLFetcherFactory factory;
131 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
132
133 // Check if there is no Translate infobar.
134 TranslateInfoBarDelegate* translate = GetExistingTranslateInfoBarDelegate();
135 EXPECT_FALSE(translate);
136
137 // Setup infobar observer.
138 content::WindowedNotificationObserver infobar(
139 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
140 content::NotificationService::AllSources());
141
142 // Setup page title observer.
143 content::WebContents* web_contents =
144 browser()->tab_strip_model()->GetActiveWebContents();
145 ASSERT_TRUE(web_contents);
146 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS"));
147 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
148
149 // Visit non-secure page which is going to be translated.
150 ui_test_utils::NavigateToURL(browser(), GetNonSecureURL(kFrenchTestPath));
151
152 // Wait for Chrome Translate infobar.
153 infobar.Wait();
154
155 // Perform Chrome Translate.
156 translate = GetExistingTranslateInfoBarDelegate();
157 ASSERT_TRUE(translate);
158 translate->Translate();
159
160 // Hook URLFetcher for element.js.
161 GURL script1_url = GetSecureURL(kMainScriptPath);
162 GURL script2_url = GetSecureURL(kElementMainScriptPath);
163 std::string element_js = "main_script_url = '" + script1_url.spec() + "';\n";
164 element_js += "element_main_script_url = '" + script2_url.spec() + "';\n";
165 element_js +=
166 "google = { 'translate' : { 'TranslateService' : function() { return {\n"
167 " isAvailable: function() {\n"
168 " cr.googleTranslate.onLoadJavascript(main_script_url);\n"
169 " return true;\n"
170 " },\n"
171 " translatePage: function(sl, tl, cb) {\n"
172 " cb(1, true);\n"
173 " }\n"
174 "} } } };\n"
175 "cr.googleTranslate.onTranslateElementLoad();\n";
176 net::TestURLFetcher* fetcher =
177 factory.GetFetcherByID(TranslateScript::kFetcherId);
178 ASSERT_TRUE(fetcher);
179 net::URLRequestStatus status;
180 status.set_status(net::URLRequestStatus::SUCCESS);
181 fetcher->set_status(status);
182 fetcher->set_url(fetcher->GetOriginalURL());
183 fetcher->set_response_code(net::HTTP_OK);
184 fetcher->SetResponseString(element_js);
185 fetcher->delegate()->OnURLFetchComplete(fetcher);
186
187 // Wait for the page title is changed after the test finished.
188 const base::string16 result = watcher.WaitAndGetTitle();
189 EXPECT_EQ("PASS", base::UTF16ToASCII(result));
190 }
191
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,IgnoreRefreshMetaTag)192 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, IgnoreRefreshMetaTag) {
193 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235
194 if (TranslateService::IsTranslateBubbleEnabled())
195 return;
196
197 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
198
199 // Check if there is no Translate infobar.
200 TranslateInfoBarDelegate* translate = GetExistingTranslateInfoBarDelegate();
201 EXPECT_FALSE(translate);
202
203 // Setup page title observer.
204 content::WebContents* web_contents =
205 browser()->tab_strip_model()->GetActiveWebContents();
206 ASSERT_TRUE(web_contents);
207 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS"));
208 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
209
210 // Visit a test page.
211 ui_test_utils::NavigateToURL(
212 browser(),
213 GetNonSecureURL(kRefreshMetaTagTestPath));
214
215 // Wait for the page title is changed after the test finished.
216 const base::string16 result = watcher.WaitAndGetTitle();
217 EXPECT_EQ("PASS", base::UTF16ToASCII(result));
218
219 // Check if there is no Translate infobar.
220 translate = GetExistingTranslateInfoBarDelegate();
221 EXPECT_FALSE(translate);
222 }
223
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,IgnoreRefreshMetaTagInCaseInsensitive)224 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,
225 IgnoreRefreshMetaTagInCaseInsensitive) {
226 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235
227 if (TranslateService::IsTranslateBubbleEnabled())
228 return;
229
230 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
231
232 // Check if there is no Translate infobar.
233 TranslateInfoBarDelegate* translate = GetExistingTranslateInfoBarDelegate();
234 EXPECT_FALSE(translate);
235
236 // Setup page title observer.
237 content::WebContents* web_contents =
238 browser()->tab_strip_model()->GetActiveWebContents();
239 ASSERT_TRUE(web_contents);
240 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS"));
241 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
242
243 // Visit a test page.
244 ui_test_utils::NavigateToURL(
245 browser(),
246 GetNonSecureURL(kRefreshMetaTagCaseInsensitiveTestPath));
247
248 // Wait for the page title is changed after the test finished.
249 const base::string16 result = watcher.WaitAndGetTitle();
250 EXPECT_EQ("PASS", base::UTF16ToASCII(result));
251
252 // Check if there is no Translate infobar.
253 translate = GetExistingTranslateInfoBarDelegate();
254 EXPECT_FALSE(translate);
255 }
256
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,IgnoreRefreshMetaTagAtOnload)257 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, IgnoreRefreshMetaTagAtOnload) {
258 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235
259 if (TranslateService::IsTranslateBubbleEnabled())
260 return;
261
262 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
263
264 // Check if there is no Translate infobar.
265 TranslateInfoBarDelegate* translate = GetExistingTranslateInfoBarDelegate();
266 EXPECT_FALSE(translate);
267
268 // Setup page title observer.
269 content::WebContents* web_contents =
270 browser()->tab_strip_model()->GetActiveWebContents();
271 ASSERT_TRUE(web_contents);
272 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS"));
273 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
274
275 // Visit a test page.
276 ui_test_utils::NavigateToURL(
277 browser(),
278 GetNonSecureURL(kRefreshMetaTagAtOnloadTestPath));
279
280 // Wait for the page title is changed after the test finished.
281 const base::string16 result = watcher.WaitAndGetTitle();
282 EXPECT_EQ("PASS", base::UTF16ToASCII(result));
283
284 // Check if there is no Translate infobar.
285 translate = GetExistingTranslateInfoBarDelegate();
286 EXPECT_FALSE(translate);
287 }
288
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,UpdateLocation)289 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, UpdateLocation) {
290 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235
291 if (TranslateService::IsTranslateBubbleEnabled())
292 return;
293
294 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
295
296 // Check if there is no Translate infobar.
297 TranslateInfoBarDelegate* translate = GetExistingTranslateInfoBarDelegate();
298 EXPECT_FALSE(translate);
299
300 // Setup page title observer.
301 content::WebContents* web_contents =
302 browser()->tab_strip_model()->GetActiveWebContents();
303 ASSERT_TRUE(web_contents);
304 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS"));
305 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
306
307 // Visit a test page.
308 ui_test_utils::NavigateToURL(
309 browser(),
310 GetNonSecureURL(kUpdateLocationTestPath));
311
312 // Wait for the page title is changed after the test finished.
313 const base::string16 result = watcher.WaitAndGetTitle();
314 EXPECT_EQ("PASS", base::UTF16ToASCII(result));
315
316 // Check if there is no Translate infobar.
317 translate = GetExistingTranslateInfoBarDelegate();
318 EXPECT_FALSE(translate);
319 }
320
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,UpdateLocationAtOnload)321 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, UpdateLocationAtOnload) {
322 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235
323 if (TranslateService::IsTranslateBubbleEnabled())
324 return;
325
326 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
327
328 // Check if there is no Translate infobar.
329 TranslateInfoBarDelegate* translate = GetExistingTranslateInfoBarDelegate();
330 EXPECT_FALSE(translate);
331
332 // Setup page title observer.
333 content::WebContents* web_contents =
334 browser()->tab_strip_model()->GetActiveWebContents();
335 ASSERT_TRUE(web_contents);
336 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS"));
337 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
338
339 // Visit a test page.
340 ui_test_utils::NavigateToURL(
341 browser(),
342 GetNonSecureURL(kUpdateLocationAtOnloadTestPath));
343
344 // Wait for the page title is changed after the test finished.
345 const base::string16 result = watcher.WaitAndGetTitle();
346 EXPECT_EQ("PASS", base::UTF16ToASCII(result));
347
348 // Check if there is no Translate infobar.
349 translate = GetExistingTranslateInfoBarDelegate();
350 EXPECT_FALSE(translate);
351 }
352