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"
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"
51 using content::NavigationController
;
52 using content::RenderViewHost
;
53 using content::WebContents
;
54 using content::WebUIController
;
55 using content::WebUIMessageHandler
;
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
,
74 const std::string
& str
) {
75 if (severity
== logging::LOG_ERROR
&&
77 std::string("CONSOLE") == file
) {
78 error_messages_
.Get().push_back(str
);
84 class WebUIJsInjectionReadyObserver
: public content::WebContentsObserver
{
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
);
101 WebUIBrowserTest
* browser_test_
;
102 std::string preload_test_fixture_
;
103 std::string preload_test_name_
;
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.
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
,
132 ConstValueVector args
;
134 return RunJavascriptFunction(function_name
, args
);
137 bool WebUIBrowserTest::RunJavascriptFunction(const std::string
& function_name
,
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
));
161 return RunJavascriptAsyncTest("RUN_TEST_F", args
);
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
,
173 ConstValueVector args
;
175 return RunJavascriptTest(test_name
, args
);
178 bool WebUIBrowserTest::RunJavascriptTest(const std::string
& test_name
,
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
,
201 ConstValueVector args
;
203 return RunJavascriptAsyncTest(test_name
, args
);
206 bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string
& test_name
,
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
,
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(¶ms
);
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
{
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
) {}
274 message_loop_runner_
->Run();
275 content::WaitForLoadStop(preview_dialog_
);
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();
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_
;
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());
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());
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
;
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
349 class MockWebUIDataSource
: public content::URLDataSource
{
351 MockWebUIDataSource() {}
354 virtual ~MockWebUIDataSource() {}
356 virtual std::string
GetSource() const OVERRIDE
{
360 virtual void StartDataRequest(
361 const std::string
& path
,
362 int render_process_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
{
375 DISALLOW_COPY_AND_ASSIGN(MockWebUIDataSource
);
378 // WebUIProvider to allow attaching the DataSource for the dummy URL when
380 class MockWebUIProvider
381 : public TestChromeWebUIControllerFactory::WebUIProvider
{
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());
395 DISALLOW_COPY_AND_ASSIGN(MockWebUIProvider
);
398 base::LazyInstance
<MockWebUIProvider
> mock_provider_
=
399 LAZY_INSTANCE_INITIALIZER
;
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() {
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
,
475 << user_libraries_iterator
->value();
477 bool ok
= base::ReadFileToString(
478 gen_test_data_directory_
.Append(*user_libraries_iterator
),
481 ok
= base::ReadFileToString(
482 test_data_directory_
.Append(*user_libraries_iterator
),
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(
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"),
514 bool WebUIBrowserTest::RunJavascriptUsingHandler(
515 const std::string
& function_name
,
516 const ConstValueVector
& function_arguments
,
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
;
529 BuildRunTestJSCall(is_async
, function_name
, function_arguments
);
532 content::WebUI::GetJavascriptCall(function_name
,
533 function_arguments
.get());
535 content
.append(called_function
);
544 result
= test_handler_
->RunJavaScriptTestWithResult(content
);
545 else if (preload_host
)
546 test_handler_
->PreloadJavaScript(content
, preload_host
);
548 test_handler_
->RunJavaScript(content
);
550 if (error_messages_
.Get().size() > 0) {
551 LOG(ERROR
) << "Encountered javascript console error(s)";
553 error_messages_
.Get().clear();
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
{
580 WebUIBrowserExpectFailTest() {
581 EXPECT_FALSE(s_test_
);
586 virtual ~WebUIBrowserExpectFailTest() {
587 EXPECT_TRUE(s_test_
);
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
);
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
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
{
636 // Calls the testDone() function from test_api.js
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"));
652 WebUIBrowserAsyncTest() {}
654 // Class to synchronize asynchronous javascript activity with the tests.
655 class AsyncWebUIMessageHandler
: public WebUIMessageHandler
{
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
*));
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_
;
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"));