OLD | NEW |
| (Empty) |
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 "content/shell/webkit_test_controller.h" | |
6 | |
7 #include <iostream> | |
8 | |
9 #include "base/base64.h" | |
10 #include "base/command_line.h" | |
11 #include "base/message_loop/message_loop.h" | |
12 #include "base/run_loop.h" | |
13 #include "base/strings/string_number_conversions.h" | |
14 #include "base/strings/stringprintf.h" | |
15 #include "content/public/browser/devtools_manager.h" | |
16 #include "content/public/browser/gpu_data_manager.h" | |
17 #include "content/public/browser/navigation_controller.h" | |
18 #include "content/public/browser/navigation_entry.h" | |
19 #include "content/public/browser/notification_service.h" | |
20 #include "content/public/browser/notification_types.h" | |
21 #include "content/public/browser/render_process_host.h" | |
22 #include "content/public/browser/render_view_host.h" | |
23 #include "content/public/browser/render_widget_host_view.h" | |
24 #include "content/public/browser/web_contents.h" | |
25 #include "content/public/browser/web_contents_view.h" | |
26 #include "content/public/common/content_switches.h" | |
27 #include "content/shell/common/shell_messages.h" | |
28 #include "content/shell/common/shell_switches.h" | |
29 #include "content/shell/common/webkit_test_helpers.h" | |
30 #include "content/shell/shell.h" | |
31 #include "content/shell/shell_browser_context.h" | |
32 #include "content/shell/shell_content_browser_client.h" | |
33 #include "ui/gfx/codec/png_codec.h" | |
34 | |
35 namespace content { | |
36 | |
37 const int kTestSVGWindowWidthDip = 480; | |
38 const int kTestSVGWindowHeightDip = 360; | |
39 | |
40 // WebKitTestResultPrinter ---------------------------------------------------- | |
41 | |
42 WebKitTestResultPrinter::WebKitTestResultPrinter( | |
43 std::ostream* output, std::ostream* error) | |
44 : state_(DURING_TEST), | |
45 capture_text_only_(false), | |
46 encode_binary_data_(false), | |
47 output_(output), | |
48 error_(error) { | |
49 } | |
50 | |
51 WebKitTestResultPrinter::~WebKitTestResultPrinter() { | |
52 } | |
53 | |
54 void WebKitTestResultPrinter::PrintTextHeader() { | |
55 if (state_ != DURING_TEST) | |
56 return; | |
57 if (!capture_text_only_) | |
58 *output_ << "Content-Type: text/plain\n"; | |
59 state_ = IN_TEXT_BLOCK; | |
60 } | |
61 | |
62 void WebKitTestResultPrinter::PrintTextBlock(const std::string& block) { | |
63 if (state_ != IN_TEXT_BLOCK) | |
64 return; | |
65 *output_ << block; | |
66 } | |
67 | |
68 void WebKitTestResultPrinter::PrintTextFooter() { | |
69 if (state_ != IN_TEXT_BLOCK) | |
70 return; | |
71 if (!capture_text_only_) { | |
72 *output_ << "#EOF\n"; | |
73 output_->flush(); | |
74 } | |
75 state_ = IN_IMAGE_BLOCK; | |
76 } | |
77 | |
78 void WebKitTestResultPrinter::PrintImageHeader( | |
79 const std::string& actual_hash, | |
80 const std::string& expected_hash) { | |
81 if (state_ != IN_IMAGE_BLOCK || capture_text_only_) | |
82 return; | |
83 *output_ << "\nActualHash: " << actual_hash << "\n"; | |
84 if (!expected_hash.empty()) | |
85 *output_ << "\nExpectedHash: " << expected_hash << "\n"; | |
86 } | |
87 | |
88 void WebKitTestResultPrinter::PrintImageBlock( | |
89 const std::vector<unsigned char>& png_image) { | |
90 if (state_ != IN_IMAGE_BLOCK || capture_text_only_) | |
91 return; | |
92 *output_ << "Content-Type: image/png\n"; | |
93 if (encode_binary_data_) { | |
94 PrintEncodedBinaryData(png_image); | |
95 return; | |
96 } | |
97 | |
98 *output_ << "Content-Length: " << png_image.size() << "\n"; | |
99 output_->write( | |
100 reinterpret_cast<const char*>(&png_image[0]), png_image.size()); | |
101 } | |
102 | |
103 void WebKitTestResultPrinter::PrintImageFooter() { | |
104 if (state_ != IN_IMAGE_BLOCK) | |
105 return; | |
106 if (!capture_text_only_) { | |
107 *output_ << "#EOF\n"; | |
108 *error_ << "#EOF\n"; | |
109 output_->flush(); | |
110 error_->flush(); | |
111 } | |
112 state_ = AFTER_TEST; | |
113 } | |
114 | |
115 void WebKitTestResultPrinter::PrintAudioHeader() { | |
116 DCHECK_EQ(state_, DURING_TEST); | |
117 if (!capture_text_only_) | |
118 *output_ << "Content-Type: audio/wav\n"; | |
119 state_ = IN_AUDIO_BLOCK; | |
120 } | |
121 | |
122 void WebKitTestResultPrinter::PrintAudioBlock( | |
123 const std::vector<unsigned char>& audio_data) { | |
124 if (state_ != IN_AUDIO_BLOCK || capture_text_only_) | |
125 return; | |
126 if (encode_binary_data_) { | |
127 PrintEncodedBinaryData(audio_data); | |
128 return; | |
129 } | |
130 | |
131 *output_ << "Content-Length: " << audio_data.size() << "\n"; | |
132 output_->write( | |
133 reinterpret_cast<const char*>(&audio_data[0]), audio_data.size()); | |
134 } | |
135 | |
136 void WebKitTestResultPrinter::PrintAudioFooter() { | |
137 if (state_ != IN_AUDIO_BLOCK) | |
138 return; | |
139 if (!capture_text_only_) { | |
140 *output_ << "#EOF\n"; | |
141 *error_ << "#EOF\n"; | |
142 output_->flush(); | |
143 error_->flush(); | |
144 } | |
145 state_ = IN_IMAGE_BLOCK; | |
146 } | |
147 | |
148 void WebKitTestResultPrinter::AddMessage(const std::string& message) { | |
149 AddMessageRaw(message + "\n"); | |
150 } | |
151 | |
152 void WebKitTestResultPrinter::AddMessageRaw(const std::string& message) { | |
153 if (state_ != DURING_TEST) | |
154 return; | |
155 *output_ << message; | |
156 } | |
157 | |
158 void WebKitTestResultPrinter::AddErrorMessage(const std::string& message) { | |
159 if (!capture_text_only_) | |
160 *error_ << message << "\n"; | |
161 if (state_ != DURING_TEST) | |
162 return; | |
163 PrintTextHeader(); | |
164 *output_ << message << "\n"; | |
165 PrintTextFooter(); | |
166 PrintImageFooter(); | |
167 } | |
168 | |
169 void WebKitTestResultPrinter::PrintEncodedBinaryData( | |
170 const std::vector<unsigned char>& data) { | |
171 *output_ << "Content-Transfer-Encoding: base64\n"; | |
172 | |
173 std::string data_base64; | |
174 const bool success = base::Base64Encode( | |
175 base::StringPiece(reinterpret_cast<const char*>(&data[0]), data.size()), | |
176 &data_base64); | |
177 DCHECK(success); | |
178 | |
179 *output_ << "Content-Length: " << data_base64.length() << "\n"; | |
180 output_->write(data_base64.c_str(), data_base64.length()); | |
181 } | |
182 | |
183 | |
184 // WebKitTestController ------------------------------------------------------- | |
185 | |
186 WebKitTestController* WebKitTestController::instance_ = NULL; | |
187 | |
188 // static | |
189 WebKitTestController* WebKitTestController::Get() { | |
190 DCHECK(instance_); | |
191 return instance_; | |
192 } | |
193 | |
194 WebKitTestController::WebKitTestController() | |
195 : main_window_(NULL), | |
196 test_phase_(BETWEEN_TESTS) { | |
197 CHECK(!instance_); | |
198 instance_ = this; | |
199 printer_.reset(new WebKitTestResultPrinter(&std::cout, &std::cerr)); | |
200 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEncodeBinary)) | |
201 printer_->set_encode_binary_data(true); | |
202 registrar_.Add(this, | |
203 NOTIFICATION_RENDERER_PROCESS_CREATED, | |
204 NotificationService::AllSources()); | |
205 GpuDataManager::GetInstance()->AddObserver(this); | |
206 ResetAfterLayoutTest(); | |
207 } | |
208 | |
209 WebKitTestController::~WebKitTestController() { | |
210 DCHECK(CalledOnValidThread()); | |
211 CHECK(instance_ == this); | |
212 CHECK(test_phase_ == BETWEEN_TESTS); | |
213 GpuDataManager::GetInstance()->RemoveObserver(this); | |
214 DiscardMainWindow(); | |
215 instance_ = NULL; | |
216 } | |
217 | |
218 bool WebKitTestController::PrepareForLayoutTest( | |
219 const GURL& test_url, | |
220 const base::FilePath& current_working_directory, | |
221 bool enable_pixel_dumping, | |
222 const std::string& expected_pixel_hash) { | |
223 DCHECK(CalledOnValidThread()); | |
224 test_phase_ = DURING_TEST; | |
225 current_working_directory_ = current_working_directory; | |
226 enable_pixel_dumping_ = enable_pixel_dumping; | |
227 expected_pixel_hash_ = expected_pixel_hash; | |
228 test_url_ = test_url; | |
229 printer_->reset(); | |
230 ShellBrowserContext* browser_context = | |
231 ShellContentBrowserClient::Get()->browser_context(); | |
232 if (test_url.spec().find("compositing/") != std::string::npos) | |
233 is_compositing_test_ = true; | |
234 initial_size_ = gfx::Size( | |
235 Shell::kDefaultTestWindowWidthDip, Shell::kDefaultTestWindowHeightDip); | |
236 // The W3C SVG layout tests use a different size than the other layout tests. | |
237 if (test_url.spec().find("W3C-SVG-1.1") != std::string::npos) | |
238 initial_size_ = gfx::Size(kTestSVGWindowWidthDip, kTestSVGWindowHeightDip); | |
239 if (!main_window_) { | |
240 main_window_ = content::Shell::CreateNewWindow( | |
241 browser_context, | |
242 GURL(), | |
243 NULL, | |
244 MSG_ROUTING_NONE, | |
245 initial_size_); | |
246 WebContentsObserver::Observe(main_window_->web_contents()); | |
247 send_configuration_to_next_host_ = true; | |
248 current_pid_ = base::kNullProcessId; | |
249 main_window_->LoadURL(test_url); | |
250 } else { | |
251 #if (defined(OS_WIN) && !defined(USE_AURA)) || \ | |
252 defined(TOOLKIT_GTK) || defined(OS_MACOSX) | |
253 // Shell::SizeTo is not implemented on all platforms. | |
254 main_window_->SizeTo(initial_size_.width(), initial_size_.height()); | |
255 #endif | |
256 main_window_->web_contents()->GetRenderViewHost()->GetView() | |
257 ->SetSize(initial_size_); | |
258 main_window_->web_contents()->GetRenderViewHost()->WasResized(); | |
259 RenderViewHost* render_view_host = | |
260 main_window_->web_contents()->GetRenderViewHost(); | |
261 WebPreferences prefs = render_view_host->GetWebkitPreferences(); | |
262 OverrideWebkitPrefs(&prefs); | |
263 render_view_host->UpdateWebkitPreferences(prefs); | |
264 SendTestConfiguration(); | |
265 | |
266 NavigationController::LoadURLParams params(test_url); | |
267 params.transition_type = PageTransitionFromInt( | |
268 PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR); | |
269 params.should_clear_history_list = true; | |
270 main_window_->web_contents()->GetController().LoadURLWithParams(params); | |
271 main_window_->web_contents()->GetView()->Focus(); | |
272 } | |
273 main_window_->web_contents()->GetRenderViewHost()->SetActive(true); | |
274 main_window_->web_contents()->GetRenderViewHost()->Focus(); | |
275 return true; | |
276 } | |
277 | |
278 bool WebKitTestController::ResetAfterLayoutTest() { | |
279 DCHECK(CalledOnValidThread()); | |
280 printer_->PrintTextFooter(); | |
281 printer_->PrintImageFooter(); | |
282 send_configuration_to_next_host_ = false; | |
283 test_phase_ = BETWEEN_TESTS; | |
284 is_compositing_test_ = false; | |
285 enable_pixel_dumping_ = false; | |
286 expected_pixel_hash_.clear(); | |
287 test_url_ = GURL(); | |
288 prefs_ = WebPreferences(); | |
289 should_override_prefs_ = false; | |
290 return true; | |
291 } | |
292 | |
293 void WebKitTestController::SetTempPath(const base::FilePath& temp_path) { | |
294 temp_path_ = temp_path; | |
295 } | |
296 | |
297 void WebKitTestController::RendererUnresponsive() { | |
298 DCHECK(CalledOnValidThread()); | |
299 LOG(WARNING) << "renderer unresponsive"; | |
300 } | |
301 | |
302 void WebKitTestController::WorkerCrashed() { | |
303 DCHECK(CalledOnValidThread()); | |
304 printer_->AddErrorMessage("#CRASHED - worker"); | |
305 DiscardMainWindow(); | |
306 } | |
307 | |
308 void WebKitTestController::OverrideWebkitPrefs(WebPreferences* prefs) { | |
309 if (should_override_prefs_) { | |
310 *prefs = prefs_; | |
311 } else { | |
312 ApplyLayoutTestDefaultPreferences(prefs); | |
313 if (is_compositing_test_) { | |
314 CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
315 if (!command_line.HasSwitch(switches::kEnableSoftwareCompositing)) | |
316 prefs->accelerated_2d_canvas_enabled = true; | |
317 prefs->accelerated_compositing_for_video_enabled = true; | |
318 prefs->mock_scrollbars_enabled = true; | |
319 } | |
320 } | |
321 } | |
322 | |
323 void WebKitTestController::OpenURL(const GURL& url) { | |
324 if (test_phase_ != DURING_TEST) | |
325 return; | |
326 | |
327 Shell::CreateNewWindow(main_window_->web_contents()->GetBrowserContext(), | |
328 url, | |
329 main_window_->web_contents()->GetSiteInstance(), | |
330 MSG_ROUTING_NONE, | |
331 gfx::Size()); | |
332 } | |
333 | |
334 void WebKitTestController::TestFinishedInSecondaryWindow() { | |
335 RenderViewHost* render_view_host = | |
336 main_window_->web_contents()->GetRenderViewHost(); | |
337 render_view_host->Send( | |
338 new ShellViewMsg_NotifyDone(render_view_host->GetRoutingID())); | |
339 } | |
340 | |
341 bool WebKitTestController::IsMainWindow(WebContents* web_contents) const { | |
342 return main_window_ && web_contents == main_window_->web_contents(); | |
343 } | |
344 | |
345 bool WebKitTestController::OnMessageReceived(const IPC::Message& message) { | |
346 DCHECK(CalledOnValidThread()); | |
347 bool handled = true; | |
348 IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message) | |
349 IPC_MESSAGE_HANDLER(ShellViewHostMsg_PrintMessage, OnPrintMessage) | |
350 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TextDump, OnTextDump) | |
351 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ImageDump, OnImageDump) | |
352 IPC_MESSAGE_HANDLER(ShellViewHostMsg_AudioDump, OnAudioDump) | |
353 IPC_MESSAGE_HANDLER(ShellViewHostMsg_OverridePreferences, | |
354 OnOverridePreferences) | |
355 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TestFinished, OnTestFinished) | |
356 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ShowDevTools, OnShowDevTools) | |
357 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseDevTools, OnCloseDevTools) | |
358 IPC_MESSAGE_HANDLER(ShellViewHostMsg_GoToOffset, OnGoToOffset) | |
359 IPC_MESSAGE_HANDLER(ShellViewHostMsg_Reload, OnReload) | |
360 IPC_MESSAGE_HANDLER(ShellViewHostMsg_LoadURLForFrame, OnLoadURLForFrame) | |
361 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CaptureSessionHistory, | |
362 OnCaptureSessionHistory) | |
363 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseRemainingWindows, | |
364 OnCloseRemainingWindows) | |
365 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ResetDone, OnResetDone) | |
366 IPC_MESSAGE_UNHANDLED(handled = false) | |
367 IPC_END_MESSAGE_MAP() | |
368 | |
369 return handled; | |
370 } | |
371 | |
372 void WebKitTestController::PluginCrashed(const base::FilePath& plugin_path, | |
373 base::ProcessId plugin_pid) { | |
374 DCHECK(CalledOnValidThread()); | |
375 printer_->AddErrorMessage( | |
376 base::StringPrintf("#CRASHED - plugin (pid %d)", plugin_pid)); | |
377 base::MessageLoop::current()->PostTask( | |
378 FROM_HERE, | |
379 base::Bind(base::IgnoreResult(&WebKitTestController::DiscardMainWindow), | |
380 base::Unretained(this))); | |
381 } | |
382 | |
383 void WebKitTestController::RenderViewCreated(RenderViewHost* render_view_host) { | |
384 DCHECK(CalledOnValidThread()); | |
385 // Might be kNullProcessHandle, in which case we will receive a notification | |
386 // later when the RenderProcessHost was created. | |
387 if (render_view_host->GetProcess()->GetHandle() != base::kNullProcessHandle) | |
388 current_pid_ = base::GetProcId(render_view_host->GetProcess()->GetHandle()); | |
389 if (!send_configuration_to_next_host_) | |
390 return; | |
391 send_configuration_to_next_host_ = false; | |
392 SendTestConfiguration(); | |
393 } | |
394 | |
395 void WebKitTestController::RenderProcessGone(base::TerminationStatus status) { | |
396 DCHECK(CalledOnValidThread()); | |
397 if (current_pid_ != base::kNullProcessId) { | |
398 printer_->AddErrorMessage(std::string("#CRASHED - renderer (pid ") + | |
399 base::IntToString(current_pid_) + ")"); | |
400 } else { | |
401 printer_->AddErrorMessage("#CRASHED - renderer"); | |
402 } | |
403 DiscardMainWindow(); | |
404 } | |
405 | |
406 void WebKitTestController::WebContentsDestroyed(WebContents* web_contents) { | |
407 DCHECK(CalledOnValidThread()); | |
408 printer_->AddErrorMessage("FAIL: main window was destroyed"); | |
409 DiscardMainWindow(); | |
410 } | |
411 | |
412 void WebKitTestController::Observe(int type, | |
413 const NotificationSource& source, | |
414 const NotificationDetails& details) { | |
415 DCHECK(CalledOnValidThread()); | |
416 switch (type) { | |
417 case NOTIFICATION_RENDERER_PROCESS_CREATED: { | |
418 if (!main_window_) | |
419 return; | |
420 RenderViewHost* render_view_host = | |
421 main_window_->web_contents()->GetRenderViewHost(); | |
422 if (!render_view_host) | |
423 return; | |
424 RenderProcessHost* render_process_host = | |
425 Source<RenderProcessHost>(source).ptr(); | |
426 if (render_process_host != render_view_host->GetProcess()) | |
427 return; | |
428 current_pid_ = base::GetProcId(render_process_host->GetHandle()); | |
429 break; | |
430 } | |
431 default: | |
432 NOTREACHED(); | |
433 } | |
434 } | |
435 | |
436 void WebKitTestController::OnGpuProcessCrashed( | |
437 base::TerminationStatus exit_code) { | |
438 DCHECK(CalledOnValidThread()); | |
439 printer_->AddErrorMessage("#CRASHED - gpu"); | |
440 DiscardMainWindow(); | |
441 } | |
442 | |
443 void WebKitTestController::TimeoutHandler() { | |
444 DCHECK(CalledOnValidThread()); | |
445 printer_->AddErrorMessage( | |
446 "FAIL: Timed out waiting for notifyDone to be called"); | |
447 DiscardMainWindow(); | |
448 } | |
449 | |
450 void WebKitTestController::DiscardMainWindow() { | |
451 // If we're running a test, we need to close all windows and exit the message | |
452 // loop. Otherwise, we're already outside of the message loop, and we just | |
453 // discard the main window. | |
454 WebContentsObserver::Observe(NULL); | |
455 if (test_phase_ != BETWEEN_TESTS) { | |
456 Shell::CloseAllWindows(); | |
457 base::MessageLoop::current()->PostTask(FROM_HERE, | |
458 base::MessageLoop::QuitClosure()); | |
459 test_phase_ = CLEAN_UP; | |
460 } else if (main_window_) { | |
461 main_window_->Close(); | |
462 } | |
463 main_window_ = NULL; | |
464 current_pid_ = base::kNullProcessId; | |
465 } | |
466 | |
467 void WebKitTestController::SendTestConfiguration() { | |
468 RenderViewHost* render_view_host = | |
469 main_window_->web_contents()->GetRenderViewHost(); | |
470 ShellTestConfiguration params; | |
471 params.current_working_directory = current_working_directory_; | |
472 params.temp_path = temp_path_; | |
473 params.test_url = test_url_; | |
474 params.enable_pixel_dumping = enable_pixel_dumping_; | |
475 params.allow_external_pages = CommandLine::ForCurrentProcess()->HasSwitch( | |
476 switches::kAllowExternalPages); | |
477 params.expected_pixel_hash = expected_pixel_hash_; | |
478 params.initial_size = initial_size_; | |
479 render_view_host->Send(new ShellViewMsg_SetTestConfiguration( | |
480 render_view_host->GetRoutingID(), params)); | |
481 } | |
482 | |
483 void WebKitTestController::OnTestFinished() { | |
484 test_phase_ = CLEAN_UP; | |
485 if (!printer_->output_finished()) | |
486 printer_->PrintImageFooter(); | |
487 RenderViewHost* render_view_host = | |
488 main_window_->web_contents()->GetRenderViewHost(); | |
489 base::MessageLoop::current()->PostTask( | |
490 FROM_HERE, | |
491 base::Bind(base::IgnoreResult(&WebKitTestController::Send), | |
492 base::Unretained(this), | |
493 new ShellViewMsg_Reset(render_view_host->GetRoutingID()))); | |
494 } | |
495 | |
496 void WebKitTestController::OnImageDump( | |
497 const std::string& actual_pixel_hash, | |
498 const SkBitmap& image) { | |
499 SkAutoLockPixels image_lock(image); | |
500 | |
501 printer_->PrintImageHeader(actual_pixel_hash, expected_pixel_hash_); | |
502 | |
503 // Only encode and dump the png if the hashes don't match. Encoding the | |
504 // image is really expensive. | |
505 if (actual_pixel_hash != expected_pixel_hash_) { | |
506 std::vector<unsigned char> png; | |
507 | |
508 // Only the expected PNGs for Mac have a valid alpha channel. | |
509 #if defined(OS_MACOSX) | |
510 bool discard_transparency = false; | |
511 #else | |
512 bool discard_transparency = true; | |
513 #endif | |
514 | |
515 std::vector<gfx::PNGCodec::Comment> comments; | |
516 comments.push_back(gfx::PNGCodec::Comment("checksum", actual_pixel_hash)); | |
517 bool success = gfx::PNGCodec::Encode( | |
518 static_cast<const unsigned char*>(image.getPixels()), | |
519 gfx::PNGCodec::FORMAT_BGRA, | |
520 gfx::Size(image.width(), image.height()), | |
521 static_cast<int>(image.rowBytes()), | |
522 discard_transparency, | |
523 comments, | |
524 &png); | |
525 if (success) | |
526 printer_->PrintImageBlock(png); | |
527 } | |
528 printer_->PrintImageFooter(); | |
529 } | |
530 | |
531 void WebKitTestController::OnAudioDump(const std::vector<unsigned char>& dump) { | |
532 printer_->PrintAudioHeader(); | |
533 printer_->PrintAudioBlock(dump); | |
534 printer_->PrintAudioFooter(); | |
535 } | |
536 | |
537 void WebKitTestController::OnTextDump(const std::string& dump) { | |
538 printer_->PrintTextHeader(); | |
539 printer_->PrintTextBlock(dump); | |
540 printer_->PrintTextFooter(); | |
541 } | |
542 | |
543 void WebKitTestController::OnPrintMessage(const std::string& message) { | |
544 printer_->AddMessageRaw(message); | |
545 } | |
546 | |
547 void WebKitTestController::OnOverridePreferences(const WebPreferences& prefs) { | |
548 should_override_prefs_ = true; | |
549 prefs_ = prefs; | |
550 } | |
551 | |
552 void WebKitTestController::OnShowDevTools() { | |
553 main_window_->ShowDevTools(); | |
554 } | |
555 | |
556 void WebKitTestController::OnCloseDevTools() { | |
557 main_window_->CloseDevTools(); | |
558 } | |
559 | |
560 void WebKitTestController::OnGoToOffset(int offset) { | |
561 main_window_->GoBackOrForward(offset); | |
562 } | |
563 | |
564 void WebKitTestController::OnReload() { | |
565 main_window_->Reload(); | |
566 } | |
567 | |
568 void WebKitTestController::OnLoadURLForFrame(const GURL& url, | |
569 const std::string& frame_name) { | |
570 main_window_->LoadURLForFrame(url, frame_name); | |
571 } | |
572 | |
573 void WebKitTestController::OnCaptureSessionHistory() { | |
574 std::vector<int> routing_ids; | |
575 std::vector<std::vector<PageState> > session_histories; | |
576 std::vector<unsigned> current_entry_indexes; | |
577 | |
578 RenderViewHost* render_view_host = | |
579 main_window_->web_contents()->GetRenderViewHost(); | |
580 | |
581 for (std::vector<Shell*>::iterator window = Shell::windows().begin(); | |
582 window != Shell::windows().end(); | |
583 ++window) { | |
584 WebContents* web_contents = (*window)->web_contents(); | |
585 // Only capture the history from windows in the same process as the main | |
586 // window. During layout tests, we only use two processes when an | |
587 // devtools window is open. This should not happen during history navigation | |
588 // tests. | |
589 if (render_view_host->GetProcess() != | |
590 web_contents->GetRenderViewHost()->GetProcess()) { | |
591 NOTREACHED(); | |
592 continue; | |
593 } | |
594 routing_ids.push_back(web_contents->GetRenderViewHost()->GetRoutingID()); | |
595 current_entry_indexes.push_back( | |
596 web_contents->GetController().GetCurrentEntryIndex()); | |
597 std::vector<PageState> history; | |
598 for (int entry = 0; entry < web_contents->GetController().GetEntryCount(); | |
599 ++entry) { | |
600 PageState state = web_contents->GetController().GetEntryAtIndex(entry)-> | |
601 GetPageState(); | |
602 if (!state.IsValid()) { | |
603 state = PageState::CreateFromURL( | |
604 web_contents->GetController().GetEntryAtIndex(entry)->GetURL()); | |
605 } | |
606 history.push_back(state); | |
607 } | |
608 session_histories.push_back(history); | |
609 } | |
610 | |
611 Send(new ShellViewMsg_SessionHistory(render_view_host->GetRoutingID(), | |
612 routing_ids, | |
613 session_histories, | |
614 current_entry_indexes)); | |
615 } | |
616 | |
617 void WebKitTestController::OnCloseRemainingWindows() { | |
618 DevToolsManager::GetInstance()->CloseAllClientHosts(); | |
619 std::vector<Shell*> open_windows(Shell::windows()); | |
620 for (size_t i = 0; i < open_windows.size(); ++i) { | |
621 if (open_windows[i] != main_window_) | |
622 open_windows[i]->Close(); | |
623 } | |
624 base::MessageLoop::current()->RunUntilIdle(); | |
625 } | |
626 | |
627 void WebKitTestController::OnResetDone() { | |
628 base::MessageLoop::current()->PostTask(FROM_HERE, | |
629 base::MessageLoop::QuitClosure()); | |
630 } | |
631 | |
632 } // namespace content | |
OLD | NEW |