1// Copyright (c) 2012 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 "chrome/browser/ui/webui/web_ui_test_handler.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/strings/utf_string_conversions.h" 10#include "base/values.h" 11#include "chrome/common/render_messages.h" 12#include "chrome/test/base/ui_test_utils.h" 13#include "content/public/browser/notification_details.h" 14#include "content/public/browser/notification_registrar.h" 15#include "content/public/browser/notification_types.h" 16#include "content/public/browser/render_frame_host.h" 17#include "content/public/browser/render_view_host.h" 18#include "content/public/browser/web_contents.h" 19#include "content/public/browser/web_ui.h" 20 21using content::RenderViewHost; 22 23WebUITestHandler::WebUITestHandler() 24 : test_done_(false), 25 test_succeeded_(false), 26 run_test_done_(false), 27 run_test_succeeded_(false), 28 is_waiting_(false) { 29} 30 31void WebUITestHandler::PreloadJavaScript(const base::string16& js_text, 32 RenderViewHost* preload_host) { 33 DCHECK(preload_host); 34 preload_host->Send(new ChromeViewMsg_WebUIJavaScript( 35 preload_host->GetRoutingID(), js_text)); 36} 37 38void WebUITestHandler::RunJavaScript(const base::string16& js_text) { 39 web_ui()->GetWebContents()->GetMainFrame()->ExecuteJavaScript(js_text); 40} 41 42bool WebUITestHandler::RunJavaScriptTestWithResult( 43 const base::string16& js_text) { 44 test_succeeded_ = false; 45 run_test_succeeded_ = false; 46 content::RenderFrameHost* frame = web_ui()->GetWebContents()->GetMainFrame(); 47 frame->ExecuteJavaScript(js_text, 48 base::Bind(&WebUITestHandler::JavaScriptComplete, 49 base::Unretained(this))); 50 return WaitForResult(); 51} 52 53void WebUITestHandler::RegisterMessages() { 54 web_ui()->RegisterMessageCallback("testResult", 55 base::Bind(&WebUITestHandler::HandleTestResult, base::Unretained(this))); 56} 57 58void WebUITestHandler::HandleTestResult(const base::ListValue* test_result) { 59 // Quit the message loop if |is_waiting_| so waiting process can get result or 60 // error. To ensure this gets done, do this before ASSERT* calls. 61 if (is_waiting_) 62 base::MessageLoopForUI::current()->Quit(); 63 64 SCOPED_TRACE("WebUITestHandler::HandleTestResult"); 65 66 EXPECT_FALSE(test_done_); 67 test_done_ = true; 68 test_succeeded_ = false; 69 70 ASSERT_TRUE(test_result->GetBoolean(0, &test_succeeded_)); 71 if (!test_succeeded_) { 72 std::string message; 73 ASSERT_TRUE(test_result->GetString(1, &message)); 74 LOG(ERROR) << message; 75 } 76} 77 78void WebUITestHandler::JavaScriptComplete(const base::Value* result) { 79 // Quit the message loop if |is_waiting_| so waiting process can get result or 80 // error. To ensure this gets done, do this before ASSERT* calls. 81 if (is_waiting_) 82 base::MessageLoopForUI::current()->Quit(); 83 84 SCOPED_TRACE("WebUITestHandler::JavaScriptComplete"); 85 86 EXPECT_FALSE(run_test_done_); 87 run_test_done_ = true; 88 run_test_succeeded_ = false; 89 90 ASSERT_TRUE(result->GetAsBoolean(&run_test_succeeded_)); 91} 92 93bool WebUITestHandler::WaitForResult() { 94 SCOPED_TRACE("WebUITestHandler::WaitForResult"); 95 test_done_ = false; 96 run_test_done_ = false; 97 is_waiting_ = true; 98 99 // Either sync test completion or the testDone() will cause message loop 100 // to quit. 101 content::RunMessageLoop(); 102 103 // Run a second message loop when not |run_test_done_| so that the sync test 104 // completes, or |run_test_succeeded_| but not |test_done_| so async tests 105 // complete. 106 if (!run_test_done_ || (run_test_succeeded_ && !test_done_)) { 107 content::RunMessageLoop(); 108 } 109 110 is_waiting_ = false; 111 112 // To succeed the test must execute as well as pass the test. 113 return run_test_succeeded_ && test_succeeded_; 114} 115