Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4275)

Unified Diff: chrome/browser/ui/webui/web_ui_browsertest.cc

Issue 7576024: Provide ability for WebUIBrowserTests to run asynchronous tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..332b59f69ab4a434417d663cb4d8c7fd4fb4209a 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");
@@ -221,9 +251,12 @@ void WebUIBrowserTest::BuildJavascriptLibraries(string16* content) {
}
string16 WebUIBrowserTest::BuildRunTestJSCall(
+ bool is_async,
const std::string& function_name,
const WebUIBrowserTest::ConstValueVector& test_func_args) {
WebUIBrowserTest::ConstValueVector arguments;
+ base::FundamentalValue is_async_arg(is_async);
+ arguments.push_back(&is_async_arg);
StringValue function_name_arg(function_name);
arguments.push_back(&function_name_arg);
ListValue baked_argument_list;
@@ -241,6 +274,7 @@ bool WebUIBrowserTest::RunJavascriptUsingHandler(
const std::string& function_name,
const ConstValueVector& function_arguments,
bool is_test,
+ bool is_async,
RenderViewHost* preload_host) {
string16 content;
@@ -250,7 +284,8 @@ bool WebUIBrowserTest::RunJavascriptUsingHandler(
if (!function_name.empty()) {
string16 called_function;
if (is_test) {
- called_function = BuildRunTestJSCall(function_name, function_arguments);
+ called_function = BuildRunTestJSCall(
+ is_async, function_name, function_arguments);
} else {
called_function = WebUI::GetJavascriptCall(function_name,
function_arguments);
@@ -315,15 +350,226 @@ 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_;
};
WebUIBrowserTest* WebUIBrowserExpectFailTest::s_test_ = NULL;
+// Test that bogus javascript fails fast - no timeout waiting for result.
IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsFast) {
AddLibrary(FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
EXPECT_FATAL_FAILURE(RunJavascriptTestNoReturn("FAILS_BogusFunctionName"),
"WebUITestHandler::Observe");
}
+
+// Test that bogus javascript fails async test fast as well - no timeout waiting
+// for result.
+IN_PROC_BROWSER_TEST_F(WebUIBrowserExpectFailTest, TestFailsAsyncFast) {
+ AddLibrary(FilePath(FILE_PATH_LITERAL("sample_downloads.js")));
+ ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
+ EXPECT_FATAL_FAILURE(
+ RunJavascriptAsyncTestNoReturn("FAILS_BogusFunctionName"),
+ "WebUITestHandler::Observe");
+}
+
+// Tests that the async framework works.
+class WebUIBrowserAsyncTest : public WebUIBrowserTest {
+ public:
+ // Calls the testDone() function from test_api.js
+ void TestDone() {
+ RunJavascriptFunction("testDone");
+ }
+
+ // 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(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 after assertion fails (no testContinues
+// message). (Sync version).
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestSyncOkTestFail) {
+ ASSERT_FALSE(RunJavascriptTest("testFailsAssert"));
+}
+
+// Test that assertions fail immediately after assertion fails (no testContinues
+// message). (Async version).
+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.
+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 continues and passes. (Sync version).
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestSyncPasses) {
+ EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
+ ASSERT_TRUE(RunJavascriptTest("testPasses"));
+}
+
+// Test that test continues and passes. (Async version).
+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::TestDone));
+ 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::TestDone));
+ 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 testDone() with failure 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::_));
+
+ // Call runAsync directly instead of deferring through startAsyncTest. It will
+ // call testDone() on failure, then return.
+ ASSERT_FALSE(RunJavascriptAsyncTest(
+ "runAsync", *Value::CreateStringValue("testAsyncDoneFailFirstSyncPass")));
+}
+
+// Test that calling testDone during RunJavascriptAsyncTest still completes
+// when waiting for async result. This is similar to the previous test, but call
+// testDone directly and expect pass result.
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestTestDoneEarlyPassesAsync) {
+ ASSERT_TRUE(RunJavascriptAsyncTest("testDone"));
+}
+
+// Test that calling testDone during RunJavascriptTest still completes when
+// waiting for async result.
+IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestTestDoneEarlyPasses) {
+ ASSERT_TRUE(RunJavascriptTest("testDone"));
+}

Powered by Google App Engine
This is Rietveld 408576698