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: 51 TranslateBrowserTest() 52 : https_server_(net::SpawnedTestServer::TYPE_HTTPS, 53 SSLOptions(SSLOptions::CERT_OK), 54 base::FilePath(kTranslateRoot)), 55 infobar_service_(NULL) {} 56 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: 68 GURL GetNonSecureURL(const std::string& path) const { 69 std::string prefix(kNonSecurePrefix); 70 return embedded_test_server()->GetURL(prefix + path); 71 } 72 73 GURL GetSecureURL(const std::string& path) const { 74 std::string prefix(kSecurePrefix); 75 return https_server_.GetURL(prefix + path); 76 } 77 78 translate::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 translate::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 translate::TranslateInfoBarDelegate* translate = 102 infobar_service_->infobar_at(i) 103 ->delegate() 104 ->AsTranslateInfoBarDelegate(); 105 if (translate) { 106 EXPECT_FALSE(delegate) << "multiple infobars are shown unexpectedly"; 107 delegate = translate; 108 continue; 109 } 110 111 // Other infobar should not be shown. 112 EXPECT_TRUE(delegate); 113 } 114 return delegate; 115 } 116 117 private: 118 net::SpawnedTestServer https_server_; 119 InfoBarService* infobar_service_; 120 121 typedef net::SpawnedTestServer::SSLOptions SSLOptions; 122 123 DISALLOW_COPY_AND_ASSIGN(TranslateBrowserTest); 124 }; 125 126 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, TranslateInIsolatedWorld) { 127 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 128 if (TranslateService::IsTranslateBubbleEnabled()) 129 return; 130 131 net::TestURLFetcherFactory factory; 132 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 133 134 // Check if there is no Translate infobar. 135 translate::TranslateInfoBarDelegate* translate = 136 GetExistingTranslateInfoBarDelegate(); 137 EXPECT_FALSE(translate); 138 139 // Setup infobar observer. 140 content::WindowedNotificationObserver infobar( 141 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, 142 content::NotificationService::AllSources()); 143 144 // Setup page title observer. 145 content::WebContents* web_contents = 146 browser()->tab_strip_model()->GetActiveWebContents(); 147 ASSERT_TRUE(web_contents); 148 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS")); 149 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 150 151 // Visit non-secure page which is going to be translated. 152 ui_test_utils::NavigateToURL(browser(), GetNonSecureURL(kFrenchTestPath)); 153 154 // Wait for Chrome Translate infobar. 155 infobar.Wait(); 156 157 // Perform Chrome Translate. 158 translate = GetExistingTranslateInfoBarDelegate(); 159 ASSERT_TRUE(translate); 160 translate->Translate(); 161 162 // Hook URLFetcher for element.js. 163 GURL script1_url = GetSecureURL(kMainScriptPath); 164 GURL script2_url = GetSecureURL(kElementMainScriptPath); 165 std::string element_js = "main_script_url = '" + script1_url.spec() + "';\n"; 166 element_js += "element_main_script_url = '" + script2_url.spec() + "';\n"; 167 element_js += 168 "google = { 'translate' : { 'TranslateService' : function() { return {\n" 169 " isAvailable: function() {\n" 170 " cr.googleTranslate.onLoadJavascript(main_script_url);\n" 171 " return true;\n" 172 " },\n" 173 " translatePage: function(sl, tl, cb) {\n" 174 " cb(1, true);\n" 175 " }\n" 176 "} } } };\n" 177 "cr.googleTranslate.onTranslateElementLoad();\n"; 178 net::TestURLFetcher* fetcher = 179 factory.GetFetcherByID(translate::TranslateScript::kFetcherId); 180 ASSERT_TRUE(fetcher); 181 net::URLRequestStatus status; 182 status.set_status(net::URLRequestStatus::SUCCESS); 183 fetcher->set_status(status); 184 fetcher->set_url(fetcher->GetOriginalURL()); 185 fetcher->set_response_code(net::HTTP_OK); 186 fetcher->SetResponseString(element_js); 187 fetcher->delegate()->OnURLFetchComplete(fetcher); 188 189 // Wait for the page title is changed after the test finished. 190 const base::string16 result = watcher.WaitAndGetTitle(); 191 EXPECT_EQ("PASS", base::UTF16ToASCII(result)); 192 } 193 194 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, IgnoreRefreshMetaTag) { 195 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 196 if (TranslateService::IsTranslateBubbleEnabled()) 197 return; 198 199 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 200 201 // Check if there is no Translate infobar. 202 translate::TranslateInfoBarDelegate* translate = 203 GetExistingTranslateInfoBarDelegate(); 204 EXPECT_FALSE(translate); 205 206 // Setup page title observer. 207 content::WebContents* web_contents = 208 browser()->tab_strip_model()->GetActiveWebContents(); 209 ASSERT_TRUE(web_contents); 210 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS")); 211 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 212 213 // Visit a test page. 214 ui_test_utils::NavigateToURL( 215 browser(), 216 GetNonSecureURL(kRefreshMetaTagTestPath)); 217 218 // Wait for the page title is changed after the test finished. 219 const base::string16 result = watcher.WaitAndGetTitle(); 220 EXPECT_EQ("PASS", base::UTF16ToASCII(result)); 221 222 // Check if there is no Translate infobar. 223 translate = GetExistingTranslateInfoBarDelegate(); 224 EXPECT_FALSE(translate); 225 } 226 227 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, 228 IgnoreRefreshMetaTagInCaseInsensitive) { 229 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 230 if (TranslateService::IsTranslateBubbleEnabled()) 231 return; 232 233 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 234 235 // Check if there is no Translate infobar. 236 translate::TranslateInfoBarDelegate* translate = 237 GetExistingTranslateInfoBarDelegate(); 238 EXPECT_FALSE(translate); 239 240 // Setup page title observer. 241 content::WebContents* web_contents = 242 browser()->tab_strip_model()->GetActiveWebContents(); 243 ASSERT_TRUE(web_contents); 244 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS")); 245 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 246 247 // Visit a test page. 248 ui_test_utils::NavigateToURL( 249 browser(), 250 GetNonSecureURL(kRefreshMetaTagCaseInsensitiveTestPath)); 251 252 // Wait for the page title is changed after the test finished. 253 const base::string16 result = watcher.WaitAndGetTitle(); 254 EXPECT_EQ("PASS", base::UTF16ToASCII(result)); 255 256 // Check if there is no Translate infobar. 257 translate = GetExistingTranslateInfoBarDelegate(); 258 EXPECT_FALSE(translate); 259 } 260 261 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, IgnoreRefreshMetaTagAtOnload) { 262 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 263 if (TranslateService::IsTranslateBubbleEnabled()) 264 return; 265 266 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 267 268 // Check if there is no Translate infobar. 269 translate::TranslateInfoBarDelegate* translate = 270 GetExistingTranslateInfoBarDelegate(); 271 EXPECT_FALSE(translate); 272 273 // Setup page title observer. 274 content::WebContents* web_contents = 275 browser()->tab_strip_model()->GetActiveWebContents(); 276 ASSERT_TRUE(web_contents); 277 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS")); 278 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 279 280 // Visit a test page. 281 ui_test_utils::NavigateToURL( 282 browser(), 283 GetNonSecureURL(kRefreshMetaTagAtOnloadTestPath)); 284 285 // Wait for the page title is changed after the test finished. 286 const base::string16 result = watcher.WaitAndGetTitle(); 287 EXPECT_EQ("PASS", base::UTF16ToASCII(result)); 288 289 // Check if there is no Translate infobar. 290 translate = GetExistingTranslateInfoBarDelegate(); 291 EXPECT_FALSE(translate); 292 } 293 294 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, UpdateLocation) { 295 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 296 if (TranslateService::IsTranslateBubbleEnabled()) 297 return; 298 299 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 300 301 // Check if there is no Translate infobar. 302 translate::TranslateInfoBarDelegate* translate = 303 GetExistingTranslateInfoBarDelegate(); 304 EXPECT_FALSE(translate); 305 306 // Setup page title observer. 307 content::WebContents* web_contents = 308 browser()->tab_strip_model()->GetActiveWebContents(); 309 ASSERT_TRUE(web_contents); 310 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS")); 311 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 312 313 // Visit a test page. 314 ui_test_utils::NavigateToURL( 315 browser(), 316 GetNonSecureURL(kUpdateLocationTestPath)); 317 318 // Wait for the page title is changed after the test finished. 319 const base::string16 result = watcher.WaitAndGetTitle(); 320 EXPECT_EQ("PASS", base::UTF16ToASCII(result)); 321 322 // Check if there is no Translate infobar. 323 translate = GetExistingTranslateInfoBarDelegate(); 324 EXPECT_FALSE(translate); 325 } 326 327 IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, UpdateLocationAtOnload) { 328 // TODO(port): Test corresponding bubble translate UX: http://crbug.com/383235 329 if (TranslateService::IsTranslateBubbleEnabled()) 330 return; 331 332 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 333 334 // Check if there is no Translate infobar. 335 translate::TranslateInfoBarDelegate* translate = 336 GetExistingTranslateInfoBarDelegate(); 337 EXPECT_FALSE(translate); 338 339 // Setup page title observer. 340 content::WebContents* web_contents = 341 browser()->tab_strip_model()->GetActiveWebContents(); 342 ASSERT_TRUE(web_contents); 343 content::TitleWatcher watcher(web_contents, base::ASCIIToUTF16("PASS")); 344 watcher.AlsoWaitForTitle(base::ASCIIToUTF16("FAIL")); 345 346 // Visit a test page. 347 ui_test_utils::NavigateToURL( 348 browser(), 349 GetNonSecureURL(kUpdateLocationAtOnloadTestPath)); 350 351 // Wait for the page title is changed after the test finished. 352 const base::string16 result = watcher.WaitAndGetTitle(); 353 EXPECT_EQ("PASS", base::UTF16ToASCII(result)); 354 355 // Check if there is no Translate infobar. 356 translate = GetExistingTranslateInfoBarDelegate(); 357 EXPECT_FALSE(translate); 358 } 359