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