Chromium Code Reviews| 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..df41cc9f389e3d263bdbb9aec98d8c1652d18180 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" |
| @@ -74,7 +76,7 @@ bool WebUIBrowserTest::RunJavascriptFunction( |
| const std::string& function_name, |
| const ConstValueVector& function_arguments) { |
| return RunJavascriptUsingHandler( |
| - function_name, function_arguments, false, NULL); |
| + function_name, function_arguments, false, false, NULL); |
| } |
| bool WebUIBrowserTest::RunJavascriptTestF(const std::string& test_fixture, |
| @@ -108,7 +110,34 @@ bool WebUIBrowserTest::RunJavascriptTest(const std::string& test_name, |
| bool WebUIBrowserTest::RunJavascriptTest( |
| const std::string& test_name, |
| const ConstValueVector& test_arguments) { |
| - return RunJavascriptUsingHandler(test_name, test_arguments, true, NULL); |
| + return RunJavascriptUsingHandler( |
| + test_name, test_arguments, true, false, NULL); |
| +} |
| + |
| +bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name) { |
| + return RunJavascriptAsyncTest(test_name, ConstValueVector()); |
| +} |
| + |
| +bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name, |
| + const Value& arg) { |
| + ConstValueVector args; |
| + args.push_back(&arg); |
| + return RunJavascriptAsyncTest(test_name, args); |
| +} |
| + |
| +bool WebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name, |
| + const Value& arg1, |
| + const Value& arg2) { |
| + ConstValueVector args; |
| + args.push_back(&arg1); |
| + args.push_back(&arg2); |
| + return RunJavascriptAsyncTest(test_name, args); |
| +} |
| + |
| +bool WebUIBrowserTest::RunJavascriptAsyncTest( |
| + const std::string& test_name, |
| + const ConstValueVector& test_arguments) { |
| + return RunJavascriptUsingHandler(test_name, test_arguments, true, true, NULL); |
| } |
| void WebUIBrowserTest::PreLoadJavascriptLibraries( |
| @@ -120,7 +149,7 @@ void WebUIBrowserTest::PreLoadJavascriptLibraries( |
| args.push_back(Value::CreateStringValue(preload_test_fixture)); |
| args.push_back(Value::CreateStringValue(preload_test_name)); |
| RunJavascriptUsingHandler( |
| - "preloadJavascriptLibraries", args, false, preload_host); |
| + "preloadJavascriptLibraries", args, false, false, preload_host); |
| libraries_preloaded_ = true; |
| } |
| @@ -208,11 +237,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"); |
| @@ -241,6 +271,7 @@ bool WebUIBrowserTest::RunJavascriptUsingHandler( |
| const std::string& function_name, |
| const ConstValueVector& function_arguments, |
| bool is_test, |
| + bool is_async, |
| RenderViewHost* preload_host) { |
| string16 content; |
| @@ -265,7 +296,7 @@ bool WebUIBrowserTest::RunJavascriptUsingHandler( |
| bool result = true; |
| if (is_test) |
| - result = test_handler_->RunJavaScriptTestWithResult(content); |
| + result = test_handler_->RunJavaScriptTestWithResult(content, is_async); |
| else if (preload_host) |
| test_handler_->PreloadJavaScript(content, preload_host); |
| else |
| @@ -315,6 +346,11 @@ class WebUIBrowserExpectFailTest : public WebUIBrowserTest { |
| s_test_->RunJavascriptTest(testname); |
| } |
| + static void RunJavascriptAsyncTestNoReturn(const std::string& testname) { |
| + EXPECT_TRUE(s_test_); |
| + s_test_->RunJavascriptAsyncTest(testname); |
| + } |
| + |
| private: |
| static WebUIBrowserTest* s_test_; |
| }; |
| @@ -327,3 +363,192 @@ IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsFast) { |
| EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("FAILS_BogusFunctionName"), |
| "WebUITestHandler::Observe"); |
| } |
| + |
| +IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsAsyncFast) { |
|
mmenke
2011/08/10 17:23:40
These tests should have brief descriptions.
Sheridan Rawlins
2011/08/11 01:58:44
Done.
|
| + AddLibrary(FilePath(FILE_PATH_LITERAL("sample_downloads.js"))); |
| + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL)); |
| + EXPECT_FATAL_FAILURE( |
| + RunJavascriptAsyncTestNoReturn("FAILS_BogusFunctionName"), |
| + "WebUITestHandler::Observe"); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsNonAsync) { |
| + AddLibrary(FilePath(FILE_PATH_LITERAL("sample_downloads.js"))); |
| + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL)); |
| + EXPECT_NONFATAL_FAILURE(RunJavascriptTest("asyncTestDone"), |
| + "WebUITestHandler::WaitForResult"); |
| +} |
| + |
| +// 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. |
|
mmenke
2011/08/10 17:23:40
nit: Capitalize "Starts" here, and just below.
Sheridan Rawlins
2011/08/11 01:58:44
Done.
|
| + void RunTestFailsAssert() { |
| + RunJavascriptFunction("runAsync", |
| + *Value::CreateStringValue("testFailsAssert")); |
| + } |
| + |
| + // starts a passing test. |
| + void RunTestPasses() { |
| + RunJavascriptFunction("runAsync", *Value::CreateStringValue("testPasses")); |
| + } |
| + |
| + protected: |
| + |
|
mmenke
2011/08/10 17:23:40
nit: Remove blank line.
Sheridan Rawlins
2011/08/11 01:58:44
Done.
|
| + 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(HandleTestFails, 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("testContinues", NewCallback( |
| + this, &AsyncWebUIMessageHandler::HandleTestContinues)); |
| + web_ui_->RegisterMessageCallback("testFails", NewCallback( |
| + this, &AsyncWebUIMessageHandler::HandleTestFails)); |
| + web_ui_->RegisterMessageCallback("testPasses", NewCallback( |
| + this, &AsyncWebUIMessageHandler::HandleTestPasses)); |
| + } |
| + |
| + // 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(). |
|
mmenke
2011/08/10 17:23:40
asyncTestDone() is, in fact, called by runAsync.
Sheridan Rawlins
2011/08/11 01:58:44
Done.
|
| +IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsAssert) { |
| + EXPECT_CALL(message_handler_, HandleTestFails(::testing::_)); |
| + ASSERT_FALSE(RunJavascriptAsyncTest( |
| + "startAsyncTest", *Value::CreateStringValue("testFailsAssert"))); |
| +} |
| + |
| +// Test that expectations continue the function, but fail the test without |
| +// calling asyncTestDone(). |
| +IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsExpect) { |
| + ::testing::InSequence s; |
| + EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
| + EXPECT_CALL(message_handler_, HandleTestFails(::testing::_)); |
| + ASSERT_FALSE(RunJavascriptAsyncTest( |
| + "startAsyncTest", *Value::CreateStringValue("testFailsExpect"))); |
| +} |
| + |
| +// 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(RunJavascriptAsyncTest( |
| + "startAsyncTest", *Value::CreateStringValue("testPasses"))); |
| +} |
| + |
| +// 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(RunJavascriptAsyncTest( |
| + "startAsyncTest", *Value::CreateStringValue("testPasses"))); |
| +} |
| + |
| +// 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)); |
| + EXPECT_CALL(message_handler_, HandleTestFails(::testing::_)); |
| + ASSERT_FALSE(RunJavascriptAsyncTest( |
| + "startAsyncTest", *Value::CreateStringValue("testPasses"))); |
| +} |
| + |
| +// Test that async fail first then sync pass still fails. |
| +IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncDoneFailFirstSyncPass) { |
| + ::testing::InSequence s; |
| + EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_)); |
| + EXPECT_CALL(message_handler_, HandleTestFails(::testing::_)); |
| + ASSERT_FALSE(RunJavascriptAsyncTest( |
| + "runAsync", *Value::CreateStringValue("testAsyncDoneFailFirstSyncPass"))); |
| +} |
| + |
| +// Test that calling asyncTestDone during RunJavascriptTest still completes when |
| +// waiting for async result. |
| +IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncTestDoneEarly) { |
| + ASSERT_TRUE(RunJavascriptAsyncTest("asyncTestDone")); |
| +} |