Home | History | Annotate | Download | only in base
      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.
      4 
      5 #include <string>
      6 
      7 #include "base/bind.h"
      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"
     17 
     18 using content::WebUIMessageHandler;
     19 
     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 {
     26  public:
     27   WebUIBrowserExpectFailTest() {
     28     EXPECT_FALSE(s_test_);
     29     s_test_ = this;
     30   }
     31 
     32  protected:
     33   virtual ~WebUIBrowserExpectFailTest() {
     34     EXPECT_TRUE(s_test_);
     35     s_test_ = NULL;
     36   }
     37 
     38   static void RunJavascriptTestNoReturn(const std::string& testname) {
     39     EXPECT_TRUE(s_test_);
     40     s_test_->RunJavascriptTest(testname);
     41   }
     42 
     43   static void RunJavascriptAsyncTestNoReturn(const std::string& testname) {
     44     EXPECT_TRUE(s_test_);
     45     s_test_->RunJavascriptAsyncTest(testname);
     46   }
     47 
     48  private:
     49   static WebUIBrowserTest* s_test_;
     50 };
     51 
     52 WebUIBrowserTest* WebUIBrowserExpectFailTest::s_test_ = NULL;
     53 
     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");
     60 }
     61 
     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");
     68 }
     69 
     70 // Test that bogus javascript fails async test fast as well - no timeout waiting
     71 // for result.
     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));
     75   EXPECT_FATAL_FAILURE(
     76       RunJavascriptAsyncTestNoReturn("DISABLED_BogusFunctionName"),
     77       "WebUITestHandler::JavaScriptComplete");
     78 }
     79 
     80 // Tests that the async framework works.
     81 class WebUIBrowserAsyncTest : public WebUIBrowserTest {
     82  public:
     83   // Calls the testDone() function from test_api.js
     84   void TestDone() {
     85     RunJavascriptFunction("testDone");
     86   }
     87 
     88   // Starts a failing test.
     89   void RunTestFailsAssert() {
     90     RunJavascriptFunction("runAsync", new base::StringValue("testFailsAssert"));
     91   }
     92 
     93   // Starts a passing test.
     94   void RunTestPasses() {
     95     RunJavascriptFunction("runAsync", new base::StringValue("testPasses"));
     96   }
     97 
     98  protected:
     99   WebUIBrowserAsyncTest() {}
    100 
    101   // Class to synchronize asynchronous javascript activity with the tests.
    102   class AsyncWebUIMessageHandler : public WebUIMessageHandler {
    103    public:
    104     AsyncWebUIMessageHandler() {}
    105 
    106     MOCK_METHOD1(HandleTestContinues, void(const base::ListValue*));
    107     MOCK_METHOD1(HandleTestFails, void(const base::ListValue*));
    108     MOCK_METHOD1(HandleTestPasses, void(const base::ListValue*));
    109 
    110    private:
    111     virtual 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)));
    124     }
    125 
    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);
    131     }
    132 
    133     DISALLOW_COPY_AND_ASSIGN(AsyncWebUIMessageHandler);
    134   };
    135 
    136   // Handler for this object.
    137   ::testing::StrictMock<AsyncWebUIMessageHandler> message_handler_;
    138 
    139  private:
    140   // Provide this object's handler.
    141   virtual WebUIMessageHandler* GetMockMessageHandler() OVERRIDE {
    142     return &message_handler_;
    143   }
    144 
    145   // Set up and browse to kDummyURL for all tests.
    146   virtual void SetUpOnMainThread() OVERRIDE {
    147     WebUIBrowserTest::SetUpOnMainThread();
    148     AddLibrary(base::FilePath(FILE_PATH_LITERAL("async.js")));
    149     ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL));
    150   }
    151 
    152   DISALLOW_COPY_AND_ASSIGN(WebUIBrowserAsyncTest);
    153 };
    154 
    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"));
    159 }
    160 
    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")));
    167 }
    168 
    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")));
    176 }
    177 
    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"));
    182 }
    183 
    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")));
    193 }
    194 
    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")));
    208 }
    209 
    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")));
    220 }
    221 
    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::_));
    227 
    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")));
    232 }
    233 
    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"));
    239 }
    240 
    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"));
    245 }
    246