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

Side by Side Diff: chrome/test/base/web_ui_browsertest.cc

Issue 304793002: Support automatically resolving dependencies in javascript tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Address potential reason for trybot failures by actually adding the .gypi file that I wrote... Created 6 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/test/base/web_ui_browsertest.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/lazy_instance.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "chrome/browser/chrome_content_browser_client.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_commands.h"
22 #include "chrome/browser/ui/browser_navigator.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
25 #include "chrome/browser/ui/webui/web_ui_test_handler.h"
26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/url_constants.h"
28 #include "chrome/test/base/test_chrome_web_ui_controller_factory.h"
29 #include "chrome/test/base/ui_test_utils.h"
30 #include "content/public/browser/navigation_controller.h"
31 #include "content/public/browser/notification_observer.h"
32 #include "content/public/browser/notification_registrar.h"
33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_types.h"
35 #include "content/public/browser/url_data_source.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/browser/web_contents_observer.h"
38 #include "content/public/browser/web_ui_controller.h"
39 #include "content/public/browser/web_ui_message_handler.h"
40 #include "content/public/test/browser_test_utils.h"
41 #include "content/public/test/test_navigation_observer.h"
42 #include "net/base/filename_util.h"
43 #include "testing/gmock/include/gmock/gmock.h"
44 #include "testing/gtest/include/gtest/gtest-spi.h"
45 #include "ui/base/resource/resource_bundle.h"
46 #include "ui/base/resource/resource_handle.h"
47
48 #if defined(ENABLE_FULL_PRINTING)
49 #include "chrome/browser/printing/print_preview_dialog_controller.h"
50 #endif
51
52 using content::NavigationController;
53 using content::RenderViewHost;
54 using content::WebContents;
55 using content::WebUIController;
56 using content::WebUIMessageHandler;
57
58 namespace {
59
60 const base::FilePath::CharType kA11yAuditLibraryJSPath[] = FILE_PATH_LITERAL(
61 "third_party/accessibility-audit/axs_testing.js");
62 const base::FilePath::CharType kMockJSPath[] =
63 FILE_PATH_LITERAL("chrome/third_party/mock4js/mock4js.js");
64 const base::FilePath::CharType kWebUILibraryJS[] =
65 FILE_PATH_LITERAL("test_api.js");
66 const base::FilePath::CharType kWebUITestFolder[] = FILE_PATH_LITERAL("webui");
67 base::LazyInstance<std::vector<std::string> > error_messages_ =
68 LAZY_INSTANCE_INITIALIZER;
69
70 // Intercepts all log messages.
71 bool LogHandler(int severity,
72 const char* file,
73 int line,
74 size_t message_start,
75 const std::string& str) {
76 if (severity == logging::LOG_ERROR &&
77 file &&
78 std::string("CONSOLE") == file) {
79 error_messages_.Get().push_back(str);
80 }
81
82 return false;
83 }
84
85 class WebUIJsInjectionReadyObserver : public content::WebContentsObserver {
86 public:
87 WebUIJsInjectionReadyObserver(content::WebContents* web_contents,
88 WebUIBrowserTest* browser_test,
89 const std::string& preload_test_fixture,
90 const std::string& preload_test_name)
91 : content::WebContentsObserver(web_contents),
92 browser_test_(browser_test),
93 preload_test_fixture_(preload_test_fixture),
94 preload_test_name_(preload_test_name) {}
95
96 virtual void RenderViewCreated(content::RenderViewHost* rvh) OVERRIDE {
97 browser_test_->PreLoadJavascriptLibraries(
98 preload_test_fixture_, preload_test_name_, rvh);
99 }
100
101 private:
102 WebUIBrowserTest* browser_test_;
103 std::string preload_test_fixture_;
104 std::string preload_test_name_;
105 };
106
107 } // namespace
108
109 WebUIBrowserTest::~WebUIBrowserTest() {}
110
111 void WebUIBrowserTest::AddLibrary(const base::FilePath& library_path) {
112 user_libraries_.push_back(library_path);
113 }
114
115 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name) {
116 ConstValueVector empty_args;
117 return RunJavascriptFunction(function_name, empty_args);
118 }
119
120 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name,
121 base::Value* arg) {
122 ConstValueVector args;
123 args.push_back(arg);
124 return RunJavascriptFunction(function_name, args);
125 }
126
127 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name,
128 base::Value* arg1,
129 base::Value* arg2) {
130 ConstValueVector args;
131 args.push_back(arg1);
132 args.push_back(arg2);
133 return RunJavascriptFunction(function_name, args);
134 }
135
136 bool WebUIBrowserTest::RunJavascriptFunction(
137 const std::string& function_name,
138 const ConstValueVector& function_arguments) {
139 return RunJavascriptUsingHandler(
140 function_name, function_arguments, false, false, NULL);
141 }
142
143 bool WebUIBrowserTest::RunJavascriptTestF(bool is_async,
144 const std::string& test_fixture,
145 const std::string& test_name) {
146 ConstValueVector args;
147 args.push_back(new base::StringValue(test_fixture));
148 args.push_back(new base::StringValue(test_name));
149
150 if (is_async)
151 return RunJavascriptAsyncTest("RUN_TEST_F", args);
152 else
153 return RunJavascriptTest("RUN_TEST_F", args);
154 }
155
156 bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name) {
157 ConstValueVector empty_args;
158 return RunJavascriptTest(test_name, empty_args);
159 }
160
161 bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name,
162 base::Value* arg) {
163 ConstValueVector args;
164 args.push_back(arg);
165 return RunJavascriptTest(test_name, args);
166 }
167
168 bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name,
169 base::Value* arg1,
170 base::Value* arg2) {
171 ConstValueVector args;
172 args.push_back(arg1);
173 args.push_back(arg2);
174 return RunJavascriptTest(test_name, args);
175 }
176
177 bool WebUIBrowserTest::RunJavascriptTest(
178 const std::string& test_name,
179 const ConstValueVector& test_arguments) {
180 return RunJavascriptUsingHandler(
181 test_name, test_arguments, true, false, NULL);
182 }
183
184 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name) {
185 ConstValueVector empty_args;
186 return RunJavascriptAsyncTest(test_name, empty_args);
187 }
188
189 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name,
190 base::Value* arg) {
191 ConstValueVector args;
192 args.push_back(arg);
193 return RunJavascriptAsyncTest(test_name, args);
194 }
195
196 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name,
197 base::Value* arg1,
198 base::Value* arg2) {
199 ConstValueVector args;
200 args.push_back(arg1);
201 args.push_back(arg2);
202 return RunJavascriptAsyncTest(test_name, args);
203 }
204
205 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name,
206 base::Value* arg1,
207 base::Value* arg2,
208 base::Value* arg3) {
209 ConstValueVector args;
210 args.push_back(arg1);
211 args.push_back(arg2);
212 args.push_back(arg3);
213 return RunJavascriptAsyncTest(test_name, args);
214 }
215
216 bool WebUIBrowserTest::RunJavascriptAsyncTest(
217 const std::string& test_name,
218 const ConstValueVector& test_arguments) {
219 return RunJavascriptUsingHandler(test_name, test_arguments, true, true, NULL);
220 }
221
222 void WebUIBrowserTest::PreLoadJavascriptLibraries(
223 const std::string& preload_test_fixture,
224 const std::string& preload_test_name,
225 RenderViewHost* preload_host) {
226 ASSERT_FALSE(libraries_preloaded_);
227 ConstValueVector args;
228 args.push_back(new base::StringValue(preload_test_fixture));
229 args.push_back(new base::StringValue(preload_test_name));
230 RunJavascriptUsingHandler(
231 "preloadJavascriptLibraries", args, false, false, preload_host);
232 libraries_preloaded_ = true;
233 }
234
235 void WebUIBrowserTest::BrowsePreload(const GURL& browse_to) {
236 content::WebContents* web_contents =
237 browser()->tab_strip_model()->GetActiveWebContents();
238 WebUIJsInjectionReadyObserver injection_observer(
239 web_contents, this, preload_test_fixture_, preload_test_name_);
240 content::TestNavigationObserver navigation_observer(web_contents);
241 chrome::NavigateParams params(browser(), GURL(browse_to),
242 content::PAGE_TRANSITION_TYPED);
243 params.disposition = CURRENT_TAB;
244 chrome::Navigate(&params);
245 navigation_observer.Wait();
246 }
247
248 #if defined(ENABLE_FULL_PRINTING)
249
250 // This custom ContentBrowserClient is used to get notified when a WebContents
251 // for the print preview dialog gets created.
252 class PrintContentBrowserClient : public chrome::ChromeContentBrowserClient {
253 public:
254 PrintContentBrowserClient(WebUIBrowserTest* browser_test,
255 const std::string& preload_test_fixture,
256 const std::string& preload_test_name)
257 : browser_test_(browser_test),
258 preload_test_fixture_(preload_test_fixture),
259 preload_test_name_(preload_test_name),
260 preview_dialog_(NULL),
261 message_loop_runner_(new content::MessageLoopRunner) {}
262
263 void Wait() {
264 message_loop_runner_->Run();
265 content::WaitForLoadStop(preview_dialog_);
266 }
267
268 private:
269 // ChromeContentBrowserClient implementation:
270 virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate(
271 content::WebContents* web_contents) OVERRIDE {
272 preview_dialog_ = web_contents;
273 observer_.reset(new WebUIJsInjectionReadyObserver(
274 preview_dialog_, browser_test_, preload_test_fixture_,
275 preload_test_name_));
276 message_loop_runner_->Quit();
277 return NULL;
278 }
279
280 WebUIBrowserTest* browser_test_;
281 scoped_ptr<WebUIJsInjectionReadyObserver> observer_;
282 std::string preload_test_fixture_;
283 std::string preload_test_name_;
284 content::WebContents* preview_dialog_;
285 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
286 };
287 #endif
288
289 void WebUIBrowserTest::BrowsePrintPreload(const GURL& browse_to) {
290 #if defined(ENABLE_FULL_PRINTING)
291 ui_test_utils::NavigateToURL(browser(), browse_to);
292
293 PrintContentBrowserClient new_client(
294 this, preload_test_fixture_, preload_test_name_);
295 content::ContentBrowserClient* old_client =
296 SetBrowserClientForTesting(&new_client);
297
298 chrome::Print(browser());
299 new_client.Wait();
300
301 SetBrowserClientForTesting(old_client);
302
303 printing::PrintPreviewDialogController* tab_controller =
304 printing::PrintPreviewDialogController::GetInstance();
305 ASSERT_TRUE(tab_controller);
306 WebContents* preview_dialog = tab_controller->GetPrintPreviewForContents(
307 browser()->tab_strip_model()->GetActiveWebContents());
308 ASSERT_TRUE(preview_dialog);
309 SetWebUIInstance(preview_dialog->GetWebUI());
310 #else
311 NOTREACHED();
312 #endif
313 }
314
315 const char WebUIBrowserTest::kDummyURL[] = "chrome://DummyURL";
316
317 WebUIBrowserTest::WebUIBrowserTest()
318 : test_handler_(new WebUITestHandler()),
319 libraries_preloaded_(false),
320 override_selected_web_ui_(NULL) {}
321
322 void WebUIBrowserTest::set_preload_test_fixture(
323 const std::string& preload_test_fixture) {
324 preload_test_fixture_ = preload_test_fixture;
325 }
326
327 void WebUIBrowserTest::set_preload_test_name(
328 const std::string& preload_test_name) {
329 preload_test_name_ = preload_test_name;
330 }
331
332 namespace {
333
334 // DataSource for the dummy URL. If no data source is provided then an error
335 // page is shown. While this doesn't matter for most tests, without it,
336 // navigation to different anchors cannot be listened to (via the hashchange
337 // event).
338 class MockWebUIDataSource : public content::URLDataSource {
339 public:
340 MockWebUIDataSource() {}
341
342 private:
343 virtual ~MockWebUIDataSource() {}
344
345 virtual std::string GetSource() const OVERRIDE {
346 return "dummyurl";
347 }
348
349 virtual void StartDataRequest(
350 const std::string& path,
351 int render_process_id,
352 int render_frame_id,
353 const content::URLDataSource::GotDataCallback& callback) OVERRIDE {
354 std::string dummy_html = "<html><body>Dummy</body></html>";
355 scoped_refptr<base::RefCountedString> response =
356 base::RefCountedString::TakeString(&dummy_html);
357 callback.Run(response.get());
358 }
359
360 virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
361 return "text/html";
362 }
363
364 DISALLOW_COPY_AND_ASSIGN(MockWebUIDataSource);
365 };
366
367 // WebUIProvider to allow attaching the DataSource for the dummy URL when
368 // testing.
369 class MockWebUIProvider
370 : public TestChromeWebUIControllerFactory::WebUIProvider {
371 public:
372 MockWebUIProvider() {}
373
374 // Returns a new WebUI
375 virtual WebUIController* NewWebUI(content::WebUI* web_ui,
376 const GURL& url) OVERRIDE {
377 WebUIController* controller = new content::WebUIController(web_ui);
378 Profile* profile = Profile::FromWebUI(web_ui);
379 content::URLDataSource::Add(profile, new MockWebUIDataSource());
380 return controller;
381 }
382
383 private:
384 DISALLOW_COPY_AND_ASSIGN(MockWebUIProvider);
385 };
386
387 base::LazyInstance<MockWebUIProvider> mock_provider_ =
388 LAZY_INSTANCE_INITIALIZER;
389
390 } // namespace
391
392 void WebUIBrowserTest::SetUpOnMainThread() {
393 logging::SetLogMessageHandler(&LogHandler);
394
395 content::WebUIControllerFactory::UnregisterFactoryForTesting(
396 ChromeWebUIControllerFactory::GetInstance());
397
398 test_factory_.reset(new TestChromeWebUIControllerFactory);
399
400 content::WebUIControllerFactory::RegisterFactory(test_factory_.get());
401
402 test_factory_->AddFactoryOverride(
403 GURL(kDummyURL).host(), mock_provider_.Pointer());
404
405 base::FilePath test_data_directory;
406 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
407 test_data_directory = test_data_directory.Append(kWebUITestFolder);
408 library_search_paths_.push_back(test_data_directory);
409
410 base::FilePath gen_test_data_directory;
411 ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA,
412 &gen_test_data_directory));
413 library_search_paths_.push_back(gen_test_data_directory);
414
415 base::FilePath source_root_directory;
416 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_root_directory));
417 library_search_paths_.push_back(source_root_directory);
418
419 // TODO(dtseng): should this be part of every BrowserTest or just WebUI test.
420 base::FilePath resources_pack_path;
421 PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
422 ResourceBundle::GetSharedInstance().AddDataPackFromPath(
423 resources_pack_path, ui::SCALE_FACTOR_NONE);
424
425 AddLibrary(base::FilePath(kA11yAuditLibraryJSPath));
426 AddLibrary(base::FilePath(kMockJSPath));
427 AddLibrary(base::FilePath(kWebUILibraryJS));
428 }
429
430 void WebUIBrowserTest::CleanUpOnMainThread() {
431 logging::SetLogMessageHandler(NULL);
432
433 test_factory_->RemoveFactoryOverride(GURL(kDummyURL).host());
434 content::WebUIControllerFactory::UnregisterFactoryForTesting(
435 test_factory_.get());
436
437 // This is needed to avoid a debug assert after the test completes, see stack
438 // trace in http://crrev.com/179347
439 content::WebUIControllerFactory::RegisterFactory(
440 ChromeWebUIControllerFactory::GetInstance());
441
442 test_factory_.reset();
443 }
444
445 void WebUIBrowserTest::SetWebUIInstance(content::WebUI* web_ui) {
446 override_selected_web_ui_ = web_ui;
447 }
448
449 WebUIMessageHandler* WebUIBrowserTest::GetMockMessageHandler() {
450 return NULL;
451 }
452
453 GURL WebUIBrowserTest::WebUITestDataPathToURL(
454 const base::FilePath::StringType& path) {
455 base::FilePath dir_test_data;
456 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &dir_test_data));
457 base::FilePath test_path(dir_test_data.Append(kWebUITestFolder).Append(path));
458 EXPECT_TRUE(base::PathExists(test_path));
459 return net::FilePathToFileURL(test_path);
460 }
461
462 void WebUIBrowserTest::BuildJavascriptLibraries(
463 std::vector<base::string16>* libraries) {
464 ASSERT_TRUE(libraries != NULL);
465 std::vector<base::FilePath>::iterator user_libraries_iterator;
466 for (user_libraries_iterator = user_libraries_.begin();
467 user_libraries_iterator != user_libraries_.end();
468 ++user_libraries_iterator) {
469 std::string library_content;
470 if (user_libraries_iterator->IsAbsolute()) {
471 ASSERT_TRUE(base::ReadFileToString(*user_libraries_iterator,
472 &library_content))
473 << user_libraries_iterator->value();
474 } else {
475 bool ok = false;
476 std::vector<base::FilePath>::iterator library_search_path_iterator;
477 for (library_search_path_iterator = library_search_paths_.begin();
478 library_search_path_iterator != library_search_paths_.end();
479 ++library_search_path_iterator) {
480 ok = base::ReadFileToString(
481 base::MakeAbsoluteFilePath(
482 library_search_path_iterator->Append(*user_libraries_iterator)),
483 &library_content);
484 if (ok)
485 break;
486 }
487 ASSERT_TRUE(ok) << "User library not found: "
488 << user_libraries_iterator->value();
489 }
490 library_content.append(";\n");
491
492 // This magic code puts filenames in stack traces.
493 library_content.append("//# sourceURL=");
494 library_content.append(user_libraries_iterator->BaseName().AsUTF8Unsafe());
495 library_content.append("\n");
496 libraries->push_back(base::UTF8ToUTF16(library_content));
497 }
498 }
499
500 base::string16 WebUIBrowserTest::BuildRunTestJSCall(
501 bool is_async,
502 const std::string& function_name,
503 const WebUIBrowserTest::ConstValueVector& test_func_args) {
504 ConstValueVector arguments;
505 base::FundamentalValue* is_async_arg = new base::FundamentalValue(is_async);
506 arguments.push_back(is_async_arg);
507 base::StringValue* function_name_arg = new base::StringValue(function_name);
508 arguments.push_back(function_name_arg);
509 base::ListValue* baked_argument_list = new base::ListValue();
510 ConstValueVector::const_iterator arguments_iterator;
511 for (arguments_iterator = test_func_args.begin();
512 arguments_iterator != test_func_args.end();
513 ++arguments_iterator) {
514 baked_argument_list->Append((*arguments_iterator)->DeepCopy());
515 }
516 arguments.push_back(baked_argument_list);
517 return content::WebUI::GetJavascriptCall(std::string("runTest"),
518 arguments.get());
519 }
520
521 bool WebUIBrowserTest::RunJavascriptUsingHandler(
522 const std::string& function_name,
523 const ConstValueVector& function_arguments,
524 bool is_test,
525 bool is_async,
526 RenderViewHost* preload_host) {
527 // Get the user libraries. Preloading them individually is best, then
528 // we can assign each one a filename for better stack traces. Otherwise
529 // append them all to |content|.
530 base::string16 content;
531 std::vector<base::string16> libraries;
532 if (!libraries_preloaded_) {
533 BuildJavascriptLibraries(&libraries);
534 if (!preload_host) {
535 content = JoinString(libraries, '\n');
536 libraries.clear();
537 }
538 }
539
540 if (!function_name.empty()) {
541 base::string16 called_function;
542 if (is_test) {
543 called_function =
544 BuildRunTestJSCall(is_async, function_name, function_arguments);
545 } else {
546 called_function =
547 content::WebUI::GetJavascriptCall(function_name,
548 function_arguments.get());
549 }
550 content.append(called_function);
551 }
552
553 if (!preload_host)
554 SetupHandlers();
555
556 bool result = true;
557
558 for (size_t i = 0; i < libraries.size(); ++i)
559 test_handler_->PreloadJavaScript(libraries[i], preload_host);
560
561 if (is_test)
562 result = test_handler_->RunJavaScriptTestWithResult(content);
563 else if (preload_host)
564 test_handler_->PreloadJavaScript(content, preload_host);
565 else
566 test_handler_->RunJavaScript(content);
567
568 if (error_messages_.Get().size() > 0) {
569 LOG(ERROR) << "Encountered javascript console error(s)";
570 result = false;
571 error_messages_.Get().clear();
572 }
573 return result;
574 }
575
576 void WebUIBrowserTest::SetupHandlers() {
577 content::WebUI* web_ui_instance = override_selected_web_ui_ ?
578 override_selected_web_ui_ :
579 browser()->tab_strip_model()->GetActiveWebContents()->GetWebUI();
580 ASSERT_TRUE(web_ui_instance != NULL);
581
582 test_handler_->set_web_ui(web_ui_instance);
583 test_handler_->RegisterMessages();
584
585 if (GetMockMessageHandler()) {
586 GetMockMessageHandler()->set_web_ui(web_ui_instance);
587 GetMockMessageHandler()->RegisterMessages();
588 }
589 }
590
591 // According to the interface for EXPECT_FATAL_FAILURE
592 // (http://code.google.com/p/googletest/wiki/AdvancedGuide#Catching_Failures)
593 // the statement must be statically available. Therefore, we make a static
594 // global s_test_ which should point to |this| for the duration of the test run
595 // and be cleared afterward.
596 class WebUIBrowserExpectFailTest : public WebUIBrowserTest {
597 public:
598 WebUIBrowserExpectFailTest() {
599 EXPECT_FALSE(s_test_);
600 s_test_ = this;
601 }
602
603 protected:
604 virtual ~WebUIBrowserExpectFailTest() {
605 EXPECT_TRUE(s_test_);
606 s_test_ = NULL;
607 }
608
609 static void RunJavascriptTestNoReturn(const std::string& testname) {
610 EXPECT_TRUE(s_test_);
611 s_test_->RunJavascriptTest(testname);
612 }
613
614 static void RunJavascriptAsyncTestNoReturn(const std::string& testname) {
615 EXPECT_TRUE(s_test_);
616 s_test_->RunJavascriptAsyncTest(testname);
617 }
618
619 private:
620 static WebUIBrowserTest* s_test_;
621 };
622
623 WebUIBrowserTest* WebUIBrowserExpectFailTest::s_test_ = NULL;
624
625 // Test that bogus javascript fails fast - no timeout waiting for result.
626 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsFast) {
627 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
628 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
629 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("DISABLED_BogusFunctionName"),
630 "WebUITestHandler::JavaScriptComplete");
631 }
632
633 // Test that bogus javascript fails fast - no timeout waiting for result.
634 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestRuntimeErrorFailsFast) {
635 AddLibrary(base::FilePath(FILE_PATH_LITERAL("runtime_error.js")));
636 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL));
637 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("TestRuntimeErrorFailsFast"),
638 "WebUITestHandler::JavaScriptComplete");
639 }
640
641 // Test that bogus javascript fails async test fast as well - no timeout waiting
642 // for result.
643 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsAsyncFast) {
644 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
645 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
646 EXPECT_FATAL_FAILURE(
647 RunJavascriptAsyncTestNoReturn("DISABLED_BogusFunctionName"),
648 "WebUITestHandler::JavaScriptComplete");
649 }
650
651 // Tests that the async framework works.
652 class WebUIBrowserAsyncTest : public WebUIBrowserTest {
653 public:
654 // Calls the testDone() function from test_api.js
655 void TestDone() {
656 RunJavascriptFunction("testDone");
657 }
658
659 // Starts a failing test.
660 void RunTestFailsAssert() {
661 RunJavascriptFunction("runAsync", new base::StringValue("testFailsAssert"));
662 }
663
664 // Starts a passing test.
665 void RunTestPasses() {
666 RunJavascriptFunction("runAsync", new base::StringValue("testPasses"));
667 }
668
669 protected:
670 WebUIBrowserAsyncTest() {}
671
672 // Class to synchronize asynchronous javascript activity with the tests.
673 class AsyncWebUIMessageHandler : public WebUIMessageHandler {
674 public:
675 AsyncWebUIMessageHandler() {}
676
677 MOCK_METHOD1(HandleTestContinues, void(const base::ListValue*));
678 MOCK_METHOD1(HandleTestFails, void(const base::ListValue*));
679 MOCK_METHOD1(HandleTestPasses, void(const base::ListValue*));
680
681 private:
682 virtual void RegisterMessages() OVERRIDE {
683 web_ui()->RegisterMessageCallback("startAsyncTest",
684 base::Bind(&AsyncWebUIMessageHandler::HandleStartAsyncTest,
685 base::Unretained(this)));
686 web_ui()->RegisterMessageCallback("testContinues",
687 base::Bind(&AsyncWebUIMessageHandler::HandleTestContinues,
688 base::Unretained(this)));
689 web_ui()->RegisterMessageCallback("testFails",
690 base::Bind(&AsyncWebUIMessageHandler::HandleTestFails,
691 base::Unretained(this)));
692 web_ui()->RegisterMessageCallback("testPasses",
693 base::Bind(&AsyncWebUIMessageHandler::HandleTestPasses,
694 base::Unretained(this)));
695 }
696
697 // Starts the test in |list_value|[0] with the runAsync wrapper.
698 void HandleStartAsyncTest(const base::ListValue* list_value) {
699 const base::Value* test_name;
700 ASSERT_TRUE(list_value->Get(0, &test_name));
701 web_ui()->CallJavascriptFunction("runAsync", *test_name);
702 }
703
704 DISALLOW_COPY_AND_ASSIGN(AsyncWebUIMessageHandler);
705 };
706
707 // Handler for this object.
708 ::testing::StrictMock<AsyncWebUIMessageHandler> message_handler_;
709
710 private:
711 // Provide this object's handler.
712 virtual WebUIMessageHandler* GetMockMessageHandler() OVERRIDE {
713 return &message_handler_;
714 }
715
716 // Set up and browse to kDummyURL for all tests.
717 virtual void SetUpOnMainThread() OVERRIDE {
718 WebUIBrowserTest::SetUpOnMainThread();
719 AddLibrary(base::FilePath(FILE_PATH_LITERAL("async.js")));
720 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL));
721 }
722
723 DISALLOW_COPY_AND_ASSIGN(WebUIBrowserAsyncTest);
724 };
725
726 // Test that assertions fail immediately after assertion fails (no testContinues
727 // message). (Sync version).
728 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestSyncOkTestFail) {
729 ASSERT_FALSE(RunJavascriptTest("testFailsAssert"));
730 }
731
732 // Test that assertions fail immediately after assertion fails (no testContinues
733 // message). (Async version).
734 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsAssert) {
735 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
736 ASSERT_FALSE(RunJavascriptAsyncTest(
737 "startAsyncTest", new base::StringValue("testFailsAssert")));
738 }
739
740 // Test that expectations continue the function, but fail the test.
741 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsExpect) {
742 ::testing::InSequence s;
743 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
744 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
745 ASSERT_FALSE(RunJavascriptAsyncTest(
746 "startAsyncTest", new base::StringValue("testFailsExpect")));
747 }
748
749 // Test that test continues and passes. (Sync version).
750 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestSyncPasses) {
751 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
752 ASSERT_TRUE(RunJavascriptTest("testPasses"));
753 }
754
755 // Test that test continues and passes. (Async version).
756 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPasses) {
757 ::testing::InSequence s;
758 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
759 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
760 .WillOnce(::testing::InvokeWithoutArgs(
761 this, &WebUIBrowserAsyncTest::TestDone));
762 ASSERT_TRUE(RunJavascriptAsyncTest(
763 "startAsyncTest", new base::StringValue("testPasses")));
764 }
765
766 // Test that two tests pass.
767 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPassPass) {
768 ::testing::InSequence s;
769 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
770 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
771 .WillOnce(::testing::InvokeWithoutArgs(
772 this, &WebUIBrowserAsyncTest::RunTestPasses));
773 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
774 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
775 .WillOnce(::testing::InvokeWithoutArgs(
776 this, &WebUIBrowserAsyncTest::TestDone));
777 ASSERT_TRUE(RunJavascriptAsyncTest(
778 "startAsyncTest", new base::StringValue("testPasses")));
779 }
780
781 // Test that first test passes; second fails.
782 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPassThenFail) {
783 ::testing::InSequence s;
784 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
785 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
786 .WillOnce(::testing::InvokeWithoutArgs(
787 this, &WebUIBrowserAsyncTest::RunTestFailsAssert));
788 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
789 ASSERT_FALSE(RunJavascriptAsyncTest(
790 "startAsyncTest", new base::StringValue("testPasses")));
791 }
792
793 // Test that testDone() with failure first then sync pass still fails.
794 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncDoneFailFirstSyncPass) {
795 ::testing::InSequence s;
796 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
797 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
798
799 // Call runAsync directly instead of deferring through startAsyncTest. It will
800 // call testDone() on failure, then return.
801 ASSERT_FALSE(RunJavascriptAsyncTest(
802 "runAsync", new base::StringValue("testAsyncDoneFailFirstSyncPass")));
803 }
804
805 // Test that calling testDone during RunJavascriptAsyncTest still completes
806 // when waiting for async result. This is similar to the previous test, but call
807 // testDone directly and expect pass result.
808 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestTestDoneEarlyPassesAsync) {
809 ASSERT_TRUE(RunJavascriptAsyncTest("testDone"));
810 }
811
812 // Test that calling testDone during RunJavascriptTest still completes when
813 // waiting for async result.
814 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestTestDoneEarlyPasses) {
815 ASSERT_TRUE(RunJavascriptTest("testDone"));
816 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698