Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / content / shell / browser / blink_test_controller.cc
blob262b8fe8a24be7034a3ce82dcaedd7b347701de4
1 // Copyright 2013 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.
5 #include "content/shell/browser/blink_test_controller.h"
7 #include <iostream>
9 #include "base/base64.h"
10 #include "base/command_line.h"
11 #include "base/location.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "content/public/browser/devtools_agent_host.h"
18 #include "content/public/browser/dom_storage_context.h"
19 #include "content/public/browser/gpu_data_manager.h"
20 #include "content/public/browser/navigation_controller.h"
21 #include "content/public/browser/navigation_entry.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/render_process_host.h"
25 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/render_widget_host_view.h"
27 #include "content/public/browser/storage_partition.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/common/content_switches.h"
30 #include "content/public/common/url_constants.h"
31 #include "content/shell/browser/layout_test/layout_test_devtools_frontend.h"
32 #include "content/shell/browser/shell.h"
33 #include "content/shell/browser/shell_browser_context.h"
34 #include "content/shell/browser/shell_content_browser_client.h"
35 #include "content/shell/browser/shell_devtools_frontend.h"
36 #include "content/shell/common/shell_messages.h"
37 #include "content/shell/common/shell_switches.h"
38 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
39 #include "ui/gfx/codec/png_codec.h"
41 namespace content {
43 const int kTestSVGWindowWidthDip = 480;
44 const int kTestSVGWindowHeightDip = 360;
46 // BlinkTestResultPrinter ----------------------------------------------------
48 BlinkTestResultPrinter::BlinkTestResultPrinter(std::ostream* output,
49 std::ostream* error)
50 : state_(DURING_TEST),
51 capture_text_only_(false),
52 encode_binary_data_(false),
53 output_(output),
54 error_(error) {
57 BlinkTestResultPrinter::~BlinkTestResultPrinter() {
60 void BlinkTestResultPrinter::PrintTextHeader() {
61 if (state_ != DURING_TEST)
62 return;
63 if (!capture_text_only_)
64 *output_ << "Content-Type: text/plain\n";
65 state_ = IN_TEXT_BLOCK;
68 void BlinkTestResultPrinter::PrintTextBlock(const std::string& block) {
69 if (state_ != IN_TEXT_BLOCK)
70 return;
71 *output_ << block;
74 void BlinkTestResultPrinter::PrintTextFooter() {
75 if (state_ != IN_TEXT_BLOCK)
76 return;
77 if (!capture_text_only_) {
78 *output_ << "#EOF\n";
79 output_->flush();
81 state_ = IN_IMAGE_BLOCK;
84 void BlinkTestResultPrinter::PrintImageHeader(
85 const std::string& actual_hash,
86 const std::string& expected_hash) {
87 if (state_ != IN_IMAGE_BLOCK || capture_text_only_)
88 return;
89 *output_ << "\nActualHash: " << actual_hash << "\n";
90 if (!expected_hash.empty())
91 *output_ << "\nExpectedHash: " << expected_hash << "\n";
94 void BlinkTestResultPrinter::PrintImageBlock(
95 const std::vector<unsigned char>& png_image) {
96 if (state_ != IN_IMAGE_BLOCK || capture_text_only_)
97 return;
98 *output_ << "Content-Type: image/png\n";
99 if (encode_binary_data_) {
100 PrintEncodedBinaryData(png_image);
101 return;
104 *output_ << "Content-Length: " << png_image.size() << "\n";
105 output_->write(
106 reinterpret_cast<const char*>(&png_image[0]), png_image.size());
109 void BlinkTestResultPrinter::PrintImageFooter() {
110 if (state_ != IN_IMAGE_BLOCK)
111 return;
112 if (!capture_text_only_) {
113 *output_ << "#EOF\n";
114 output_->flush();
116 state_ = AFTER_TEST;
119 void BlinkTestResultPrinter::PrintAudioHeader() {
120 DCHECK_EQ(state_, DURING_TEST);
121 if (!capture_text_only_)
122 *output_ << "Content-Type: audio/wav\n";
123 state_ = IN_AUDIO_BLOCK;
126 void BlinkTestResultPrinter::PrintAudioBlock(
127 const std::vector<unsigned char>& audio_data) {
128 if (state_ != IN_AUDIO_BLOCK || capture_text_only_)
129 return;
130 if (encode_binary_data_) {
131 PrintEncodedBinaryData(audio_data);
132 return;
135 *output_ << "Content-Length: " << audio_data.size() << "\n";
136 output_->write(
137 reinterpret_cast<const char*>(&audio_data[0]), audio_data.size());
140 void BlinkTestResultPrinter::PrintAudioFooter() {
141 if (state_ != IN_AUDIO_BLOCK)
142 return;
143 if (!capture_text_only_) {
144 *output_ << "#EOF\n";
145 output_->flush();
147 state_ = IN_IMAGE_BLOCK;
150 void BlinkTestResultPrinter::AddMessage(const std::string& message) {
151 AddMessageRaw(message + "\n");
154 void BlinkTestResultPrinter::AddMessageRaw(const std::string& message) {
155 if (state_ != DURING_TEST)
156 return;
157 *output_ << message;
160 void BlinkTestResultPrinter::AddErrorMessage(const std::string& message) {
161 if (!capture_text_only_)
162 *error_ << message << "\n";
163 if (state_ != DURING_TEST)
164 return;
165 PrintTextHeader();
166 *output_ << message << "\n";
167 PrintTextFooter();
168 PrintImageFooter();
171 void BlinkTestResultPrinter::PrintEncodedBinaryData(
172 const std::vector<unsigned char>& data) {
173 *output_ << "Content-Transfer-Encoding: base64\n";
175 std::string data_base64;
176 base::Base64Encode(
177 base::StringPiece(reinterpret_cast<const char*>(&data[0]), data.size()),
178 &data_base64);
180 *output_ << "Content-Length: " << data_base64.length() << "\n";
181 output_->write(data_base64.c_str(), data_base64.length());
184 void BlinkTestResultPrinter::CloseStderr() {
185 if (state_ != AFTER_TEST)
186 return;
187 if (!capture_text_only_) {
188 *error_ << "#EOF\n";
189 error_->flush();
193 // BlinkTestController -------------------------------------------------------
195 BlinkTestController* BlinkTestController::instance_ = NULL;
197 // static
198 BlinkTestController* BlinkTestController::Get() {
199 DCHECK(instance_);
200 return instance_;
203 BlinkTestController::BlinkTestController()
204 : main_window_(NULL),
205 test_phase_(BETWEEN_TESTS),
206 is_leak_detection_enabled_(
207 base::CommandLine::ForCurrentProcess()->HasSwitch(
208 switches::kEnableLeakDetection)),
209 crash_when_leak_found_(false),
210 devtools_frontend_(NULL) {
211 CHECK(!instance_);
212 instance_ = this;
214 if (is_leak_detection_enabled_) {
215 std::string switchValue =
216 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
217 switches::kEnableLeakDetection);
218 crash_when_leak_found_ = switchValue == switches::kCrashOnFailure;
221 printer_.reset(new BlinkTestResultPrinter(&std::cout, &std::cerr));
222 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
223 switches::kEncodeBinary))
224 printer_->set_encode_binary_data(true);
225 registrar_.Add(this,
226 NOTIFICATION_RENDERER_PROCESS_CREATED,
227 NotificationService::AllSources());
228 GpuDataManager::GetInstance()->AddObserver(this);
229 ResetAfterLayoutTest();
232 BlinkTestController::~BlinkTestController() {
233 DCHECK(CalledOnValidThread());
234 CHECK(instance_ == this);
235 CHECK(test_phase_ == BETWEEN_TESTS);
236 GpuDataManager::GetInstance()->RemoveObserver(this);
237 DiscardMainWindow();
238 instance_ = NULL;
241 bool BlinkTestController::PrepareForLayoutTest(
242 const GURL& test_url,
243 const base::FilePath& current_working_directory,
244 bool enable_pixel_dumping,
245 const std::string& expected_pixel_hash) {
246 DCHECK(CalledOnValidThread());
247 test_phase_ = DURING_TEST;
248 current_working_directory_ = current_working_directory;
249 enable_pixel_dumping_ = enable_pixel_dumping;
250 expected_pixel_hash_ = expected_pixel_hash;
251 test_url_ = test_url;
252 printer_->reset();
253 ShellBrowserContext* browser_context =
254 ShellContentBrowserClient::Get()->browser_context();
255 if (test_url.spec().find("compositing/") != std::string::npos)
256 is_compositing_test_ = true;
257 initial_size_ = Shell::GetShellDefaultSize();
258 // The W3C SVG layout tests use a different size than the other layout tests.
259 if (test_url.spec().find("W3C-SVG-1.1") != std::string::npos)
260 initial_size_ = gfx::Size(kTestSVGWindowWidthDip, kTestSVGWindowHeightDip);
261 if (!main_window_) {
262 main_window_ = content::Shell::CreateNewWindow(
263 browser_context,
264 GURL(),
265 NULL,
266 initial_size_);
267 WebContentsObserver::Observe(main_window_->web_contents());
268 send_configuration_to_next_host_ = true;
269 current_pid_ = base::kNullProcessId;
270 main_window_->LoadURL(test_url);
271 } else {
272 #if defined(OS_MACOSX)
273 // Shell::SizeTo is not implemented on all platforms.
274 main_window_->SizeTo(initial_size_);
275 #endif
276 main_window_->web_contents()->GetRenderViewHost()->GetView()
277 ->SetSize(initial_size_);
278 main_window_->web_contents()->GetRenderViewHost()->WasResized();
279 RenderViewHost* render_view_host =
280 main_window_->web_contents()->GetRenderViewHost();
281 WebPreferences prefs = render_view_host->GetWebkitPreferences();
282 OverrideWebkitPrefs(&prefs);
283 render_view_host->UpdateWebkitPreferences(prefs);
284 SendTestConfiguration();
286 NavigationController::LoadURLParams params(test_url);
287 params.transition_type = ui::PageTransitionFromInt(
288 ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
289 params.should_clear_history_list = true;
290 main_window_->web_contents()->GetController().LoadURLWithParams(params);
291 main_window_->web_contents()->Focus();
293 main_window_->web_contents()->GetRenderViewHost()->SetActive(true);
294 main_window_->web_contents()->GetRenderViewHost()->Focus();
295 return true;
298 bool BlinkTestController::ResetAfterLayoutTest() {
299 DCHECK(CalledOnValidThread());
300 printer_->PrintTextFooter();
301 printer_->PrintImageFooter();
302 printer_->CloseStderr();
303 send_configuration_to_next_host_ = false;
304 test_phase_ = BETWEEN_TESTS;
305 is_compositing_test_ = false;
306 enable_pixel_dumping_ = false;
307 expected_pixel_hash_.clear();
308 test_url_ = GURL();
309 prefs_ = WebPreferences();
310 should_override_prefs_ = false;
312 #if defined(OS_ANDROID)
313 // Re-using the shell's main window on Android causes issues with networking
314 // requests never succeeding. See http://crbug.com/277652.
315 DiscardMainWindow();
316 #endif
317 return true;
320 void BlinkTestController::SetTempPath(const base::FilePath& temp_path) {
321 temp_path_ = temp_path;
324 void BlinkTestController::RendererUnresponsive() {
325 DCHECK(CalledOnValidThread());
326 LOG(WARNING) << "renderer unresponsive";
329 void BlinkTestController::OverrideWebkitPrefs(WebPreferences* prefs) {
330 if (should_override_prefs_) {
331 *prefs = prefs_;
332 } else {
333 ApplyLayoutTestDefaultPreferences(prefs);
334 if (is_compositing_test_) {
335 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
336 if (!command_line.HasSwitch(switches::kDisableGpu))
337 prefs->accelerated_2d_canvas_enabled = true;
338 prefs->mock_scrollbars_enabled = true;
343 void BlinkTestController::OpenURL(const GURL& url) {
344 if (test_phase_ != DURING_TEST)
345 return;
347 Shell::CreateNewWindow(main_window_->web_contents()->GetBrowserContext(),
348 url,
349 main_window_->web_contents()->GetSiteInstance(),
350 gfx::Size());
353 void BlinkTestController::TestFinishedInSecondaryWindow() {
354 RenderViewHost* render_view_host =
355 main_window_->web_contents()->GetRenderViewHost();
356 render_view_host->Send(
357 new ShellViewMsg_NotifyDone(render_view_host->GetRoutingID()));
360 bool BlinkTestController::IsMainWindow(WebContents* web_contents) const {
361 return main_window_ && web_contents == main_window_->web_contents();
364 bool BlinkTestController::OnMessageReceived(const IPC::Message& message) {
365 DCHECK(CalledOnValidThread());
366 bool handled = true;
367 IPC_BEGIN_MESSAGE_MAP(BlinkTestController, message)
368 IPC_MESSAGE_HANDLER(ShellViewHostMsg_PrintMessage, OnPrintMessage)
369 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TextDump, OnTextDump)
370 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ImageDump, OnImageDump)
371 IPC_MESSAGE_HANDLER(ShellViewHostMsg_AudioDump, OnAudioDump)
372 IPC_MESSAGE_HANDLER(ShellViewHostMsg_OverridePreferences,
373 OnOverridePreferences)
374 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TestFinished, OnTestFinished)
375 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ClearDevToolsLocalStorage,
376 OnClearDevToolsLocalStorage)
377 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ShowDevTools, OnShowDevTools)
378 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseDevTools, OnCloseDevTools)
379 IPC_MESSAGE_HANDLER(ShellViewHostMsg_GoToOffset, OnGoToOffset)
380 IPC_MESSAGE_HANDLER(ShellViewHostMsg_Reload, OnReload)
381 IPC_MESSAGE_HANDLER(ShellViewHostMsg_LoadURLForFrame, OnLoadURLForFrame)
382 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CaptureSessionHistory,
383 OnCaptureSessionHistory)
384 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseRemainingWindows,
385 OnCloseRemainingWindows)
386 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ResetDone, OnResetDone)
387 IPC_MESSAGE_HANDLER(ShellViewHostMsg_LeakDetectionDone, OnLeakDetectionDone)
388 IPC_MESSAGE_UNHANDLED(handled = false)
389 IPC_END_MESSAGE_MAP()
391 return handled;
394 void BlinkTestController::PluginCrashed(const base::FilePath& plugin_path,
395 base::ProcessId plugin_pid) {
396 DCHECK(CalledOnValidThread());
397 printer_->AddErrorMessage(
398 base::StringPrintf("#CRASHED - plugin (pid %d)", plugin_pid));
399 base::ThreadTaskRunnerHandle::Get()->PostTask(
400 FROM_HERE,
401 base::Bind(base::IgnoreResult(&BlinkTestController::DiscardMainWindow),
402 base::Unretained(this)));
405 void BlinkTestController::RenderViewCreated(RenderViewHost* render_view_host) {
406 DCHECK(CalledOnValidThread());
407 // Might be kNullProcessHandle, in which case we will receive a notification
408 // later when the RenderProcessHost was created.
409 if (render_view_host->GetProcess()->GetHandle() != base::kNullProcessHandle)
410 current_pid_ = base::GetProcId(render_view_host->GetProcess()->GetHandle());
411 if (!send_configuration_to_next_host_)
412 return;
413 send_configuration_to_next_host_ = false;
414 SendTestConfiguration();
417 void BlinkTestController::RenderProcessGone(base::TerminationStatus status) {
418 DCHECK(CalledOnValidThread());
419 if (current_pid_ != base::kNullProcessId) {
420 printer_->AddErrorMessage(std::string("#CRASHED - renderer (pid ") +
421 base::IntToString(current_pid_) + ")");
422 } else {
423 printer_->AddErrorMessage("#CRASHED - renderer");
425 DiscardMainWindow();
428 void BlinkTestController::DevToolsProcessCrashed() {
429 DCHECK(CalledOnValidThread());
430 printer_->AddErrorMessage("#CRASHED - devtools");
431 if (devtools_frontend_)
432 devtools_frontend_->Close();
433 devtools_frontend_ = NULL;
436 void BlinkTestController::WebContentsDestroyed() {
437 DCHECK(CalledOnValidThread());
438 printer_->AddErrorMessage("FAIL: main window was destroyed");
439 DiscardMainWindow();
442 void BlinkTestController::Observe(int type,
443 const NotificationSource& source,
444 const NotificationDetails& details) {
445 DCHECK(CalledOnValidThread());
446 switch (type) {
447 case NOTIFICATION_RENDERER_PROCESS_CREATED: {
448 if (!main_window_)
449 return;
450 RenderViewHost* render_view_host =
451 main_window_->web_contents()->GetRenderViewHost();
452 if (!render_view_host)
453 return;
454 RenderProcessHost* render_process_host =
455 Source<RenderProcessHost>(source).ptr();
456 if (render_process_host != render_view_host->GetProcess())
457 return;
458 current_pid_ = base::GetProcId(render_process_host->GetHandle());
459 break;
461 default:
462 NOTREACHED();
466 void BlinkTestController::OnGpuProcessCrashed(
467 base::TerminationStatus exit_code) {
468 DCHECK(CalledOnValidThread());
469 printer_->AddErrorMessage("#CRASHED - gpu");
470 DiscardMainWindow();
473 void BlinkTestController::DiscardMainWindow() {
474 // If we're running a test, we need to close all windows and exit the message
475 // loop. Otherwise, we're already outside of the message loop, and we just
476 // discard the main window.
477 WebContentsObserver::Observe(NULL);
478 if (test_phase_ != BETWEEN_TESTS) {
479 Shell::CloseAllWindows();
480 base::ThreadTaskRunnerHandle::Get()->PostTask(
481 FROM_HERE, base::MessageLoop::QuitClosure());
482 test_phase_ = CLEAN_UP;
483 } else if (main_window_) {
484 main_window_->Close();
486 main_window_ = NULL;
487 current_pid_ = base::kNullProcessId;
490 void BlinkTestController::SendTestConfiguration() {
491 RenderViewHost* render_view_host =
492 main_window_->web_contents()->GetRenderViewHost();
493 ShellTestConfiguration params;
494 params.current_working_directory = current_working_directory_;
495 params.temp_path = temp_path_;
496 params.test_url = test_url_;
497 params.enable_pixel_dumping = enable_pixel_dumping_;
498 params.allow_external_pages =
499 base::CommandLine::ForCurrentProcess()->HasSwitch(
500 switches::kAllowExternalPages);
501 params.expected_pixel_hash = expected_pixel_hash_;
502 params.initial_size = initial_size_;
503 render_view_host->Send(new ShellViewMsg_SetTestConfiguration(
504 render_view_host->GetRoutingID(), params));
507 void BlinkTestController::OnTestFinished() {
508 test_phase_ = CLEAN_UP;
509 if (!printer_->output_finished())
510 printer_->PrintImageFooter();
511 RenderViewHost* render_view_host =
512 main_window_->web_contents()->GetRenderViewHost();
513 main_window_->web_contents()->ExitFullscreen();
514 base::ThreadTaskRunnerHandle::Get()->PostTask(
515 FROM_HERE,
516 base::Bind(base::IgnoreResult(&BlinkTestController::Send),
517 base::Unretained(this),
518 new ShellViewMsg_Reset(render_view_host->GetRoutingID())));
521 void BlinkTestController::OnImageDump(const std::string& actual_pixel_hash,
522 const SkBitmap& image) {
523 SkAutoLockPixels image_lock(image);
525 printer_->PrintImageHeader(actual_pixel_hash, expected_pixel_hash_);
527 // Only encode and dump the png if the hashes don't match. Encoding the
528 // image is really expensive.
529 if (actual_pixel_hash != expected_pixel_hash_) {
530 std::vector<unsigned char> png;
532 bool discard_transparency = true;
533 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
534 switches::kEnableOverlayFullscreenVideo))
535 discard_transparency = false;
537 std::vector<gfx::PNGCodec::Comment> comments;
538 comments.push_back(gfx::PNGCodec::Comment("checksum", actual_pixel_hash));
539 bool success = gfx::PNGCodec::Encode(
540 static_cast<const unsigned char*>(image.getPixels()),
541 gfx::PNGCodec::FORMAT_BGRA,
542 gfx::Size(image.width(), image.height()),
543 static_cast<int>(image.rowBytes()),
544 discard_transparency,
545 comments,
546 &png);
547 if (success)
548 printer_->PrintImageBlock(png);
550 printer_->PrintImageFooter();
553 void BlinkTestController::OnAudioDump(const std::vector<unsigned char>& dump) {
554 printer_->PrintAudioHeader();
555 printer_->PrintAudioBlock(dump);
556 printer_->PrintAudioFooter();
559 void BlinkTestController::OnTextDump(const std::string& dump) {
560 printer_->PrintTextHeader();
561 printer_->PrintTextBlock(dump);
562 printer_->PrintTextFooter();
565 void BlinkTestController::OnPrintMessage(const std::string& message) {
566 printer_->AddMessageRaw(message);
569 void BlinkTestController::OnOverridePreferences(const WebPreferences& prefs) {
570 should_override_prefs_ = true;
571 prefs_ = prefs;
574 void BlinkTestController::OnClearDevToolsLocalStorage() {
575 ShellBrowserContext* browser_context =
576 ShellContentBrowserClient::Get()->browser_context();
577 StoragePartition* storage_partition =
578 BrowserContext::GetStoragePartition(browser_context, NULL);
579 storage_partition->GetDOMStorageContext()->DeleteLocalStorage(
580 content::LayoutTestDevToolsFrontend::GetDevToolsPathAsURL("", "")
581 .GetOrigin());
584 void BlinkTestController::OnShowDevTools(const std::string& settings,
585 const std::string& frontend_url) {
586 if (!devtools_frontend_) {
587 devtools_frontend_ = LayoutTestDevToolsFrontend::Show(
588 main_window_->web_contents(), settings, frontend_url);
589 } else {
590 devtools_frontend_->ReuseFrontend(settings, frontend_url);
592 devtools_frontend_->Activate();
593 devtools_frontend_->Focus();
596 void BlinkTestController::OnCloseDevTools() {
597 if (devtools_frontend_)
598 devtools_frontend_->DisconnectFromTarget();
601 void BlinkTestController::OnGoToOffset(int offset) {
602 main_window_->GoBackOrForward(offset);
605 void BlinkTestController::OnReload() {
606 main_window_->Reload();
609 void BlinkTestController::OnLoadURLForFrame(const GURL& url,
610 const std::string& frame_name) {
611 main_window_->LoadURLForFrame(url, frame_name);
614 void BlinkTestController::OnCaptureSessionHistory() {
615 std::vector<int> routing_ids;
616 std::vector<std::vector<PageState> > session_histories;
617 std::vector<unsigned> current_entry_indexes;
619 RenderViewHost* render_view_host =
620 main_window_->web_contents()->GetRenderViewHost();
622 for (std::vector<Shell*>::iterator window = Shell::windows().begin();
623 window != Shell::windows().end();
624 ++window) {
625 WebContents* web_contents = (*window)->web_contents();
626 // Only capture the history from windows in the same process as the main
627 // window. During layout tests, we only use two processes when an
628 // devtools window is open.
629 if (render_view_host->GetProcess() !=
630 web_contents->GetRenderViewHost()->GetProcess()) {
631 continue;
633 routing_ids.push_back(web_contents->GetRenderViewHost()->GetRoutingID());
634 current_entry_indexes.push_back(
635 web_contents->GetController().GetCurrentEntryIndex());
636 std::vector<PageState> history;
637 for (int entry = 0; entry < web_contents->GetController().GetEntryCount();
638 ++entry) {
639 PageState state = web_contents->GetController().GetEntryAtIndex(entry)->
640 GetPageState();
641 if (!state.IsValid()) {
642 state = PageState::CreateFromURL(
643 web_contents->GetController().GetEntryAtIndex(entry)->GetURL());
645 history.push_back(state);
647 session_histories.push_back(history);
650 Send(new ShellViewMsg_SessionHistory(render_view_host->GetRoutingID(),
651 routing_ids,
652 session_histories,
653 current_entry_indexes));
656 void BlinkTestController::OnCloseRemainingWindows() {
657 DevToolsAgentHost::DetachAllClients();
658 std::vector<Shell*> open_windows(Shell::windows());
659 Shell* devtools_shell = devtools_frontend_ ?
660 devtools_frontend_->frontend_shell() : NULL;
661 for (size_t i = 0; i < open_windows.size(); ++i) {
662 if (open_windows[i] != main_window_ && open_windows[i] != devtools_shell)
663 open_windows[i]->Close();
665 base::MessageLoop::current()->RunUntilIdle();
668 void BlinkTestController::OnResetDone() {
669 if (is_leak_detection_enabled_) {
670 if (main_window_ && main_window_->web_contents()) {
671 RenderViewHost* render_view_host =
672 main_window_->web_contents()->GetRenderViewHost();
673 render_view_host->Send(
674 new ShellViewMsg_TryLeakDetection(render_view_host->GetRoutingID()));
676 return;
679 base::ThreadTaskRunnerHandle::Get()->PostTask(
680 FROM_HERE, base::MessageLoop::QuitClosure());
683 void BlinkTestController::OnLeakDetectionDone(
684 const LeakDetectionResult& result) {
685 if (!result.leaked) {
686 base::ThreadTaskRunnerHandle::Get()->PostTask(
687 FROM_HERE, base::MessageLoop::QuitClosure());
688 return;
691 printer_->AddErrorMessage(
692 base::StringPrintf("#LEAK - renderer pid %d (%s)", current_pid_,
693 result.detail.c_str()));
694 CHECK(!crash_when_leak_found_);
696 DiscardMainWindow();
699 } // namespace content