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 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 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 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 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 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 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 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