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/command_line.h"
10 #include "base/values.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/url_constants.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "chrome/test/base/web_ui_browser_test.h"
15 #include "content/public/browser/web_ui.h"
16 #include "content/public/browser/web_ui_message_handler.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest-spi.h"
20 using content::WebUIMessageHandler
;
22 // According to the interface for EXPECT_FATAL_FAILURE
23 // (http://code.google.com/p/googletest/wiki/AdvancedGuide#Catching_Failures)
24 // the statement must be statically available. Therefore, we make a static
25 // global s_test_ which should point to |this| for the duration of the test run
26 // and be cleared afterward.
27 class WebUIBrowserExpectFailTest
: public WebUIBrowserTest
{
29 WebUIBrowserExpectFailTest() {
30 EXPECT_FALSE(s_test_
);
34 // Disable new downloads UI as it is very very slow. https://crbug.com/526577
35 // TODO(dbeam): remove this once the downloads UI is not slow.
36 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
37 WebUIBrowserTest::SetUpCommandLine(command_line
);
38 command_line
->AppendSwitch(switches::kDisableMaterialDesignDownloads
);
42 ~WebUIBrowserExpectFailTest() override
{
47 static void RunJavascriptTestNoReturn(const std::string
& testname
) {
49 s_test_
->RunJavascriptTest(testname
);
52 static void RunJavascriptAsyncTestNoReturn(const std::string
& testname
) {
54 s_test_
->RunJavascriptAsyncTest(testname
);
58 static WebUIBrowserTest
* s_test_
;
61 WebUIBrowserTest
* WebUIBrowserExpectFailTest::s_test_
= NULL
;
63 // Test that bogus javascript fails fast - no timeout waiting for result.
64 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest
, TestFailsFast
) {
65 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
66 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL
));
67 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("DISABLED_BogusFunctionName"),
68 "WebUITestHandler::JavaScriptComplete");
71 // Test that bogus javascript fails fast - no timeout waiting for result.
72 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest
, TestRuntimeErrorFailsFast
) {
73 AddLibrary(base::FilePath(FILE_PATH_LITERAL("runtime_error.js")));
74 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL
));
75 EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("TestRuntimeErrorFailsFast"),
76 "WebUITestHandler::JavaScriptComplete");
79 // Test that bogus javascript fails async test fast as well - no timeout waiting
81 IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest
, TestFailsAsyncFast
) {
82 AddLibrary(base::FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
83 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL
));
85 RunJavascriptAsyncTestNoReturn("DISABLED_BogusFunctionName"),
86 "WebUITestHandler::JavaScriptComplete");
89 // Tests that the async framework works.
90 class WebUIBrowserAsyncTest
: public WebUIBrowserTest
{
92 // Calls the testDone() function from test_api.js
94 RunJavascriptFunction("testDone");
97 // Starts a failing test.
98 void RunTestFailsAssert() {
99 RunJavascriptFunction("runAsync", new base::StringValue("testFailsAssert"));
102 // Starts a passing test.
103 void RunTestPasses() {
104 RunJavascriptFunction("runAsync", new base::StringValue("testPasses"));
108 WebUIBrowserAsyncTest() {}
110 // Class to synchronize asynchronous javascript activity with the tests.
111 class AsyncWebUIMessageHandler
: public WebUIMessageHandler
{
113 AsyncWebUIMessageHandler() {}
115 MOCK_METHOD1(HandleTestContinues
, void(const base::ListValue
*));
116 MOCK_METHOD1(HandleTestFails
, void(const base::ListValue
*));
117 MOCK_METHOD1(HandleTestPasses
, void(const base::ListValue
*));
120 void RegisterMessages() override
{
121 web_ui()->RegisterMessageCallback("startAsyncTest",
122 base::Bind(&AsyncWebUIMessageHandler::HandleStartAsyncTest
,
123 base::Unretained(this)));
124 web_ui()->RegisterMessageCallback("testContinues",
125 base::Bind(&AsyncWebUIMessageHandler::HandleTestContinues
,
126 base::Unretained(this)));
127 web_ui()->RegisterMessageCallback("testFails",
128 base::Bind(&AsyncWebUIMessageHandler::HandleTestFails
,
129 base::Unretained(this)));
130 web_ui()->RegisterMessageCallback("testPasses",
131 base::Bind(&AsyncWebUIMessageHandler::HandleTestPasses
,
132 base::Unretained(this)));
135 // Starts the test in |list_value|[0] with the runAsync wrapper.
136 void HandleStartAsyncTest(const base::ListValue
* list_value
) {
137 const base::Value
* test_name
;
138 ASSERT_TRUE(list_value
->Get(0, &test_name
));
139 web_ui()->CallJavascriptFunction("runAsync", *test_name
);
142 DISALLOW_COPY_AND_ASSIGN(AsyncWebUIMessageHandler
);
145 // Handler for this object.
146 ::testing::StrictMock
<AsyncWebUIMessageHandler
> message_handler_
;
149 // Provide this object's handler.
150 WebUIMessageHandler
* GetMockMessageHandler() override
{
151 return &message_handler_
;
154 // Set up and browse to kDummyURL for all tests.
155 void SetUpOnMainThread() override
{
156 WebUIBrowserTest::SetUpOnMainThread();
157 AddLibrary(base::FilePath(FILE_PATH_LITERAL("async.js")));
158 ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL
));
161 DISALLOW_COPY_AND_ASSIGN(WebUIBrowserAsyncTest
);
164 // Test that assertions fail immediately after assertion fails (no testContinues
165 // message). (Sync version).
166 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestSyncOkTestFail
) {
167 ASSERT_FALSE(RunJavascriptTest("testFailsAssert"));
170 // Test that assertions fail immediately after assertion fails (no testContinues
171 // message). (Async version).
172 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncFailsAssert
) {
173 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
174 ASSERT_FALSE(RunJavascriptAsyncTest(
175 "startAsyncTest", new base::StringValue("testFailsAssert")));
178 // Test that expectations continue the function, but fail the test.
179 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncFailsExpect
) {
180 ::testing::InSequence s
;
181 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
182 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
183 ASSERT_FALSE(RunJavascriptAsyncTest(
184 "startAsyncTest", new base::StringValue("testFailsExpect")));
187 // Test that test continues and passes. (Sync version).
188 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestSyncPasses
) {
189 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
190 ASSERT_TRUE(RunJavascriptTest("testPasses"));
193 // Test that test continues and passes. (Async version).
194 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncPasses
) {
195 ::testing::InSequence s
;
196 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
197 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
198 .WillOnce(::testing::InvokeWithoutArgs(
199 this, &WebUIBrowserAsyncTest::TestDone
));
200 ASSERT_TRUE(RunJavascriptAsyncTest(
201 "startAsyncTest", new base::StringValue("testPasses")));
204 // Test that two tests pass.
205 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncPassPass
) {
206 ::testing::InSequence s
;
207 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
208 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
209 .WillOnce(::testing::InvokeWithoutArgs(
210 this, &WebUIBrowserAsyncTest::RunTestPasses
));
211 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
212 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
213 .WillOnce(::testing::InvokeWithoutArgs(
214 this, &WebUIBrowserAsyncTest::TestDone
));
215 ASSERT_TRUE(RunJavascriptAsyncTest(
216 "startAsyncTest", new base::StringValue("testPasses")));
219 // Test that first test passes; second fails.
220 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncPassThenFail
) {
221 ::testing::InSequence s
;
222 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
223 EXPECT_CALL(message_handler_
, HandleTestPasses(::testing::_
))
224 .WillOnce(::testing::InvokeWithoutArgs(
225 this, &WebUIBrowserAsyncTest::RunTestFailsAssert
));
226 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
227 ASSERT_FALSE(RunJavascriptAsyncTest(
228 "startAsyncTest", new base::StringValue("testPasses")));
231 // Test that testDone() with failure first then sync pass still fails.
232 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestAsyncDoneFailFirstSyncPass
) {
233 ::testing::InSequence s
;
234 EXPECT_CALL(message_handler_
, HandleTestContinues(::testing::_
));
235 EXPECT_CALL(message_handler_
, HandleTestFails(::testing::_
));
237 // Call runAsync directly instead of deferring through startAsyncTest. It will
238 // call testDone() on failure, then return.
239 ASSERT_FALSE(RunJavascriptAsyncTest(
240 "runAsync", new base::StringValue("testAsyncDoneFailFirstSyncPass")));
243 // Test that calling testDone during RunJavascriptAsyncTest still completes
244 // when waiting for async result. This is similar to the previous test, but call
245 // testDone directly and expect pass result.
246 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestTestDoneEarlyPassesAsync
) {
247 ASSERT_TRUE(RunJavascriptAsyncTest("testDone"));
250 // Test that calling testDone during RunJavascriptTest still completes when
251 // waiting for async result.
252 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest
, TestTestDoneEarlyPasses
) {
253 ASSERT_TRUE(RunJavascriptTest("testDone"));