browser_test_utils.cc revision f2477e01787aa58f445919b809d89e252beef54f
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Use of this source code is governed by a BSD-style license that can be 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// found in the LICENSE file. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/test/browser_test_utils.h" 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/command_line.h" 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/json/json_reader.h" 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/path_service.h" 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/process/kill.h" 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/rand_util.h" 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/strings/string_number_conversions.h" 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/strings/utf_string_conversions.h" 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/synchronization/waitable_event.h" 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/test/test_timeouts.h" 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "base/values.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/browser_context.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/dom_operation_notification_details.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/notification_service.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/notification_types.h" 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/render_process_host.h" 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/render_view_host.h" 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/web_contents.h" 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/web_contents_observer.h" 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/browser/web_contents_view.h" 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "content/public/test/test_utils.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "grit/webui_resources.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "net/base/net_util.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "net/cookies/cookie_store.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "net/test/python_utils.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "net/url_request/url_request_context.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "net/url_request/url_request_context_getter.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "testing/gtest/include/gtest/gtest.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ui/base/resource/resource_bundle.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ui/events/keycodes/dom4/keycode_converter.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace content { 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace { 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass DOMOperationObserver : public NotificationObserver, 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org public WebContentsObserver { 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org public: 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org explicit DOMOperationObserver(RenderViewHost* rvh) 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : WebContentsObserver(WebContents::FromRenderViewHost(rvh)), 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org did_respond_(false) { 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org registrar_.Add(this, NOTIFICATION_DOM_OPERATION_RESPONSE, 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Source<RenderViewHost>(rvh)); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org message_loop_runner_ = new MessageLoopRunner; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void Observe(int type, 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const NotificationSource& source, 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const NotificationDetails& details) OVERRIDE { 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DCHECK(type == NOTIFICATION_DOM_OPERATION_RESPONSE); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Details<DomOperationNotificationDetails> dom_op_details(details); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org response_ = dom_op_details->json; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org did_respond_ = true; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org message_loop_runner_->Quit(); 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Overridden from WebContentsObserver: 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE { 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org message_loop_runner_->Quit(); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool WaitAndGetResponse(std::string* response) WARN_UNUSED_RESULT { 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org message_loop_runner_->Run(); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *response = response_; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return did_respond_; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org private: 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NotificationRegistrar registrar_; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string response_; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool did_respond_; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_refptr<MessageLoopRunner> message_loop_runner_; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver); 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute. 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptHelper(RenderViewHost* render_view_host, 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& frame_xpath, 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& original_script, 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<Value>* result) WARN_UNUSED_RESULT; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Executes the passed |original_script| in the frame pointed to by 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// |frame_xpath|. If |result| is not NULL, stores the value that the evaluation 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// of the script in |result|. Returns true on success. 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptHelper(RenderViewHost* render_view_host, 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& frame_xpath, 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& original_script, 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<Value>* result) { 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO(jcampan): we should make the domAutomationController not require an 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // automation id. 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string script = 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "window.domAutomationController.setAutomationId(0);" + original_script; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DOMOperationObserver dom_op_observer(render_view_host); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org render_view_host->ExecuteJavascriptInWebFrame(UTF8ToUTF16(frame_xpath), 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UTF8ToUTF16(script)); 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string json; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!dom_op_observer.WaitAndGetResponse(&json)) { 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DLOG(ERROR) << "Cannot communicate with DOMOperationObserver."; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Nothing more to do for callers that ignore the returned JS value. 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!result) 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->reset(reader.ReadToValue(json)); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!result->get()) { 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DLOG(ERROR) << reader.GetErrorMessage(); 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid BuildSimpleWebKeyEvent(blink::WebInputEvent::Type type, 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::KeyboardCode key_code, 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int native_key_code, 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int modifiers, 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NativeWebKeyboardEvent* event) { 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->nativeKeyCode = native_key_code; 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->windowsKeyCode = key_code; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->setKeyIdentifierFromWindowsKeyCode(); 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->type = type; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->modifiers = modifiers; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->isSystemKey = false; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->timeStampSeconds = base::Time::Now().ToDoubleT(); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->skip_in_browser = true; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == blink::WebInputEvent::Char || 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type == blink::WebInputEvent::RawKeyDown) { 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->text[0] = key_code; 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->unmodifiedText[0] = key_code; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid InjectRawKeyEvent(WebContents* web_contents, 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::Type type, 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::KeyboardCode key_code, 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int native_key_code, 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int modifiers) { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NativeWebKeyboardEvent event; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BuildSimpleWebKeyEvent(type, key_code, native_key_code, modifiers, &event); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents->GetRenderViewHost()->ForwardKeyboardEvent(event); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GetCookiesCallback(std::string* cookies_out, 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::WaitableEvent* event, 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& cookies) { 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *cookies_out = cookies; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->Signal(); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid GetCookiesOnIOThread(const GURL& url, 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org net::URLRequestContextGetter* context_getter, 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::WaitableEvent* event, 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string* cookies) { 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org net::CookieStore* cookie_store = 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org context_getter->GetURLRequestContext()->cookie_store(); 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cookie_store->GetCookiesWithOptionsAsync( 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org url, net::CookieOptions(), 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&GetCookiesCallback, cookies, event)); 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SetCookieCallback(bool* result, 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::WaitableEvent* event, 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool success) { 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *result = success; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event->Signal(); 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SetCookieOnIOThread(const GURL& url, 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& value, 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org net::URLRequestContextGetter* context_getter, 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::WaitableEvent* event, 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool* result) { 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org net::CookieStore* cookie_store = 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org context_getter->GetURLRequestContext()->cookie_store(); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cookie_store->SetCookieWithOptionsAsync( 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org url, value, net::CookieOptions(), 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&SetCookieCallback, result, event)); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // namespace 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGURL GetFileUrlWithQuery(const base::FilePath& path, 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& query_string) { 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GURL url = net::FilePathToFileURL(path); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!query_string.empty()) { 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GURL::Replacements replacements; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org replacements.SetQueryStr(query_string); 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return url.ReplaceComponents(replacements); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return url; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid WaitForLoadStop(WebContents* web_contents) { 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WindowedNotificationObserver load_stop_observer( 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NOTIFICATION_LOAD_STOP, 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Source<NavigationController>(&web_contents->GetController())); 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // In many cases, the load may have finished before we get here. Only wait if 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // the tab still has a pending navigation. 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!web_contents->IsLoading()) 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org load_stop_observer.Wait(); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CrashTab(WebContents* web_contents) { 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RenderProcessHost* rph = web_contents->GetRenderProcessHost(); 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WindowedNotificationObserver observer( 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NOTIFICATION_RENDERER_PROCESS_CLOSED, 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Source<RenderProcessHost>(rph)); 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::KillProcess(rph->GetHandle(), 0, false); 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org observer.Wait(); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SimulateMouseClick(WebContents* web_contents, 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int modifiers, 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebMouseEvent::Button button) { 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int x = web_contents->GetView()->GetContainerSize().width() / 2; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int y = web_contents->GetView()->GetContainerSize().height() / 2; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SimulateMouseClickAt(web_contents, modifiers, button, gfx::Point(x, y)); 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SimulateMouseClickAt(WebContents* web_contents, 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int modifiers, 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebMouseEvent::Button button, 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const gfx::Point& point) { 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebMouseEvent mouse_event; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.type = blink::WebInputEvent::MouseDown; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.button = button; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.x = point.x(); 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.y = point.y(); 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.modifiers = modifiers; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Mac needs globalX/globalY for events to plugins. 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gfx::Rect offset; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents->GetView()->GetContainerBounds(&offset); 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.globalX = point.x() + offset.x(); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.globalY = point.y() + offset.y(); 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.clickCount = 1; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.type = blink::WebInputEvent::MouseUp; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SimulateMouseEvent(WebContents* web_contents, 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::Type type, 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const gfx::Point& point) { 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebMouseEvent mouse_event; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.type = type; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.x = point.x(); 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mouse_event.y = point.y(); 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SimulateKeyPress(WebContents* web_contents, 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::KeyboardCode key_code, 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool control, 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool shift, 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool alt, 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool command) { 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SimulateKeyPressWithCode( 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, key_code, NULL, control, shift, alt, command); 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid SimulateKeyPressWithCode(WebContents* web_contents, 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::KeyboardCode key_code, 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char* code, 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool control, 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool shift, 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool alt, 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool command) { 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::KeycodeConverter* key_converter = ui::KeycodeConverter::GetInstance(); 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int native_key_code = key_converter->CodeToNativeKeycode(code); 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int modifiers = 0; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // The order of these key down events shouldn't matter for our simulation. 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // For our simulation we can use either the left keys or the right keys. 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (control) { 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers |= blink::WebInputEvent::ControlKey; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::RawKeyDown, 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_CONTROL, 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("ControlLeft"), 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shift) { 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers |= blink::WebInputEvent::ShiftKey; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::RawKeyDown, 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_SHIFT, 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("ShiftLeft"), 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (alt) { 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers |= blink::WebInputEvent::AltKey; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::RawKeyDown, 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_MENU, 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("AltLeft"), 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (command) { 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers |= blink::WebInputEvent::MetaKey; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::RawKeyDown, 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_COMMAND, 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("OSLeft"), 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::RawKeyDown, 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_code, 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org native_key_code, 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::Char, 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_code, 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org native_key_code, 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::KeyUp, 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_code, 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org native_key_code, 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // The order of these key releases shouldn't matter for our simulation. 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (control) { 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers &= ~blink::WebInputEvent::ControlKey; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::KeyUp, 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_CONTROL, 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("ControlLeft"), 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shift) { 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers &= ~blink::WebInputEvent::ShiftKey; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::KeyUp, 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_SHIFT, 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("ShiftLeft"), 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (alt) { 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers &= ~blink::WebInputEvent::AltKey; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::KeyUp, 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_MENU, 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("AltLeft"), 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (command) { 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers &= ~blink::WebInputEvent::MetaKey; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InjectRawKeyEvent( 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org web_contents, 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blink::WebInputEvent::KeyUp, 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ui::VKEY_COMMAND, 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key_converter->CodeToNativeKeycode("OSLeft"), 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org modifiers); 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT_EQ(modifiers, 0); 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace internal { 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgToRenderViewHost::ToRenderViewHost(WebContents* web_contents) 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : render_view_host_(web_contents->GetRenderViewHost()) { 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgToRenderViewHost::ToRenderViewHost(RenderViewHost* render_view_host) 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : render_view_host_(render_view_host) { 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // namespace internal 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptInFrame(const internal::ToRenderViewHost& adapter, 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& frame_xpath, 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& original_script) { 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string script = 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org original_script + ";window.domAutomationController.send(0);"; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ExecuteScriptHelper(adapter.render_view_host(), frame_xpath, script, 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NULL); 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptInFrameAndExtractInt( 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const internal::ToRenderViewHost& adapter, 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& frame_xpath, 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script, 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int* result) { 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DCHECK(result); 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<Value> value; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ExecuteScriptHelper(adapter.render_view_host(), frame_xpath, script, 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &value) || !value.get()) 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value->GetAsInteger(result); 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptInFrameAndExtractBool( 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const internal::ToRenderViewHost& adapter, 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& frame_xpath, 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script, 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool* result) { 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DCHECK(result); 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<Value> value; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ExecuteScriptHelper(adapter.render_view_host(), frame_xpath, script, 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &value) || !value.get()) 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value->GetAsBoolean(result); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptInFrameAndExtractString( 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const internal::ToRenderViewHost& adapter, 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& frame_xpath, 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script, 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string* result) { 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DCHECK(result); 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scoped_ptr<Value> value; 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ExecuteScriptHelper(adapter.render_view_host(), frame_xpath, script, 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &value) || !value.get()) 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return value->GetAsString(result); 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScript(const internal::ToRenderViewHost& adapter, 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script) { 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ExecuteScriptInFrame(adapter, std::string(), script); 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptAndExtractInt(const internal::ToRenderViewHost& adapter, 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script, int* result) { 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ExecuteScriptInFrameAndExtractInt(adapter, std::string(), script, 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result); 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptAndExtractBool(const internal::ToRenderViewHost& adapter, 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script, bool* result) { 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ExecuteScriptInFrameAndExtractBool(adapter, std::string(), script, 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result); 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteScriptAndExtractString(const internal::ToRenderViewHost& adapter, 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& script, 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string* result) { 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ExecuteScriptInFrameAndExtractString(adapter, std::string(), script, 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result); 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ExecuteWebUIResourceTest( 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const internal::ToRenderViewHost& adapter, 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::vector<int>& js_resource_ids) { 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Inject WebUI test runner script first prior to other scripts required to 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // run the test as scripts may depend on it being declared. 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::vector<int> ids; 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ids.push_back(IDR_WEBUI_JS_WEBUI_RESOURCE_TEST); 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ids.insert(ids.end(), js_resource_ids.begin(), js_resource_ids.end()); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string script; 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (std::vector<int>::iterator iter = ids.begin(); 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != ids.end(); 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iter) { 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ResourceBundle::GetSharedInstance().GetRawDataResource(*iter) 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org .AppendToString(&script); 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org script.append("\n"); 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!content::ExecuteScript(adapter, script)) 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org content::DOMMessageQueue message_queue; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!content::ExecuteScript(adapter, "runTests()")) 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string message; 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do { 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!message_queue.WaitForMessage(&message)) 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } while (message.compare("\"PENDING\"") == 0); 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return message.compare("\"SUCCESS\"") == 0; 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstd::string GetCookies(BrowserContext* browser_context, const GURL& url) { 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string cookies; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::WaitableEvent event(true, false); 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org net::URLRequestContextGetter* context_getter = 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org browser_context->GetRequestContext(); 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BrowserThread::PostTask( 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BrowserThread::IO, FROM_HERE, 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&GetCookiesOnIOThread, url, 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org make_scoped_refptr(context_getter), &event, &cookies)); 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event.Wait(); 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return cookies; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool SetCookie(BrowserContext* browser_context, 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GURL& url, 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string& value) { 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool result = false; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::WaitableEvent event(true, false); 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org net::URLRequestContextGetter* context_getter = 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org browser_context->GetRequestContext(); 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BrowserThread::PostTask( 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BrowserThread::IO, FROM_HERE, 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base::Bind(&SetCookieOnIOThread, url, value, 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org make_scoped_refptr(context_getter), &event, &result)); 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org event.Wait(); 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTitleWatcher::TitleWatcher(WebContents* web_contents, 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const string16& expected_title) 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : WebContentsObserver(web_contents), 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org message_loop_runner_(new MessageLoopRunner) { 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EXPECT_TRUE(web_contents != NULL); 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expected_titles_.push_back(expected_title); 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TitleWatcher::AlsoWaitForTitle(const string16& expected_title) { 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expected_titles_.push_back(expected_title); 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTitleWatcher::~TitleWatcher() { 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst string16& TitleWatcher::WaitAndGetTitle() { 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org message_loop_runner_->Run(); 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return observed_title_; 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid TitleWatcher::DidStopLoading(RenderViewHost* render_view_host) { 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // When navigating through the history, the restored NavigationEntry's title 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // will be used. If the entry ends up having the same title after we return 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // to it, as will usually be the case, then WebContentsObserver::TitleSet 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // will then be suppressed, since the NavigationEntry's title hasn't changed. 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TestTitle(); 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 568 569void TitleWatcher::TitleWasSet(NavigationEntry* entry, bool explicit_set) { 570 TestTitle(); 571} 572 573void TitleWatcher::TestTitle() { 574 std::vector<string16>::const_iterator it = 575 std::find(expected_titles_.begin(), 576 expected_titles_.end(), 577 web_contents()->GetTitle()); 578 if (it == expected_titles_.end()) 579 return; 580 581 observed_title_ = *it; 582 message_loop_runner_->Quit(); 583} 584 585WebContentsDestroyedWatcher::WebContentsDestroyedWatcher( 586 WebContents* web_contents) 587 : WebContentsObserver(web_contents), 588 message_loop_runner_(new MessageLoopRunner) { 589 EXPECT_TRUE(web_contents != NULL); 590} 591 592WebContentsDestroyedWatcher::~WebContentsDestroyedWatcher() { 593} 594 595void WebContentsDestroyedWatcher::Wait() { 596 message_loop_runner_->Run(); 597} 598 599void WebContentsDestroyedWatcher::WebContentsDestroyed( 600 WebContents* web_contents) { 601 message_loop_runner_->Quit(); 602} 603 604DOMMessageQueue::DOMMessageQueue() : waiting_for_message_(false) { 605 registrar_.Add(this, NOTIFICATION_DOM_OPERATION_RESPONSE, 606 NotificationService::AllSources()); 607} 608 609DOMMessageQueue::~DOMMessageQueue() {} 610 611void DOMMessageQueue::Observe(int type, 612 const NotificationSource& source, 613 const NotificationDetails& details) { 614 Details<DomOperationNotificationDetails> dom_op_details(details); 615 Source<RenderViewHost> sender(source); 616 message_queue_.push(dom_op_details->json); 617 if (waiting_for_message_) { 618 waiting_for_message_ = false; 619 message_loop_runner_->Quit(); 620 } 621} 622 623void DOMMessageQueue::ClearQueue() { 624 message_queue_ = std::queue<std::string>(); 625} 626 627bool DOMMessageQueue::WaitForMessage(std::string* message) { 628 if (message_queue_.empty()) { 629 waiting_for_message_ = true; 630 // This will be quit when a new message comes in. 631 message_loop_runner_ = new MessageLoopRunner; 632 message_loop_runner_->Run(); 633 } 634 // The queue should not be empty, unless we were quit because of a timeout. 635 if (message_queue_.empty()) 636 return false; 637 if (message) 638 *message = message_queue_.front(); 639 message_queue_.pop(); 640 return true; 641} 642 643} // namespace content 644