Index: chrome/browser/ui/webui/web_ui_browsertest.cc |
diff --git a/chrome/browser/ui/webui/web_ui_browsertest.cc b/chrome/browser/ui/webui/web_ui_browsertest.cc |
index 63e50d60d05ca6bfbe216dfa303d9c725cece022..657ff3a964e2244e7f50804b4bc9a2ec9b50ec27 100644 |
--- a/chrome/browser/ui/webui/web_ui_browsertest.cc |
+++ b/chrome/browser/ui/webui/web_ui_browsertest.cc |
@@ -13,12 +13,14 @@ |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_navigator.h" |
#include "chrome/browser/ui/webui/chrome_web_ui.h" |
+#include "chrome/browser/ui/webui/test_chrome_web_ui_factory.h" |
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/url_constants.h" |
#include "chrome/test/base/test_tab_strip_model_observer.h" |
#include "chrome/test/base/ui_test_utils.h" |
#include "content/browser/tab_contents/tab_contents.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest-spi.h" |
#include "ui/base/resource/resource_bundle.h" |
@@ -156,6 +158,10 @@ void WebUIBrowserTest::BrowsePrintPreload( |
tabstrip_observer.WaitForObservation(); |
} |
+bool WebUIBrowserTest::WaitForAsyncResult() { |
+ return test_handler_->WaitForAsyncResult(); |
+} |
+ |
WebUIBrowserTest::WebUIBrowserTest() |
: test_handler_(new WebUITestHandler()), |
libraries_preloaded_(false) {} |
@@ -208,11 +214,12 @@ void WebUIBrowserTest::BuildJavascriptLibraries(string16* content) { |
std::string library_content; |
if (user_libraries_iterator->IsAbsolute()) { |
ASSERT_TRUE(file_util::ReadFileToString(*user_libraries_iterator, |
- &library_content)); |
+ &library_content)) |
+ << user_libraries_iterator->value(); |
} else { |
ASSERT_TRUE(file_util::ReadFileToString( |
test_data_directory_.Append(*user_libraries_iterator), |
- &library_content)); |
+ &library_content)) << user_libraries_iterator->value(); |
} |
utf8_content.append(library_content); |
utf8_content.append(";\n"); |
@@ -327,3 +334,160 @@ IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsFast) { |
EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("FAILS_BogusFunctionName"), |
"WebUITestHandler::Observe"); |
} |
+ |
+// Tests that the async framework works. |
+class WebUIBrowserAsyncTest : public WebUIBrowserTest { |
+ public: |
+ // Calls the asyncTestDone() function from test_api.js |
+ void AsyncTestDone() { |
+ RunJavascriptFunction("asyncTestDone"); |
+ } |
+ |
+ // starts a failing test. |
+ void RunTestFailsAssert() { |
+ RunJavascriptFunction("runAsync", |
+ *Value::CreateStringValue("testFailsAssert")); |
+ } |
+ |
+ // starts a passing test. |
+ void RunTestPasses() { |
+ RunJavascriptFunction("runAsync", *Value::CreateStringValue("testPasses")); |
+ } |
+ |
+ protected: |
+ |
+ WebUIBrowserAsyncTest() {} |
+ |
+ static const char kDummyURL[]; |
+ |
+ // Class to synchronize asynchronous javascript activity with the tests. |
+ class AsyncWebUIMessageHandler : public WebUIMessageHandler { |
+ public: |
+ AsyncWebUIMessageHandler() {} |
+ |
+ MOCK_METHOD1(HandleTestContinues, void(const ListValue*)); |
+ MOCK_METHOD1(HandleTestPasses, void(const ListValue*)); |
+ |
+ private: |
+ virtual void RegisterMessages() OVERRIDE { |
+ web_ui_->RegisterMessageCallback("startAsyncTest", NewCallback( |
+ this, &AsyncWebUIMessageHandler::HandleStartAsyncTest)); |
+ web_ui_->RegisterMessageCallback("testPasses", NewCallback( |
+ this, &AsyncWebUIMessageHandler::HandleTestPasses)); |
+ web_ui_->RegisterMessageCallback("testContinues", NewCallback( |
+ this, &AsyncWebUIMessageHandler::HandleTestContinues)); |
+ } |
+ |
+ // Starts the test in |list_value|[0] with the runAsync wrapper. |
+ void HandleStartAsyncTest(const ListValue* list_value) { |
+ Value* test_name; |
+ ASSERT_TRUE(list_value->Get(0, &test_name)); |
+ web_ui_->CallJavascriptFunction("runAsync", *test_name); |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AsyncWebUIMessageHandler); |
+ }; |
+ |
+ // Handler for this object. |
+ ::testing::StrictMock<AsyncWebUIMessageHandler> message_handler_; |
+ |
+ private: |
+ // Class to provide a ChromeWebUI for |kDummyURL|. |
+ class MockWebUIProvider : public TestChromeWebUIFactory::WebUIProvider { |
+ public: |
+ MockWebUIProvider() {} |
+ |
+ // Returns a new ChromeWebUI |
+ WebUI* NewWebUI(TabContents* tab_contents, const GURL& url) OVERRIDE { |
+ return new ChromeWebUI(tab_contents); |
+ } |
+ }; |
+ |
+ // Provide this object's handler. |
+ virtual WebUIMessageHandler* GetMockMessageHandler() OVERRIDE { |
+ return &message_handler_; |
+ } |
+ |
+ // Set up the kDummyURL to be a WebUI page. |
+ virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { |
+ WebUIBrowserTest::SetUpInProcessBrowserTestFixture(); |
+ TestChromeWebUIFactory::AddFactoryOverride(GURL(kDummyURL).host(), |
+ &mock_provider_); |
+ } |
+ |
+ // Tear down the kDummyURL WebUI page. |
+ virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { |
+ WebUIBrowserTest::TearDownInProcessBrowserTestFixture(); |
+ TestChromeWebUIFactory::RemoveFactoryOverride(GURL(kDummyURL).host()); |
+ } |
+ |
+ // Set up and browse to kDummyURL for all tests. |
+ virtual void SetUpOnMainThread() OVERRIDE { |
+ WebUIBrowserTest::SetUpOnMainThread(); |
+ AddLibrary(FilePath(FILE_PATH_LITERAL("async.js"))); |
+ ui_test_utils::NavigateToURL(browser(), GURL(kDummyURL)); |
+ } |
+ |
+ // Provider for this object. |
+ MockWebUIProvider mock_provider_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WebUIBrowserAsyncTest); |
+}; |
+ |
+const char WebUIBrowserAsyncTest::kDummyURL[] = "chrome://Dummy"; |
+ |
+// Test that assertions fail immediately without calling asyncTestDone(). |
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsAssert) { |
+ ASSERT_TRUE(RunJavascriptTest("startAsyncTest", |
+ *Value::CreateStringValue("testFailsAssert"))); |
+ ASSERT_FALSE(WaitForAsyncResult()); |
+} |
+ |
+// Test that expectations continue the function, but fail the test without |
+// calling asyncTestDone(). |
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsExpect) { |
+ EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
+ ASSERT_TRUE(RunJavascriptTest("startAsyncTest", |
+ *Value::CreateStringValue("testFailsExpect"))); |
+ ASSERT_FALSE(WaitForAsyncResult()); |
+} |
+ |
+// Test that test passes when this object's handler calls asyncTestDone(). |
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPasses) { |
+ ::testing::InSequence s; |
+ EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
+ EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_)) |
+ .WillOnce(::testing::InvokeWithoutArgs( |
+ this, &WebUIBrowserAsyncTest::AsyncTestDone)); |
+ ASSERT_TRUE(RunJavascriptTest("startAsyncTest", |
+ *Value::CreateStringValue("testPasses"))); |
+ ASSERT_TRUE(WaitForAsyncResult()); |
+} |
+ |
+// Test that two tests pass |
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPassPass) { |
+ ::testing::InSequence s; |
+ EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
+ EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_)) |
+ .WillOnce(::testing::InvokeWithoutArgs( |
+ this, &WebUIBrowserAsyncTest::RunTestPasses)); |
+ EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
+ EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_)) |
+ .WillOnce(::testing::InvokeWithoutArgs( |
+ this, &WebUIBrowserAsyncTest::AsyncTestDone)); |
+ ASSERT_TRUE(RunJavascriptTest("startAsyncTest", |
+ *Value::CreateStringValue("testPasses"))); |
+ ASSERT_TRUE(WaitForAsyncResult()); |
+} |
+ |
+// Test that first test passes; second fails. |
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncPassThenFail) { |
+ ::testing::InSequence s; |
+ EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
+ EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_)) |
+ .WillOnce(::testing::InvokeWithoutArgs( |
+ this, &WebUIBrowserAsyncTest::RunTestFailsAssert)); |
+ ASSERT_TRUE(RunJavascriptTest("startAsyncTest", |
+ *Value::CreateStringValue("testPasses"))); |
+ ASSERT_FALSE(WaitForAsyncResult()); |
+} |