Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: chrome/browser/ui/webui/web_ui_browsertest.cc

Issue 7087014: Support automatic javascript test registry in gtest when creating WebUI tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 #include "chrome/browser/ui/webui/web_ui_browsertest.h" 4 #include "chrome/browser/ui/webui/web_ui_browsertest.h"
5 5
6 #include <string> 6 #include <string>
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/at_exit.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/singleton.h"
9 #include "base/path_service.h" 12 #include "base/path_service.h"
10 #include "base/values.h" 13 #include "base/values.h"
11 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser.h"
12 #include "chrome/common/chrome_paths.h" 15 #include "chrome/common/chrome_paths.h"
13 #include "chrome/common/url_constants.h" 16 #include "chrome/common/url_constants.h"
14 #include "chrome/test/ui_test_utils.h" 17 #include "chrome/test/ui_test_utils.h"
15 #include "content/browser/tab_contents/tab_contents.h" 18 #include "content/browser/tab_contents/tab_contents.h"
16 #include "content/browser/webui/web_ui.h" 19 #include "content/browser/webui/web_ui.h"
17 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
21 #include "v8/include/v8.h"
18 22
19 static const FilePath::CharType* kWebUILibraryJS = 23 namespace {
20 FILE_PATH_LITERAL("test_api.js"); 24 const FilePath::CharType* kWebUILibraryJS = FILE_PATH_LITERAL("test_api.js");
21 static const FilePath::CharType* kWebUITestFolder = FILE_PATH_LITERAL("webui"); 25 const FilePath::CharType* kWebUITestFolder = FILE_PATH_LITERAL("webui");
22 static std::vector<std::string> error_messages_; 26
27 base::LazyInstance<std::vector<std::string> > error_messages_(
28 base::LINKER_INITIALIZED);
29
30 // GTEST registration happens at linker initialization. When
31 // |linker_initialized| is true, set up and tear down enough to enable the
32 // PathService to give us path to the test data directory.
33 FilePath GetTestDataDirectory(bool linker_initialized) {
34 scoped_ptr<base::AtExitManager> at_exit_manager;
35 if (linker_initialized) {
36 at_exit_manager.reset(new base::AtExitManager());
37 chrome::RegisterPathProvider();
38 }
39
40 FilePath test_data_directory;
41 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
42 return test_data_directory.Append(kWebUITestFolder);
43 }
23 44
24 // Intercepts all log messages. 45 // Intercepts all log messages.
25 bool LogHandler(int severity, 46 bool LogHandler(int severity,
26 const char* file, 47 const char* file,
27 int line, 48 int line,
28 size_t message_start, 49 size_t message_start,
29 const std::string& str) { 50 const std::string& str) {
30 if (severity == logging::LOG_ERROR) { 51 if (severity == logging::LOG_ERROR) {
31 error_messages_.push_back(str); 52 error_messages_.Get().push_back(str);
32 return true; 53 return true;
33 } else { 54 } else {
34 // For debugging messages while developing tests. 55 // For debugging messages while developing tests.
35 return false; 56 return false;
36 } 57 }
37 } 58 }
38 59
60 // Read the specified |library| into |content|, prepending |test_data_directory|
61 // when |library| is relative.
62 void ReadLibraryToString(const FilePath& test_data_directory,
63 const FilePath& library,
64 std::string* content) {
65 ASSERT_TRUE(content);
66 if (library.IsAbsolute()) {
67 ASSERT_TRUE(file_util::ReadFileToString(library, content));
68 } else {
69 ASSERT_TRUE(file_util::ReadFileToString(test_data_directory.Append(library),
70 content));
71 }
72 }
73
74 // Gets functions defined in |library_path| starting with "test". |testFuncs|
75 // may not be NULL.
76 bool GetTestFuncs(const FilePath& library_path,
77 std::vector<std::string>* testFuncs) {
78 DCHECK(testFuncs);
79
80 std::string content = "var window = {};";
81 ReadLibraryToString(GetTestDataDirectory(true), library_path, &content);
82 content.append(
83 "(function () {"
84 " var funcs = new Array();"
85 " for (var func in this) {"
86 " if (typeof this[func] == 'function')"
87 " funcs.push(func);"
88 " }"
89 " return funcs;"
90 "})()");
91
92 v8::HandleScope handle_scope;
93 v8::Persistent<v8::Context> context = v8::Context::New();
94 v8::Context::Scope context_scope(context);
95 v8::Handle<v8::String> source = v8::String::New(content.data(),
96 content.size());
97 v8::Handle<v8::Script> script = v8::Script::Compile(source);
98 v8::TryCatch trycatch;
99 v8::Handle<v8::Array> result = script->Run().As<v8::Array>();
100 context.Dispose();
101 if (result.IsEmpty()) {
102 v8::Handle<v8::Value> exception = trycatch.Exception();
103 v8::String::AsciiValue exception_str(exception);
104 NOTREACHED() << "Exception: " << *exception_str;
105 return false;
106 }
107
108 for (uint32_t index = 0; index < result->Length(); ++index) {
109 v8::Local<v8::String> value(result->Get(index).As<v8::String>());
110 if (value.IsEmpty()) {
111 return false;
112 }
113 v8::String::AsciiValue ascii(value);
114 testFuncs->push_back(std::string(*ascii, ascii.length()));
115 }
116 return true;
117 }
118
119 } // namespace
120
39 WebUIBrowserTest::~WebUIBrowserTest() {} 121 WebUIBrowserTest::~WebUIBrowserTest() {}
40 122
41 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name) { 123 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name) {
42 return RunJavascriptFunction(function_name, ConstValueVector()); 124 return RunJavascriptFunction(function_name, ConstValueVector());
43 } 125 }
44 126
45 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name, 127 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name,
46 const Value& arg) { 128 const Value& arg) {
47 ConstValueVector args; 129 ConstValueVector args;
48 args.push_back(&arg); 130 args.push_back(&arg);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 bool WebUIBrowserTest::RunJavascriptTest( 169 bool WebUIBrowserTest::RunJavascriptTest(
88 const std::string& test_name, 170 const std::string& test_name,
89 const ConstValueVector& test_arguments) { 171 const ConstValueVector& test_arguments) {
90 return RunJavascriptUsingHandler(test_name, test_arguments, true); 172 return RunJavascriptUsingHandler(test_name, test_arguments, true);
91 } 173 }
92 174
93 WebUIBrowserTest::WebUIBrowserTest() 175 WebUIBrowserTest::WebUIBrowserTest()
94 : test_handler_(new WebUITestHandler()) {} 176 : test_handler_(new WebUITestHandler()) {}
95 177
96 void WebUIBrowserTest::SetUpInProcessBrowserTestFixture() { 178 void WebUIBrowserTest::SetUpInProcessBrowserTestFixture() {
97 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_)); 179 test_data_directory_ = GetTestDataDirectory(false);
98 test_data_directory_ = test_data_directory_.Append(kWebUITestFolder);
99 180
100 // TODO(dtseng): should this be part of every BrowserTest or just WebUI test. 181 // TODO(dtseng): should this be part of every BrowserTest or just WebUI test.
101 FilePath resources_pack_path; 182 FilePath resources_pack_path;
102 PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); 183 PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
103 ResourceBundle::AddDataPackToSharedInstance(resources_pack_path); 184 ResourceBundle::AddDataPackToSharedInstance(resources_pack_path);
104 185
105 AddLibrary(FilePath(kWebUILibraryJS)); 186 AddLibrary(FilePath(kWebUILibraryJS));
106 } 187 }
107 188
108 WebUIMessageHandler* WebUIBrowserTest::GetMockMessageHandler() { 189 WebUIMessageHandler* WebUIBrowserTest::GetMockMessageHandler() {
109 return NULL; 190 return NULL;
110 } 191 }
111 192
112 void WebUIBrowserTest::BuildJavascriptLibraries(std::string* content) { 193 int WebUIBrowserTest::AddJSToRegistry(
194 const FilePath& library_path,
195 const char* test_case_name, const char* name,
196 const char* type_param,
197 const char* value_param,
198 ::testing::internal::TypeId fixture_class_id,
199 ::testing::internal::SetUpTestCaseFunc set_up_tc,
200 ::testing::internal::TearDownTestCaseFunc tear_down_tc,
201 ::testing::internal::TestMetaFactoryBase<std::string>* meta_factory) {
202 std::vector<std::string> testFuncs;
203 EXPECT_TRUE(GetTestFuncs(library_path, &testFuncs));
204 for (std::vector<std::string>::const_iterator it = testFuncs.begin();
205 it != testFuncs.end(); ++it) {
206 std::string test_name = *it + "/" + name;
207 ::testing::internal::MakeAndRegisterTestInfo(
208 test_case_name, test_name.c_str(),
209 type_param,
210 value_param,
211 fixture_class_id,
212 set_up_tc,
213 tear_down_tc,
214 meta_factory->CreateTestFactory(*it));
215 }
216 return testFuncs.size();
217 }
218
219 void WebUIBrowserTest::BuildJavascriptLibraries(std::string* content) const {
113 ASSERT_TRUE(content != NULL); 220 ASSERT_TRUE(content != NULL);
114 std::string library_content, src_content; 221 std::string library_content;
115 222
116 std::vector<FilePath>::iterator user_libraries_iterator; 223 std::vector<FilePath>::const_iterator user_libraries_iterator;
117 for (user_libraries_iterator = user_libraries.begin(); 224 for (user_libraries_iterator = user_libraries_.begin();
118 user_libraries_iterator != user_libraries.end(); 225 user_libraries_iterator != user_libraries_.end();
119 ++user_libraries_iterator) { 226 ++user_libraries_iterator) {
120 if (user_libraries_iterator->IsAbsolute()) { 227 ReadLibraryToString(test_data_directory_, *user_libraries_iterator,
121 ASSERT_TRUE(file_util::ReadFileToString(*user_libraries_iterator, 228 &library_content);
122 &library_content));
123 } else {
124 ASSERT_TRUE(file_util::ReadFileToString(
125 test_data_directory_.Append(*user_libraries_iterator),
126 &library_content));
127 }
128 content->append(library_content); 229 content->append(library_content);
129 content->append(";\n"); 230 content->append(";\n");
130 } 231 }
131 } 232 }
132 233
133 string16 WebUIBrowserTest::BuildRunTestJSCall( 234 string16 WebUIBrowserTest::BuildRunTestJSCall(
134 const std::string& function_name, 235 const std::string& function_name,
135 const WebUIBrowserTest::ConstValueVector& test_func_args) { 236 const WebUIBrowserTest::ConstValueVector& test_func_args) {
136 WebUIBrowserTest::ConstValueVector arguments; 237 WebUIBrowserTest::ConstValueVector arguments;
137 StringValue function_name_arg(function_name); 238 StringValue function_name_arg(function_name);
(...skipping 24 matching lines...) Expand all
162 called_function = WebUI::GetJavascriptCall(function_name, 263 called_function = WebUI::GetJavascriptCall(function_name,
163 function_arguments); 264 function_arguments);
164 } 265 }
165 content.append(UTF16ToUTF8(called_function)); 266 content.append(UTF16ToUTF8(called_function));
166 } 267 }
167 SetupHandlers(); 268 SetupHandlers();
168 logging::SetLogMessageHandler(&LogHandler); 269 logging::SetLogMessageHandler(&LogHandler);
169 bool result = test_handler_->RunJavascript(content, is_test); 270 bool result = test_handler_->RunJavascript(content, is_test);
170 logging::SetLogMessageHandler(NULL); 271 logging::SetLogMessageHandler(NULL);
171 272
172 if (error_messages_.size() > 0) { 273 if (error_messages_.Get().size() > 0) {
173 LOG(ERROR) << "Encountered javascript console error(s)"; 274 LOG(ERROR) << "Encountered javascript console error(s)";
174 result = false; 275 result = false;
175 error_messages_.clear(); 276 error_messages_.Get().clear();
176 } 277 }
177 return result; 278 return result;
178 } 279 }
179 280
180 void WebUIBrowserTest::SetupHandlers() { 281 void WebUIBrowserTest::SetupHandlers() {
181 WebUI* web_ui_instance = 282 WebUI* web_ui_instance =
182 browser()->GetSelectedTabContents()->web_ui(); 283 browser()->GetSelectedTabContents()->web_ui();
183 ASSERT_TRUE(web_ui_instance != NULL); 284 ASSERT_TRUE(web_ui_instance != NULL);
184 web_ui_instance->register_callback_overwrites(true); 285 web_ui_instance->register_callback_overwrites(true);
185 test_handler_->Attach(web_ui_instance); 286 test_handler_->Attach(web_ui_instance);
186 287
187 if (GetMockMessageHandler()) 288 if (GetMockMessageHandler())
188 GetMockMessageHandler()->Attach(web_ui_instance); 289 GetMockMessageHandler()->Attach(web_ui_instance);
189 } 290 }
190 291
191 void WebUIBrowserTest::AddLibrary(const FilePath& library_path) { 292 void WebUIBrowserTest::AddLibrary(const FilePath& library_path) {
192 user_libraries.push_back(library_path); 293 user_libraries_.push_back(library_path);
193 } 294 }
194 295
195 IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, TestSamplePass) { 296 IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, TestSamplePass) {
196 AddLibrary(FilePath(FILE_PATH_LITERAL("sample_downloads.js"))); 297 AddLibrary(FilePath(FILE_PATH_LITERAL("sample_passing.js")));
197 298
198 // Navigate to UI. 299 // Navigate to UI.
199 // TODO(dtseng): make accessor for subclasses to return? 300 // TODO(dtseng): make accessor for subclasses to return?
200 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL)); 301 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
201 302
202 ASSERT_TRUE(RunJavascriptTest("testAssertFalse")); 303 ASSERT_TRUE(RunJavascriptTest("testAssertFalse"));
203 ASSERT_TRUE(RunJavascriptTest("testInitialFocus")); 304 ASSERT_TRUE(RunJavascriptTest("testInitialFocus"));
305 }
306
307 IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, TestSampleFail) {
308 AddLibrary(FilePath(FILE_PATH_LITERAL("sample_failing.js")));
309
310 // Navigate to UI.
311 // TODO(dtseng): make accessor for subclasses to return?
312 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
313
204 ASSERT_FALSE(RunJavascriptTest("testConsoleError")); 314 ASSERT_FALSE(RunJavascriptTest("testConsoleError"));
205 } 315 }
316
317 WEB_UI_BROWSER_TEST_JS(WebUIBrowserTest, TestJSPass,
318 FILE_PATH_LITERAL("sample_passing.js")) {
319 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
320 }
321
322 WEB_UI_BROWSER_TEST_JS_FALSE(WebUIBrowserTest, TestJSFail,
323 FILE_PATH_LITERAL("sample_failing.js")) {
324 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
325 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698