blob: 4bde4c23889cf3a663cc8e3a03333063c7b7e444 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "build/build_config.h"
#include "components/translate/content/browser/translate_waiter.h"
#include "components/translate/core/browser/language_state.h"
#include "components/translate/core/browser/translate_error_details.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/translate/core/common/translate_switches.h"
#include "content/public/browser/browser_context.h"
#include "net/base/mock_network_change_notifier.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "weblayer/browser/browser_context_impl.h"
#include "weblayer/browser/profile_impl.h"
#include "weblayer/browser/tab_impl.h"
#include "weblayer/browser/translate_client_impl.h"
#include "weblayer/public/tab.h"
#include "weblayer/shell/browser/shell.h"
#include "weblayer/test/weblayer_browser_test.h"
#include "weblayer/test/weblayer_browser_test_utils.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
#include "components/infobars/android/infobar_android.h" // nogncheck
#include "components/infobars/core/infobar_manager.h" // nogncheck
#include "components/translate/core/browser/translate_download_manager.h"
#include "weblayer/browser/infobar_service.h"
#include "weblayer/browser/translate_compact_infobar.h"
#include "weblayer/shell/android/browsertests_apk/translate_test_bridge.h"
#endif
namespace weblayer {
namespace {
static std::string kTestValidScript = R"(
var google = {};
google.translate = (function() {
return {
TranslateService: function() {
return {
isAvailable : function() {
return true;
},
restore : function() {
return;
},
getDetectedLanguage : function() {
return "fr";
},
translatePage : function(originalLang, targetLang,
onTranslateProgress) {
var error = (originalLang == 'auto') ? true : false;
onTranslateProgress(100, true, error);
}
};
}
};
})();
cr.googleTranslate.onTranslateElementLoad();)";
static std::string kTestScriptInitializationError = R"(
var google = {};
google.translate = (function() {
return {
TranslateService: function() {
return error;
}
};
})();
cr.googleTranslate.onTranslateElementLoad();)";
static std::string kTestScriptTimeout = R"(
var google = {};
google.translate = (function() {
return {
TranslateService: function() {
return {
isAvailable : function() {
return false;
},
};
}
};
})();
cr.googleTranslate.onTranslateElementLoad();)";
TranslateClientImpl* GetTranslateClient(Shell* shell) {
return TranslateClientImpl::FromWebContents(
static_cast<TabImpl*>(shell->tab())->web_contents());
}
std::unique_ptr<translate::TranslateWaiter> CreateTranslateWaiter(
Shell* shell,
translate::TranslateWaiter::WaitEvent wait_event) {
return std::make_unique<translate::TranslateWaiter>(
GetTranslateClient(shell)->translate_driver(), wait_event);
}
void WaitUntilLanguageDetermined(Shell* shell) {
CreateTranslateWaiter(
shell, translate::TranslateWaiter::WaitEvent::kLanguageDetermined)
->Wait();
}
void WaitUntilPageTranslated(Shell* shell) {
CreateTranslateWaiter(shell,
translate::TranslateWaiter::WaitEvent::kPageTranslated)
->Wait();
}
} // namespace
#if defined(OS_ANDROID)
class TestInfoBarManagerObserver : public infobars::InfoBarManager::Observer {
public:
TestInfoBarManagerObserver() = default;
~TestInfoBarManagerObserver() override = default;
void OnInfoBarAdded(infobars::InfoBar* infobar) override {
if (on_infobar_added_callback_)
std::move(on_infobar_added_callback_).Run();
}
void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override {
if (on_infobar_removed_callback_)
std::move(on_infobar_removed_callback_).Run();
}
void set_on_infobar_added_callback(base::OnceClosure callback) {
on_infobar_added_callback_ = std::move(callback);
}
void set_on_infobar_removed_callback(base::OnceClosure callback) {
on_infobar_removed_callback_ = std::move(callback);
}
private:
base::OnceClosure on_infobar_added_callback_;
base::OnceClosure on_infobar_removed_callback_;
};
#endif // if defined(OS_ANDROID)
class TranslateBrowserTest : public WebLayerBrowserTest {
public:
TranslateBrowserTest() {
error_subscription_ =
translate::TranslateManager::RegisterTranslateErrorCallback(
base::BindRepeating(&TranslateBrowserTest::OnTranslateError,
base::Unretained(this)));
}
~TranslateBrowserTest() override = default;
void SetUpOnMainThread() override {
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&TranslateBrowserTest::HandleRequest, base::Unretained(this)));
embedded_test_server()->StartAcceptingConnections();
// Translation will not be offered if NetworkChangeNotifier reports that the
// app is offline, which can occur on bots. Prevent this.
// NOTE: MockNetworkChangeNotifier cannot be instantiated earlier than this
// due to its dependence on browser state having been created.
mock_network_change_notifier_ =
std::make_unique<net::test::ScopedMockNetworkChangeNotifier>();
mock_network_change_notifier_->mock_network_change_notifier()
->SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
// By default, translation is not offered if the Google API key is not set.
GetTranslateClient(shell())
->GetTranslateManager()
->SetIgnoreMissingKeyForTesting(true);
GetTranslateClient(shell())->GetTranslatePrefs()->ResetToDefaults();
}
void TearDownOnMainThread() override {
mock_network_change_notifier_.reset();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
command_line->AppendSwitchASCII(
translate::switches::kTranslateScriptURL,
embedded_test_server()->GetURL("/mock_translate_script.js").spec());
}
protected:
translate::TranslateErrors::Type GetPageTranslatedResult() {
return error_type_;
}
void SetTranslateScript(const std::string& script) { script_ = script; }
private:
std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
const net::test_server::HttpRequest& request) {
if (request.GetURL().path() != "/mock_translate_script.js")
return nullptr;
auto http_response =
std::make_unique<net::test_server::BasicHttpResponse>();
http_response->set_code(net::HTTP_OK);
http_response->set_content(script_);
http_response->set_content_type("text/javascript");
return std::move(http_response);
}
void OnTranslateError(const translate::TranslateErrorDetails& details) {
error_type_ = details.error;
}
std::unique_ptr<net::test::ScopedMockNetworkChangeNotifier>
mock_network_change_notifier_;
translate::TranslateErrors::Type error_type_ =
translate::TranslateErrors::NONE;
std::unique_ptr<
translate::TranslateManager::TranslateErrorCallbackList::Subscription>
error_subscription_;
std::string script_;
};
// Tests that the CLD (Compact Language Detection) works properly.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageLanguageDetection) {
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Go to a page in English.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/english_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("en", translate_client->GetLanguageState().original_language());
// Now navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
}
// Test that the translation was successful.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageTranslationSuccess) {
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// Translate the page through TranslateManager.
translate::TranslateManager* manager =
translate_client->GetTranslateManager();
manager->TranslatePage(
translate_client->GetLanguageState().original_language(), "en", true);
WaitUntilPageTranslated(shell());
EXPECT_FALSE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult());
}
class IncognitoTranslateBrowserTest : public TranslateBrowserTest {
public:
IncognitoTranslateBrowserTest() { SetShellStartsInIncognitoMode(); }
};
// Test that the translation infrastructure is set up properly when the user is
// in incognito mode.
IN_PROC_BROWSER_TEST_F(IncognitoTranslateBrowserTest,
PageTranslationSuccess_IncognitoMode) {
ASSERT_TRUE(GetProfile()->GetBrowserContext()->IsOffTheRecord());
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// Translate the page through TranslateManager.
translate::TranslateManager* manager =
translate_client->GetTranslateManager();
manager->TranslatePage(
translate_client->GetLanguageState().original_language(), "en", true);
WaitUntilPageTranslated(shell());
EXPECT_FALSE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult());
}
// Test if there was an error during translation.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageTranslationError) {
#if defined(OS_ANDROID)
// TODO(crbug.com/1094903): Determine why this test times out on the M
// trybot.
if (base::android::BuildInfo::GetInstance()->sdk_int() <=
base::android::SDK_VERSION_MARSHMALLOW) {
return;
}
#endif
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Translate the page through TranslateManager.
translate::TranslateManager* manager =
translate_client->GetTranslateManager();
manager->TranslatePage(
translate_client->GetLanguageState().original_language(), "en", true);
WaitUntilPageTranslated(shell());
EXPECT_TRUE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::TRANSLATION_ERROR,
GetPageTranslatedResult());
}
// Test if there was an error during translate library initialization.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,
PageTranslationInitializationError) {
SetTranslateScript(kTestScriptInitializationError);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// Translate the page through TranslateManager.
translate::TranslateManager* manager =
translate_client->GetTranslateManager();
manager->TranslatePage(
translate_client->GetLanguageState().original_language(), "en", true);
WaitUntilPageTranslated(shell());
EXPECT_TRUE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::INITIALIZATION_ERROR,
GetPageTranslatedResult());
}
// Test the checks translate lib never gets ready and throws timeout.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, PageTranslationTimeoutError) {
SetTranslateScript(kTestScriptTimeout);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// Translate the page through TranslateManager.
translate::TranslateManager* manager =
translate_client->GetTranslateManager();
manager->TranslatePage(
translate_client->GetLanguageState().original_language(), "en", true);
WaitUntilPageTranslated(shell());
EXPECT_TRUE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::TRANSLATION_TIMEOUT,
GetPageTranslatedResult());
}
// Test that autotranslation kicks in if configured via prefs.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, Autotranslation) {
#if defined(OS_ANDROID)
// TODO(crbug.com/1094903): Determine why this test times out on the M
// trybot.
if (base::android::BuildInfo::GetInstance()->sdk_int() <=
base::android::SDK_VERSION_MARSHMALLOW) {
return;
}
#endif
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
// Before browsing, set autotranslate from French to Chinese.
translate_client->GetTranslatePrefs()->WhitelistLanguagePair("fr", "zh-CN");
// Navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// Autotranslation should kick in.
WaitUntilPageTranslated(shell());
EXPECT_FALSE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult());
EXPECT_EQ("zh-CN", translate_client->GetLanguageState().current_language());
}
#if defined(OS_ANDROID)
// Test that the translation infobar is presented when visiting a page with a
// translation opportunity and removed when navigating away.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, TranslateInfoBarPresentation) {
auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
auto* infobar_service = InfoBarService::FromWebContents(web_contents);
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
TestInfoBarManagerObserver infobar_observer;
infobar_service->AddObserver(&infobar_observer);
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
EXPECT_EQ(0u, infobar_service->infobar_count());
// Navigate to a page in French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// The translate infobar should be added.
run_loop.Run();
EXPECT_EQ(1u, infobar_service->infobar_count());
auto* infobar =
static_cast<infobars::InfoBarAndroid*>(infobar_service->infobar_at(0));
EXPECT_TRUE(infobar->HasSetJavaInfoBar());
base::RunLoop run_loop2;
infobar_observer.set_on_infobar_removed_callback(run_loop2.QuitClosure());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
// The translate infobar should be removed.
run_loop2.Run();
EXPECT_EQ(0u, infobar_service->infobar_count());
infobar_service->RemoveObserver(&infobar_observer);
}
#endif
#if defined(OS_ANDROID)
// Test that the translation can be successfully initiated via infobar.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest, TranslationViaInfoBar) {
// TODO(crbug.com/1094903): Determine why this test times out on the M
// trybot.
if (base::android::BuildInfo::GetInstance()->sdk_int() <=
base::android::SDK_VERSION_MARSHMALLOW) {
return;
}
auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
auto* infobar_service = InfoBarService::FromWebContents(web_contents);
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
TestInfoBarManagerObserver infobar_observer;
infobar_service->AddObserver(&infobar_observer);
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
// Navigate to a page in French and wait for the infobar to be added.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
run_loop.Run();
// Select the target language via the Java infobar and ensure that translation
// occurs.
auto* infobar =
static_cast<TranslateCompactInfoBar*>(infobar_service->infobar_at(0));
TranslateTestBridge::SelectButton(
infobar, infobars::InfoBarAndroid::ActionType::ACTION_TRANSLATE);
WaitUntilPageTranslated(shell());
EXPECT_FALSE(translate_client->GetLanguageState().translation_error());
EXPECT_EQ(translate::TranslateErrors::NONE, GetPageTranslatedResult());
// The translate infobar should still be present.
EXPECT_EQ(1u, infobar_service->infobar_count());
// NOTE: The notification that the translate state of the page changed can
// occur synchronously once reversion is initiated, so it's necessary to start
// listening for that notification prior to initiating the reversion.
auto translate_reversion_waiter = CreateTranslateWaiter(
shell(), translate::TranslateWaiter::WaitEvent::kIsPageTranslatedChanged);
// Revert to the source language via the Java infobar and ensure that the
// translation is undone.
TranslateTestBridge::SelectButton(
infobar,
infobars::InfoBarAndroid::ActionType::ACTION_TRANSLATE_SHOW_ORIGINAL);
translate_reversion_waiter->Wait();
EXPECT_EQ("fr", translate_client->GetLanguageState().current_language());
// The translate infobar should still be present.
EXPECT_EQ(1u, infobar_service->infobar_count());
infobar_service->RemoveObserver(&infobar_observer);
}
#endif
#if defined(OS_ANDROID)
// Test that the translation infobar stays present when the "never translate
// language" item is clicked. Note that this behavior is intentionally different
// from that of Chrome, where the infobar is removed in this case and a snackbar
// is shown. As WebLayer has no snackbars, the UX decision was to simply leave
// the infobar open to allow the user to revert the decision if desired.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,
TranslateInfoBarNeverTranslateLanguage) {
auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
auto* infobar_service = InfoBarService::FromWebContents(web_contents);
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
TestInfoBarManagerObserver infobar_observer;
infobar_service->AddObserver(&infobar_observer);
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
// Navigate to a page in French and wait for the infobar to be added.
EXPECT_EQ(0u, infobar_service->infobar_count());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
run_loop.Run();
auto* infobar =
static_cast<TranslateCompactInfoBar*>(infobar_service->infobar_at(0));
TranslateTestBridge::ClickOverflowMenuItem(
infobar,
TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_LANGUAGE);
// The translate infobar should still be present.
EXPECT_EQ(1u, infobar_service->infobar_count());
// However, the infobar should not be shown on a new navigation to a page in
// French.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page2.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// NOTE: There is no notification to wait for for the event of the infobar not
// showing. However, in practice the infobar is added synchronously, so if it
// were to be shown, this check would fail.
EXPECT_EQ(0u, infobar_service->infobar_count());
// The infobar *should* be shown on a navigation to this site if the page's
// language is detected as something other than French.
base::RunLoop run_loop2;
infobar_observer.set_on_infobar_added_callback(run_loop2.QuitClosure());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/german_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("de", translate_client->GetLanguageState().original_language());
run_loop2.Run();
EXPECT_EQ(1u, infobar_service->infobar_count());
infobar_service->RemoveObserver(&infobar_observer);
}
// Test that the translation infobar stays present when the "never translate
// site" item is clicked. Note that this behavior is intentionally different
// from that of Chrome, where the infobar is removed in this case and a snackbar
// is shown. As WebLayer has no snackbars, the UX decision was to simply leave
// the infobar open to allow the user to revert the decision if desired.
IN_PROC_BROWSER_TEST_F(TranslateBrowserTest,
TranslateInfoBarNeverTranslateSite) {
auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
auto* infobar_service = InfoBarService::FromWebContents(web_contents);
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
TestInfoBarManagerObserver infobar_observer;
infobar_service->AddObserver(&infobar_observer);
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
// Navigate to a page in French and wait for the infobar to be added.
EXPECT_EQ(0u, infobar_service->infobar_count());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
run_loop.Run();
auto* infobar =
static_cast<TranslateCompactInfoBar*>(infobar_service->infobar_at(0));
TranslateTestBridge::ClickOverflowMenuItem(
infobar, TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_SITE);
// The translate infobar should still be present.
EXPECT_EQ(1u, infobar_service->infobar_count());
// However, the infobar should not be shown on a new navigation to this site,
// independent of the detected language.
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page2.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
// NOTE: There is no notification to wait for for the event of the infobar not
// showing. However, in practice the infobar is added synchronously, so if it
// were to be shown, this check would fail.
EXPECT_EQ(0u, infobar_service->infobar_count());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/german_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("de", translate_client->GetLanguageState().original_language());
EXPECT_EQ(0u, infobar_service->infobar_count());
infobar_service->RemoveObserver(&infobar_observer);
}
// Parameterized to run tests on the "never translate language" and "never
// translate site" menu items.
class NeverTranslateMenuItemTranslateBrowserTest
: public TranslateBrowserTest,
public testing::WithParamInterface<
TranslateTestBridge::OverflowMenuItemId> {};
// Test that clicking and unclicking a never translate item ends up being a
// no-op.
// Disabled due to flakiness on P (crbug.com/1114795).
IN_PROC_BROWSER_TEST_P(
NeverTranslateMenuItemTranslateBrowserTest,
DISABLED_TranslateInfoBarToggleAndToggleBackNeverTranslateItem) {
auto* web_contents = static_cast<TabImpl*>(shell()->tab())->web_contents();
auto* infobar_service = InfoBarService::FromWebContents(web_contents);
SetTranslateScript(kTestValidScript);
TranslateClientImpl* translate_client = GetTranslateClient(shell());
NavigateAndWaitForCompletion(GURL("about:blank"), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("und", translate_client->GetLanguageState().original_language());
TestInfoBarManagerObserver infobar_observer;
infobar_service->AddObserver(&infobar_observer);
// Navigate to a page in French, wait for the infobar to be added, and click
// twice on the given overflow menu item.
{
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
EXPECT_EQ(0u, infobar_service->infobar_count());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
run_loop.Run();
auto* infobar =
static_cast<TranslateCompactInfoBar*>(infobar_service->infobar_at(0));
TranslateTestBridge::ClickOverflowMenuItem(infobar, GetParam());
// The translate infobar should still be present.
EXPECT_EQ(1u, infobar_service->infobar_count());
TranslateTestBridge::ClickOverflowMenuItem(infobar, GetParam());
}
// The infobar should be shown on a new navigation to a page in the same
// language.
{
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/french_page2.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("fr", translate_client->GetLanguageState().original_language());
run_loop.Run();
}
// The infobar should be shown on a new navigation to a page in a different
// language in the same site.
{
base::RunLoop run_loop;
infobar_observer.set_on_infobar_added_callback(run_loop.QuitClosure());
NavigateAndWaitForCompletion(
GURL(embedded_test_server()->GetURL("/german_page.html")), shell());
WaitUntilLanguageDetermined(shell());
EXPECT_EQ("de", translate_client->GetLanguageState().original_language());
run_loop.Run();
}
infobar_service->RemoveObserver(&infobar_observer);
}
INSTANTIATE_TEST_SUITE_P(
All,
NeverTranslateMenuItemTranslateBrowserTest,
::testing::Values(
TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_LANGUAGE,
TranslateTestBridge::OverflowMenuItemId::NEVER_TRANSLATE_SITE));
#endif // #if defined(OS_ANDROID)
} // namespace weblayer