1 // Copyright (c) 2012 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 <algorithm> 6 #include <set> 7 #include <vector> 8 9 #include "base/command_line.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/prefs/pref_change_registrar.h" 12 #include "base/prefs/pref_service.h" 13 #include "base/strings/stringprintf.h" 14 #include "chrome/app/chrome_command_ids.h" 15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/extensions/test_extension_system.h" 17 #include "chrome/browser/infobars/infobar.h" 18 #include "chrome/browser/infobars/infobar_service.h" 19 #include "chrome/browser/prefs/session_startup_pref.h" 20 #include "chrome/browser/tab_contents/render_view_context_menu.h" 21 #include "chrome/browser/translate/translate_infobar_delegate.h" 22 #include "chrome/browser/translate/translate_language_list.h" 23 #include "chrome/browser/translate/translate_manager.h" 24 #include "chrome/browser/translate/translate_prefs.h" 25 #include "chrome/browser/translate/translate_script.h" 26 #include "chrome/browser/translate/translate_tab_helper.h" 27 #include "chrome/browser/ui/browser.h" 28 #include "chrome/browser/ui/tabs/tab_strip_model.h" 29 #include "chrome/browser/ui/translate/translate_bubble_factory.h" 30 #include "chrome/browser/ui/translate/translate_bubble_model.h" 31 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" 32 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/pref_names.h" 34 #include "chrome/common/render_messages.h" 35 #include "chrome/common/translate/language_detection_details.h" 36 #include "chrome/common/url_constants.h" 37 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 38 #include "chrome/test/base/in_process_browser_test.h" 39 #include "chrome/test/base/testing_browser_process.h" 40 #include "chrome/test/base/testing_profile.h" 41 #include "chrome/test/base/ui_test_utils.h" 42 #include "content/public/browser/navigation_details.h" 43 #include "content/public/browser/navigation_entry.h" 44 #include "content/public/browser/notification_details.h" 45 #include "content/public/browser/notification_registrar.h" 46 #include "content/public/browser/web_contents.h" 47 #include "content/public/test/mock_render_process_host.h" 48 #include "content/public/test/test_renderer_host.h" 49 #include "net/url_request/test_url_fetcher_factory.h" 50 #include "net/url_request/url_fetcher_delegate.h" 51 #include "testing/gmock/include/gmock/gmock.h" 52 #include "third_party/WebKit/public/web/WebContextMenuData.h" 53 54 55 // An observer that keeps track of whether a navigation entry was committed. 56 class NavEntryCommittedObserver : public content::NotificationObserver { 57 public: 58 explicit NavEntryCommittedObserver(content::WebContents* web_contents) { 59 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 60 content::Source<content::NavigationController>( 61 &web_contents->GetController())); 62 } 63 64 virtual void Observe(int type, 65 const content::NotificationSource& source, 66 const content::NotificationDetails& details) OVERRIDE { 67 DCHECK(type == content::NOTIFICATION_NAV_ENTRY_COMMITTED); 68 details_ = 69 *(content::Details<content::LoadCommittedDetails>(details).ptr()); 70 } 71 72 const content::LoadCommittedDetails& load_committed_details() const { 73 return details_; 74 } 75 76 private: 77 content::LoadCommittedDetails details_; 78 content::NotificationRegistrar registrar_; 79 80 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver); 81 }; 82 83 class TranslateManagerBrowserTest : public ChromeRenderViewHostTestHarness, 84 public content::NotificationObserver { 85 public: 86 TranslateManagerBrowserTest() 87 : pref_callback_( 88 base::Bind(&TranslateManagerBrowserTest::OnPreferenceChanged, 89 base::Unretained(this))) { 90 } 91 92 // Simulates navigating to a page and getting the page contents and language 93 // for that navigation. 94 void SimulateNavigation(const GURL& url, 95 const std::string& lang, 96 bool page_translatable) { 97 NavigateAndCommit(url); 98 SimulateOnTranslateLanguageDetermined(lang, page_translatable); 99 } 100 101 void SimulateOnTranslateLanguageDetermined(const std::string& lang, 102 bool page_translatable) { 103 LanguageDetectionDetails details; 104 details.adopted_language = lang; 105 content::RenderViewHostTester::TestOnMessageReceived( 106 rvh(), 107 ChromeViewHostMsg_TranslateLanguageDetermined( 108 0, details, page_translatable)); 109 } 110 111 void SimulateOnPageTranslated(int routing_id, 112 const std::string& source_lang, 113 const std::string& target_lang, 114 TranslateErrors::Type error) { 115 content::RenderViewHostTester::TestOnMessageReceived( 116 rvh(), 117 ChromeViewHostMsg_PageTranslated( 118 routing_id, 0, source_lang, target_lang, error)); 119 } 120 121 void SimulateOnPageTranslated(const std::string& source_lang, 122 const std::string& target_lang) { 123 SimulateOnPageTranslated(0, source_lang, target_lang, 124 TranslateErrors::NONE); 125 } 126 127 bool GetTranslateMessage(int* page_id, 128 std::string* original_lang, 129 std::string* target_lang) { 130 const IPC::Message* message = 131 process()->sink().GetFirstMessageMatching( 132 ChromeViewMsg_TranslatePage::ID); 133 if (!message) 134 return false; 135 Tuple4<int, std::string, std::string, std::string> translate_param; 136 ChromeViewMsg_TranslatePage::Read(message, &translate_param); 137 if (page_id) 138 *page_id = translate_param.a; 139 // Ignore translate_param.b which is the script injected in the page. 140 if (original_lang) 141 *original_lang = translate_param.c; 142 if (target_lang) 143 *target_lang = translate_param.d; 144 return true; 145 } 146 147 InfoBarService* infobar_service() { 148 return InfoBarService::FromWebContents(web_contents()); 149 } 150 151 // Returns the translate infobar if there is 1 infobar and it is a translate 152 // infobar. 153 TranslateInfoBarDelegate* GetTranslateInfoBar() { 154 return (infobar_service()->infobar_count() == 1) ? 155 infobar_service()->infobar_at(0)->delegate()-> 156 AsTranslateInfoBarDelegate() : NULL; 157 } 158 159 // If there is 1 infobar and it is a translate infobar, closes it and returns 160 // true. Returns false otherwise. 161 bool CloseTranslateInfoBar() { 162 InfoBarDelegate* infobar = GetTranslateInfoBar(); 163 if (!infobar) 164 return false; 165 infobar->InfoBarDismissed(); // Simulates closing the infobar. 166 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); 167 return true; 168 } 169 170 // Checks whether |infobar| has been removed and clears the removed infobar 171 // list. 172 bool CheckInfoBarRemovedAndReset(InfoBarDelegate* delegate) { 173 bool found = removed_infobars_.count(delegate) != 0; 174 removed_infobars_.clear(); 175 return found; 176 } 177 178 void ExpireTranslateScriptImmediately() { 179 TranslateManager::GetInstance()->SetTranslateScriptExpirationDelay(0); 180 } 181 182 // If there is 1 infobar and it is a translate infobar, deny translation and 183 // returns true. Returns false otherwise. 184 bool DenyTranslation() { 185 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 186 if (!infobar) 187 return false; 188 infobar->TranslationDeclined(); 189 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0)); 190 return true; 191 } 192 193 void ReloadAndWait(bool successful_reload) { 194 NavEntryCommittedObserver nav_observer(web_contents()); 195 if (successful_reload) 196 Reload(); 197 else 198 FailedReload(); 199 200 // Ensures it is really handled a reload. 201 const content::LoadCommittedDetails& nav_details = 202 nav_observer.load_committed_details(); 203 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. 204 EXPECT_EQ(content::NAVIGATION_TYPE_EXISTING_PAGE, nav_details.type); 205 206 // The TranslateManager class processes the navigation entry committed 207 // notification in a posted task; process that task. 208 base::MessageLoop::current()->RunUntilIdle(); 209 } 210 211 virtual void Observe(int type, 212 const content::NotificationSource& source, 213 const content::NotificationDetails& details) { 214 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); 215 removed_infobars_.insert( 216 content::Details<InfoBar::RemovedDetails>(details)->first->delegate()); 217 } 218 219 MOCK_METHOD1(OnPreferenceChanged, void(const std::string&)); 220 221 protected: 222 virtual void SetUp() { 223 // This test is a unit test but runs in the browser_tests suite. Therefore 224 // it needs to manage its own TestingBrowserProcess. 225 // TODO(jamescook): Figure out how to move this suite back to unit_tests. 226 // Right now it fails to get the translate infobar if you run it there. 227 TestingBrowserProcess::CreateInstance(); 228 // Access the TranslateManager singleton so it is created before we call 229 // ChromeRenderViewHostTestHarness::SetUp() to match what's done in Chrome, 230 // where the TranslateManager is created before the WebContents. This 231 // matters as they both register for similar events and we want the 232 // notifications to happen in the same sequence (TranslateManager first, 233 // WebContents second). Also clears the translate script so it is fetched 234 // everytime and sets the expiration delay to a large value by default (in 235 // case it was zeroed in a previous test). 236 TranslateManager::GetInstance()->ClearTranslateScript(); 237 TranslateManager::GetInstance()-> 238 SetTranslateScriptExpirationDelay(60 * 60 * 1000); 239 TranslateManager::GetInstance()->set_translate_max_reload_attemps(0); 240 241 ChromeRenderViewHostTestHarness::SetUp(); 242 InfoBarService::CreateForWebContents(web_contents()); 243 TranslateTabHelper::CreateForWebContents(web_contents()); 244 245 notification_registrar_.Add(this, 246 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 247 content::Source<InfoBarService>(infobar_service())); 248 } 249 250 virtual void TearDown() { 251 process()->sink().ClearMessages(); 252 253 notification_registrar_.Remove(this, 254 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 255 content::Source<InfoBarService>(infobar_service())); 256 257 ChromeRenderViewHostTestHarness::TearDown(); 258 TestingBrowserProcess::DeleteInstance(); 259 } 260 261 void SimulateTranslateScriptURLFetch(bool success) { 262 net::TestURLFetcher* fetcher = 263 url_fetcher_factory_.GetFetcherByID(TranslateScript::kFetcherId); 264 ASSERT_TRUE(fetcher); 265 net::URLRequestStatus status; 266 status.set_status(success ? net::URLRequestStatus::SUCCESS : 267 net::URLRequestStatus::FAILED); 268 fetcher->set_url(fetcher->GetOriginalURL()); 269 fetcher->set_status(status); 270 fetcher->set_response_code(success ? 200 : 500); 271 fetcher->delegate()->OnURLFetchComplete(fetcher); 272 } 273 274 void SimulateSupportedLanguagesURLFetch( 275 bool success, 276 const std::vector<std::string>& languages, 277 bool use_alpha_languages, 278 const std::vector<std::string>& alpha_languages) { 279 net::URLRequestStatus status; 280 status.set_status(success ? net::URLRequestStatus::SUCCESS : 281 net::URLRequestStatus::FAILED); 282 283 std::string data; 284 if (success) { 285 data = base::StringPrintf( 286 "%s{\"sl\": {\"bla\": \"bla\"}, \"%s\": {", 287 TranslateLanguageList::kLanguageListCallbackName, 288 TranslateLanguageList::kTargetLanguagesKey); 289 const char* comma = ""; 290 for (size_t i = 0; i < languages.size(); ++i) { 291 data += base::StringPrintf( 292 "%s\"%s\": \"UnusedFullName\"", comma, languages[i].c_str()); 293 if (i == 0) 294 comma = ","; 295 } 296 297 if (use_alpha_languages) { 298 data += base::StringPrintf("},\"%s\": {", 299 TranslateLanguageList::kAlphaLanguagesKey); 300 comma = ""; 301 for (size_t i = 0; i < alpha_languages.size(); ++i) { 302 data += base::StringPrintf("%s\"%s\": 1", comma, 303 alpha_languages[i].c_str()); 304 if (i == 0) 305 comma = ","; 306 } 307 } 308 309 data += "}})"; 310 } 311 net::TestURLFetcher* fetcher = 312 url_fetcher_factory_.GetFetcherByID(TranslateLanguageList::kFetcherId); 313 ASSERT_TRUE(fetcher != NULL); 314 fetcher->set_url(fetcher->GetOriginalURL()); 315 fetcher->set_status(status); 316 fetcher->set_response_code(success ? 200 : 500); 317 fetcher->SetResponseString(data); 318 fetcher->delegate()->OnURLFetchComplete(fetcher); 319 } 320 321 void SetPrefObserverExpectation(const char* path) { 322 EXPECT_CALL(*this, OnPreferenceChanged(std::string(path))); 323 } 324 325 PrefChangeRegistrar::NamedChangeCallback pref_callback_; 326 327 private: 328 content::NotificationRegistrar notification_registrar_; 329 net::TestURLFetcherFactory url_fetcher_factory_; 330 331 // The infobars that have been removed. 332 // WARNING: the pointers point to deleted objects, use only for comparison. 333 std::set<InfoBarDelegate*> removed_infobars_; 334 335 DISALLOW_COPY_AND_ASSIGN(TranslateManagerBrowserTest); 336 }; 337 338 class MockTranslateBubbleFactory : public TranslateBubbleFactory { 339 public: 340 MockTranslateBubbleFactory() { 341 } 342 343 virtual void ShowImplementation( 344 BrowserWindow* window, 345 content::WebContents* web_contents, 346 TranslateBubbleModel::ViewState view_state, 347 TranslateErrors::Type error_type) OVERRIDE { 348 if (model_) { 349 model_->SetViewState(view_state); 350 return; 351 } 352 353 TranslateTabHelper* translate_tab_helper = 354 TranslateTabHelper::FromWebContents(web_contents); 355 std::string source_language = 356 translate_tab_helper->language_state().original_language(); 357 std::string target_language = TranslateManager::GetLanguageCode( 358 g_browser_process->GetApplicationLocale()); 359 scoped_ptr<TranslateUIDelegate> ui_delegate( 360 new TranslateUIDelegate(web_contents, 361 source_language, 362 target_language)); 363 model_.reset( 364 new TranslateBubbleModelImpl(view_state, ui_delegate.Pass())); 365 } 366 367 TranslateBubbleModel* model() { return model_.get(); } 368 369 private: 370 scoped_ptr<TranslateBubbleModel> model_; 371 372 DISALLOW_COPY_AND_ASSIGN(MockTranslateBubbleFactory); 373 }; 374 375 namespace { 376 377 class TestRenderViewContextMenu : public RenderViewContextMenu { 378 public: 379 static TestRenderViewContextMenu* CreateContextMenu( 380 content::WebContents* web_contents) { 381 content::ContextMenuParams params; 382 params.media_type = blink::WebContextMenuData::MediaTypeNone; 383 params.x = 0; 384 params.y = 0; 385 params.has_image_contents = true; 386 params.media_flags = 0; 387 params.spellcheck_enabled = false; 388 params.is_editable = false; 389 params.page_url = web_contents->GetController().GetActiveEntry()->GetURL(); 390 #if defined(OS_MACOSX) 391 params.writing_direction_default = 0; 392 params.writing_direction_left_to_right = 0; 393 params.writing_direction_right_to_left = 0; 394 #endif // OS_MACOSX 395 params.edit_flags = blink::WebContextMenuData::CanTranslate; 396 return new TestRenderViewContextMenu(web_contents, params); 397 } 398 399 bool IsItemPresent(int id) { 400 return menu_model_.GetIndexOfCommandId(id) != -1; 401 } 402 403 virtual void PlatformInit() OVERRIDE { } 404 virtual void PlatformCancel() OVERRIDE { } 405 virtual bool GetAcceleratorForCommandId( 406 int command_id, 407 ui::Accelerator* accelerator) OVERRIDE { return false; } 408 409 private: 410 TestRenderViewContextMenu(content::WebContents* web_contents, 411 const content::ContextMenuParams& params) 412 : RenderViewContextMenu(web_contents, params) { 413 } 414 415 DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu); 416 }; 417 418 } // namespace 419 420 TEST_F(TranslateManagerBrowserTest, NormalTranslate) { 421 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 422 423 // We should have an infobar. 424 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 425 ASSERT_TRUE(infobar != NULL); 426 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 427 infobar->infobar_type()); 428 429 // Simulate clicking translate. 430 process()->sink().ClearMessages(); 431 infobar->Translate(); 432 433 // The "Translating..." infobar should be showing. 434 infobar = GetTranslateInfoBar(); 435 ASSERT_TRUE(infobar != NULL); 436 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type()); 437 438 // Simulate the translate script being retrieved (it only needs to be done 439 // once in the test as it is cached). 440 SimulateTranslateScriptURLFetch(true); 441 442 // Test that we sent the right message to the renderer. 443 int page_id = 0; 444 std::string original_lang, target_lang; 445 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 446 EXPECT_EQ("fr", original_lang); 447 EXPECT_EQ("en", target_lang); 448 449 // Simulate the render notifying the translation has been done. 450 SimulateOnPageTranslated("fr", "en"); 451 452 // The after translate infobar should be showing. 453 infobar = GetTranslateInfoBar(); 454 ASSERT_TRUE(infobar != NULL); 455 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->infobar_type()); 456 457 // Simulate changing the original language and translating. 458 process()->sink().ClearMessages(); 459 std::string new_original_lang = infobar->language_code_at(0); 460 infobar->UpdateOriginalLanguageIndex(0); 461 infobar->Translate(); 462 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 463 EXPECT_EQ(new_original_lang, original_lang); 464 EXPECT_EQ("en", target_lang); 465 // Simulate the render notifying the translation has been done. 466 SimulateOnPageTranslated(new_original_lang, "en"); 467 infobar = GetTranslateInfoBar(); 468 ASSERT_TRUE(infobar != NULL); 469 470 // Simulate changing the target language and translating. 471 process()->sink().ClearMessages(); 472 std::string new_target_lang = infobar->language_code_at(1); 473 infobar->UpdateTargetLanguageIndex(1); 474 infobar->Translate(); 475 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 476 EXPECT_EQ(new_original_lang, original_lang); 477 EXPECT_EQ(new_target_lang, target_lang); 478 // Simulate the render notifying the translation has been done. 479 SimulateOnPageTranslated(new_original_lang, new_target_lang); 480 infobar = GetTranslateInfoBar(); 481 ASSERT_TRUE(infobar != NULL); 482 EXPECT_EQ(new_target_lang, infobar->target_language_code()); 483 484 // Reloading should trigger translation iff Always Translate is on. 485 ReloadAndWait(true); 486 infobar = GetTranslateInfoBar(); 487 ASSERT_TRUE(infobar != NULL); 488 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 489 infobar->infobar_type()); 490 infobar->UpdateTargetLanguageIndex(1); 491 infobar->ToggleAlwaysTranslate(); 492 ReloadAndWait(true); 493 infobar = GetTranslateInfoBar(); 494 ASSERT_TRUE(infobar != NULL); 495 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type()); 496 EXPECT_EQ(new_target_lang, infobar->target_language_code()); 497 } 498 499 TEST_F(TranslateManagerBrowserTest, TranslateScriptNotAvailable) { 500 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 501 502 // We should have an infobar. 503 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 504 ASSERT_TRUE(infobar != NULL); 505 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 506 infobar->infobar_type()); 507 508 // Simulate clicking translate. 509 process()->sink().ClearMessages(); 510 infobar->Translate(); 511 SimulateTranslateScriptURLFetch(false); 512 513 // We should not have sent any message to translate to the renderer. 514 EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL)); 515 516 // And we should have an error infobar showing. 517 infobar = GetTranslateInfoBar(); 518 ASSERT_TRUE(infobar != NULL); 519 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, 520 infobar->infobar_type()); 521 } 522 523 // Ensures we deal correctly with pages for which the browser does not recognize 524 // the language (the translate server may or not detect the language). 525 TEST_F(TranslateManagerBrowserTest, TranslateUnknownLanguage) { 526 // Simulate navigating to a page ("und" is the string returned by the CLD for 527 // languages it does not recognize). 528 SimulateNavigation(GURL("http://www.google.mys"), "und", true); 529 530 // We should not have an infobar as we don't know the language. 531 ASSERT_TRUE(GetTranslateInfoBar() == NULL); 532 533 // Translate the page anyway throught the context menu. 534 scoped_ptr<TestRenderViewContextMenu> menu( 535 TestRenderViewContextMenu::CreateContextMenu(web_contents())); 536 menu->Init(); 537 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 538 539 // To test that bug #49018 if fixed, make sure we deal correctly with errors. 540 // Simulate a failure to fetch the translate script. 541 SimulateTranslateScriptURLFetch(false); 542 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 543 ASSERT_TRUE(infobar != NULL); 544 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, 545 infobar->infobar_type()); 546 EXPECT_TRUE(infobar->is_error()); 547 infobar->MessageInfoBarButtonPressed(); 548 SimulateTranslateScriptURLFetch(true); // This time succeed. 549 550 // Simulate the render notifying the translation has been done, the server 551 // having detected the page was in a known and supported language. 552 SimulateOnPageTranslated("fr", "en"); 553 554 // The after translate infobar should be showing. 555 infobar = GetTranslateInfoBar(); 556 ASSERT_TRUE(infobar != NULL); 557 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->infobar_type()); 558 EXPECT_EQ("fr", infobar->original_language_code()); 559 EXPECT_EQ("en", infobar->target_language_code()); 560 561 // Let's run the same steps but this time the server detects the page is 562 // already in English. 563 SimulateNavigation(GURL("http://www.google.com"), "und", true); 564 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 565 menu->Init(); 566 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 567 SimulateOnPageTranslated(1, "en", "en", TranslateErrors::IDENTICAL_LANGUAGES); 568 infobar = GetTranslateInfoBar(); 569 ASSERT_TRUE(infobar != NULL); 570 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, 571 infobar->infobar_type()); 572 EXPECT_EQ(TranslateErrors::IDENTICAL_LANGUAGES, infobar->error_type()); 573 574 // Let's run the same steps again but this time the server fails to detect the 575 // page's language (it returns an empty string). 576 SimulateNavigation(GURL("http://www.google.com"), "und", true); 577 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 578 menu->Init(); 579 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 580 SimulateOnPageTranslated(2, std::string(), "en", 581 TranslateErrors::UNKNOWN_LANGUAGE); 582 infobar = GetTranslateInfoBar(); 583 ASSERT_TRUE(infobar != NULL); 584 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, 585 infobar->infobar_type()); 586 EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE, infobar->error_type()); 587 } 588 589 // Tests that we show/don't show an info-bar for the languages. 590 TEST_F(TranslateManagerBrowserTest, TestLanguages) { 591 std::vector<std::string> languages; 592 languages.push_back("en"); 593 languages.push_back("ja"); 594 languages.push_back("fr"); 595 languages.push_back("ht"); 596 languages.push_back("xx"); 597 languages.push_back("zh"); 598 languages.push_back("zh-CN"); 599 languages.push_back("und"); 600 601 GURL url("http://www.google.com"); 602 for (size_t i = 0; i < languages.size(); ++i) { 603 std::string lang = languages[i]; 604 SCOPED_TRACE(::testing::Message() << "Iteration " << i << 605 " language=" << lang); 606 607 // We should not have a translate infobar. 608 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 609 ASSERT_TRUE(infobar == NULL); 610 611 SimulateNavigation(url, lang, true); 612 613 // Verify we have/don't have an info-bar as expected. 614 infobar = GetTranslateInfoBar(); 615 bool expected = TranslateManager::IsSupportedLanguage(lang) && 616 lang != "en"; 617 EXPECT_EQ(expected, infobar != NULL); 618 619 if (infobar != NULL) 620 EXPECT_TRUE(CloseTranslateInfoBar()); 621 } 622 } 623 624 // Test the fetching of languages from the translate server 625 TEST_F(TranslateManagerBrowserTest, FetchLanguagesFromTranslateServer) { 626 std::vector<std::string> server_languages; 627 // A list of languages to fake being returned by the translate server. 628 server_languages.push_back("aa"); 629 server_languages.push_back("ak"); 630 server_languages.push_back("ab"); 631 server_languages.push_back("en-CA"); 632 server_languages.push_back("zh"); 633 server_languages.push_back("yi"); 634 server_languages.push_back("fr-FR"); 635 server_languages.push_back("xx"); 636 637 std::vector<std::string> alpha_languages; 638 alpha_languages.push_back("aa"); 639 alpha_languages.push_back("yi"); 640 641 // First, get the default languages list. Note that calling 642 // GetSupportedLanguages() invokes RequestLanguageList() internally. 643 std::vector<std::string> default_supported_languages; 644 TranslateManager::GetSupportedLanguages(&default_supported_languages); 645 // To make sure we got the defaults and don't confuse them with the mocks. 646 ASSERT_NE(default_supported_languages.size(), server_languages.size()); 647 648 // Check that we still get the defaults until the URLFetch has completed. 649 std::vector<std::string> current_supported_languages; 650 TranslateManager::GetSupportedLanguages(¤t_supported_languages); 651 EXPECT_EQ(default_supported_languages, current_supported_languages); 652 653 // Also check that it didn't change if we failed the URL fetch. 654 SimulateSupportedLanguagesURLFetch(false, std::vector<std::string>(), 655 true, std::vector<std::string>()); 656 current_supported_languages.clear(); 657 TranslateManager::GetSupportedLanguages(¤t_supported_languages); 658 EXPECT_EQ(default_supported_languages, current_supported_languages); 659 660 // Now check that we got the appropriate set of languages from the server. 661 SimulateSupportedLanguagesURLFetch(true, server_languages, 662 true, alpha_languages); 663 current_supported_languages.clear(); 664 TranslateManager::GetSupportedLanguages(¤t_supported_languages); 665 // "xx" can't be displayed in the Translate inforbar, so this is eliminated. 666 EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size()); 667 // Not sure we need to guarantee the order of languages, so we find them. 668 for (size_t i = 0; i < server_languages.size(); ++i) { 669 const std::string& lang = server_languages[i]; 670 if (lang == "xx") 671 continue; 672 EXPECT_NE(current_supported_languages.end(), 673 std::find(current_supported_languages.begin(), 674 current_supported_languages.end(), 675 lang)); 676 bool is_alpha = std::find(alpha_languages.begin(), 677 alpha_languages.end(), 678 lang) != alpha_languages.end(); 679 EXPECT_EQ(TranslateManager::IsAlphaLanguage(lang), is_alpha); 680 } 681 } 682 683 // Test the fetching of languages from the translate server without 'al' 684 // parameter. 685 TEST_F(TranslateManagerBrowserTest, 686 FetchLanguagesFromTranslateServerWithoutAlpha) { 687 std::vector<std::string> server_languages; 688 server_languages.push_back("aa"); 689 server_languages.push_back("ak"); 690 server_languages.push_back("ab"); 691 server_languages.push_back("en-CA"); 692 server_languages.push_back("zh"); 693 server_languages.push_back("yi"); 694 server_languages.push_back("fr-FR"); 695 server_languages.push_back("xx"); 696 697 std::vector<std::string> alpha_languages; 698 alpha_languages.push_back("aa"); 699 alpha_languages.push_back("yi"); 700 701 // call GetSupportedLanguages to call RequestLanguageList internally. 702 std::vector<std::string> default_supported_languages; 703 TranslateManager::GetSupportedLanguages(&default_supported_languages); 704 705 SimulateSupportedLanguagesURLFetch(true, server_languages, 706 false, alpha_languages); 707 708 std::vector<std::string> current_supported_languages; 709 TranslateManager::GetSupportedLanguages(¤t_supported_languages); 710 711 // "xx" can't be displayed in the Translate inforbar, so this is eliminated. 712 EXPECT_EQ(server_languages.size() - 1, current_supported_languages.size()); 713 714 for (size_t i = 0; i < server_languages.size(); ++i) { 715 const std::string& lang = server_languages[i]; 716 if (lang == "xx") 717 continue; 718 EXPECT_NE(current_supported_languages.end(), 719 std::find(current_supported_languages.begin(), 720 current_supported_languages.end(), 721 lang)); 722 EXPECT_FALSE(TranslateManager::IsAlphaLanguage(lang)); 723 } 724 } 725 726 // Tests auto-translate on page. 727 TEST_F(TranslateManagerBrowserTest, AutoTranslateOnNavigate) { 728 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 729 730 // Simulate the user translating. 731 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 732 ASSERT_TRUE(infobar != NULL); 733 infobar->Translate(); 734 // Simulate the translate script being retrieved. 735 SimulateTranslateScriptURLFetch(true); 736 SimulateOnPageTranslated("fr", "en"); 737 738 // Now navigate to a new page in the same language. 739 process()->sink().ClearMessages(); 740 SimulateNavigation(GURL("http://news.google.fr"), "fr", true); 741 742 // This should have automatically triggered a translation. 743 int page_id = 0; 744 std::string original_lang, target_lang; 745 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 746 EXPECT_EQ(1, page_id); 747 EXPECT_EQ("fr", original_lang); 748 EXPECT_EQ("en", target_lang); 749 750 // Now navigate to a page in a different language. 751 process()->sink().ClearMessages(); 752 SimulateNavigation(GURL("http://news.google.es"), "es", true); 753 754 // This should not have triggered a translate. 755 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 756 } 757 758 // Tests that multiple OnPageContents do not cause multiple infobars. 759 TEST_F(TranslateManagerBrowserTest, MultipleOnPageContents) { 760 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 761 762 // Simulate clicking 'Nope' (don't translate). 763 EXPECT_TRUE(DenyTranslation()); 764 EXPECT_EQ(0U, infobar_service()->infobar_count()); 765 766 // Send a new PageContents, we should not show an infobar. 767 SimulateOnTranslateLanguageDetermined("fr", true); 768 EXPECT_EQ(0U, infobar_service()->infobar_count()); 769 770 // Do the same steps but simulate closing the infobar this time. 771 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); 772 EXPECT_TRUE(CloseTranslateInfoBar()); 773 EXPECT_EQ(0U, infobar_service()->infobar_count()); 774 SimulateOnTranslateLanguageDetermined("fr", true); 775 EXPECT_EQ(0U, infobar_service()->infobar_count()); 776 } 777 778 // Test that reloading the page brings back the infobar if the 779 // reload succeeded and does not bring it back the reload fails. 780 TEST_F(TranslateManagerBrowserTest, Reload) { 781 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 782 783 EXPECT_TRUE(CloseTranslateInfoBar()); 784 785 // Reload should bring back the infobar if the reload succeeds. 786 ReloadAndWait(true); 787 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 788 EXPECT_TRUE(CloseTranslateInfoBar()); 789 790 // ...But not show it if the reload fails. 791 ReloadAndWait(false); 792 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 793 794 // If we set reload attempts to a high value, we will not see the infobar 795 // immediately. 796 TranslateManager::GetInstance()->set_translate_max_reload_attemps(100); 797 ReloadAndWait(true); 798 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 799 } 800 801 // Test that reloading the page by way of typing again the URL in the 802 // location bar brings back the infobar. 803 TEST_F(TranslateManagerBrowserTest, ReloadFromLocationBar) { 804 GURL url("http://www.google.fr"); 805 SimulateNavigation(url, "fr", true); 806 807 EXPECT_TRUE(CloseTranslateInfoBar()); 808 809 // Create a pending navigation and simulate a page load. That should be the 810 // equivalent of typing the URL again in the location bar. 811 NavEntryCommittedObserver nav_observer(web_contents()); 812 web_contents()->GetController().LoadURL(url, content::Referrer(), 813 content::PAGE_TRANSITION_TYPED, 814 std::string()); 815 rvh_tester()->SendNavigate(0, url); 816 817 // Test that we are really getting a same page navigation, the test would be 818 // useless if it was not the case. 819 const content::LoadCommittedDetails& nav_details = 820 nav_observer.load_committed_details(); 821 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. 822 EXPECT_EQ(content::NAVIGATION_TYPE_SAME_PAGE, nav_details.type); 823 824 // The TranslateManager class processes the navigation entry committed 825 // notification in a posted task; process that task. 826 base::MessageLoop::current()->RunUntilIdle(); 827 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 828 } 829 830 // Tests that a closed translate infobar does not reappear when navigating 831 // in-page. 832 TEST_F(TranslateManagerBrowserTest, CloseInfoBarInPageNavigation) { 833 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 834 835 EXPECT_TRUE(CloseTranslateInfoBar()); 836 837 // Navigate in page, no infobar should be shown. 838 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); 839 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 840 841 // Navigate out of page, a new infobar should show. 842 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); 843 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 844 } 845 846 // Tests that a closed translate infobar does not reappear when navigating 847 // in a subframe. (http://crbug.com/48215) 848 TEST_F(TranslateManagerBrowserTest, CloseInfoBarInSubframeNavigation) { 849 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 850 851 EXPECT_TRUE(CloseTranslateInfoBar()); 852 853 // Simulate a sub-frame auto-navigating. 854 rvh_tester()->SendNavigateWithTransition( 855 1, GURL("http://pub.com"), content::PAGE_TRANSITION_AUTO_SUBFRAME); 856 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 857 858 // Simulate the user navigating in a sub-frame. 859 rvh_tester()->SendNavigateWithTransition( 860 2, GURL("http://pub.com"), content::PAGE_TRANSITION_MANUAL_SUBFRAME); 861 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 862 863 // Navigate out of page, a new infobar should show. 864 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); 865 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 866 } 867 868 // Tests that denying translation is sticky when navigating in page. 869 TEST_F(TranslateManagerBrowserTest, DenyTranslateInPageNavigation) { 870 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 871 872 // Simulate clicking 'Nope' (don't translate). 873 EXPECT_TRUE(DenyTranslation()); 874 875 // Navigate in page, no infobar should be shown. 876 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); 877 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 878 879 // Navigate out of page, a new infobar should show. 880 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); 881 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 882 } 883 884 // Tests that after translating and closing the infobar, the infobar does not 885 // return when navigating in page. 886 TEST_F(TranslateManagerBrowserTest, TranslateCloseInfoBarInPageNavigation) { 887 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 888 889 // Simulate the user translating. 890 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 891 ASSERT_TRUE(infobar != NULL); 892 infobar->Translate(); 893 // Simulate the translate script being retrieved. 894 SimulateTranslateScriptURLFetch(true); 895 SimulateOnPageTranslated("fr", "en"); 896 897 EXPECT_TRUE(CloseTranslateInfoBar()); 898 899 // Navigate in page, no infobar should be shown. 900 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); 901 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 902 903 // Navigate out of page, a new infobar should show. 904 // Note that we navigate to a page in a different language so we don't trigger 905 // the auto-translate feature (it would translate the page automatically and 906 // the before translate inforbar would not be shown). 907 SimulateNavigation(GURL("http://www.google.de"), "de", true); 908 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 909 } 910 911 // Tests that the after translate the infobar still shows when navigating 912 // in-page. 913 TEST_F(TranslateManagerBrowserTest, TranslateInPageNavigation) { 914 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 915 916 // Simulate the user translating. 917 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 918 ASSERT_TRUE(infobar != NULL); 919 infobar->Translate(); 920 SimulateTranslateScriptURLFetch(true); 921 SimulateOnPageTranslated("fr", "en"); 922 // The after translate infobar is showing. 923 infobar = GetTranslateInfoBar(); 924 ASSERT_TRUE(infobar != NULL); 925 926 // Navigate out of page, a new infobar should show. 927 // See note in TranslateCloseInfoBarInPageNavigation test on why it is 928 // important to navigate to a page in a different language for this test. 929 SimulateNavigation(GURL("http://www.google.de"), "de", true); 930 // The old infobar is gone. 931 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar)); 932 // And there is a new one. 933 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 934 } 935 936 // Tests that no translate infobar is shown when navigating to a page in an 937 // unsupported language. 938 TEST_F(TranslateManagerBrowserTest, CLDReportsUnsupportedPageLanguage) { 939 // Simulate navigating to a page and getting an unsupported language. 940 SimulateNavigation(GURL("http://www.google.com"), "qbz", true); 941 942 // No info-bar should be shown. 943 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 944 } 945 946 // Tests that we deal correctly with unsupported languages returned by the 947 // server. 948 // The translation server might return a language we don't support. 949 TEST_F(TranslateManagerBrowserTest, ServerReportsUnsupportedLanguage) { 950 SimulateNavigation(GURL("http://mail.google.fr"), "fr", true); 951 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 952 ASSERT_TRUE(infobar != NULL); 953 process()->sink().ClearMessages(); 954 infobar->Translate(); 955 SimulateTranslateScriptURLFetch(true); 956 // Simulate the render notifying the translation has been done, but it 957 // reports a language we don't support. 958 SimulateOnPageTranslated("qbz", "en"); 959 960 // An error infobar should be showing to report that we don't support this 961 // language. 962 infobar = GetTranslateInfoBar(); 963 ASSERT_TRUE(infobar != NULL); 964 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, 965 infobar->infobar_type()); 966 967 // This infobar should have a button (so the string should not be empty). 968 ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty()); 969 970 // Pressing the button on that infobar should revert to the original language. 971 process()->sink().ClearMessages(); 972 infobar->MessageInfoBarButtonPressed(); 973 const IPC::Message* message = 974 process()->sink().GetFirstMessageMatching( 975 ChromeViewMsg_RevertTranslation::ID); 976 EXPECT_TRUE(message != NULL); 977 // And it should have removed the infobar. 978 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 979 } 980 981 // Tests that no translate infobar is shown and context menu is disabled, when 982 // Chrome is in a language that the translate server does not support. 983 TEST_F(TranslateManagerBrowserTest, UnsupportedUILanguage) { 984 std::string original_lang = g_browser_process->GetApplicationLocale(); 985 g_browser_process->SetApplicationLocale("qbz"); 986 987 // Make sure that the accept language list only contains unsupported languages 988 Profile* profile = 989 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 990 PrefService* prefs = profile->GetPrefs(); 991 prefs->SetString(prefs::kAcceptLanguages, "qbz"); 992 993 // Simulate navigating to a page in a language supported by the translate 994 // server. 995 SimulateNavigation(GURL("http://www.google.com"), "en", true); 996 997 // No info-bar should be shown. 998 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 999 1000 // And the context menu option should be disabled too. 1001 scoped_ptr<TestRenderViewContextMenu> menu( 1002 TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1003 menu->Init(); 1004 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1005 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1006 1007 g_browser_process->SetApplicationLocale(original_lang); 1008 } 1009 1010 // Tests that the first supported accept language is selected 1011 TEST_F(TranslateManagerBrowserTest, TranslateAcceptLanguage) { 1012 // Set locate to non-existant language 1013 std::string original_lang = g_browser_process->GetApplicationLocale(); 1014 g_browser_process->SetApplicationLocale("qbz"); 1015 1016 // Set Qbz and French as the only accepted languages 1017 Profile* profile = 1018 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1019 PrefService* prefs = profile->GetPrefs(); 1020 prefs->SetString(prefs::kAcceptLanguages, "qbz,fr"); 1021 1022 // Go to a German page 1023 SimulateNavigation(GURL("http://google.de"), "de", true); 1024 1025 // Expect the infobar to pop up 1026 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1027 1028 // Set Qbz and English-US as the only accepted languages to test the country 1029 // code removal code which was causing a crash as filed in Issue 90106, 1030 // a crash caused by a language with a country code that wasn't recognized. 1031 prefs->SetString(prefs::kAcceptLanguages, "qbz,en-us"); 1032 1033 // Go to a German page 1034 SimulateNavigation(GURL("http://google.de"), "de", true); 1035 1036 // Expect the infobar to pop up 1037 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1038 } 1039 1040 // Tests that the translate enabled preference is honored. 1041 TEST_F(TranslateManagerBrowserTest, TranslateEnabledPref) { 1042 // Make sure the pref allows translate. 1043 Profile* profile = 1044 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1045 PrefService* prefs = profile->GetPrefs(); 1046 prefs->SetBoolean(prefs::kEnableTranslate, true); 1047 1048 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1049 1050 // An infobar should be shown. 1051 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1052 EXPECT_TRUE(infobar != NULL); 1053 1054 // Disable translate. 1055 prefs->SetBoolean(prefs::kEnableTranslate, false); 1056 1057 // Navigate to a new page, that should close the previous infobar. 1058 GURL url("http://www.youtube.fr"); 1059 NavigateAndCommit(url); 1060 infobar = GetTranslateInfoBar(); 1061 EXPECT_TRUE(infobar == NULL); 1062 1063 // Simulate getting the page contents and language, that should not trigger 1064 // a translate infobar. 1065 SimulateOnTranslateLanguageDetermined("fr", true); 1066 infobar = GetTranslateInfoBar(); 1067 EXPECT_TRUE(infobar == NULL); 1068 } 1069 1070 // Tests the "Never translate <language>" pref. 1071 TEST_F(TranslateManagerBrowserTest, NeverTranslateLanguagePref) { 1072 GURL url("http://www.google.fr"); 1073 SimulateNavigation(url, "fr", true); 1074 1075 // An infobar should be shown. 1076 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1077 1078 // Select never translate this language. 1079 Profile* profile = 1080 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1081 PrefService* prefs = profile->GetPrefs(); 1082 PrefChangeRegistrar registrar; 1083 registrar.Init(prefs); 1084 registrar.Add(TranslatePrefs::kPrefTranslateBlockedLanguages, 1085 pref_callback_); 1086 TranslatePrefs translate_prefs(prefs); 1087 EXPECT_FALSE(translate_prefs.IsBlockedLanguage("fr")); 1088 EXPECT_TRUE(translate_prefs.CanTranslateLanguage(profile, "fr")); 1089 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateBlockedLanguages); 1090 translate_prefs.BlockLanguage("fr"); 1091 EXPECT_TRUE(translate_prefs.IsBlockedLanguage("fr")); 1092 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host())); 1093 EXPECT_FALSE(translate_prefs.CanTranslateLanguage(profile, "fr")); 1094 1095 EXPECT_TRUE(CloseTranslateInfoBar()); 1096 1097 // Navigate to a new page also in French. 1098 SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true); 1099 1100 // There should not be a translate infobar. 1101 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1102 1103 // Remove the language from the blacklist. 1104 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateBlockedLanguages); 1105 translate_prefs.UnblockLanguage("fr"); 1106 EXPECT_FALSE(translate_prefs.IsBlockedLanguage("fr")); 1107 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host())); 1108 EXPECT_TRUE(translate_prefs.CanTranslateLanguage(profile, "fr")); 1109 1110 // Navigate to a page in French. 1111 SimulateNavigation(url, "fr", true); 1112 1113 // There should be a translate infobar. 1114 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1115 } 1116 1117 // Tests the "Never translate this site" pref. 1118 TEST_F(TranslateManagerBrowserTest, NeverTranslateSitePref) { 1119 GURL url("http://www.google.fr"); 1120 std::string host(url.host()); 1121 SimulateNavigation(url, "fr", true); 1122 1123 // An infobar should be shown. 1124 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1125 1126 // Select never translate this site. 1127 Profile* profile = 1128 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1129 PrefService* prefs = profile->GetPrefs(); 1130 PrefChangeRegistrar registrar; 1131 registrar.Init(prefs); 1132 registrar.Add(TranslatePrefs::kPrefTranslateSiteBlacklist, pref_callback_); 1133 TranslatePrefs translate_prefs(prefs); 1134 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host)); 1135 EXPECT_TRUE(translate_prefs.CanTranslateLanguage(profile, "fr")); 1136 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist); 1137 translate_prefs.BlacklistSite(host); 1138 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(host)); 1139 EXPECT_TRUE(translate_prefs.CanTranslateLanguage(profile, "fr")); 1140 1141 EXPECT_TRUE(CloseTranslateInfoBar()); 1142 1143 // Navigate to a new page also on the same site. 1144 SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true); 1145 1146 // There should not be a translate infobar. 1147 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1148 1149 // Remove the site from the blacklist. 1150 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist); 1151 translate_prefs.RemoveSiteFromBlacklist(host); 1152 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host)); 1153 EXPECT_TRUE(translate_prefs.CanTranslateLanguage(profile, "fr")); 1154 1155 // Navigate to a page in French. 1156 SimulateNavigation(url, "fr", true); 1157 1158 // There should be a translate infobar. 1159 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1160 } 1161 1162 // Tests the "Always translate this language" pref. 1163 TEST_F(TranslateManagerBrowserTest, AlwaysTranslateLanguagePref) { 1164 // Select always translate French to English. 1165 Profile* profile = 1166 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1167 PrefService* prefs = profile->GetPrefs(); 1168 PrefChangeRegistrar registrar; 1169 registrar.Init(prefs); 1170 registrar.Add(TranslatePrefs::kPrefTranslateWhitelists, pref_callback_); 1171 TranslatePrefs translate_prefs(prefs); 1172 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); 1173 translate_prefs.WhitelistLanguagePair("fr", "en"); 1174 1175 // Load a page in French. 1176 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1177 1178 // It should have triggered an automatic translation to English. 1179 1180 // The translating infobar should be showing. 1181 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1182 ASSERT_TRUE(infobar != NULL); 1183 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type()); 1184 SimulateTranslateScriptURLFetch(true); 1185 int page_id = 0; 1186 std::string original_lang, target_lang; 1187 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1188 EXPECT_EQ("fr", original_lang); 1189 EXPECT_EQ("en", target_lang); 1190 process()->sink().ClearMessages(); 1191 1192 // Try another language, it should not be autotranslated. 1193 SimulateNavigation(GURL("http://www.google.es"), "es", true); 1194 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1195 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1196 EXPECT_TRUE(CloseTranslateInfoBar()); 1197 1198 // Let's switch to incognito mode, it should not be autotranslated in that 1199 // case either. 1200 TestingProfile* test_profile = 1201 static_cast<TestingProfile*>(web_contents()->GetBrowserContext()); 1202 test_profile->ForceIncognito(true); 1203 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); 1204 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1205 EXPECT_TRUE(GetTranslateInfoBar() != NULL); 1206 EXPECT_TRUE(CloseTranslateInfoBar()); 1207 test_profile->ForceIncognito(false); // Get back to non incognito. 1208 1209 // Now revert the always translate pref and make sure we go back to expected 1210 // behavior, which is show a "before translate" infobar. 1211 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); 1212 translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en"); 1213 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1214 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1215 infobar = GetTranslateInfoBar(); 1216 ASSERT_TRUE(infobar != NULL); 1217 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 1218 infobar->infobar_type()); 1219 } 1220 1221 // Context menu. 1222 TEST_F(TranslateManagerBrowserTest, ContextMenu) { 1223 // Blacklist www.google.fr and French for translation. 1224 GURL url("http://www.google.fr"); 1225 Profile* profile = 1226 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1227 TranslatePrefs translate_prefs(profile->GetPrefs()); 1228 translate_prefs.BlockLanguage("fr"); 1229 translate_prefs.BlacklistSite(url.host()); 1230 EXPECT_TRUE(translate_prefs.IsBlockedLanguage("fr")); 1231 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(url.host())); 1232 1233 // Simulate navigating to a page in French. The translate menu should show but 1234 // should only be enabled when the page language has been received. 1235 NavigateAndCommit(url); 1236 scoped_ptr<TestRenderViewContextMenu> menu( 1237 TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1238 menu->Init(); 1239 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1240 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1241 1242 // Simulate receiving the language. 1243 SimulateOnTranslateLanguageDetermined("fr", true); 1244 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1245 menu->Init(); 1246 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1247 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1248 1249 // Use the menu to translate the page. 1250 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1251 1252 // That should have triggered a translation. 1253 // The "translating..." infobar should be showing. 1254 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1255 ASSERT_TRUE(infobar != NULL); 1256 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->infobar_type()); 1257 SimulateTranslateScriptURLFetch(true); 1258 int page_id = 0; 1259 std::string original_lang, target_lang; 1260 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1261 EXPECT_EQ("fr", original_lang); 1262 EXPECT_EQ("en", target_lang); 1263 process()->sink().ClearMessages(); 1264 1265 // This should also have reverted the blacklisting of this site and language. 1266 EXPECT_FALSE(translate_prefs.IsBlockedLanguage("fr")); 1267 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host())); 1268 1269 // Let's simulate the page being translated. 1270 SimulateOnPageTranslated("fr", "en"); 1271 1272 // The translate menu should now be disabled. 1273 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1274 menu->Init(); 1275 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1276 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1277 1278 // Test that selecting translate in the context menu WHILE the page is being 1279 // translated does nothing (this could happen if autotranslate kicks-in and 1280 // the user selects the menu while the translation is being performed). 1281 SimulateNavigation(GURL("http://www.google.es"), "es", true); 1282 infobar = GetTranslateInfoBar(); 1283 ASSERT_TRUE(infobar != NULL); 1284 infobar->Translate(); 1285 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1286 process()->sink().ClearMessages(); 1287 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1288 menu->Init(); 1289 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1290 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1291 // No message expected since the translation should have been ignored. 1292 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1293 1294 // Now test that selecting translate in the context menu AFTER the page has 1295 // been translated does nothing. 1296 SimulateNavigation(GURL("http://www.google.de"), "de", true); 1297 infobar = GetTranslateInfoBar(); 1298 ASSERT_TRUE(infobar != NULL); 1299 infobar->Translate(); 1300 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1301 process()->sink().ClearMessages(); 1302 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1303 menu->Init(); 1304 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1305 SimulateOnPageTranslated("de", "en"); 1306 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1307 // No message expected since the translation should have been ignored. 1308 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1309 1310 // Test that the translate context menu is enabled when the page is in an 1311 // unknown language. 1312 SimulateNavigation(url, "und", true); 1313 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1314 menu->Init(); 1315 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1316 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1317 1318 // Test that the translate context menu is enabled even if the page is in an 1319 // unsupported language. 1320 SimulateNavigation(url, "qbz", true); 1321 menu.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1322 menu->Init(); 1323 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1324 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1325 } 1326 1327 // Tests that an extra always/never translate button is shown on the "before 1328 // translate" infobar when the translation is accepted/declined 3 times, 1329 // only when not in incognito mode. 1330 TEST_F(TranslateManagerBrowserTest, BeforeTranslateExtraButtons) { 1331 Profile* profile = 1332 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); 1333 TranslatePrefs translate_prefs(profile->GetPrefs()); 1334 translate_prefs.ResetTranslationAcceptedCount("fr"); 1335 translate_prefs.ResetTranslationDeniedCount("fr"); 1336 translate_prefs.ResetTranslationAcceptedCount("de"); 1337 translate_prefs.ResetTranslationDeniedCount("de"); 1338 1339 // We'll do 4 times in incognito mode first to make sure the button is not 1340 // shown in that case, then 4 times in normal mode. 1341 TranslateInfoBarDelegate* infobar; 1342 TestingProfile* test_profile = 1343 static_cast<TestingProfile*>(web_contents()->GetBrowserContext()); 1344 static_cast<extensions::TestExtensionSystem*>( 1345 extensions::ExtensionSystem::Get(test_profile))-> 1346 CreateProcessManager(); 1347 test_profile->ForceIncognito(true); 1348 for (int i = 0; i < 8; ++i) { 1349 SCOPED_TRACE(::testing::Message() << "Iteration " << i << 1350 " incognito mode=" << test_profile->IsOffTheRecord()); 1351 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1352 infobar = GetTranslateInfoBar(); 1353 ASSERT_TRUE(infobar != NULL); 1354 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 1355 infobar->infobar_type()); 1356 if (i < 7) { 1357 EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateShortcut()); 1358 infobar->Translate(); 1359 process()->sink().ClearMessages(); 1360 } else { 1361 EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateShortcut()); 1362 } 1363 if (i == 3) 1364 test_profile->ForceIncognito(false); 1365 } 1366 // Simulate the user pressing "Always translate French". 1367 infobar->AlwaysTranslatePageLanguage(); 1368 EXPECT_TRUE(translate_prefs.IsLanguagePairWhitelisted("fr", "en")); 1369 // Simulate the translate script being retrieved (it only needs to be done 1370 // once in the test as it is cached). 1371 SimulateTranslateScriptURLFetch(true); 1372 // That should have triggered a page translate. 1373 int page_id = 0; 1374 std::string original_lang, target_lang; 1375 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1376 process()->sink().ClearMessages(); 1377 1378 // Now test that declining the translation causes a "never translate" button 1379 // to be shown (in non incognito mode only). 1380 test_profile->ForceIncognito(true); 1381 for (int i = 0; i < 8; ++i) { 1382 SCOPED_TRACE(::testing::Message() << "Iteration " << i << 1383 " incognito mode=" << test_profile->IsOffTheRecord()); 1384 SimulateNavigation(GURL("http://www.google.de"), "de", true); 1385 infobar = GetTranslateInfoBar(); 1386 ASSERT_TRUE(infobar != NULL); 1387 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 1388 infobar->infobar_type()); 1389 if (i < 7) { 1390 EXPECT_FALSE(infobar->ShouldShowNeverTranslateShortcut()); 1391 infobar->TranslationDeclined(); 1392 } else { 1393 EXPECT_TRUE(infobar->ShouldShowNeverTranslateShortcut()); 1394 } 1395 if (i == 3) 1396 test_profile->ForceIncognito(false); 1397 } 1398 // Simulate the user pressing "Never translate French". 1399 infobar->NeverTranslatePageLanguage(); 1400 EXPECT_TRUE(translate_prefs.IsBlockedLanguage("de")); 1401 // No translation should have occured and the infobar should be gone. 1402 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1403 process()->sink().ClearMessages(); 1404 ASSERT_TRUE(GetTranslateInfoBar() == NULL); 1405 } 1406 1407 // Tests that we don't show a translate infobar when a page instructs that it 1408 // should not be translated. 1409 TEST_F(TranslateManagerBrowserTest, NonTranslatablePage) { 1410 SimulateNavigation(GURL("http://mail.google.fr"), "fr", false); 1411 1412 // We should not have an infobar. 1413 EXPECT_TRUE(GetTranslateInfoBar() == NULL); 1414 1415 // The context menu is enabled to allow users to force translation. 1416 scoped_ptr<TestRenderViewContextMenu> menu( 1417 TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1418 menu->Init(); 1419 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); 1420 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); 1421 } 1422 1423 // Tests that the script is expired and refetched as expected. 1424 TEST_F(TranslateManagerBrowserTest, ScriptExpires) { 1425 ExpireTranslateScriptImmediately(); 1426 1427 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1428 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1429 ASSERT_TRUE(infobar != NULL); 1430 process()->sink().ClearMessages(); 1431 infobar->Translate(); 1432 SimulateTranslateScriptURLFetch(true); 1433 SimulateOnPageTranslated("fr", "en"); 1434 1435 // A task should have been posted to clear the script, run it. 1436 base::MessageLoop::current()->RunUntilIdle(); 1437 1438 // Do another navigation and translation. 1439 SimulateNavigation(GURL("http://www.google.es"), "es", true); 1440 infobar = GetTranslateInfoBar(); 1441 ASSERT_TRUE(infobar != NULL); 1442 process()->sink().ClearMessages(); 1443 infobar->Translate(); 1444 // If we don't simulate the URL fetch, the TranslateManager should be waiting 1445 // for the script and no message should have been sent to the renderer. 1446 EXPECT_TRUE( 1447 process()->sink().GetFirstMessageMatching( 1448 ChromeViewMsg_TranslatePage::ID) == NULL); 1449 // Now simulate the URL fetch. 1450 SimulateTranslateScriptURLFetch(true); 1451 // Now the message should have been sent. 1452 int page_id = 0; 1453 std::string original_lang, target_lang; 1454 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); 1455 EXPECT_EQ("es", original_lang); 1456 EXPECT_EQ("en", target_lang); 1457 } 1458 1459 TEST_F(TranslateManagerBrowserTest, DownloadsAndHistoryNotTranslated) { 1460 ASSERT_FALSE(TranslateManager::IsTranslatableURL( 1461 GURL(chrome::kChromeUIDownloadsURL))); 1462 ASSERT_FALSE(TranslateManager::IsTranslatableURL( 1463 GURL(chrome::kChromeUIHistoryURL))); 1464 } 1465 1466 #if !defined(OS_ANDROID) && !defined(OS_IOS) 1467 1468 TEST_F(TranslateManagerBrowserTest, BubbleNormalTranslate) { 1469 // Prepare for the bubble 1470 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1471 command_line->AppendSwitch(switches::kEnableTranslateNewUX); 1472 MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; 1473 scoped_ptr<TranslateBubbleFactory> factory_ptr(factory); 1474 TranslateBubbleFactory::SetFactory(factory); 1475 1476 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1477 1478 // Check the bubble exists instead of the infobar. 1479 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1480 ASSERT_TRUE(infobar == NULL); 1481 TranslateBubbleModel* bubble = factory->model(); 1482 ASSERT_TRUE(bubble != NULL); 1483 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, 1484 bubble->GetViewState()); 1485 1486 // Simulate clicking translate. 1487 process()->sink().ClearMessages(); 1488 bubble->Translate(); 1489 1490 // Check the bubble shows "Translating...". 1491 bubble = factory->model(); 1492 ASSERT_TRUE(bubble != NULL); 1493 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_TRANSLATING, 1494 bubble->GetViewState()); 1495 1496 // Simulate the translate script being retrieved (it only needs to be done 1497 // once in the test as it is cached). 1498 SimulateTranslateScriptURLFetch(true); 1499 1500 // Simulate the render notifying the translation has been done. 1501 SimulateOnPageTranslated("fr", "en"); 1502 1503 // Check the bubble shows "Translated." 1504 bubble = factory->model(); 1505 ASSERT_TRUE(bubble != NULL); 1506 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_AFTER_TRANSLATE, 1507 bubble->GetViewState()); 1508 } 1509 1510 TEST_F(TranslateManagerBrowserTest, BubbleTranslateScriptNotAvailable) { 1511 // Prepare for the bubble 1512 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1513 command_line->AppendSwitch(switches::kEnableTranslateNewUX); 1514 MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; 1515 scoped_ptr<TranslateBubbleFactory> factory_ptr(factory); 1516 TranslateBubbleFactory::SetFactory(factory); 1517 1518 SimulateNavigation(GURL("http://www.google.fr"), "fr", true); 1519 1520 // Check the bubble exists instead of the infobar. 1521 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1522 ASSERT_TRUE(infobar == NULL); 1523 TranslateBubbleModel* bubble = factory->model(); 1524 ASSERT_TRUE(bubble != NULL); 1525 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE, 1526 bubble->GetViewState()); 1527 1528 // Simulate clicking translate. 1529 process()->sink().ClearMessages(); 1530 bubble->Translate(); 1531 SimulateTranslateScriptURLFetch(false); 1532 1533 // We should not have sent any message to translate to the renderer. 1534 EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL)); 1535 1536 // And we should have an error infobar showing. 1537 bubble = factory->model(); 1538 ASSERT_TRUE(bubble != NULL); 1539 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_ERROR, 1540 bubble->GetViewState()); 1541 } 1542 1543 TEST_F(TranslateManagerBrowserTest, BubbleUnknownLanguage) { 1544 // Prepare for the bubble 1545 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1546 command_line->AppendSwitch(switches::kEnableTranslateNewUX); 1547 MockTranslateBubbleFactory* factory = new MockTranslateBubbleFactory; 1548 scoped_ptr<TranslateBubbleFactory> factory_ptr(factory); 1549 TranslateBubbleFactory::SetFactory(factory); 1550 1551 // Simulate navigating to a page ("und" is the string returned by the CLD for 1552 // languages it does not recognize). 1553 SimulateNavigation(GURL("http://www.google.mys"), "und", true); 1554 1555 // We should not have a bubble as we don't know the language. 1556 ASSERT_TRUE(factory->model() == NULL); 1557 1558 // Translate the page anyway throught the context menu. 1559 scoped_ptr<TestRenderViewContextMenu> menu( 1560 TestRenderViewContextMenu::CreateContextMenu(web_contents())); 1561 menu->Init(); 1562 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE, 0); 1563 1564 // Check the bubble exists instead of the infobar. 1565 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); 1566 ASSERT_TRUE(infobar == NULL); 1567 TranslateBubbleModel* bubble = factory->model(); 1568 ASSERT_TRUE(bubble != NULL); 1569 EXPECT_EQ(TranslateBubbleModel::VIEW_STATE_TRANSLATING, 1570 bubble->GetViewState()); 1571 } 1572 1573 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) 1574 1575 // Test is flaky on Win http://crbug.com/166334 1576 #if defined(OS_WIN) 1577 #define MAYBE_PRE_TranslateSessionRestore DISABLED_PRE_TranslateSessionRestore 1578 #else 1579 #define MAYBE_PRE_TranslateSessionRestore PRE_TranslateSessionRestore 1580 #endif 1581 // Test that session restore restores the translate infobar and other translate 1582 // settings. 1583 IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, 1584 MAYBE_PRE_TranslateSessionRestore) { 1585 SessionStartupPref pref(SessionStartupPref::LAST); 1586 SessionStartupPref::SetStartupPref(browser()->profile(), pref); 1587 1588 content::WebContents* current_web_contents = 1589 browser()->tab_strip_model()->GetActiveWebContents(); 1590 TranslateTabHelper* translate_tab_helper = 1591 TranslateTabHelper::FromWebContents(current_web_contents); 1592 content::Source<content::WebContents> source(current_web_contents); 1593 1594 ui_test_utils::WindowedNotificationObserverWithDetails< 1595 LanguageDetectionDetails> 1596 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 1597 source); 1598 1599 GURL french_url = ui_test_utils::GetTestUrl( 1600 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("french_page.html"))); 1601 ui_test_utils::NavigateToURL(browser(), french_url); 1602 fr_language_detected_signal.Wait(); 1603 LanguageDetectionDetails details; 1604 EXPECT_TRUE(fr_language_detected_signal.GetDetailsFor( 1605 source.map_key(), &details)); 1606 EXPECT_EQ("fr", details.adopted_language); 1607 EXPECT_EQ("fr", translate_tab_helper->language_state().original_language()); 1608 } 1609 1610 #if defined (OS_WIN) 1611 #define MAYBE_TranslateSessionRestore DISABLED_TranslateSessionRestore 1612 #else 1613 #define MAYBE_TranslateSessionRestore TranslateSessionRestore 1614 #endif 1615 IN_PROC_BROWSER_TEST_F(InProcessBrowserTest, MAYBE_TranslateSessionRestore) { 1616 content::WebContents* current_web_contents = 1617 browser()->tab_strip_model()->GetActiveWebContents(); 1618 content::Source<content::WebContents> source(current_web_contents); 1619 1620 ui_test_utils::WindowedNotificationObserverWithDetails< 1621 LanguageDetectionDetails> 1622 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 1623 source); 1624 fr_language_detected_signal.Wait(); 1625 } 1626