// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/webui/web_ui_test_handler.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/common/render_messages.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" using content::RenderViewHost; WebUITestHandler::WebUITestHandler() : test_done_(false), test_succeeded_(false), run_test_done_(false), run_test_succeeded_(false), is_waiting_(false) { } void WebUITestHandler::PreloadJavaScript(const base::string16& js_text, RenderViewHost* preload_host) { DCHECK(preload_host); preload_host->Send(new ChromeViewMsg_WebUIJavaScript( preload_host->GetRoutingID(), js_text)); } void WebUITestHandler::RunJavaScript(const base::string16& js_text) { web_ui()->GetWebContents()->GetMainFrame()->ExecuteJavaScript(js_text); } bool WebUITestHandler::RunJavaScriptTestWithResult( const base::string16& js_text) { test_succeeded_ = false; run_test_succeeded_ = false; content::RenderFrameHost* frame = web_ui()->GetWebContents()->GetMainFrame(); frame->ExecuteJavaScript(js_text, base::Bind(&WebUITestHandler::JavaScriptComplete, base::Unretained(this))); return WaitForResult(); } void WebUITestHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("testResult", base::Bind(&WebUITestHandler::HandleTestResult, base::Unretained(this))); } void WebUITestHandler::HandleTestResult(const base::ListValue* test_result) { // Quit the message loop if |is_waiting_| so waiting process can get result or // error. To ensure this gets done, do this before ASSERT* calls. if (is_waiting_) base::MessageLoopForUI::current()->Quit(); SCOPED_TRACE("WebUITestHandler::HandleTestResult"); EXPECT_FALSE(test_done_); test_done_ = true; test_succeeded_ = false; ASSERT_TRUE(test_result->GetBoolean(0, &test_succeeded_)); if (!test_succeeded_) { std::string message; ASSERT_TRUE(test_result->GetString(1, &message)); LOG(ERROR) << message; } } void WebUITestHandler::JavaScriptComplete(const base::Value* result) { // Quit the message loop if |is_waiting_| so waiting process can get result or // error. To ensure this gets done, do this before ASSERT* calls. if (is_waiting_) base::MessageLoopForUI::current()->Quit(); SCOPED_TRACE("WebUITestHandler::JavaScriptComplete"); EXPECT_FALSE(run_test_done_); run_test_done_ = true; run_test_succeeded_ = false; ASSERT_TRUE(result->GetAsBoolean(&run_test_succeeded_)); } bool WebUITestHandler::WaitForResult() { SCOPED_TRACE("WebUITestHandler::WaitForResult"); test_done_ = false; run_test_done_ = false; is_waiting_ = true; // Either sync test completion or the testDone() will cause message loop // to quit. content::RunMessageLoop(); // Run a second message loop when not |run_test_done_| so that the sync test // completes, or |run_test_succeeded_| but not |test_done_| so async tests // complete. if (!run_test_done_ || (run_test_succeeded_ && !test_done_)) { content::RunMessageLoop(); } is_waiting_ = false; // To succeed the test must execute as well as pass the test. return run_test_succeeded_ && test_succeeded_; }