1 // Copyright 2014 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.
8 #include "base/bind_helpers.h"
9 #include "base/values.h"
10 #include "chrome/common/url_constants.h"
11 #include "chrome/test/base/ui_test_utils.h"
12 #include "chrome/test/base/web_ui_browser_test.h"
13 #include "content/public/browser/web_ui.h"
14 #include "content/public/browser/web_ui_message_handler.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest-spi.h"
18 using content::WebUIMessageHandler
;
20 // According to the interface for EXPECT_FATAL_FAILURE
21 // (http://code.google.com/p/googletest/wiki/AdvancedGuide#Catching_Failures)
22 // the statement must be statically available. Therefore, we make a static
23 // global s_test_ which should point to |this| for the duration of the test run
24 // and be cleared afterward.
25 class WebUIBrowserExpectFailTest
: public WebUIBrowserTest
{
27 WebUIBrowserExpectFailTest() {
28 EXPECT_FALSE(s_test_
);
33 ~WebUIBrowserExpectFailTest() override
{
38 static void RunJavascriptTestNoReturn(const std::string
& testname
) {
40 s_test_
->RunJavascriptTest(testname
);
43 static void RunJavascriptAsyncTestNoReturn(const std::string
& testname
) {
45 s_test_
->RunJavascriptAsyncTest(testname
);
49 static WebUIBrowserTest
* s_test_
;
52 WebUIBrowserTest
* WebUIBrowserExpectFailTest::s_test_
= NULL
;
54 // Test that bogus javascript fails fast - no timeout waiting for result.
55 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest
, TestFailsFast
) {
56 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
57 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL
));
58 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("DISABLED_BogusFunctionName"),
59 "WebUITestHandler::JavaScriptComplete");
62 // Test that bogus javascript fails fast - no timeout waiting for result.
63 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest
, TestRuntimeErrorFailsFast
) {
64 AddLibrary(base::FilePath(FILE_PATH_LITERAL("runtime_error.js")));
65 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL
));
66 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("TestRuntimeErrorFailsFast"),
67 "WebUITestHandler::JavaScriptComplete");
70 // Test that bogus javascript fails async test fast as well - no timeout waiting
72 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest
, TestFailsAsyncFast
) {
73 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
74 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL
));
76 RunJavascriptAsyncTestNoReturn("DISABLED_BogusFunctionName"),
77 "WebUITestHandler::JavaScriptComplete");
80 // Tests that the async framework works.
81 class WebUIBrowserAsyncTest
: public WebUIBrowserTest
{
83 // Calls the testDone() function from test_api.js
85 RunJavascriptFunction("testDone");
88 // Starts a failing test.
89 void RunTestFailsAssert() {
90 RunJavascriptFunction("runAsync", new base::StringValue("testFailsAssert"));
93 // Starts a passing test.
94 void RunTestPasses() {
95 RunJavascriptFunction("runAsync", new base::StringValue("testPasses"));
99 WebUIBrowserAsyncTest() {}
101 // Class to synchronize asynchronous javascript activity with the tests.
102 class AsyncWebUIMessageHandler
: public WebUIMessageHandler
{
104 AsyncWebUIMessageHandler() {}
106 MOCK_METHOD1(HandleTestContinues
, void(const base::ListValue
*));
107 MOCK_METHOD1(HandleTestFails
, void(const base::ListValue
*));
108 MOCK_METHOD1(HandleTestPasses
, void(const base::ListValue
*));
111 void RegisterMessages() override
{
112 web_ui()->RegisterMessageCallback("startAsyncTest",
113 base::Bind(&AsyncWebUIMessageHandler::HandleStartAsyncTest
,
114 base::Unretained(this)));
115 web_ui()->RegisterMessageCallback("testContinues",
116 base::Bind(&AsyncWebUIMessageHandler::HandleTestContinues
,
117 base::Unretained(this)));
118 web_ui()->RegisterMessageCallback("testFails",
119 base::Bind(&AsyncWebUIMessageHandler::HandleTestFails
,
120 base::Unretained(this)));
121 web_ui()->RegisterMessageCallback("testPasses",
122 base::Bind(&AsyncWebUIMessageHandler::HandleTestPasses
,
123 base::Unretained(this)));
126 // Starts the test in |list_value|[0] with the runAsync wrapper.
127 void HandleStartAsyncTest(const base::ListValue
* list_value
) {
128 const base::Value
* test_name
;
129 ASSERT_TRUE(list_value
->Get(0, &test_name
));
130 web_ui()->CallJavascriptFunction("runAsync", *test_name
);
133 DISALLOW_COPY_AND_ASSIGN(AsyncWebUIMessageHandler
);
136 // Handler for this object.
137 ::testing::StrictMock
<AsyncWebUIMessageHandler
> message_handler_
;
140 // Provide this object's handler.
141 WebUIMessageHandler
* GetMockMessageHandler() override
{
142 return &message_handler_
;
145 // Set up and browse to kDummyURL for all tests.
146 void SetUpOnMainThread() override
{
147 WebUIBrowserTest::SetUpOnMainThread();
148 AddLibrary(base::FilePath(FILE_PATH_LITERAL("async.js")));
149 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL
));
152 DISALLOW_COPY_AND_ASSIGN(WebUIBrowserAsyncTest
);
155 // Test that assertions fail immediately after assertion fails (no testContinues
156 // message). (Sync version).
157 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestSyncOkTestFail
) {
158 ASSERT_FALSE(RunJavascriptTest("testFailsAssert"));
161 // Test that assertions fail immediately after assertion fails (no testContinues
162 // message). (Async version).
163 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncFailsAssert
) {
164 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
165 ASSERT_FALSE(RunJavascriptAsyncTest(
166 "startAsyncTest", new base::StringValue("testFailsAssert")));
169 // Test that expectations continue the function, but fail the test.
170 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncFailsExpect
) {
171 ::testing::InSequence s
;
172 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
173 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
174 ASSERT_FALSE(RunJavascriptAsyncTest(
175 "startAsyncTest", new base::StringValue("testFailsExpect")));
178 // Test that test continues and passes. (Sync version).
179 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestSyncPasses
) {
180 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
181 ASSERT_TRUE(RunJavascriptTest("testPasses"));
184 // Test that test continues and passes. (Async version).
185 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncPasses
) {
186 ::testing::InSequence s
;
187 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
188 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
189 .WillOnce(::testing::InvokeWithoutArgs(
190 this, &WebUIBrowserAsyncTest::TestDone
));
191 ASSERT_TRUE(RunJavascriptAsyncTest(
192 "startAsyncTest", new base::StringValue("testPasses")));
195 // Test that two tests pass.
196 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncPassPass
) {
197 ::testing::InSequence s
;
198 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
199 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
200 .WillOnce(::testing::InvokeWithoutArgs(
201 this, &WebUIBrowserAsyncTest::RunTestPasses
));
202 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
203 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
204 .WillOnce(::testing::InvokeWithoutArgs(
205 this, &WebUIBrowserAsyncTest::TestDone
));
206 ASSERT_TRUE(RunJavascriptAsyncTest(
207 "startAsyncTest", new base::StringValue("testPasses")));
210 // Test that first test passes; second fails.
211 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncPassThenFail
) {
212 ::testing::InSequence s
;
213 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
214 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
215 .WillOnce(::testing::InvokeWithoutArgs(
216 this, &WebUIBrowserAsyncTest::RunTestFailsAssert
));
217 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
218 ASSERT_FALSE(RunJavascriptAsyncTest(
219 "startAsyncTest", new base::StringValue("testPasses")));
222 // Test that testDone() with failure first then sync pass still fails.
223 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncDoneFailFirstSyncPass
) {
224 ::testing::InSequence s
;
225 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
226 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
228 // Call runAsync directly instead of deferring through startAsyncTest. It will
229 // call testDone() on failure, then return.
230 ASSERT_FALSE(RunJavascriptAsyncTest(
231 "runAsync", new base::StringValue("testAsyncDoneFailFirstSyncPass")));
234 // Test that calling testDone during RunJavascriptAsyncTest still completes
235 // when waiting for async result. This is similar to the previous test, but call
236 // testDone directly and expect pass result.
237 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestTestDoneEarlyPassesAsync
) {
238 ASSERT_TRUE(RunJavascriptAsyncTest("testDone"));
241 // Test that calling testDone during RunJavascriptTest still completes when
242 // waiting for async result.
243 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestTestDoneEarlyPasses
) {
244 ASSERT_TRUE(RunJavascriptTest("testDone"));