Move render_view_context_menu.* and related files out of tab_contents.
[chromium-blink-merge.git] / chrome / test / base / web_ui_browsertest.cc
blob81f54c65450f9b22b9d9cbc972722423fd8ecb9e
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.
5 #include "chrome/test/base/web_ui_browsertest.h"
7 #include <string>
8 #include <vector>
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/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "chrome/browser/chrome_content_browser_client.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_commands.h"
21 #include "chrome/browser/ui/browser_navigator.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
24 #include "chrome/browser/ui/webui/web_ui_test_handler.h"
25 #include "chrome/common/chrome_paths.h"
26 #include "chrome/common/url_constants.h"
27 #include "chrome/test/base/test_chrome_web_ui_controller_factory.h"
28 #include "chrome/test/base/ui_test_utils.h"
29 #include "content/public/browser/navigation_controller.h"
30 #include "content/public/browser/notification_observer.h"
31 #include "content/public/browser/notification_registrar.h"
32 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/notification_types.h"
34 #include "content/public/browser/url_data_source.h"
35 #include "content/public/browser/web_contents.h"
36 #include "content/public/browser/web_contents_observer.h"
37 #include "content/public/browser/web_ui_controller.h"
38 #include "content/public/browser/web_ui_message_handler.h"
39 #include "content/public/test/browser_test_utils.h"
40 #include "content/public/test/test_navigation_observer.h"
41 #include "net/base/net_util.h"
42 #include "testing/gmock/include/gmock/gmock.h"
43 #include "testing/gtest/include/gtest/gtest-spi.h"
44 #include "ui/base/resource/resource_bundle.h"
45 #include "ui/base/resource/resource_handle.h"
47 #if defined(ENABLE_FULL_PRINTING)
48 #include "chrome/browser/printing/print_preview_dialog_controller.h"
49 #endif
51 using content::NavigationController;
52 using content::RenderViewHost;
53 using content::WebContents;
54 using content::WebUIController;
55 using content::WebUIMessageHandler;
57 namespace {
59 const base::FilePath::CharType kA11yAuditLibraryJSPath[] = FILE_PATH_LITERAL(
60 "third_party/accessibility-audit/axs_testing.js");
61 const base::FilePath::CharType kMockJSPath[] =
62 FILE_PATH_LITERAL("chrome/third_party/mock4js/mock4js.js");
63 const base::FilePath::CharType kWebUILibraryJS[] =
64 FILE_PATH_LITERAL("test_api.js");
65 const base::FilePath::CharType kWebUITestFolder[] = FILE_PATH_LITERAL("webui");
66 base::LazyInstance<std::vector<std::string> > error_messages_ =
67 LAZY_INSTANCE_INITIALIZER;
69 // Intercepts all log messages.
70 bool LogHandler(int severity,
71 const char* file,
72 int line,
73 size_t message_start,
74 const std::string& str) {
75 if (severity == logging::LOG_ERROR &&
76 file &&
77 std::string("CONSOLE") == file) {
78 error_messages_.Get().push_back(str);
81 return false;
84 class WebUIJsInjectionReadyObserver : public content::WebContentsObserver {
85 public:
86 WebUIJsInjectionReadyObserver(content::WebContents* web_contents,
87 WebUIBrowserTest* browser_test,
88 const std::string& preload_test_fixture,
89 const std::string& preload_test_name)
90 : content::WebContentsObserver(web_contents),
91 browser_test_(browser_test),
92 preload_test_fixture_(preload_test_fixture),
93 preload_test_name_(preload_test_name) {}
95 virtual void RenderViewCreated(content::RenderViewHost* rvh) OVERRIDE {
96 browser_test_->PreLoadJavascriptLibraries(
97 preload_test_fixture_, preload_test_name_, rvh);
100 private:
101 WebUIBrowserTest* browser_test_;
102 std::string preload_test_fixture_;
103 std::string preload_test_name_;
106 } // namespace
108 WebUIBrowserTest::~WebUIBrowserTest() {}
110 void WebUIBrowserTest::AddLibrary(const base::FilePath& library_path) {
111 user_libraries_.push_back(library_path);
114 // Add a helper JS library to the given WebUIBrowserTest from a path relative to
115 // base::DIR_SOURCE_ROOT.
116 // static
117 void AddLibraryFromSourceRoot(WebUIBrowserTest* browser_test,
118 const base::FilePath& path) {
119 base::FilePath filePath;
120 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &filePath));
121 filePath = filePath.Append(path);
122 browser_test->AddLibrary(filePath);
125 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name) {
126 ConstValueVector empty_args;
127 return RunJavascriptFunction(function_name, empty_args);
130 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name,
131 base::Value* arg) {
132 ConstValueVector args;
133 args.push_back(arg);
134 return RunJavascriptFunction(function_name, args);
137 bool WebUIBrowserTest::RunJavascriptFunction(const std::string& function_name,
138 base::Value* arg1,
139 base::Value* arg2) {
140 ConstValueVector args;
141 args.push_back(arg1);
142 args.push_back(arg2);
143 return RunJavascriptFunction(function_name, args);
146 bool WebUIBrowserTest::RunJavascriptFunction(
147 const std::string& function_name,
148 const ConstValueVector& function_arguments) {
149 return RunJavascriptUsingHandler(
150 function_name, function_arguments, false, false, NULL);
153 bool WebUIBrowserTest::RunJavascriptTestF(bool is_async,
154 const std::string& test_fixture,
155 const std::string& test_name) {
156 ConstValueVector args;
157 args.push_back(new base::StringValue(test_fixture));
158 args.push_back(new base::StringValue(test_name));
160 if (is_async)
161 return RunJavascriptAsyncTest("RUN_TEST_F", args);
162 else
163 return RunJavascriptTest("RUN_TEST_F", args);
166 bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name) {
167 ConstValueVector empty_args;
168 return RunJavascriptTest(test_name, empty_args);
171 bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name,
172 base::Value* arg) {
173 ConstValueVector args;
174 args.push_back(arg);
175 return RunJavascriptTest(test_name, args);
178 bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name,
179 base::Value* arg1,
180 base::Value* arg2) {
181 ConstValueVector args;
182 args.push_back(arg1);
183 args.push_back(arg2);
184 return RunJavascriptTest(test_name, args);
187 bool WebUIBrowserTest::RunJavascriptTest(
188 const std::string& test_name,
189 const ConstValueVector& test_arguments) {
190 return RunJavascriptUsingHandler(
191 test_name, test_arguments, true, false, NULL);
194 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name) {
195 ConstValueVector empty_args;
196 return RunJavascriptAsyncTest(test_name, empty_args);
199 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name,
200 base::Value* arg) {
201 ConstValueVector args;
202 args.push_back(arg);
203 return RunJavascriptAsyncTest(test_name, args);
206 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name,
207 base::Value* arg1,
208 base::Value* arg2) {
209 ConstValueVector args;
210 args.push_back(arg1);
211 args.push_back(arg2);
212 return RunJavascriptAsyncTest(test_name, args);
215 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name,
216 base::Value* arg1,
217 base::Value* arg2,
218 base::Value* arg3) {
219 ConstValueVector args;
220 args.push_back(arg1);
221 args.push_back(arg2);
222 args.push_back(arg3);
223 return RunJavascriptAsyncTest(test_name, args);
226 bool WebUIBrowserTest::RunJavascriptAsyncTest(
227 const std::string& test_name,
228 const ConstValueVector& test_arguments) {
229 return RunJavascriptUsingHandler(test_name, test_arguments, true, true, NULL);
232 void WebUIBrowserTest::PreLoadJavascriptLibraries(
233 const std::string& preload_test_fixture,
234 const std::string& preload_test_name,
235 RenderViewHost* preload_host) {
236 ASSERT_FALSE(libraries_preloaded_);
237 ConstValueVector args;
238 args.push_back(new base::StringValue(preload_test_fixture));
239 args.push_back(new base::StringValue(preload_test_name));
240 RunJavascriptUsingHandler(
241 "preloadJavascriptLibraries", args, false, false, preload_host);
242 libraries_preloaded_ = true;
245 void WebUIBrowserTest::BrowsePreload(const GURL& browse_to) {
246 content::WebContents* web_contents =
247 browser()->tab_strip_model()->GetActiveWebContents();
248 WebUIJsInjectionReadyObserver injection_observer(
249 web_contents, this, preload_test_fixture_, preload_test_name_);
250 content::TestNavigationObserver navigation_observer(web_contents);
251 chrome::NavigateParams params(browser(), GURL(browse_to),
252 content::PAGE_TRANSITION_TYPED);
253 params.disposition = CURRENT_TAB;
254 chrome::Navigate(&params);
255 navigation_observer.Wait();
258 #if defined(ENABLE_FULL_PRINTING)
260 // This custom ContentBrowserClient is used to get notified when a WebContents
261 // for the print preview dialog gets created.
262 class PrintContentBrowserClient : public chrome::ChromeContentBrowserClient {
263 public:
264 PrintContentBrowserClient(WebUIBrowserTest* browser_test,
265 const std::string& preload_test_fixture,
266 const std::string& preload_test_name)
267 : browser_test_(browser_test),
268 preload_test_fixture_(preload_test_fixture),
269 preload_test_name_(preload_test_name),
270 preview_dialog_(NULL),
271 message_loop_runner_(new content::MessageLoopRunner) {}
273 void Wait() {
274 message_loop_runner_->Run();
275 content::WaitForLoadStop(preview_dialog_);
278 private:
279 // ChromeContentBrowserClient implementation:
280 virtual content::WebContentsViewPort* OverrideCreateWebContentsView(
281 content::WebContents* web_contents,
282 content::RenderViewHostDelegateView** view) OVERRIDE {
283 preview_dialog_ = web_contents;
284 observer_.reset(new WebUIJsInjectionReadyObserver(
285 preview_dialog_, browser_test_, preload_test_fixture_,
286 preload_test_name_));
287 message_loop_runner_->Quit();
288 return NULL;
291 WebUIBrowserTest* browser_test_;
292 scoped_ptr<WebUIJsInjectionReadyObserver> observer_;
293 std::string preload_test_fixture_;
294 std::string preload_test_name_;
295 content::WebContents* preview_dialog_;
296 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
298 #endif
300 void WebUIBrowserTest::BrowsePrintPreload(const GURL& browse_to) {
301 #if defined(ENABLE_FULL_PRINTING)
302 ui_test_utils::NavigateToURL(browser(), browse_to);
304 PrintContentBrowserClient new_client(
305 this, preload_test_fixture_, preload_test_name_);
306 content::ContentBrowserClient* old_client =
307 SetBrowserClientForTesting(&new_client);
309 chrome::Print(browser());
310 new_client.Wait();
312 SetBrowserClientForTesting(old_client);
314 printing::PrintPreviewDialogController* tab_controller =
315 printing::PrintPreviewDialogController::GetInstance();
316 ASSERT_TRUE(tab_controller);
317 WebContents* preview_dialog = tab_controller->GetPrintPreviewForContents(
318 browser()->tab_strip_model()->GetActiveWebContents());
319 ASSERT_TRUE(preview_dialog);
320 SetWebUIInstance(preview_dialog->GetWebUI());
321 #else
322 NOTREACHED();
323 #endif
326 const char WebUIBrowserTest::kDummyURL[] = "chrome://DummyURL";
328 WebUIBrowserTest::WebUIBrowserTest()
329 : test_handler_(new WebUITestHandler()),
330 libraries_preloaded_(false),
331 override_selected_web_ui_(NULL) {}
333 void WebUIBrowserTest::set_preload_test_fixture(
334 const std::string& preload_test_fixture) {
335 preload_test_fixture_ = preload_test_fixture;
338 void WebUIBrowserTest::set_preload_test_name(
339 const std::string& preload_test_name) {
340 preload_test_name_ = preload_test_name;
343 namespace {
345 // DataSource for the dummy URL. If no data source is provided then an error
346 // page is shown. While this doesn't matter for most tests, without it,
347 // navigation to different anchors cannot be listened to (via the hashchange
348 // event).
349 class MockWebUIDataSource : public content::URLDataSource {
350 public:
351 MockWebUIDataSource() {}
353 private:
354 virtual ~MockWebUIDataSource() {}
356 virtual std::string GetSource() const OVERRIDE {
357 return "dummyurl";
360 virtual void StartDataRequest(
361 const std::string& path,
362 int render_process_id,
363 int render_frame_id,
364 const content::URLDataSource::GotDataCallback& callback) OVERRIDE {
365 std::string dummy_html = "<html><body>Dummy</body></html>";
366 scoped_refptr<base::RefCountedString> response =
367 base::RefCountedString::TakeString(&dummy_html);
368 callback.Run(response.get());
371 virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
372 return "text/html";
375 DISALLOW_COPY_AND_ASSIGN(MockWebUIDataSource);
378 // WebUIProvider to allow attaching the DataSource for the dummy URL when
379 // testing.
380 class MockWebUIProvider
381 : public TestChromeWebUIControllerFactory::WebUIProvider {
382 public:
383 MockWebUIProvider() {}
385 // Returns a new WebUI
386 virtual WebUIController* NewWebUI(content::WebUI* web_ui,
387 const GURL& url) OVERRIDE {
388 WebUIController* controller = new content::WebUIController(web_ui);
389 Profile* profile = Profile::FromWebUI(web_ui);
390 content::URLDataSource::Add(profile, new MockWebUIDataSource());
391 return controller;
394 private:
395 DISALLOW_COPY_AND_ASSIGN(MockWebUIProvider);
398 base::LazyInstance<MockWebUIProvider> mock_provider_ =
399 LAZY_INSTANCE_INITIALIZER;
401 } // namespace
403 void WebUIBrowserTest::SetUpOnMainThread() {
404 logging::SetLogMessageHandler(&LogHandler);
406 content::WebUIControllerFactory::UnregisterFactoryForTesting(
407 ChromeWebUIControllerFactory::GetInstance());
409 test_factory_.reset(new TestChromeWebUIControllerFactory);
411 content::WebUIControllerFactory::RegisterFactory(test_factory_.get());
413 test_factory_->AddFactoryOverride(
414 GURL(kDummyURL).host(), mock_provider_.Pointer());
416 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_));
417 test_data_directory_ = test_data_directory_.Append(kWebUITestFolder);
418 ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA,
419 &gen_test_data_directory_));
421 // TODO(dtseng): should this be part of every BrowserTest or just WebUI test.
422 base::FilePath resources_pack_path;
423 PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
424 ResourceBundle::GetSharedInstance().AddDataPackFromPath(
425 resources_pack_path, ui::SCALE_FACTOR_NONE);
427 AddLibraryFromSourceRoot(this, base::FilePath(kA11yAuditLibraryJSPath));
428 AddLibraryFromSourceRoot(this, base::FilePath(kMockJSPath));
429 AddLibrary(base::FilePath(kWebUILibraryJS));
432 void WebUIBrowserTest::CleanUpOnMainThread() {
433 logging::SetLogMessageHandler(NULL);
435 test_factory_->RemoveFactoryOverride(GURL(kDummyURL).host());
436 content::WebUIControllerFactory::UnregisterFactoryForTesting(
437 test_factory_.get());
439 // This is needed to avoid a debug assert after the test completes, see stack
440 // trace in http://crrev.com/179347
441 content::WebUIControllerFactory::RegisterFactory(
442 ChromeWebUIControllerFactory::GetInstance());
444 test_factory_.reset();
447 void WebUIBrowserTest::SetWebUIInstance(content::WebUI* web_ui) {
448 override_selected_web_ui_ = web_ui;
451 WebUIMessageHandler* WebUIBrowserTest::GetMockMessageHandler() {
452 return NULL;
455 GURL WebUIBrowserTest::WebUITestDataPathToURL(
456 const base::FilePath::StringType& path) {
457 base::FilePath dir_test_data;
458 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &dir_test_data));
459 base::FilePath test_path(dir_test_data.Append(kWebUITestFolder).Append(path));
460 EXPECT_TRUE(base::PathExists(test_path));
461 return net::FilePathToFileURL(test_path);
464 void WebUIBrowserTest::BuildJavascriptLibraries(base::string16* content) {
465 ASSERT_TRUE(content != NULL);
466 std::string utf8_content;
467 std::vector<base::FilePath>::iterator user_libraries_iterator;
468 for (user_libraries_iterator = user_libraries_.begin();
469 user_libraries_iterator != user_libraries_.end();
470 ++user_libraries_iterator) {
471 std::string library_content;
472 if (user_libraries_iterator->IsAbsolute()) {
473 ASSERT_TRUE(base::ReadFileToString(*user_libraries_iterator,
474 &library_content))
475 << user_libraries_iterator->value();
476 } else {
477 bool ok = base::ReadFileToString(
478 gen_test_data_directory_.Append(*user_libraries_iterator),
479 &library_content);
480 if (!ok) {
481 ok = base::ReadFileToString(
482 test_data_directory_.Append(*user_libraries_iterator),
483 &library_content);
485 ASSERT_TRUE(ok) << user_libraries_iterator->value();
487 utf8_content.append(library_content);
488 utf8_content.append(";\n");
490 content->append(base::UTF8ToUTF16(utf8_content));
493 base::string16 WebUIBrowserTest::BuildRunTestJSCall(
494 bool is_async,
495 const std::string& function_name,
496 const WebUIBrowserTest::ConstValueVector& test_func_args) {
497 ConstValueVector arguments;
498 base::FundamentalValue* is_async_arg = new base::FundamentalValue(is_async);
499 arguments.push_back(is_async_arg);
500 base::StringValue* function_name_arg = new base::StringValue(function_name);
501 arguments.push_back(function_name_arg);
502 base::ListValue* baked_argument_list = new base::ListValue();
503 ConstValueVector::const_iterator arguments_iterator;
504 for (arguments_iterator = test_func_args.begin();
505 arguments_iterator != test_func_args.end();
506 ++arguments_iterator) {
507 baked_argument_list->Append((*arguments_iterator)->DeepCopy());
509 arguments.push_back(baked_argument_list);
510 return content::WebUI::GetJavascriptCall(std::string("runTest"),
511 arguments.get());
514 bool WebUIBrowserTest::RunJavascriptUsingHandler(
515 const std::string& function_name,
516 const ConstValueVector& function_arguments,
517 bool is_test,
518 bool is_async,
519 RenderViewHost* preload_host) {
521 base::string16 content;
522 if (!libraries_preloaded_)
523 BuildJavascriptLibraries(&content);
525 if (!function_name.empty()) {
526 base::string16 called_function;
527 if (is_test) {
528 called_function =
529 BuildRunTestJSCall(is_async, function_name, function_arguments);
530 } else {
531 called_function =
532 content::WebUI::GetJavascriptCall(function_name,
533 function_arguments.get());
535 content.append(called_function);
538 if (!preload_host)
539 SetupHandlers();
541 bool result = true;
543 if (is_test)
544 result = test_handler_->RunJavaScriptTestWithResult(content);
545 else if (preload_host)
546 test_handler_->PreloadJavaScript(content, preload_host);
547 else
548 test_handler_->RunJavaScript(content);
550 if (error_messages_.Get().size() > 0) {
551 LOG(ERROR) << "Encountered javascript console error(s)";
552 result = false;
553 error_messages_.Get().clear();
555 return result;
558 void WebUIBrowserTest::SetupHandlers() {
559 content::WebUI* web_ui_instance = override_selected_web_ui_ ?
560 override_selected_web_ui_ :
561 browser()->tab_strip_model()->GetActiveWebContents()->GetWebUI();
562 ASSERT_TRUE(web_ui_instance != NULL);
564 test_handler_->set_web_ui(web_ui_instance);
565 test_handler_->RegisterMessages();
567 if (GetMockMessageHandler()) {
568 GetMockMessageHandler()->set_web_ui(web_ui_instance);
569 GetMockMessageHandler()->RegisterMessages();
573 // According to the interface for EXPECT_FATAL_FAILURE
574 // (http://code.google.com/p/googletest/wiki/AdvancedGuide#Catching_Failures)
575 // the statement must be statically available. Therefore, we make a static
576 // global s_test_ which should point to |this| for the duration of the test run
577 // and be cleared afterward.
578 class WebUIBrowserExpectFailTest : public WebUIBrowserTest {
579 public:
580 WebUIBrowserExpectFailTest() {
581 EXPECT_FALSE(s_test_);
582 s_test_ = this;
585 protected:
586 virtual ~WebUIBrowserExpectFailTest() {
587 EXPECT_TRUE(s_test_);
588 s_test_ = NULL;
591 static void RunJavascriptTestNoReturn(const std::string& testname) {
592 EXPECT_TRUE(s_test_);
593 s_test_->RunJavascriptTest(testname);
596 static void RunJavascriptAsyncTestNoReturn(const std::string& testname) {
597 EXPECT_TRUE(s_test_);
598 s_test_->RunJavascriptAsyncTest(testname);
601 private:
602 static WebUIBrowserTest* s_test_;
605 WebUIBrowserTest* WebUIBrowserExpectFailTest::s_test_ = NULL;
607 // Test that bogus javascript fails fast - no timeout waiting for result.
608 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsFast) {
609 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
610 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
611 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("DISABLED_BogusFunctionName"),
612 "WebUITestHandler::JavaScriptComplete");
615 // Test that bogus javascript fails fast - no timeout waiting for result.
616 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestRuntimeErrorFailsFast) {
617 AddLibrary(base::FilePath(FILE_PATH_LITERAL("runtime_error.js")));
618 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL));
619 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("TestRuntimeErrorFailsFast"),
620 "WebUITestHandler::JavaScriptComplete");
623 // Test that bogus javascript fails async test fast as well - no timeout waiting
624 // for result.
625 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsAsyncFast) {
626 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
627 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
628 EXPECT_FATAL_FAILURE(
629 RunJavascriptAsyncTestNoReturn("DISABLED_BogusFunctionName"),
630 "WebUITestHandler::JavaScriptComplete");
633 // Tests that the async framework works.
634 class WebUIBrowserAsyncTest : public WebUIBrowserTest {
635 public:
636 // Calls the testDone() function from test_api.js
637 void TestDone() {
638 RunJavascriptFunction("testDone");
641 // Starts a failing test.
642 void RunTestFailsAssert() {
643 RunJavascriptFunction("runAsync", new base::StringValue("testFailsAssert"));
646 // Starts a passing test.
647 void RunTestPasses() {
648 RunJavascriptFunction("runAsync", new base::StringValue("testPasses"));
651 protected:
652 WebUIBrowserAsyncTest() {}
654 // Class to synchronize asynchronous javascript activity with the tests.
655 class AsyncWebUIMessageHandler : public WebUIMessageHandler {
656 public:
657 AsyncWebUIMessageHandler() {}
659 MOCK_METHOD1(HandleTestContinues, void(const base::ListValue*));
660 MOCK_METHOD1(HandleTestFails, void(const base::ListValue*));
661 MOCK_METHOD1(HandleTestPasses, void(const base::ListValue*));
663 private:
664 virtual void RegisterMessages() OVERRIDE {
665 web_ui()->RegisterMessageCallback("startAsyncTest",
666 base::Bind(&AsyncWebUIMessageHandler::HandleStartAsyncTest,
667 base::Unretained(this)));
668 web_ui()->RegisterMessageCallback("testContinues",
669 base::Bind(&AsyncWebUIMessageHandler::HandleTestContinues,
670 base::Unretained(this)));
671 web_ui()->RegisterMessageCallback("testFails",
672 base::Bind(&AsyncWebUIMessageHandler::HandleTestFails,
673 base::Unretained(this)));
674 web_ui()->RegisterMessageCallback("testPasses",
675 base::Bind(&AsyncWebUIMessageHandler::HandleTestPasses,
676 base::Unretained(this)));
679 // Starts the test in |list_value|[0] with the runAsync wrapper.
680 void HandleStartAsyncTest(const base::ListValue* list_value) {
681 const base::Value* test_name;
682 ASSERT_TRUE(list_value->Get(0, &test_name));
683 web_ui()->CallJavascriptFunction("runAsync", *test_name);
686 DISALLOW_COPY_AND_ASSIGN(AsyncWebUIMessageHandler);
689 // Handler for this object.
690 ::testing::StrictMock<AsyncWebUIMessageHandler> message_handler_;
692 private:
693 // Provide this object's handler.
694 virtual WebUIMessageHandler* GetMockMessageHandler() OVERRIDE {
695 return &message_handler_;
698 // Set up and browse to kDummyURL for all tests.
699 virtual void SetUpOnMainThread() OVERRIDE {
700 WebUIBrowserTest::SetUpOnMainThread();
701 AddLibrary(base::FilePath(FILE_PATH_LITERAL("async.js")));
702 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL));
705 DISALLOW_COPY_AND_ASSIGN(WebUIBrowserAsyncTest);
708 // Test that assertions fail immediately after assertion fails (no testContinues
709 // message). (Sync version).
710 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestSyncOkTestFail) {
711 ASSERT_FALSE(RunJavascriptTest("testFailsAssert"));
714 // Test that assertions fail immediately after assertion fails (no testContinues
715 // message). (Async version).
716 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsAssert) {
717 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
718 ASSERT_FALSE(RunJavascriptAsyncTest(
719 "startAsyncTest", new base::StringValue("testFailsAssert")));
722 // Test that expectations continue the function, but fail the test.
723 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsExpect) {
724 ::testing::InSequence s;
725 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
726 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
727 ASSERT_FALSE(RunJavascriptAsyncTest(
728 "startAsyncTest", new base::StringValue("testFailsExpect")));
731 // Test that test continues and passes. (Sync version).
732 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestSyncPasses) {
733 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
734 ASSERT_TRUE(RunJavascriptTest("testPasses"));
737 // Test that test continues and passes. (Async version).
738 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPasses) {
739 ::testing::InSequence s;
740 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
741 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
742 .WillOnce(::testing::InvokeWithoutArgs(
743 this, &WebUIBrowserAsyncTest::TestDone));
744 ASSERT_TRUE(RunJavascriptAsyncTest(
745 "startAsyncTest", new base::StringValue("testPasses")));
748 // Test that two tests pass.
749 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPassPass) {
750 ::testing::InSequence s;
751 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
752 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
753 .WillOnce(::testing::InvokeWithoutArgs(
754 this, &WebUIBrowserAsyncTest::RunTestPasses));
755 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
756 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
757 .WillOnce(::testing::InvokeWithoutArgs(
758 this, &WebUIBrowserAsyncTest::TestDone));
759 ASSERT_TRUE(RunJavascriptAsyncTest(
760 "startAsyncTest", new base::StringValue("testPasses")));
763 // Test that first test passes; second fails.
764 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPassThenFail) {
765 ::testing::InSequence s;
766 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
767 EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
768 .WillOnce(::testing::InvokeWithoutArgs(
769 this, &WebUIBrowserAsyncTest::RunTestFailsAssert));
770 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
771 ASSERT_FALSE(RunJavascriptAsyncTest(
772 "startAsyncTest", new base::StringValue("testPasses")));
775 // Test that testDone() with failure first then sync pass still fails.
776 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncDoneFailFirstSyncPass) {
777 ::testing::InSequence s;
778 EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
779 EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
781 // Call runAsync directly instead of deferring through startAsyncTest. It will
782 // call testDone() on failure, then return.
783 ASSERT_FALSE(RunJavascriptAsyncTest(
784 "runAsync", new base::StringValue("testAsyncDoneFailFirstSyncPass")));
787 // Test that calling testDone during RunJavascriptAsyncTest still completes
788 // when waiting for async result. This is similar to the previous test, but call
789 // testDone directly and expect pass result.
790 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestTestDoneEarlyPassesAsync) {
791 ASSERT_TRUE(RunJavascriptAsyncTest("testDone"));
794 // Test that calling testDone during RunJavascriptTest still completes when
795 // waiting for async result.
796 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestTestDoneEarlyPasses) {
797 ASSERT_TRUE(RunJavascriptTest("testDone"));