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

Side by Side Diff: chrome/test/base/render_view_test.cc

Issue 8230034: Split most of RenderViewTest and associated classes into content. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ready for review! Created 9 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
jam 2011/10/13 17:35:32 weird how rietveld shows this as M instead of D
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/test/base/render_view_test.h"
6
7 #include "chrome/browser/extensions/extension_function_dispatcher.h"
8 #include "chrome/common/extensions/extension.h"
9 #include "chrome/common/print_messages.h"
10 #include "chrome/common/render_messages.h"
11 #include "chrome/renderer/autofill/password_autofill_manager.h"
12 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
13 #include "chrome/renderer/extensions/chrome_v8_extension.h"
14 #include "chrome/renderer/extensions/event_bindings.h"
15 #include "chrome/renderer/extensions/extension_dispatcher.h"
16 #include "chrome/renderer/extensions/extension_process_bindings.h"
17 #include "chrome/renderer/extensions/renderer_extension_bindings.h"
18 #include "content/common/dom_storage_common.h"
19 #include "content/common/native_web_keyboard_event.h"
20 #include "content/common/renderer_preferences.h"
21 #include "content/common/view_messages.h"
22 #include "content/renderer/render_view_impl.h"
23 #include "content/renderer/renderer_main_platform_delegate.h"
24 #include "content/test/mock_render_process.h"
25 #include "grit/renderer_resources.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h "
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
33 #include "webkit/glue/webkit_glue.h"
34
35 #if defined(OS_LINUX) && !defined(USE_AURA)
36 #include "ui/base/gtk/event_synthesis_gtk.h"
37 #endif
38
39 using WebKit::WebFrame;
40 using WebKit::WebInputEvent;
41 using WebKit::WebMouseEvent;
42 using WebKit::WebScriptController;
43 using WebKit::WebScriptSource;
44 using WebKit::WebString;
45 using WebKit::WebURLRequest;
46 using autofill::AutofillAgent;
47 using autofill::PasswordAutofillManager;
48
49 namespace {
50 const int32 kRouteId = 5;
51 const int32 kOpenerId = 7;
52 } // namespace
53
54 RenderViewTest::RenderViewTest() : extension_dispatcher_(NULL), view_(NULL) {
55 }
56
57 RenderViewTest::~RenderViewTest() {
58 }
59
60 void RenderViewTest::ProcessPendingMessages() {
61 msg_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask());
62 msg_loop_.Run();
63 }
64
65 WebFrame* RenderViewTest::GetMainFrame() {
66 return view_->GetWebView()->mainFrame();
67 }
68
69 void RenderViewTest::ExecuteJavaScript(const char* js) {
70 GetMainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(js)));
71 }
72
73 bool RenderViewTest::ExecuteJavaScriptAndReturnIntValue(
74 const string16& script,
75 int* int_result) {
76 v8::Handle<v8::Value> result =
77 GetMainFrame()->executeScriptAndReturnValue(WebScriptSource(script));
78 if (result.IsEmpty() || !result->IsInt32())
79 return false;
80
81 if (int_result)
82 *int_result = result->Int32Value();
83
84 return true;
85 }
86
87 void RenderViewTest::LoadHTML(const char* html) {
88 std::string url_str = "data:text/html;charset=utf-8,";
89 url_str.append(html);
90 GURL url(url_str);
91
92 GetMainFrame()->loadRequest(WebURLRequest(url));
93
94 // The load actually happens asynchronously, so we pump messages to process
95 // the pending continuation.
96 ProcessPendingMessages();
97 }
98
99 void RenderViewTest::SetUp() {
100 content::GetContentClient()->set_renderer(&chrome_content_renderer_client_);
101 extension_dispatcher_ = new ExtensionDispatcher();
102 chrome_content_renderer_client_.SetExtensionDispatcher(extension_dispatcher_);
103 sandbox_init_wrapper_.reset(new SandboxInitWrapper());
104 command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
105 params_.reset(new MainFunctionParams(*command_line_, *sandbox_init_wrapper_,
106 NULL));
107 platform_.reset(new RendererMainPlatformDelegate(*params_));
108 platform_->PlatformInitialize();
109
110 // Setting flags and really doing anything with WebKit is fairly fragile and
111 // hacky, but this is the world we live in...
112 webkit_glue::SetJavaScriptFlags(" --expose-gc");
113 WebKit::initialize(&webkit_platform_support_);
114
115 WebScriptController::registerExtension(new ChromeV8Extension(
116 "extensions/json_schema.js", IDR_JSON_SCHEMA_JS, NULL));
117 WebScriptController::registerExtension(EventBindings::Get(
118 extension_dispatcher_));
119 WebScriptController::registerExtension(RendererExtensionBindings::Get(
120 extension_dispatcher_));
121 WebScriptController::registerExtension(ExtensionProcessBindings::Get(
122 extension_dispatcher_));
123 WebScriptController::registerExtension(new ChromeV8Extension(
124 "extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL));
125
126 mock_process_.reset(new MockRenderProcess);
127
128 render_thread_.set_routing_id(kRouteId);
129
130 // This needs to pass the mock render thread to the view.
131 RenderViewImpl* view = RenderViewImpl::Create(
132 0,
133 kOpenerId,
134 RendererPreferences(),
135 WebPreferences(),
136 new SharedRenderViewCounter(0),
137 kRouteId,
138 kInvalidSessionStorageNamespaceId,
139 string16());
140 view->AddRef();
141 view_ = view;
142
143 // Attach a pseudo keyboard device to this object.
144 mock_keyboard_.reset(new MockKeyboard());
145
146 // RenderView doesn't expose it's PasswordAutofillManager or
147 // AutofillAgent objects, because it has no need to store them directly
148 // (they're stored as RenderViewObserver*). So just create another set.
149 password_autofill_ = new PasswordAutofillManager(view_);
150 autofill_agent_ = new AutofillAgent(view_, password_autofill_);
151 }
152
153 void RenderViewTest::TearDown() {
154 // Try very hard to collect garbage before shutting down.
155 GetMainFrame()->collectGarbage();
156 GetMainFrame()->collectGarbage();
157
158 render_thread_.SendCloseMessage();
159
160 // Run the loop so the release task from the renderwidget executes.
161 ProcessPendingMessages();
162
163 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
164 impl->Release();
165 view_ = NULL;
166
167 mock_process_.reset();
168
169 // After resetting the view_ and mock_process_ we may get some new tasks
170 // which need to be processed before shutting down WebKit
171 // (http://crbug.com/21508).
172 msg_loop_.RunAllPending();
173
174 WebKit::shutdown();
175
176 mock_keyboard_.reset();
177
178 platform_->PlatformUninitialize();
179 platform_.reset();
180 params_.reset();
181 command_line_.reset();
182 sandbox_init_wrapper_.reset();
183
184 extension_dispatcher_->OnRenderProcessShutdown();
185 extension_dispatcher_ = NULL;
186 }
187
188 int RenderViewTest::SendKeyEvent(MockKeyboard::Layout layout,
189 int key_code,
190 MockKeyboard::Modifiers modifiers,
191 std::wstring* output) {
192 #if defined(OS_WIN)
193 // Retrieve the Unicode character for the given tuple (keyboard-layout,
194 // key-code, and modifiers).
195 // Exit when a keyboard-layout driver cannot assign a Unicode character to
196 // the tuple to prevent sending an invalid key code to the RenderView object.
197 CHECK(mock_keyboard_.get());
198 CHECK(output);
199 int length = mock_keyboard_->GetCharacters(layout, key_code, modifiers,
200 output);
201 if (length != 1)
202 return -1;
203
204 // Create IPC messages from Windows messages and send them to our
205 // back-end.
206 // A keyboard event of Windows consists of three Windows messages:
207 // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
208 // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
209 // WM_CHAR sends a composed Unicode character.
210 NativeWebKeyboardEvent keydown_event(NULL, WM_KEYDOWN, key_code, 0);
211 SendNativeKeyEvent(keydown_event);
212
213 NativeWebKeyboardEvent char_event(NULL, WM_CHAR, (*output)[0], 0);
214 SendNativeKeyEvent(char_event);
215
216 NativeWebKeyboardEvent keyup_event(NULL, WM_KEYUP, key_code, 0);
217 SendNativeKeyEvent(keyup_event);
218
219 return length;
220 #elif defined(OS_LINUX) && !defined(USE_AURA)
221 // We ignore |layout|, which means we are only testing the layout of the
222 // current locale. TODO(estade): fix this to respect |layout|.
223 std::vector<GdkEvent*> events;
224 ui::SynthesizeKeyPressEvents(
225 NULL, static_cast<ui::KeyboardCode>(key_code),
226 modifiers & (MockKeyboard::LEFT_CONTROL | MockKeyboard::RIGHT_CONTROL),
227 modifiers & (MockKeyboard::LEFT_SHIFT | MockKeyboard::RIGHT_SHIFT),
228 modifiers & (MockKeyboard::LEFT_ALT | MockKeyboard::RIGHT_ALT),
229 &events);
230
231 guint32 unicode_key = 0;
232 for (size_t i = 0; i < events.size(); ++i) {
233 // Only send the up/down events for key press itself (skip the up/down
234 // events for the modifier keys).
235 if ((i + 1) == (events.size() / 2) || i == (events.size() / 2)) {
236 unicode_key = gdk_keyval_to_unicode(events[i]->key.keyval);
237 NativeWebKeyboardEvent webkit_event(&events[i]->key);
238 SendNativeKeyEvent(webkit_event);
239
240 // Need to add a char event after the key down.
241 if (webkit_event.type == WebKit::WebInputEvent::RawKeyDown) {
242 NativeWebKeyboardEvent char_event = webkit_event;
243 char_event.type = WebKit::WebInputEvent::Char;
244 char_event.skip_in_browser = true;
245 SendNativeKeyEvent(char_event);
246 }
247 }
248 gdk_event_free(events[i]);
249 }
250
251 *output = std::wstring(1, unicode_key);
252 return 1;
253 #else
254 NOTIMPLEMENTED();
255 return L'\0';
256 #endif
257 }
258
259 void RenderViewTest::SendNativeKeyEvent(
260 const NativeWebKeyboardEvent& key_event) {
261 scoped_ptr<IPC::Message> input_message(new ViewMsg_HandleInputEvent(0));
262 input_message->WriteData(reinterpret_cast<const char*>(&key_event),
263 sizeof(WebKit::WebKeyboardEvent));
264 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
265 impl->OnMessageReceived(*input_message);
266 }
267
268 const char* const kGetCoordinatesScript =
269 "(function() {"
270 " function GetCoordinates(elem) {"
271 " if (!elem)"
272 " return [ 0, 0];"
273 " var coordinates = [ elem.offsetLeft, elem.offsetTop];"
274 " var parent_coordinates = GetCoordinates(elem.offsetParent);"
275 " coordinates[0] += parent_coordinates[0];"
276 " coordinates[1] += parent_coordinates[1];"
277 " return coordinates;"
278 " };"
279 " var elem = document.getElementById('$1');"
280 " if (!elem)"
281 " return null;"
282 " var bounds = GetCoordinates(elem);"
283 " bounds[2] = elem.offsetWidth;"
284 " bounds[3] = elem.offsetHeight;"
285 " return bounds;"
286 "})();";
287 gfx::Rect RenderViewTest::GetElementBounds(const std::string& element_id) {
288 std::vector<std::string> params;
289 params.push_back(element_id);
290 std::string script =
291 ReplaceStringPlaceholders(kGetCoordinatesScript, params, NULL);
292
293 v8::HandleScope handle_scope;
294 v8::Handle<v8::Value> value = GetMainFrame()->executeScriptAndReturnValue(
295 WebScriptSource(WebString::fromUTF8(script)));
296 if (value.IsEmpty() || !value->IsArray())
297 return gfx::Rect();
298
299 v8::Handle<v8::Array> array = value.As<v8::Array>();
300 if (array->Length() != 4)
301 return gfx::Rect();
302 std::vector<int> coords;
303 for (int i = 0; i < 4; ++i) {
304 v8::Handle<v8::Number> index = v8::Number::New(i);
305 v8::Local<v8::Value> value = array->Get(index);
306 if (value.IsEmpty() || !value->IsInt32())
307 return gfx::Rect();
308 coords.push_back(value->Int32Value());
309 }
310 return gfx::Rect(coords[0], coords[1], coords[2], coords[3]);
311 }
312
313 bool RenderViewTest::SimulateElementClick(const std::string& element_id) {
314 gfx::Rect bounds = GetElementBounds(element_id);
315 if (bounds.IsEmpty())
316 return false;
317 WebMouseEvent mouse_event;
318 mouse_event.type = WebInputEvent::MouseDown;
319 mouse_event.button = WebMouseEvent::ButtonLeft;
320 mouse_event.x = bounds.CenterPoint().x();
321 mouse_event.y = bounds.CenterPoint().y();
322 mouse_event.clickCount = 1;
323 ViewMsg_HandleInputEvent input_event(0);
324 scoped_ptr<IPC::Message> input_message(new ViewMsg_HandleInputEvent(0));
325 input_message->WriteData(reinterpret_cast<const char*>(&mouse_event),
326 sizeof(WebMouseEvent));
327 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
328 impl->OnMessageReceived(*input_message);
329 return true;
330 }
331
332 void RenderViewTest::ClearHistory() {
333 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
334 impl->page_id_ = -1;
335 impl->history_list_offset_ = -1;
336 impl->history_list_length_ = 0;
337 impl->history_page_ids_.clear();
338 }
339
340 bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) {
341 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
342 return impl->OnMessageReceived(msg);
343 }
344
345 void RenderViewTest::OnNavigate(const ViewMsg_Navigate_Params& params) {
346 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
347 impl->OnNavigate(params);
348 }
349
350 void RenderViewTest::DidNavigateWithinPage(WebKit::WebFrame* frame,
351 bool is_new_navigation) {
352 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
353 impl->didNavigateWithinPage(frame, is_new_navigation);
354 }
355
356 void RenderViewTest::SendContentStateImmediately() {
357 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
358 impl->set_send_content_state_immediately(true);
359 }
360
361 WebKit::WebWidget* RenderViewTest::GetWebWidget() {
362 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
363 return impl->webwidget();
364 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698