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