1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/stringprintf.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/test/base/chrome_render_view_test.h"
8 #include "components/translate/core/common/translate_errors.h"
9 #include "grit/components_resources.h"
10 #include "third_party/WebKit/public/web/WebLocalFrame.h"
11 #include "third_party/WebKit/public/web/WebScriptSource.h"
12 #include "ui/base/resource/resource_bundle.h"
13 #include "v8/include/v8.h"
15 using blink::WebScriptSource
;
19 // JavaScript code to set runtime test flags.
20 const char kThrowInitializationError
[] = "throwInitializationError = true";
21 const char kThrowUnexpectedScriptError
[] = "throwUnexpectedScriptError = true";
22 const char kCallbackReturnBooleanError
[] = "callbackReturnBooleanError = true";
23 const char kCallbackReturnNumberError
[] = "callbackReturnNumberError = true";
24 const char kSetCallbackErrorCode
[] = "callbackErrorCode = ";
26 // JavaScript code to check if any error happens.
27 const char kError
[] = "cr.googleTranslate.error";
29 // JavaScript code to get error code.
30 const char kErrorCode
[] = "cr.googleTranslate.errorCode";
32 // JavaScript code to check if the library is ready.
33 const char kLibReady
[] = "cr.googleTranslate.libReady";
35 // JavaScript code to perform translation.
36 const char kTranslate
[] = "cr.googleTranslate.translate('auto', 'en')";
38 // JavaScript code to mimic element.js provided by a translate server.
39 const char kElementJs
[] =
40 "translateApiKey = '';"
42 "google.translate = {};"
43 "google.translate.TranslateService = function() {"
44 " if (window['throwInitializationError']) {"
45 " throw 'API initialization error';"
48 " isAvailable: function() { return true; },"
49 " restore: function() {},"
50 " translatePage: function(originalLang, targetLang, cb) {"
51 " if (window['throwUnexpectedScriptError']) {"
52 " throw 'all your base are belong to us';"
54 " if (window['callbackReturnBooleanError']) {"
55 " cb(0, false, true);"
57 " if (window['callbackReturnNumberError']) {"
58 " cb(0, false, callbackErrorCode);"
63 "cr.googleTranslate.onTranslateElementLoad();";
65 std::string
GenerateSetCallbackErrorCodeScript(int code
) {
66 return base::StringPrintf("%s%d", kSetCallbackErrorCode
, code
);
71 // This class is for testing resource/translate.js works and reports errors
73 class TranslateScriptBrowserTest
: public ChromeRenderViewTest
{
75 TranslateScriptBrowserTest() {}
78 void InjectElementLibrary() {
80 base::StringPiece translate_js
= ResourceBundle::GetSharedInstance().
81 GetRawDataResource(IDR_TRANSLATE_JS
);
82 translate_js
.CopyToString(&script
);
84 ExecuteScript(script
);
87 void ExecuteScript(const std::string
& script
) {
88 WebScriptSource source
= WebScriptSource(base::ASCIIToUTF16(script
));
89 GetMainFrame()->executeScript(source
);
93 return ExecuteScriptAndGetBoolResult(kError
);
96 double GetErrorCode() {
97 return ExecuteScriptAndGetNumberResult(kErrorCode
);
101 return ExecuteScriptAndGetBoolResult(kLibReady
);
105 void SetUp() override
{ ChromeRenderViewTest::SetUp(); }
107 void TearDown() override
{ ChromeRenderViewTest::TearDown(); }
109 double ExecuteScriptAndGetNumberResult(const std::string
& script
) {
110 WebScriptSource source
= WebScriptSource(base::ASCIIToUTF16(script
));
111 v8::HandleScope
handle_scope(v8::Isolate::GetCurrent());
112 v8::Local
<v8::Value
> result
=
113 GetMainFrame()->executeScriptAndReturnValue(source
);
114 if (result
.IsEmpty() || !result
->IsNumber()) {
116 // TODO(toyoshim): Return NaN here and the real implementation in
117 // TranslateHelper::ExecuteScriptAndGetDoubleResult().
120 return result
->NumberValue();
123 bool ExecuteScriptAndGetBoolResult(const std::string
& script
) {
124 WebScriptSource source
= WebScriptSource(base::ASCIIToUTF16(script
));
125 v8::HandleScope
handle_scope(v8::Isolate::GetCurrent());
126 v8::Local
<v8::Value
> result
=
127 GetMainFrame()->executeScriptAndReturnValue(source
);
128 if (result
.IsEmpty() || !result
->IsBoolean()) {
132 return result
->BooleanValue();
135 DISALLOW_COPY_AND_ASSIGN(TranslateScriptBrowserTest
);
138 // Test if onTranslateElementLoad() succeeds to initialize the element library.
139 TEST_F(TranslateScriptBrowserTest
, ElementLoadSuccess
) {
140 InjectElementLibrary();
141 EXPECT_TRUE(IsLibReady());
142 EXPECT_FALSE(GetError());
143 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
146 // Test if onTranslateElementLoad() fails to initialize the element library and
147 // report the right error code.
148 TEST_F(TranslateScriptBrowserTest
, ElementLoadFailure
) {
149 ExecuteScript(kThrowInitializationError
);
151 InjectElementLibrary();
152 EXPECT_FALSE(IsLibReady());
153 EXPECT_TRUE(GetError());
154 EXPECT_EQ(translate::TranslateErrors::INITIALIZATION_ERROR
, GetErrorCode());
157 // Test if cr.googleTranslate.translate() works.
158 TEST_F(TranslateScriptBrowserTest
, TranslateSuccess
) {
159 InjectElementLibrary();
160 EXPECT_TRUE(IsLibReady());
161 EXPECT_FALSE(GetError());
162 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
164 ExecuteScript(kTranslate
);
166 EXPECT_FALSE(GetError());
167 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
170 // Test if cr.googleTranslate.translate() handles library exception correctly.
171 TEST_F(TranslateScriptBrowserTest
, TranslateFail
) {
172 ExecuteScript(kThrowUnexpectedScriptError
);
174 InjectElementLibrary();
175 EXPECT_TRUE(IsLibReady());
176 EXPECT_FALSE(GetError());
177 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
179 ExecuteScript(kTranslate
);
181 EXPECT_TRUE(GetError());
182 EXPECT_EQ(translate::TranslateErrors::UNEXPECTED_SCRIPT_ERROR
,
186 // Test if onTranslateProgress callback handles boolean type error correctly.
187 // Remove this test once server side changes the API to return a number.
188 TEST_F(TranslateScriptBrowserTest
, CallbackGetBooleanError
) {
189 ExecuteScript(kCallbackReturnBooleanError
);
191 InjectElementLibrary();
192 EXPECT_TRUE(IsLibReady());
193 EXPECT_FALSE(GetError());
194 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
196 ExecuteScript(kTranslate
);
198 EXPECT_TRUE(GetError());
199 EXPECT_EQ(translate::TranslateErrors::TRANSLATION_ERROR
, GetErrorCode());
202 // Test if onTranslateProgress callback handles number type error correctly and
203 // converts it to the proper error code.
204 TEST_F(TranslateScriptBrowserTest
, CallbackGetNumberError1
) {
205 ExecuteScript(kCallbackReturnNumberError
);
206 ExecuteScript(GenerateSetCallbackErrorCodeScript(1));
208 InjectElementLibrary();
209 EXPECT_TRUE(IsLibReady());
210 EXPECT_FALSE(GetError());
211 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
213 ExecuteScript(kTranslate
);
215 EXPECT_TRUE(GetError());
216 EXPECT_EQ(translate::TranslateErrors::TRANSLATION_ERROR
, GetErrorCode());
219 // Test if onTranslateProgress callback handles number type error correctly and
220 // converts it to the proper error code.
221 TEST_F(TranslateScriptBrowserTest
, CallbackGetNumberError2
) {
222 ExecuteScript(kCallbackReturnNumberError
);
223 ExecuteScript(GenerateSetCallbackErrorCodeScript(2));
225 InjectElementLibrary();
226 EXPECT_TRUE(IsLibReady());
227 EXPECT_FALSE(GetError());
228 EXPECT_EQ(translate::TranslateErrors::NONE
, GetErrorCode());
230 ExecuteScript(kTranslate
);
232 EXPECT_TRUE(GetError());
233 EXPECT_EQ(translate::TranslateErrors::UNSUPPORTED_LANGUAGE
, GetErrorCode());
236 // TODO(toyoshim): Add test for onLoadJavaScript.