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.
10 #include "base/json/json_writer.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/prefs/pref_change_registrar.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/stringprintf.h"
15 #include "base/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "chrome/app/chrome_command_ids.h"
18 #include "chrome/browser/extensions/test_extension_system.h"
19 #include "chrome/browser/infobars/infobar.h"
20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/prefs/session_startup_pref.h"
22 #include "chrome/browser/tab_contents/render_view_context_menu.h"
23 #include "chrome/browser/translate/translate_infobar_delegate.h"
24 #include "chrome/browser/translate/translate_manager.h"
25 #include "chrome/browser/translate/translate_prefs.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/common/chrome_notification_types.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/render_messages.h"
32 #include "chrome/common/url_constants.h"
33 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
34 #include "chrome/test/base/in_process_browser_test.h"
35 #include "chrome/test/base/testing_browser_process.h"
36 #include "chrome/test/base/testing_profile.h"
37 #include "chrome/test/base/ui_test_utils.h"
38 #include "content/public/browser/navigation_details.h"
39 #include "content/public/browser/navigation_entry.h"
40 #include "content/public/browser/notification_details.h"
41 #include "content/public/browser/notification_registrar.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/test/mock_notification_observer.h"
44 #include "content/public/test/mock_render_process_host.h"
45 #include "content/public/test/render_view_test.h"
46 #include "content/public/test/test_browser_thread.h"
47 #include "content/public/test/test_renderer_host.h"
48 #include "grit/generated_resources.h"
49 #include "ipc/ipc_test_sink.h"
50 #include "net/url_request/test_url_fetcher_factory.h"
51 #include "testing/gmock/include/gmock/gmock.h"
52 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
53 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
54 #include "third_party/cld/languages/public/languages.h"
56 using content::BrowserThread
;
57 using content::NavigationController
;
58 using content::RenderViewHostTester
;
59 using content::WebContents
;
61 using testing::Pointee
;
62 using testing::Property
;
63 using WebKit::WebContextMenuData
;
65 // An observer that keeps track of whether a navigation entry was committed.
66 class NavEntryCommittedObserver
: public content::NotificationObserver
{
68 explicit NavEntryCommittedObserver(WebContents
* web_contents
) {
69 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
70 content::Source
<NavigationController
>(
71 &web_contents
->GetController()));
74 virtual void Observe(int type
,
75 const content::NotificationSource
& source
,
76 const content::NotificationDetails
& details
) OVERRIDE
{
77 DCHECK(type
== content::NOTIFICATION_NAV_ENTRY_COMMITTED
);
79 *(content::Details
<content::LoadCommittedDetails
>(details
).ptr());
82 const content::LoadCommittedDetails
&
83 get_load_commited_details() const {
88 content::LoadCommittedDetails details_
;
89 content::NotificationRegistrar registrar_
;
91 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver
);
94 class TranslateManagerBrowserTest
: public ChromeRenderViewHostTestHarness
,
95 public content::NotificationObserver
{
97 TranslateManagerBrowserTest()
99 base::Bind(&TranslateManagerBrowserTest::OnPreferenceChanged
,
100 base::Unretained(this))),
101 ui_thread_(BrowserThread::UI
, &message_loop_
) {
104 // Simulates navigating to a page and getting the page contents and language
105 // for that navigation.
106 void SimulateNavigation(const GURL
& url
,
107 const std::string
& lang
,
108 bool page_translatable
) {
109 NavigateAndCommit(url
);
110 SimulateOnTranslateLanguageDetermined(lang
, page_translatable
);
113 void SimulateOnTranslateLanguageDetermined(const std::string
& lang
,
114 bool page_translatable
) {
115 RenderViewHostTester::TestOnMessageReceived(
117 ChromeViewHostMsg_TranslateLanguageDetermined(
118 0, lang
, page_translatable
));
121 bool GetTranslateMessage(int* page_id
,
122 std::string
* original_lang
,
123 std::string
* target_lang
) {
124 const IPC::Message
* message
=
125 process()->sink().GetFirstMessageMatching(
126 ChromeViewMsg_TranslatePage::ID
);
129 Tuple4
<int, std::string
, std::string
, std::string
> translate_param
;
130 ChromeViewMsg_TranslatePage::Read(message
, &translate_param
);
132 *page_id
= translate_param
.a
;
133 // Ignore translate_param.b which is the script injected in the page.
135 *original_lang
= translate_param
.c
;
137 *target_lang
= translate_param
.d
;
141 InfoBarService
* infobar_service() {
142 return InfoBarService::FromWebContents(web_contents());
145 // Returns the translate infobar if there is 1 infobar and it is a translate
147 TranslateInfoBarDelegate
* GetTranslateInfoBar() {
148 return (infobar_service()->GetInfoBarCount() == 1) ?
149 infobar_service()->GetInfoBarDelegateAt(0)->
150 AsTranslateInfoBarDelegate() : NULL
;
153 // If there is 1 infobar and it is a translate infobar, closes it and returns
154 // true. Returns false otherwise.
155 bool CloseTranslateInfoBar() {
156 InfoBarDelegate
* infobar
= GetTranslateInfoBar();
159 infobar
->InfoBarDismissed(); // Simulates closing the infobar.
160 infobar_service()->RemoveInfoBar(infobar
);
164 // Checks whether |infobar| has been removed and clears the removed infobar
166 bool CheckInfoBarRemovedAndReset(InfoBarDelegate
* delegate
) {
167 bool found
= removed_infobars_
.count(delegate
) != 0;
168 removed_infobars_
.clear();
172 // Returns true if at least one infobar was closed.
173 bool InfoBarRemoved() {
174 return !removed_infobars_
.empty();
177 // Clears the list of stored removed infobars.
178 void ClearRemovedInfoBars() {
179 removed_infobars_
.clear();
182 void ExpireTranslateScriptImmediately() {
183 TranslateManager::GetInstance()->set_translate_script_expiration_delay(0);
186 // If there is 1 infobar and it is a translate infobar, deny translation and
187 // returns true. Returns false otherwise.
188 bool DenyTranslation() {
189 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
192 infobar
->TranslationDeclined();
193 infobar_service()->RemoveInfoBar(infobar
);
197 void ReloadAndWait(bool successful_reload
) {
198 NavEntryCommittedObserver
nav_observer(web_contents());
199 if (successful_reload
)
204 // Ensures it is really handled a reload.
205 const content::LoadCommittedDetails
& nav_details
=
206 nav_observer
.get_load_commited_details();
207 EXPECT_TRUE(nav_details
.entry
!= NULL
); // There was a navigation.
208 EXPECT_EQ(content::NAVIGATION_TYPE_EXISTING_PAGE
, nav_details
.type
);
210 // The TranslateManager class processes the navigation entry committed
211 // notification in a posted task; process that task.
212 MessageLoop::current()->RunUntilIdle();
215 virtual void Observe(int type
,
216 const content::NotificationSource
& source
,
217 const content::NotificationDetails
& details
) {
218 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
, type
);
219 removed_infobars_
.insert(
220 content::Details
<InfoBarRemovedDetails
>(details
)->first
);
223 MOCK_METHOD1(OnPreferenceChanged
, void(const std::string
&));
226 virtual void SetUp() {
227 WebKit::initialize(webkit_platform_support_
.Get());
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 set_translate_script_expiration_delay(60 * 60 * 1000);
240 ChromeRenderViewHostTestHarness::SetUp();
241 InfoBarService::CreateForWebContents(web_contents());
242 TranslateTabHelper::CreateForWebContents(web_contents());
244 notification_registrar_
.Add(this,
245 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
,
246 content::Source
<InfoBarService
>(infobar_service()));
249 virtual void TearDown() {
250 process()->sink().ClearMessages();
252 notification_registrar_
.Remove(this,
253 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
,
254 content::Source
<InfoBarService
>(infobar_service()));
256 ChromeRenderViewHostTestHarness::TearDown();
260 void SimulateTranslateScriptURLFetch(bool success
) {
261 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
262 ASSERT_TRUE(fetcher
);
263 net::URLRequestStatus status
;
264 status
.set_status(success
? net::URLRequestStatus::SUCCESS
:
265 net::URLRequestStatus::FAILED
);
266 fetcher
->set_url(fetcher
->GetOriginalURL());
267 fetcher
->set_status(status
);
268 fetcher
->set_response_code(success
? 200 : 500);
269 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
272 void SimulateSupportedLanguagesURLFetch(
273 bool success
, const std::vector
<std::string
>& languages
) {
274 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(1);
275 ASSERT_TRUE(fetcher
);
276 net::URLRequestStatus status
;
277 status
.set_status(success
? net::URLRequestStatus::SUCCESS
:
278 net::URLRequestStatus::FAILED
);
282 data
= base::StringPrintf("%s{\"sl\": {\"bla\": \"bla\"}, \"%s\": {",
283 TranslateManager::kLanguageListCallbackName
,
284 TranslateManager::kTargetLanguagesKey
);
285 const char* comma
= "";
286 for (size_t i
= 0; i
< languages
.size(); ++i
) {
287 data
+= base::StringPrintf(
288 "%s\"%s\": \"UnusedFullName\"", comma
, languages
[i
].c_str());
294 fetcher
->set_url(fetcher
->GetOriginalURL());
295 fetcher
->set_status(status
);
296 fetcher
->set_response_code(success
? 200 : 500);
297 fetcher
->SetResponseString(data
);
298 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
301 void SetPrefObserverExpectation(const char* path
) {
302 EXPECT_CALL(*this, OnPreferenceChanged(std::string(path
)));
305 PrefChangeRegistrar::NamedChangeCallback pref_callback_
;
308 content::NotificationRegistrar notification_registrar_
;
309 net::TestURLFetcherFactory url_fetcher_factory_
;
310 content::TestBrowserThread ui_thread_
;
311 content::RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox
312 webkit_platform_support_
;
314 // The infobars that have been removed.
315 // WARNING: the pointers point to deleted objects, use only for comparison.
316 std::set
<InfoBarDelegate
*> removed_infobars_
;
318 DISALLOW_COPY_AND_ASSIGN(TranslateManagerBrowserTest
);
323 class TestRenderViewContextMenu
: public RenderViewContextMenu
{
325 static TestRenderViewContextMenu
* CreateContextMenu(
326 WebContents
* web_contents
) {
327 content::ContextMenuParams params
;
328 params
.media_type
= WebKit::WebContextMenuData::MediaTypeNone
;
331 params
.is_image_blocked
= false;
332 params
.media_flags
= 0;
333 params
.spellcheck_enabled
= false;
334 params
.is_editable
= false;
335 params
.page_url
= web_contents
->GetController().GetActiveEntry()->GetURL();
336 #if defined(OS_MACOSX)
337 params
.writing_direction_default
= 0;
338 params
.writing_direction_left_to_right
= 0;
339 params
.writing_direction_right_to_left
= 0;
341 params
.edit_flags
= WebContextMenuData::CanTranslate
;
342 return new TestRenderViewContextMenu(web_contents
, params
);
345 bool IsItemPresent(int id
) {
346 return menu_model_
.GetIndexOfCommandId(id
) != -1;
349 virtual void PlatformInit() OVERRIDE
{ }
350 virtual void PlatformCancel() OVERRIDE
{ }
351 virtual bool GetAcceleratorForCommandId(
353 ui::Accelerator
* accelerator
) OVERRIDE
{ return false; }
356 TestRenderViewContextMenu(WebContents
* web_contents
,
357 const content::ContextMenuParams
& params
)
358 : RenderViewContextMenu(web_contents
, params
) {
361 DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu
);
366 TEST_F(TranslateManagerBrowserTest
, NormalTranslate
) {
367 // Simulate navigating to a page.
368 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
370 // We should have an infobar.
371 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
372 ASSERT_TRUE(infobar
!= NULL
);
373 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE
,
374 infobar
->infobar_type());
376 // Simulate clicking translate.
377 process()->sink().ClearMessages();
378 infobar
->Translate();
380 // The "Translating..." infobar should be showing.
381 infobar
= GetTranslateInfoBar();
382 ASSERT_TRUE(infobar
!= NULL
);
383 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING
, infobar
->infobar_type());
385 // Simulate the translate script being retrieved (it only needs to be done
386 // once in the test as it is cached).
387 SimulateTranslateScriptURLFetch(true);
389 // Test that we sent the right message to the renderer.
391 std::string original_lang
, target_lang
;
392 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
393 EXPECT_EQ("fr", original_lang
);
394 EXPECT_EQ("en", target_lang
);
396 // Simulate the render notifying the translation has been done.
397 RenderViewHostTester::TestOnMessageReceived(
399 ChromeViewHostMsg_PageTranslated(
400 0, 0, "fr", "en", TranslateErrors::NONE
));
402 // The after translate infobar should be showing.
403 infobar
= GetTranslateInfoBar();
404 ASSERT_TRUE(infobar
!= NULL
);
405 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE
, infobar
->infobar_type());
407 // Simulate changing the original language and translating.
408 process()->sink().ClearMessages();
409 std::string new_original_lang
= infobar
->language_code_at(0);
410 infobar
->set_original_language_index(0);
411 infobar
->Translate();
412 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
413 EXPECT_EQ(new_original_lang
, original_lang
);
414 EXPECT_EQ("en", target_lang
);
415 // Simulate the render notifying the translation has been done.
416 RenderViewHostTester::TestOnMessageReceived(
418 ChromeViewHostMsg_PageTranslated(
419 0, 0, new_original_lang
, "en", TranslateErrors::NONE
));
420 // infobar is now invalid.
421 TranslateInfoBarDelegate
* new_infobar
= GetTranslateInfoBar();
422 ASSERT_TRUE(new_infobar
!= NULL
);
423 infobar
= new_infobar
;
425 // Simulate changing the target language and translating.
426 process()->sink().ClearMessages();
427 std::string new_target_lang
= infobar
->language_code_at(1);
428 infobar
->set_target_language_index(1);
429 infobar
->Translate();
430 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
431 EXPECT_EQ(new_original_lang
, original_lang
);
432 EXPECT_EQ(new_target_lang
, target_lang
);
433 // Simulate the render notifying the translation has been done.
434 RenderViewHostTester::TestOnMessageReceived(
436 ChromeViewHostMsg_PageTranslated(
437 0, 0, new_original_lang
, new_target_lang
, TranslateErrors::NONE
));
438 // infobar is now invalid.
439 new_infobar
= GetTranslateInfoBar();
440 ASSERT_TRUE(new_infobar
!= NULL
);
442 // Verify reload keeps the same settings.
444 new_infobar
= GetTranslateInfoBar();
445 ASSERT_TRUE(new_infobar
!= NULL
);
446 ASSERT_EQ(new_target_lang
, infobar
->target_language_code());
449 TEST_F(TranslateManagerBrowserTest
, TranslateScriptNotAvailable
) {
450 // Simulate navigating to a page.
451 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
453 // We should have an infobar.
454 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
455 ASSERT_TRUE(infobar
!= NULL
);
456 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE
,
457 infobar
->infobar_type());
459 // Simulate clicking translate.
460 process()->sink().ClearMessages();
461 infobar
->Translate();
462 // Simulate a failure retrieving the translate script.
463 SimulateTranslateScriptURLFetch(false);
465 // We should not have sent any message to translate to the renderer.
466 EXPECT_FALSE(GetTranslateMessage(NULL
, NULL
, NULL
));
468 // And we should have an error infobar showing.
469 infobar
= GetTranslateInfoBar();
470 ASSERT_TRUE(infobar
!= NULL
);
471 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR
,
472 infobar
->infobar_type());
475 // Ensures we deal correctly with pages for which the browser does not recognize
476 // the language (the translate server may or not detect the language).
477 TEST_F(TranslateManagerBrowserTest
, TranslateUnknownLanguage
) {
478 // Simulate navigating to a page ("und" is the string returned by the CLD for
479 // languages it does not recognize).
480 SimulateNavigation(GURL("http://www.google.mys"), "und", true);
482 // We should not have an infobar as we don't know the language.
483 ASSERT_TRUE(GetTranslateInfoBar() == NULL
);
485 // Translate the page anyway throught the context menu.
486 scoped_ptr
<TestRenderViewContextMenu
> menu(
487 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
489 menu
->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE
, 0);
491 // To test that bug #49018 if fixed, make sure we deal correctly with errors.
492 // Simulate a failure to fetch the translate script.
493 SimulateTranslateScriptURLFetch(false);
494 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
495 ASSERT_TRUE(infobar
!= NULL
);
496 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR
,
497 infobar
->infobar_type());
498 EXPECT_TRUE(infobar
->IsError());
499 infobar
->MessageInfoBarButtonPressed();
500 SimulateTranslateScriptURLFetch(true); // This time succeed.
502 // Simulate the render notifying the translation has been done, the server
503 // having detected the page was in a known and supported language.
504 RenderViewHostTester::TestOnMessageReceived(
506 ChromeViewHostMsg_PageTranslated(
507 0, 0, "fr", "en", TranslateErrors::NONE
));
509 // The after translate infobar should be showing.
510 infobar
= GetTranslateInfoBar();
511 ASSERT_TRUE(infobar
!= NULL
);
512 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE
, infobar
->infobar_type());
513 EXPECT_EQ("fr", infobar
->original_language_code());
514 EXPECT_EQ("en", infobar
->target_language_code());
516 // Let's run the same steps but this time the server detects the page is
517 // already in English.
518 SimulateNavigation(GURL("http://www.google.com"), "und", true);
519 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
521 menu
->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE
, 0);
522 RenderViewHostTester::TestOnMessageReceived(
524 ChromeViewHostMsg_PageTranslated(
525 1, 0, "en", "en", TranslateErrors::IDENTICAL_LANGUAGES
));
526 infobar
= GetTranslateInfoBar();
527 ASSERT_TRUE(infobar
!= NULL
);
528 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR
,
529 infobar
->infobar_type());
530 EXPECT_EQ(TranslateErrors::IDENTICAL_LANGUAGES
, infobar
->error_type());
532 // Let's run the same steps again but this time the server fails to detect the
533 // page's language (it returns an empty string).
534 SimulateNavigation(GURL("http://www.google.com"), "und", true);
535 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
537 menu
->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE
, 0);
538 RenderViewHostTester::TestOnMessageReceived(
540 ChromeViewHostMsg_PageTranslated(
541 2, 0, std::string(), "en", TranslateErrors::UNKNOWN_LANGUAGE
));
542 infobar
= GetTranslateInfoBar();
543 ASSERT_TRUE(infobar
!= NULL
);
544 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR
,
545 infobar
->infobar_type());
546 EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE
, infobar
->error_type());
549 // Tests that we show/don't show an info-bar for all languages the CLD can
551 TEST_F(TranslateManagerBrowserTest
, TestAllLanguages
) {
552 // The index in kExpectation are the Language enum (see languages.pb.h).
553 // true if we expect a translate infobar for that language.
554 // Note the supported languages are in translation_manager.cc, see
555 // kSupportedLanguages.
556 bool kExpectations
[] = {
558 false, true, true, true, true, true, false, true, true, true,
560 false, true, true, true, true, true, true, true, true, true,
562 true, true, true, true, true, false, false, true, true, true,
564 true, true, false, true, true, true, true, false, true, false,
566 true, false, true, false, false, true, false, true, false, false,
568 false, false, false, true, true, true, true, false, false, false,
570 false, false, true, true, false, true, true, false, true, true,
572 false, false, false, false, false, false, false, true, false, false,
574 false, true, true, false, false, false, false, false, false, false,
576 false, true, false, false, false, false, false, false, false, false,
578 false, true, false, false, false, false, false, false, false, false,
580 false, false, false, false, false, false, false, false, false, false,
582 false, false, false, false, false, false, false, false, false, false,
584 false, false, false, false, false, false, false, false, false, true,
586 false, false, false, false, false, false, false, false, false, false,
588 false, false, false, false, false, false, false, false, false, false,
593 GURL
url("http://www.google.com");
594 for (size_t i
= 0; i
< arraysize(kExpectations
); ++i
) {
595 ASSERT_LT(i
, static_cast<size_t>(NUM_LANGUAGES
));
597 std::string lang
= LanguageCodeWithDialects(static_cast<Language
>(i
));
598 SCOPED_TRACE(::testing::Message() << "Iteration " << i
<<
599 " language=" << lang
);
601 // We should not have a translate infobar.
602 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
603 ASSERT_TRUE(infobar
== NULL
);
605 // Simulate navigating to a page.
606 NavigateAndCommit(url
);
607 SimulateOnTranslateLanguageDetermined(lang
, true);
609 // Verify we have/don't have an info-bar as expected.
610 infobar
= GetTranslateInfoBar();
611 EXPECT_EQ(kExpectations
[i
], infobar
!= NULL
);
613 // Close the info-bar if applicable.
615 EXPECT_TRUE(CloseTranslateInfoBar());
619 // Test the fetching of languages from the translate server
620 TEST_F(TranslateManagerBrowserTest
, FetchLanguagesFromTranslateServer
) {
621 std::vector
<std::string
> server_languages
;
622 // A list of languages to fake being returned by the translate server.
623 server_languages
.push_back("aa");
624 server_languages
.push_back("bb");
625 server_languages
.push_back("ab");
626 server_languages
.push_back("en-CA");
627 server_languages
.push_back("zz");
628 server_languages
.push_back("yy");
629 server_languages
.push_back("fr-FR");
631 // First, get the default languages list:
632 std::vector
<std::string
> default_supported_languages
;
633 TranslateManager::GetSupportedLanguages(&default_supported_languages
);
634 // To make sure we got the defaults and don't confuse them with the mocks.
635 ASSERT_NE(default_supported_languages
.size(), server_languages
.size());
638 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
639 PrefService
* prefs
= profile
->GetPrefs();
640 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs
);
642 // Check that we still get the defaults until the URLFetch has completed.
643 std::vector
<std::string
> current_supported_languages
;
644 TranslateManager::GetSupportedLanguages(¤t_supported_languages
);
645 EXPECT_EQ(default_supported_languages
, current_supported_languages
);
647 // Also check that it didn't change if we failed the URL fetch.
648 SimulateSupportedLanguagesURLFetch(false, std::vector
<std::string
>());
649 current_supported_languages
.clear();
650 TranslateManager::GetSupportedLanguages(¤t_supported_languages
);
651 EXPECT_EQ(default_supported_languages
, current_supported_languages
);
653 // Now check that we got the appropriate set of languages from the server.
654 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs
);
655 SimulateSupportedLanguagesURLFetch(true, server_languages
);
656 current_supported_languages
.clear();
657 TranslateManager::GetSupportedLanguages(¤t_supported_languages
);
658 // Not sure we need to guarantee the order of languages, so we find them.
659 EXPECT_EQ(server_languages
.size(), current_supported_languages
.size());
660 for (size_t i
= 0; i
< server_languages
.size(); ++i
) {
661 EXPECT_NE(current_supported_languages
.end(),
662 std::find(current_supported_languages
.begin(),
663 current_supported_languages
.end(),
664 server_languages
[i
]));
667 // Reset to original state.
668 TranslateManager::GetInstance()->FetchLanguageListFromTranslateServer(prefs
);
669 SimulateSupportedLanguagesURLFetch(true, default_supported_languages
);
672 std::string
GetLanguageListString(
673 const std::vector
<std::string
>& language_list
) {
674 // The translate manager is expecting a JSON string like:
675 // sl({'sl': {'XX': 'LanguageName', ...}, 'tl': {'XX': 'LanguageName', ...}})
676 // We only need to set the tl (target languages) dictionary.
677 scoped_ptr
<DictionaryValue
> target_languages_dict(new DictionaryValue
);
678 for (size_t i
= 0; i
< language_list
.size(); ++i
) {
679 // The value is ignored, we only use the key.
680 target_languages_dict
->Set(language_list
[i
], Value::CreateNullValue());
683 DictionaryValue language_list_dict
;
684 language_list_dict
.Set("tl", target_languages_dict
.release());
685 std::string language_list_json_str
;
686 base::JSONWriter::Write(&language_list_dict
, &language_list_json_str
);
687 std::string
language_list_str("sl(");
688 language_list_str
+= language_list_json_str
;
689 language_list_str
+= ")";
690 return language_list_str
;
693 // Tests auto-translate on page.
694 TEST_F(TranslateManagerBrowserTest
, AutoTranslateOnNavigate
) {
695 // Simulate navigating to a page and getting its language.
696 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
698 // Simulate the user translating.
699 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
700 ASSERT_TRUE(infobar
!= NULL
);
701 infobar
->Translate();
702 // Simulate the translate script being retrieved.
703 SimulateTranslateScriptURLFetch(true);
705 RenderViewHostTester::TestOnMessageReceived(
707 ChromeViewHostMsg_PageTranslated(
708 0, 0, "fr", "en", TranslateErrors::NONE
));
710 // Now navigate to a new page in the same language.
711 process()->sink().ClearMessages();
712 SimulateNavigation(GURL("http://news.google.fr"), "fr", true);
714 // This should have automatically triggered a translation.
716 std::string original_lang
, target_lang
;
717 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
718 EXPECT_EQ(1, page_id
);
719 EXPECT_EQ("fr", original_lang
);
720 EXPECT_EQ("en", target_lang
);
722 // Now navigate to a page in a different language.
723 process()->sink().ClearMessages();
724 SimulateNavigation(GURL("http://news.google.es"), "es", true);
726 // This should not have triggered a translate.
727 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
730 // Tests that multiple OnPageContents do not cause multiple infobars.
731 TEST_F(TranslateManagerBrowserTest
, MultipleOnPageContents
) {
732 // Simulate navigating to a page and getting its language.
733 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
735 // Simulate clicking 'Nope' (don't translate).
736 EXPECT_TRUE(DenyTranslation());
737 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
739 // Send a new PageContents, we should not show an infobar.
740 SimulateOnTranslateLanguageDetermined("fr", true);
741 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
743 // Do the same steps but simulate closing the infobar this time.
744 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true);
745 EXPECT_TRUE(CloseTranslateInfoBar());
746 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
747 SimulateOnTranslateLanguageDetermined("fr", true);
748 EXPECT_EQ(0U, infobar_service()->GetInfoBarCount());
751 // Test that reloading the page brings back the infobar if the
752 // reload succeeded and does not bring it back the reload fails.
753 TEST_F(TranslateManagerBrowserTest
, Reload
) {
754 // Simulate navigating to a page and getting its language.
755 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
757 // Close the infobar.
758 EXPECT_TRUE(CloseTranslateInfoBar());
760 // Reload should bring back the infobar if the page succeds
762 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
764 // Close the infobar.
765 EXPECT_TRUE(CloseTranslateInfoBar());
767 // And not show it if the reload fails
768 ReloadAndWait(false);
769 EXPECT_EQ(NULL
, GetTranslateInfoBar());
772 // Test that reloading the page by way of typing again the URL in the
773 // location bar brings back the infobar.
774 TEST_F(TranslateManagerBrowserTest
, ReloadFromLocationBar
) {
775 GURL
url("http://www.google.fr");
777 // Simulate navigating to a page and getting its language.
778 SimulateNavigation(url
, "fr", true);
780 // Close the infobar.
781 EXPECT_TRUE(CloseTranslateInfoBar());
783 // Create a pending navigation and simulate a page load. That should be the
784 // equivalent of typing the URL again in the location bar.
785 NavEntryCommittedObserver
nav_observer(web_contents());
786 web_contents()->GetController().LoadURL(url
, content::Referrer(),
787 content::PAGE_TRANSITION_TYPED
,
789 rvh_tester()->SendNavigate(0, url
);
791 // Test that we are really getting a same page navigation, the test would be
792 // useless if it was not the case.
793 const content::LoadCommittedDetails
& nav_details
=
794 nav_observer
.get_load_commited_details();
795 EXPECT_TRUE(nav_details
.entry
!= NULL
); // There was a navigation.
796 EXPECT_EQ(content::NAVIGATION_TYPE_SAME_PAGE
, nav_details
.type
);
798 // The TranslateManager class processes the navigation entry committed
799 // notification in a posted task; process that task.
800 MessageLoop::current()->RunUntilIdle();
801 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
804 // Tests that a closed translate infobar does not reappear when navigating
806 TEST_F(TranslateManagerBrowserTest
, CloseInfoBarInPageNavigation
) {
807 // Simulate navigating to a page and getting its language.
808 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
810 // Close the infobar.
811 EXPECT_TRUE(CloseTranslateInfoBar());
813 // Navigate in page, no infobar should be shown.
814 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr",
816 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
818 // Navigate out of page, a new infobar should show.
819 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
820 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
823 // Tests that a closed translate infobar does not reappear when navigating
824 // in a subframe. (http://crbug.com/48215)
825 TEST_F(TranslateManagerBrowserTest
, CloseInfoBarInSubframeNavigation
) {
826 // Simulate navigating to a page and getting its language.
827 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
829 // Close the infobar.
830 EXPECT_TRUE(CloseTranslateInfoBar());
832 // Simulate a sub-frame auto-navigating.
833 rvh_tester()->SendNavigateWithTransition(
834 1, GURL("http://pub.com"), content::PAGE_TRANSITION_AUTO_SUBFRAME
);
835 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
837 // Simulate the user navigating in a sub-frame.
838 rvh_tester()->SendNavigateWithTransition(
839 2, GURL("http://pub.com"), content::PAGE_TRANSITION_MANUAL_SUBFRAME
);
840 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
842 // Navigate out of page, a new infobar should show.
843 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
844 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
847 // Tests that denying translation is sticky when navigating in page.
848 TEST_F(TranslateManagerBrowserTest
, DenyTranslateInPageNavigation
) {
849 // Simulate navigating to a page and getting its language.
850 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
852 // Simulate clicking 'Nope' (don't translate).
853 EXPECT_TRUE(DenyTranslation());
855 // Navigate in page, no infobar should be shown.
856 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true);
857 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
859 // Navigate out of page, a new infobar should show.
860 SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true);
861 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
864 // Tests that after translating and closing the infobar, the infobar does not
865 // return when navigating in page.
866 TEST_F(TranslateManagerBrowserTest
, TranslateCloseInfoBarInPageNavigation
) {
867 // Simulate navigating to a page and getting its language.
868 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
870 // Simulate the user translating.
871 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
872 ASSERT_TRUE(infobar
!= NULL
);
873 infobar
->Translate();
874 // Simulate the translate script being retrieved.
875 SimulateTranslateScriptURLFetch(true);
876 RenderViewHostTester::TestOnMessageReceived(
878 ChromeViewHostMsg_PageTranslated(
879 0, 0, "fr", "en", TranslateErrors::NONE
));
881 // Close the infobar.
882 EXPECT_TRUE(CloseTranslateInfoBar());
884 // Navigate in page, no infobar should be shown.
885 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true);
886 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
888 // Navigate out of page, a new infobar should show.
889 // Note that we navigate to a page in a different language so we don't trigger
890 // the auto-translate feature (it would translate the page automatically and
891 // the before translate inforbar would not be shown).
892 SimulateNavigation(GURL("http://www.google.de"), "de", true);
893 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
896 // Tests that the after translate the infobar still shows when navigating
898 TEST_F(TranslateManagerBrowserTest
, TranslateInPageNavigation
) {
899 // Simulate navigating to a page and getting its language.
900 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
902 // Simulate the user translating.
903 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
904 ASSERT_TRUE(infobar
!= NULL
);
905 infobar
->Translate();
906 // Simulate the translate script being retrieved.
907 SimulateTranslateScriptURLFetch(true);
908 RenderViewHostTester::TestOnMessageReceived(
910 ChromeViewHostMsg_PageTranslated(
911 0, 0, "fr", "en", TranslateErrors::NONE
));
912 // The after translate infobar is showing.
913 infobar
= GetTranslateInfoBar();
914 ASSERT_TRUE(infobar
!= NULL
);
916 // Navigate out of page, a new infobar should show.
917 // See note in TranslateCloseInfoBarInPageNavigation test on why it is
918 // important to navigate to a page in a different language for this test.
919 SimulateNavigation(GURL("http://www.google.de"), "de", true);
920 // The old infobar is gone.
921 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar
));
922 // And there is a new one.
923 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
926 // Tests that no translate infobar is shown when navigating to a page in an
927 // unsupported language.
928 TEST_F(TranslateManagerBrowserTest
, CLDReportsUnsupportedPageLanguage
) {
929 // Simulate navigating to a page and getting an unsupported language.
930 SimulateNavigation(GURL("http://www.google.com"), "qbz", true);
932 // No info-bar should be shown.
933 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
936 // Tests that we deal correctly with unsupported languages returned by the
938 // The translation server might return a language we don't support.
939 TEST_F(TranslateManagerBrowserTest
, ServerReportsUnsupportedLanguage
) {
940 // Simulate navigating to a page and translating it.
941 SimulateNavigation(GURL("http://mail.google.fr"), "fr", true);
942 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
943 ASSERT_TRUE(infobar
!= NULL
);
944 process()->sink().ClearMessages();
945 infobar
->Translate();
946 SimulateTranslateScriptURLFetch(true);
947 // Simulate the render notifying the translation has been done, but it
948 // reports a language we don't support.
949 RenderViewHostTester::TestOnMessageReceived(
951 ChromeViewHostMsg_PageTranslated(
952 0, 0, "qbz", "en", TranslateErrors::NONE
));
954 // An error infobar should be showing to report that we don't support this
956 infobar
= GetTranslateInfoBar();
957 ASSERT_TRUE(infobar
!= NULL
);
958 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR
,
959 infobar
->infobar_type());
961 // This infobar should have a button (so the string should not be empty).
962 ASSERT_FALSE(infobar
->GetMessageInfoBarButtonText().empty());
964 // Pressing the button on that infobar should revert to the original language.
965 process()->sink().ClearMessages();
966 infobar
->MessageInfoBarButtonPressed();
967 const IPC::Message
* message
=
968 process()->sink().GetFirstMessageMatching(
969 ChromeViewMsg_RevertTranslation::ID
);
970 EXPECT_TRUE(message
!= NULL
);
971 // And it should have removed the infobar.
972 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
975 // Tests that no translate infobar is shown and context menu is disabled, when
976 // Chrome is in a language that the translate server does not support.
977 TEST_F(TranslateManagerBrowserTest
, UnsupportedUILanguage
) {
978 std::string original_lang
= g_browser_process
->GetApplicationLocale();
979 g_browser_process
->SetApplicationLocale("qbz");
981 // Make sure that the accept language list only contains unsupported languages
983 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
984 PrefService
* prefs
= profile
->GetPrefs();
985 prefs
->SetString(prefs::kAcceptLanguages
, "qbz");
987 // Simulate navigating to a page in a language supported by the translate
989 SimulateNavigation(GURL("http://www.google.com"), "en", true);
991 // No info-bar should be shown.
992 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
994 // And the context menu option should be disabled too.
995 scoped_ptr
<TestRenderViewContextMenu
> menu(
996 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
998 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
999 EXPECT_FALSE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1001 g_browser_process
->SetApplicationLocale(original_lang
);
1004 // Tests that the first supported accept language is selected
1005 TEST_F(TranslateManagerBrowserTest
, TranslateAcceptLanguage
) {
1006 // Set locate to non-existant language
1007 std::string original_lang
= g_browser_process
->GetApplicationLocale();
1008 g_browser_process
->SetApplicationLocale("qbz");
1010 // Set Qbz and French as the only accepted languages
1012 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1013 PrefService
* prefs
= profile
->GetPrefs();
1014 prefs
->SetString(prefs::kAcceptLanguages
, "qbz,fr");
1016 // Go to a German page
1017 SimulateNavigation(GURL("http://google.de"), "de", true);
1019 // Expect the infobar to pop up
1020 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1022 // Set Qbz and English-US as the only accepted languages to test the country
1023 // code removal code which was causing a crash as filed in Issue 90106,
1024 // a crash caused by a language with a country code that wasn't recognized.
1025 prefs
->SetString(prefs::kAcceptLanguages
, "qbz,en-us");
1027 // Go to a German page
1028 SimulateNavigation(GURL("http://google.de"), "de", true);
1030 // Expect the infobar to pop up
1031 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1034 // Tests that the translate enabled preference is honored.
1035 TEST_F(TranslateManagerBrowserTest
, TranslateEnabledPref
) {
1036 // Make sure the pref allows translate.
1038 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1039 PrefService
* prefs
= profile
->GetPrefs();
1040 prefs
->SetBoolean(prefs::kEnableTranslate
, true);
1042 // Simulate navigating to a page and getting its language.
1043 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1045 // An infobar should be shown.
1046 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
1047 EXPECT_TRUE(infobar
!= NULL
);
1049 // Disable translate.
1050 prefs
->SetBoolean(prefs::kEnableTranslate
, false);
1052 // Navigate to a new page, that should close the previous infobar.
1053 GURL
url("http://www.youtube.fr");
1054 NavigateAndCommit(url
);
1055 infobar
= GetTranslateInfoBar();
1056 EXPECT_TRUE(infobar
== NULL
);
1058 // Simulate getting the page contents and language, that should not trigger
1059 // a translate infobar.
1060 SimulateOnTranslateLanguageDetermined("fr", true);
1061 infobar
= GetTranslateInfoBar();
1062 EXPECT_TRUE(infobar
== NULL
);
1065 // Tests the "Never translate <language>" pref.
1066 TEST_F(TranslateManagerBrowserTest
, NeverTranslateLanguagePref
) {
1067 // Simulate navigating to a page and getting its language.
1068 GURL
url("http://www.google.fr");
1069 SimulateNavigation(url
, "fr", true);
1071 // An infobar should be shown.
1072 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1074 // Select never translate this language.
1076 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1077 PrefService
* prefs
= profile
->GetPrefs();
1078 PrefChangeRegistrar registrar
;
1079 registrar
.Init(prefs
);
1080 registrar
.Add(TranslatePrefs::kPrefTranslateLanguageBlacklist
,
1082 TranslatePrefs
translate_prefs(prefs
);
1083 EXPECT_FALSE(translate_prefs
.IsLanguageBlacklisted("fr"));
1084 EXPECT_TRUE(translate_prefs
.CanTranslate(prefs
, "fr", url
));
1085 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist
);
1086 translate_prefs
.BlacklistLanguage("fr");
1087 EXPECT_TRUE(translate_prefs
.IsLanguageBlacklisted("fr"));
1088 EXPECT_FALSE(translate_prefs
.CanTranslate(prefs
, "fr", url
));
1090 // Close the infobar.
1091 EXPECT_TRUE(CloseTranslateInfoBar());
1093 // Navigate to a new page also in French.
1094 SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true);
1096 // There should not be a translate infobar.
1097 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
1099 // Remove the language from the blacklist.
1100 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist
);
1101 translate_prefs
.RemoveLanguageFromBlacklist("fr");
1102 EXPECT_FALSE(translate_prefs
.IsLanguageBlacklisted("fr"));
1103 EXPECT_TRUE(translate_prefs
.CanTranslate(prefs
, "fr", url
));
1105 // Navigate to a page in French.
1106 SimulateNavigation(url
, "fr", true);
1108 // There should be a translate infobar.
1109 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1112 // Tests the "Never translate this site" pref.
1113 TEST_F(TranslateManagerBrowserTest
, NeverTranslateSitePref
) {
1114 // Simulate navigating to a page and getting its language.
1115 GURL
url("http://www.google.fr");
1116 std::string
host(url
.host());
1117 SimulateNavigation(url
, "fr", true);
1119 // An infobar should be shown.
1120 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1122 // Select never translate this site.
1124 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1125 PrefService
* prefs
= profile
->GetPrefs();
1126 PrefChangeRegistrar registrar
;
1127 registrar
.Init(prefs
);
1128 registrar
.Add(TranslatePrefs::kPrefTranslateSiteBlacklist
, pref_callback_
);
1129 TranslatePrefs
translate_prefs(prefs
);
1130 EXPECT_FALSE(translate_prefs
.IsSiteBlacklisted(host
));
1131 EXPECT_TRUE(translate_prefs
.CanTranslate(prefs
, "fr", url
));
1132 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist
);
1133 translate_prefs
.BlacklistSite(host
);
1134 EXPECT_TRUE(translate_prefs
.IsSiteBlacklisted(host
));
1135 EXPECT_FALSE(translate_prefs
.CanTranslate(prefs
, "fr", url
));
1137 // Close the infobar.
1138 EXPECT_TRUE(CloseTranslateInfoBar());
1140 // Navigate to a new page also on the same site.
1141 SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true);
1143 // There should not be a translate infobar.
1144 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
1146 // Remove the site from the blacklist.
1147 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist
);
1148 translate_prefs
.RemoveSiteFromBlacklist(host
);
1149 EXPECT_FALSE(translate_prefs
.IsSiteBlacklisted(host
));
1150 EXPECT_TRUE(translate_prefs
.CanTranslate(prefs
, "fr", url
));
1152 // Navigate to a page in French.
1153 SimulateNavigation(url
, "fr", true);
1155 // There should be a translate infobar.
1156 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1159 // Tests the "Always translate this language" pref.
1160 TEST_F(TranslateManagerBrowserTest
, AlwaysTranslateLanguagePref
) {
1161 // Select always translate French to English.
1163 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1164 PrefService
* prefs
= profile
->GetPrefs();
1165 PrefChangeRegistrar registrar
;
1166 registrar
.Init(prefs
);
1167 registrar
.Add(TranslatePrefs::kPrefTranslateWhitelists
, pref_callback_
);
1168 TranslatePrefs
translate_prefs(prefs
);
1169 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists
);
1170 translate_prefs
.WhitelistLanguagePair("fr", "en");
1172 // Load a page in French.
1173 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1175 // It should have triggered an automatic translation to English.
1177 // The translating infobar should be showing.
1178 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
1179 ASSERT_TRUE(infobar
!= NULL
);
1180 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING
, infobar
->infobar_type());
1181 // Simulate the translate script being retrieved.
1182 SimulateTranslateScriptURLFetch(true);
1184 std::string original_lang
, target_lang
;
1185 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1186 EXPECT_EQ("fr", original_lang
);
1187 EXPECT_EQ("en", target_lang
);
1188 process()->sink().ClearMessages();
1190 // Try another language, it should not be autotranslated.
1191 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1192 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1193 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1194 EXPECT_TRUE(CloseTranslateInfoBar());
1196 // Let's switch to incognito mode, it should not be autotranslated in that
1198 TestingProfile
* test_profile
=
1199 static_cast<TestingProfile
*>(web_contents()->GetBrowserContext());
1200 test_profile
->set_incognito(true);
1201 SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true);
1202 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1203 EXPECT_TRUE(GetTranslateInfoBar() != NULL
);
1204 EXPECT_TRUE(CloseTranslateInfoBar());
1205 test_profile
->set_incognito(false); // Get back to non incognito.
1207 // Now revert the always translate pref and make sure we go back to expected
1208 // behavior, which is show a "before translate" infobar.
1209 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists
);
1210 translate_prefs
.RemoveLanguagePairFromWhitelist("fr", "en");
1211 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1212 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1213 infobar
= GetTranslateInfoBar();
1214 ASSERT_TRUE(infobar
!= NULL
);
1215 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE
,
1216 infobar
->infobar_type());
1220 TEST_F(TranslateManagerBrowserTest
, ContextMenu
) {
1221 // Blacklist www.google.fr and French for translation.
1222 GURL
url("http://www.google.fr");
1224 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1225 TranslatePrefs
translate_prefs(profile
->GetPrefs());
1226 translate_prefs
.BlacklistLanguage("fr");
1227 translate_prefs
.BlacklistSite(url
.host());
1228 EXPECT_TRUE(translate_prefs
.IsLanguageBlacklisted("fr"));
1229 EXPECT_TRUE(translate_prefs
.IsSiteBlacklisted(url
.host()));
1231 // Simulate navigating to a page in French. The translate menu should show but
1232 // should only be enabled when the page language has been received.
1233 NavigateAndCommit(url
);
1234 scoped_ptr
<TestRenderViewContextMenu
> menu(
1235 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1237 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
1238 EXPECT_FALSE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1240 // Simulate receiving the language.
1241 SimulateOnTranslateLanguageDetermined("fr", true);
1242 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1244 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
1245 EXPECT_TRUE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1247 // Use the menu to translate the page.
1248 menu
->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE
, 0);
1250 // That should have triggered a translation.
1251 // The "translating..." infobar should be showing.
1252 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
1253 ASSERT_TRUE(infobar
!= NULL
);
1254 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING
, infobar
->infobar_type());
1255 // Simulate the translate script being retrieved.
1256 SimulateTranslateScriptURLFetch(true);
1258 std::string original_lang
, target_lang
;
1259 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1260 EXPECT_EQ("fr", original_lang
);
1261 EXPECT_EQ("en", target_lang
);
1262 process()->sink().ClearMessages();
1264 // This should also have reverted the blacklisting of this site and language.
1265 EXPECT_FALSE(translate_prefs
.IsLanguageBlacklisted("fr"));
1266 EXPECT_FALSE(translate_prefs
.IsSiteBlacklisted(url
.host()));
1268 // Let's simulate the page being translated.
1269 RenderViewHostTester::TestOnMessageReceived(
1271 ChromeViewHostMsg_PageTranslated(
1272 0, 0, "fr", "en", TranslateErrors::NONE
));
1274 // The translate menu should now be disabled.
1275 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1277 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
1278 EXPECT_FALSE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1280 // Test that selecting translate in the context menu WHILE the page is being
1281 // translated does nothing (this could happen if autotranslate kicks-in and
1282 // the user selects the menu while the translation is being performed).
1283 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1284 infobar
= GetTranslateInfoBar();
1285 ASSERT_TRUE(infobar
!= NULL
);
1286 infobar
->Translate();
1287 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1288 process()->sink().ClearMessages();
1289 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1291 EXPECT_TRUE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1292 menu
->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE
, 0);
1293 // No message expected since the translation should have been ignored.
1294 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1296 // Now test that selecting translate in the context menu AFTER the page has
1297 // been translated does nothing.
1298 SimulateNavigation(GURL("http://www.google.de"), "de", true);
1299 infobar
= GetTranslateInfoBar();
1300 ASSERT_TRUE(infobar
!= NULL
);
1301 infobar
->Translate();
1302 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1303 process()->sink().ClearMessages();
1304 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1306 EXPECT_TRUE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1307 RenderViewHostTester::TestOnMessageReceived(
1309 ChromeViewHostMsg_PageTranslated(
1310 0, 0, "de", "en", TranslateErrors::NONE
));
1311 menu
->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE
, 0);
1312 // No message expected since the translation should have been ignored.
1313 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1315 // Test that the translate context menu is enabled when the page is in an
1316 // unknown language.
1317 SimulateNavigation(url
, "und", true);
1318 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1320 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
1321 EXPECT_TRUE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1323 // Test that the translate context menu is disabled when the page is in an
1324 // unsupported language.
1325 SimulateNavigation(url
, "qbz", true);
1326 menu
.reset(TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1328 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
1329 EXPECT_FALSE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1332 // Tests that an extra always/never translate button is shown on the "before
1333 // translate" infobar when the translation is accepted/declined 3 times,
1334 // only when not in incognito mode.
1335 TEST_F(TranslateManagerBrowserTest
, BeforeTranslateExtraButtons
) {
1337 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
1338 TranslatePrefs
translate_prefs(profile
->GetPrefs());
1339 translate_prefs
.ResetTranslationAcceptedCount("fr");
1340 translate_prefs
.ResetTranslationDeniedCount("fr");
1341 translate_prefs
.ResetTranslationAcceptedCount("de");
1342 translate_prefs
.ResetTranslationDeniedCount("de");
1344 // We'll do 4 times in incognito mode first to make sure the button is not
1345 // shown in that case, then 4 times in normal mode.
1346 TranslateInfoBarDelegate
* infobar
;
1347 TestingProfile
* test_profile
=
1348 static_cast<TestingProfile
*>(web_contents()->GetBrowserContext());
1349 static_cast<extensions::TestExtensionSystem
*>(
1350 extensions::ExtensionSystem::Get(test_profile
))->
1351 CreateExtensionProcessManager();
1352 test_profile
->set_incognito(true);
1353 for (int i
= 0; i
< 8; ++i
) {
1354 SCOPED_TRACE(::testing::Message() << "Iteration " << i
<<
1355 " incognito mode=" << test_profile
->IsOffTheRecord());
1356 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1357 infobar
= GetTranslateInfoBar();
1358 ASSERT_TRUE(infobar
!= NULL
);
1359 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE
,
1360 infobar
->infobar_type());
1362 EXPECT_FALSE(infobar
->ShouldShowAlwaysTranslateButton());
1363 infobar
->Translate();
1364 process()->sink().ClearMessages();
1366 EXPECT_TRUE(infobar
->ShouldShowAlwaysTranslateButton());
1369 test_profile
->set_incognito(false);
1371 // Simulate the user pressing "Always translate French".
1372 infobar
->AlwaysTranslatePageLanguage();
1373 EXPECT_TRUE(translate_prefs
.IsLanguagePairWhitelisted("fr", "en"));
1374 // Simulate the translate script being retrieved (it only needs to be done
1375 // once in the test as it is cached).
1376 SimulateTranslateScriptURLFetch(true);
1377 // That should have triggered a page translate.
1379 std::string original_lang
, target_lang
;
1380 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1381 process()->sink().ClearMessages();
1383 // Now test that declining the translation causes a "never translate" button
1384 // to be shown (in non incognito mode only).
1385 test_profile
->set_incognito(true);
1386 for (int i
= 0; i
< 8; ++i
) {
1387 SCOPED_TRACE(::testing::Message() << "Iteration " << i
<<
1388 " incognito mode=" << test_profile
->IsOffTheRecord());
1389 SimulateNavigation(GURL("http://www.google.de"), "de", true);
1390 infobar
= GetTranslateInfoBar();
1391 ASSERT_TRUE(infobar
!= NULL
);
1392 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE
,
1393 infobar
->infobar_type());
1395 EXPECT_FALSE(infobar
->ShouldShowNeverTranslateButton());
1396 infobar
->TranslationDeclined();
1398 EXPECT_TRUE(infobar
->ShouldShowNeverTranslateButton());
1401 test_profile
->set_incognito(false);
1403 // Simulate the user pressing "Never translate French".
1404 infobar
->NeverTranslatePageLanguage();
1405 EXPECT_TRUE(translate_prefs
.IsLanguageBlacklisted("de"));
1406 // No translation should have occured and the infobar should be gone.
1407 EXPECT_FALSE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1408 process()->sink().ClearMessages();
1409 ASSERT_TRUE(GetTranslateInfoBar() == NULL
);
1412 // Tests that we don't show a translate infobar when a page instructs that it
1413 // should not be translated.
1414 TEST_F(TranslateManagerBrowserTest
, NonTranslatablePage
) {
1415 // Simulate navigating to a page.
1416 SimulateNavigation(GURL("http://mail.google.fr"), "fr", false);
1418 // We should not have an infobar.
1419 EXPECT_TRUE(GetTranslateInfoBar() == NULL
);
1421 // The context menu should be disabled.
1422 scoped_ptr
<TestRenderViewContextMenu
> menu(
1423 TestRenderViewContextMenu::CreateContextMenu(web_contents()));
1425 EXPECT_TRUE(menu
->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE
));
1426 EXPECT_FALSE(menu
->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE
));
1429 // Tests that the script is expired and refetched as expected.
1430 TEST_F(TranslateManagerBrowserTest
, ScriptExpires
) {
1431 ExpireTranslateScriptImmediately();
1433 // Simulate navigating to a page and translating it.
1434 SimulateNavigation(GURL("http://www.google.fr"), "fr", true);
1435 TranslateInfoBarDelegate
* infobar
= GetTranslateInfoBar();
1436 ASSERT_TRUE(infobar
!= NULL
);
1437 process()->sink().ClearMessages();
1438 infobar
->Translate();
1439 SimulateTranslateScriptURLFetch(true);
1440 RenderViewHostTester::TestOnMessageReceived(
1442 ChromeViewHostMsg_PageTranslated(
1443 0, 0, "fr", "en", TranslateErrors::NONE
));
1445 // A task should have been posted to clear the script, run it.
1446 MessageLoop::current()->RunUntilIdle();
1448 // Do another navigation and translation.
1449 SimulateNavigation(GURL("http://www.google.es"), "es", true);
1450 infobar
= GetTranslateInfoBar();
1451 ASSERT_TRUE(infobar
!= NULL
);
1452 process()->sink().ClearMessages();
1453 infobar
->Translate();
1454 // If we don't simulate the URL fetch, the TranslateManager should be waiting
1455 // for the script and no message should have been sent to the renderer.
1457 process()->sink().GetFirstMessageMatching(
1458 ChromeViewMsg_TranslatePage::ID
) ==
1460 // Now simulate the URL fetch.
1461 SimulateTranslateScriptURLFetch(true);
1462 // Now the message should have been sent.
1464 std::string original_lang
, target_lang
;
1465 EXPECT_TRUE(GetTranslateMessage(&page_id
, &original_lang
, &target_lang
));
1466 EXPECT_EQ("es", original_lang
);
1467 EXPECT_EQ("en", target_lang
);
1470 TEST_F(TranslateManagerBrowserTest
, DownloadsAndHistoryNotTranslated
) {
1471 ASSERT_FALSE(TranslateManager::IsTranslatableURL(
1472 GURL(chrome::kChromeUIDownloadsURL
)));
1473 ASSERT_FALSE(TranslateManager::IsTranslatableURL(
1474 GURL(chrome::kChromeUIHistoryURL
)));
1477 // Test is flaky on Win http://crbug.com/166334
1479 #define MAYBE_PRE_TranslateSessionRestore DISABLED_PRE_TranslateSessionRestore
1481 #define MAYBE_PRE_TranslateSessionRestore PRE_TranslateSessionRestore
1483 // Test that session restore restores the translate infobar and other translate
1485 IN_PROC_BROWSER_TEST_F(InProcessBrowserTest
,
1486 MAYBE_PRE_TranslateSessionRestore
) {
1487 SessionStartupPref
pref(SessionStartupPref::LAST
);
1488 SessionStartupPref::SetStartupPref(browser()->profile(), pref
);
1490 WebContents
* current_web_contents
=
1491 browser()->tab_strip_model()->GetActiveWebContents();
1492 TranslateTabHelper
* translate_tab_helper
=
1493 TranslateTabHelper::FromWebContents(current_web_contents
);
1494 content::Source
<WebContents
> source(current_web_contents
);
1496 ui_test_utils::WindowedNotificationObserverWithDetails
<std::string
>
1497 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1500 GURL french_url
= ui_test_utils::GetTestUrl(
1501 base::FilePath(), base::FilePath(FILE_PATH_LITERAL("french_page.html")));
1502 ui_test_utils::NavigateToURL(browser(), french_url
);
1503 fr_language_detected_signal
.Wait();
1505 EXPECT_TRUE(fr_language_detected_signal
.GetDetailsFor(
1506 source
.map_key(), &lang
));
1507 EXPECT_EQ("fr", lang
);
1508 EXPECT_EQ("fr", translate_tab_helper
->language_state().original_language());
1511 #if defined (OS_WIN)
1512 #define MAYBE_TranslateSessionRestore DISABLED_TranslateSessionRestore
1514 #define MAYBE_TranslateSessionRestore TranslateSessionRestore
1516 IN_PROC_BROWSER_TEST_F(InProcessBrowserTest
, MAYBE_TranslateSessionRestore
) {
1517 WebContents
* current_web_contents
=
1518 browser()->tab_strip_model()->GetActiveWebContents();
1519 content::Source
<WebContents
> source(current_web_contents
);
1521 ui_test_utils::WindowedNotificationObserverWithDetails
<std::string
>
1522 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1524 fr_language_detected_signal
.Wait();