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"
9 #include "base/base64.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/location.h"
13 #include "base/run_loop.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "content/public/browser/devtools_agent_host.h"
19 #include "content/public/browser/dom_storage_context.h"
20 #include "content/public/browser/gpu_data_manager.h"
21 #include "content/public/browser/navigation_controller.h"
22 #include "content/public/browser/navigation_entry.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/notification_types.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/render_widget_host_view.h"
28 #include "content/public/browser/service_worker_context.h"
29 #include "content/public/browser/storage_partition.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/content_switches.h"
32 #include "content/public/common/url_constants.h"
33 #include "content/shell/browser/layout_test/layout_test_devtools_frontend.h"
34 #include "content/shell/browser/shell.h"
35 #include "content/shell/browser/shell_browser_context.h"
36 #include "content/shell/browser/shell_content_browser_client.h"
37 #include "content/shell/browser/shell_devtools_frontend.h"
38 #include "content/shell/common/shell_messages.h"
39 #include "content/shell/common/shell_switches.h"
40 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
41 #include "ui/gfx/codec/png_codec.h"
45 const int kTestSVGWindowWidthDip
= 480;
46 const int kTestSVGWindowHeightDip
= 360;
48 // BlinkTestResultPrinter ----------------------------------------------------
50 BlinkTestResultPrinter::BlinkTestResultPrinter(std::ostream
* output
,
52 : state_(DURING_TEST
),
53 capture_text_only_(false),
54 encode_binary_data_(false),
59 BlinkTestResultPrinter::~BlinkTestResultPrinter() {
62 void BlinkTestResultPrinter::PrintTextHeader() {
63 if (state_
!= DURING_TEST
)
65 if (!capture_text_only_
)
66 *output_
<< "Content-Type: text/plain\n";
67 state_
= IN_TEXT_BLOCK
;
70 void BlinkTestResultPrinter::PrintTextBlock(const std::string
& block
) {
71 if (state_
!= IN_TEXT_BLOCK
)
76 void BlinkTestResultPrinter::PrintTextFooter() {
77 if (state_
!= IN_TEXT_BLOCK
)
79 if (!capture_text_only_
) {
83 state_
= IN_IMAGE_BLOCK
;
86 void BlinkTestResultPrinter::PrintImageHeader(
87 const std::string
& actual_hash
,
88 const std::string
& expected_hash
) {
89 if (state_
!= IN_IMAGE_BLOCK
|| capture_text_only_
)
91 *output_
<< "\nActualHash: " << actual_hash
<< "\n";
92 if (!expected_hash
.empty())
93 *output_
<< "\nExpectedHash: " << expected_hash
<< "\n";
96 void BlinkTestResultPrinter::PrintImageBlock(
97 const std::vector
<unsigned char>& png_image
) {
98 if (state_
!= IN_IMAGE_BLOCK
|| capture_text_only_
)
100 *output_
<< "Content-Type: image/png\n";
101 if (encode_binary_data_
) {
102 PrintEncodedBinaryData(png_image
);
106 *output_
<< "Content-Length: " << png_image
.size() << "\n";
108 reinterpret_cast<const char*>(&png_image
[0]), png_image
.size());
111 void BlinkTestResultPrinter::PrintImageFooter() {
112 if (state_
!= IN_IMAGE_BLOCK
)
114 if (!capture_text_only_
) {
115 *output_
<< "#EOF\n";
121 void BlinkTestResultPrinter::PrintAudioHeader() {
122 DCHECK_EQ(state_
, DURING_TEST
);
123 if (!capture_text_only_
)
124 *output_
<< "Content-Type: audio/wav\n";
125 state_
= IN_AUDIO_BLOCK
;
128 void BlinkTestResultPrinter::PrintAudioBlock(
129 const std::vector
<unsigned char>& audio_data
) {
130 if (state_
!= IN_AUDIO_BLOCK
|| capture_text_only_
)
132 if (encode_binary_data_
) {
133 PrintEncodedBinaryData(audio_data
);
137 *output_
<< "Content-Length: " << audio_data
.size() << "\n";
139 reinterpret_cast<const char*>(&audio_data
[0]), audio_data
.size());
142 void BlinkTestResultPrinter::PrintAudioFooter() {
143 if (state_
!= IN_AUDIO_BLOCK
)
145 if (!capture_text_only_
) {
146 *output_
<< "#EOF\n";
149 state_
= IN_IMAGE_BLOCK
;
152 void BlinkTestResultPrinter::AddMessage(const std::string
& message
) {
153 AddMessageRaw(message
+ "\n");
156 void BlinkTestResultPrinter::AddMessageRaw(const std::string
& message
) {
157 if (state_
!= DURING_TEST
)
162 void BlinkTestResultPrinter::AddErrorMessage(const std::string
& message
) {
163 if (!capture_text_only_
)
164 *error_
<< message
<< "\n";
165 if (state_
!= DURING_TEST
)
168 *output_
<< message
<< "\n";
173 void BlinkTestResultPrinter::PrintEncodedBinaryData(
174 const std::vector
<unsigned char>& data
) {
175 *output_
<< "Content-Transfer-Encoding: base64\n";
177 std::string data_base64
;
179 base::StringPiece(reinterpret_cast<const char*>(&data
[0]), data
.size()),
182 *output_
<< "Content-Length: " << data_base64
.length() << "\n";
183 output_
->write(data_base64
.c_str(), data_base64
.length());
186 void BlinkTestResultPrinter::CloseStderr() {
187 if (state_
!= AFTER_TEST
)
189 if (!capture_text_only_
) {
195 // BlinkTestController -------------------------------------------------------
197 BlinkTestController
* BlinkTestController::instance_
= NULL
;
200 BlinkTestController
* BlinkTestController::Get() {
205 BlinkTestController::BlinkTestController()
206 : main_window_(NULL
),
207 test_phase_(BETWEEN_TESTS
),
208 is_leak_detection_enabled_(
209 base::CommandLine::ForCurrentProcess()->HasSwitch(
210 switches::kEnableLeakDetection
)),
211 crash_when_leak_found_(false),
212 devtools_frontend_(NULL
) {
216 if (is_leak_detection_enabled_
) {
217 std::string switchValue
=
218 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
219 switches::kEnableLeakDetection
);
220 crash_when_leak_found_
= switchValue
== switches::kCrashOnFailure
;
223 printer_
.reset(new BlinkTestResultPrinter(&std::cout
, &std::cerr
));
224 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
225 switches::kEncodeBinary
))
226 printer_
->set_encode_binary_data(true);
228 NOTIFICATION_RENDERER_PROCESS_CREATED
,
229 NotificationService::AllSources());
230 GpuDataManager::GetInstance()->AddObserver(this);
231 ResetAfterLayoutTest();
234 BlinkTestController::~BlinkTestController() {
235 DCHECK(CalledOnValidThread());
236 CHECK(instance_
== this);
237 CHECK(test_phase_
== BETWEEN_TESTS
);
238 GpuDataManager::GetInstance()->RemoveObserver(this);
243 bool BlinkTestController::PrepareForLayoutTest(
244 const GURL
& test_url
,
245 const base::FilePath
& current_working_directory
,
246 bool enable_pixel_dumping
,
247 const std::string
& expected_pixel_hash
) {
248 DCHECK(CalledOnValidThread());
249 test_phase_
= DURING_TEST
;
250 current_working_directory_
= current_working_directory
;
251 enable_pixel_dumping_
= enable_pixel_dumping
;
252 expected_pixel_hash_
= expected_pixel_hash
;
253 test_url_
= test_url
;
255 ShellBrowserContext
* browser_context
=
256 ShellContentBrowserClient::Get()->browser_context();
257 if (test_url
.spec().find("compositing/") != std::string::npos
)
258 is_compositing_test_
= true;
259 initial_size_
= Shell::GetShellDefaultSize();
260 // The W3C SVG layout tests use a different size than the other layout tests.
261 if (test_url
.spec().find("W3C-SVG-1.1") != std::string::npos
)
262 initial_size_
= gfx::Size(kTestSVGWindowWidthDip
, kTestSVGWindowHeightDip
);
264 main_window_
= content::Shell::CreateNewWindow(
269 WebContentsObserver::Observe(main_window_
->web_contents());
270 send_configuration_to_next_host_
= true;
271 current_pid_
= base::kNullProcessId
;
272 main_window_
->LoadURL(test_url
);
274 #if defined(OS_MACOSX)
275 // Shell::SizeTo is not implemented on all platforms.
276 main_window_
->SizeTo(initial_size_
);
278 main_window_
->web_contents()->GetRenderViewHost()->GetView()
279 ->SetSize(initial_size_
);
280 main_window_
->web_contents()->GetRenderViewHost()->WasResized();
281 RenderViewHost
* render_view_host
=
282 main_window_
->web_contents()->GetRenderViewHost();
283 WebPreferences prefs
= render_view_host
->GetWebkitPreferences();
284 OverrideWebkitPrefs(&prefs
);
285 render_view_host
->UpdateWebkitPreferences(prefs
);
286 SendTestConfiguration();
288 NavigationController::LoadURLParams
params(test_url
);
289 params
.transition_type
= ui::PageTransitionFromInt(
290 ui::PAGE_TRANSITION_TYPED
| ui::PAGE_TRANSITION_FROM_ADDRESS_BAR
);
291 params
.should_clear_history_list
= true;
292 main_window_
->web_contents()->GetController().LoadURLWithParams(params
);
293 main_window_
->web_contents()->Focus();
295 main_window_
->web_contents()->GetRenderViewHost()->SetActive(true);
296 main_window_
->web_contents()->GetRenderViewHost()->Focus();
300 bool BlinkTestController::ResetAfterLayoutTest() {
301 DCHECK(CalledOnValidThread());
302 printer_
->PrintTextFooter();
303 printer_
->PrintImageFooter();
304 printer_
->CloseStderr();
305 send_configuration_to_next_host_
= false;
306 test_phase_
= BETWEEN_TESTS
;
307 is_compositing_test_
= false;
308 enable_pixel_dumping_
= false;
309 expected_pixel_hash_
.clear();
311 prefs_
= WebPreferences();
312 should_override_prefs_
= false;
314 #if defined(OS_ANDROID)
315 // Re-using the shell's main window on Android causes issues with networking
316 // requests never succeeding. See http://crbug.com/277652.
322 void BlinkTestController::SetTempPath(const base::FilePath
& temp_path
) {
323 temp_path_
= temp_path
;
326 void BlinkTestController::RendererUnresponsive() {
327 DCHECK(CalledOnValidThread());
328 LOG(WARNING
) << "renderer unresponsive";
331 void BlinkTestController::OverrideWebkitPrefs(WebPreferences
* prefs
) {
332 if (should_override_prefs_
) {
335 ApplyLayoutTestDefaultPreferences(prefs
);
336 if (is_compositing_test_
) {
337 base::CommandLine
& command_line
= *base::CommandLine::ForCurrentProcess();
338 if (!command_line
.HasSwitch(switches::kDisableGpu
))
339 prefs
->accelerated_2d_canvas_enabled
= true;
340 prefs
->mock_scrollbars_enabled
= true;
345 void BlinkTestController::OpenURL(const GURL
& url
) {
346 if (test_phase_
!= DURING_TEST
)
349 Shell::CreateNewWindow(main_window_
->web_contents()->GetBrowserContext(),
351 main_window_
->web_contents()->GetSiteInstance(),
355 void BlinkTestController::TestFinishedInSecondaryWindow() {
356 RenderViewHost
* render_view_host
=
357 main_window_
->web_contents()->GetRenderViewHost();
358 render_view_host
->Send(
359 new ShellViewMsg_NotifyDone(render_view_host
->GetRoutingID()));
362 bool BlinkTestController::IsMainWindow(WebContents
* web_contents
) const {
363 return main_window_
&& web_contents
== main_window_
->web_contents();
366 bool BlinkTestController::OnMessageReceived(const IPC::Message
& message
) {
367 DCHECK(CalledOnValidThread());
369 IPC_BEGIN_MESSAGE_MAP(BlinkTestController
, message
)
370 IPC_MESSAGE_HANDLER(ShellViewHostMsg_PrintMessage
, OnPrintMessage
)
371 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TextDump
, OnTextDump
)
372 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ImageDump
, OnImageDump
)
373 IPC_MESSAGE_HANDLER(ShellViewHostMsg_AudioDump
, OnAudioDump
)
374 IPC_MESSAGE_HANDLER(ShellViewHostMsg_OverridePreferences
,
375 OnOverridePreferences
)
376 IPC_MESSAGE_HANDLER(ShellViewHostMsg_TestFinished
, OnTestFinished
)
377 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ClearDevToolsLocalStorage
,
378 OnClearDevToolsLocalStorage
)
379 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ShowDevTools
, OnShowDevTools
)
380 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseDevTools
, OnCloseDevTools
)
381 IPC_MESSAGE_HANDLER(ShellViewHostMsg_GoToOffset
, OnGoToOffset
)
382 IPC_MESSAGE_HANDLER(ShellViewHostMsg_Reload
, OnReload
)
383 IPC_MESSAGE_HANDLER(ShellViewHostMsg_LoadURLForFrame
, OnLoadURLForFrame
)
384 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CaptureSessionHistory
,
385 OnCaptureSessionHistory
)
386 IPC_MESSAGE_HANDLER(ShellViewHostMsg_CloseRemainingWindows
,
387 OnCloseRemainingWindows
)
388 IPC_MESSAGE_HANDLER(ShellViewHostMsg_ResetDone
, OnResetDone
)
389 IPC_MESSAGE_HANDLER(ShellViewHostMsg_LeakDetectionDone
, OnLeakDetectionDone
)
390 IPC_MESSAGE_UNHANDLED(handled
= false)
391 IPC_END_MESSAGE_MAP()
396 void BlinkTestController::PluginCrashed(const base::FilePath
& plugin_path
,
397 base::ProcessId plugin_pid
) {
398 DCHECK(CalledOnValidThread());
399 printer_
->AddErrorMessage(
400 base::StringPrintf("#CRASHED - plugin (pid %d)", plugin_pid
));
401 base::ThreadTaskRunnerHandle::Get()->PostTask(
403 base::Bind(base::IgnoreResult(&BlinkTestController::DiscardMainWindow
),
404 base::Unretained(this)));
407 void BlinkTestController::RenderViewCreated(RenderViewHost
* render_view_host
) {
408 DCHECK(CalledOnValidThread());
409 // Might be kNullProcessHandle, in which case we will receive a notification
410 // later when the RenderProcessHost was created.
411 if (render_view_host
->GetProcess()->GetHandle() != base::kNullProcessHandle
)
412 current_pid_
= base::GetProcId(render_view_host
->GetProcess()->GetHandle());
413 if (!send_configuration_to_next_host_
)
415 send_configuration_to_next_host_
= false;
416 SendTestConfiguration();
419 void BlinkTestController::RenderProcessGone(base::TerminationStatus status
) {
420 DCHECK(CalledOnValidThread());
421 if (current_pid_
!= base::kNullProcessId
) {
422 printer_
->AddErrorMessage(std::string("#CRASHED - renderer (pid ") +
423 base::IntToString(current_pid_
) + ")");
425 printer_
->AddErrorMessage("#CRASHED - renderer");
430 void BlinkTestController::DevToolsProcessCrashed() {
431 DCHECK(CalledOnValidThread());
432 printer_
->AddErrorMessage("#CRASHED - devtools");
433 if (devtools_frontend_
)
434 devtools_frontend_
->Close();
435 devtools_frontend_
= NULL
;
438 void BlinkTestController::WebContentsDestroyed() {
439 DCHECK(CalledOnValidThread());
440 printer_
->AddErrorMessage("FAIL: main window was destroyed");
444 void BlinkTestController::Observe(int type
,
445 const NotificationSource
& source
,
446 const NotificationDetails
& details
) {
447 DCHECK(CalledOnValidThread());
449 case NOTIFICATION_RENDERER_PROCESS_CREATED
: {
452 RenderViewHost
* render_view_host
=
453 main_window_
->web_contents()->GetRenderViewHost();
454 if (!render_view_host
)
456 RenderProcessHost
* render_process_host
=
457 Source
<RenderProcessHost
>(source
).ptr();
458 if (render_process_host
!= render_view_host
->GetProcess())
460 current_pid_
= base::GetProcId(render_process_host
->GetHandle());
468 void BlinkTestController::OnGpuProcessCrashed(
469 base::TerminationStatus exit_code
) {
470 DCHECK(CalledOnValidThread());
471 printer_
->AddErrorMessage("#CRASHED - gpu");
475 void BlinkTestController::DiscardMainWindow() {
476 // If we're running a test, we need to close all windows and exit the message
477 // loop. Otherwise, we're already outside of the message loop, and we just
478 // discard the main window.
479 WebContentsObserver::Observe(NULL
);
480 if (test_phase_
!= BETWEEN_TESTS
) {
481 Shell::CloseAllWindows();
482 base::ThreadTaskRunnerHandle::Get()->PostTask(
483 FROM_HERE
, base::MessageLoop::QuitClosure());
484 test_phase_
= CLEAN_UP
;
485 } else if (main_window_
) {
486 main_window_
->Close();
489 current_pid_
= base::kNullProcessId
;
492 void BlinkTestController::SendTestConfiguration() {
493 RenderViewHost
* render_view_host
=
494 main_window_
->web_contents()->GetRenderViewHost();
495 ShellTestConfiguration params
;
496 params
.current_working_directory
= current_working_directory_
;
497 params
.temp_path
= temp_path_
;
498 params
.test_url
= test_url_
;
499 params
.enable_pixel_dumping
= enable_pixel_dumping_
;
500 params
.allow_external_pages
=
501 base::CommandLine::ForCurrentProcess()->HasSwitch(
502 switches::kAllowExternalPages
);
503 params
.expected_pixel_hash
= expected_pixel_hash_
;
504 params
.initial_size
= initial_size_
;
505 render_view_host
->Send(new ShellViewMsg_SetTestConfiguration(
506 render_view_host
->GetRoutingID(), params
));
509 void BlinkTestController::OnTestFinished() {
510 test_phase_
= CLEAN_UP
;
511 if (!printer_
->output_finished())
512 printer_
->PrintImageFooter();
513 RenderViewHost
* render_view_host
=
514 main_window_
->web_contents()->GetRenderViewHost();
515 main_window_
->web_contents()->ExitFullscreen();
517 ShellBrowserContext
* browser_context
=
518 ShellContentBrowserClient::Get()->browser_context();
519 StoragePartition
* storage_partition
=
520 BrowserContext::GetStoragePartition(browser_context
, nullptr);
521 storage_partition
->GetServiceWorkerContext()->ClearAllServiceWorkersForTest(
522 base::Bind(base::IgnoreResult(&BlinkTestController::Send
),
523 base::Unretained(this),
524 new ShellViewMsg_Reset(render_view_host
->GetRoutingID())));
527 void BlinkTestController::OnImageDump(const std::string
& actual_pixel_hash
,
528 const SkBitmap
& image
) {
529 SkAutoLockPixels
image_lock(image
);
531 printer_
->PrintImageHeader(actual_pixel_hash
, expected_pixel_hash_
);
533 // Only encode and dump the png if the hashes don't match. Encoding the
534 // image is really expensive.
535 if (actual_pixel_hash
!= expected_pixel_hash_
) {
536 std::vector
<unsigned char> png
;
538 bool discard_transparency
= true;
539 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
540 switches::kForceOverlayFullscreenVideo
))
541 discard_transparency
= false;
543 std::vector
<gfx::PNGCodec::Comment
> comments
;
544 comments
.push_back(gfx::PNGCodec::Comment("checksum", actual_pixel_hash
));
545 bool success
= gfx::PNGCodec::Encode(
546 static_cast<const unsigned char*>(image
.getPixels()),
547 gfx::PNGCodec::FORMAT_BGRA
,
548 gfx::Size(image
.width(), image
.height()),
549 static_cast<int>(image
.rowBytes()),
550 discard_transparency
,
554 printer_
->PrintImageBlock(png
);
556 printer_
->PrintImageFooter();
559 void BlinkTestController::OnAudioDump(const std::vector
<unsigned char>& dump
) {
560 printer_
->PrintAudioHeader();
561 printer_
->PrintAudioBlock(dump
);
562 printer_
->PrintAudioFooter();
565 void BlinkTestController::OnTextDump(const std::string
& dump
) {
566 printer_
->PrintTextHeader();
567 printer_
->PrintTextBlock(dump
);
568 printer_
->PrintTextFooter();
571 void BlinkTestController::OnPrintMessage(const std::string
& message
) {
572 printer_
->AddMessageRaw(message
);
575 void BlinkTestController::OnOverridePreferences(const WebPreferences
& prefs
) {
576 should_override_prefs_
= true;
580 void BlinkTestController::OnClearDevToolsLocalStorage() {
581 ShellBrowserContext
* browser_context
=
582 ShellContentBrowserClient::Get()->browser_context();
583 StoragePartition
* storage_partition
=
584 BrowserContext::GetStoragePartition(browser_context
, NULL
);
585 storage_partition
->GetDOMStorageContext()->DeleteLocalStorage(
586 content::LayoutTestDevToolsFrontend::GetDevToolsPathAsURL("", "")
590 void BlinkTestController::OnShowDevTools(const std::string
& settings
,
591 const std::string
& frontend_url
) {
592 if (!devtools_frontend_
) {
593 devtools_frontend_
= LayoutTestDevToolsFrontend::Show(
594 main_window_
->web_contents(), settings
, frontend_url
);
596 devtools_frontend_
->ReuseFrontend(settings
, frontend_url
);
598 devtools_frontend_
->Activate();
599 devtools_frontend_
->Focus();
602 void BlinkTestController::OnCloseDevTools() {
603 if (devtools_frontend_
)
604 devtools_frontend_
->DisconnectFromTarget();
607 void BlinkTestController::OnGoToOffset(int offset
) {
608 main_window_
->GoBackOrForward(offset
);
611 void BlinkTestController::OnReload() {
612 main_window_
->Reload();
615 void BlinkTestController::OnLoadURLForFrame(const GURL
& url
,
616 const std::string
& frame_name
) {
617 main_window_
->LoadURLForFrame(url
, frame_name
);
620 void BlinkTestController::OnCaptureSessionHistory() {
621 std::vector
<int> routing_ids
;
622 std::vector
<std::vector
<PageState
> > session_histories
;
623 std::vector
<unsigned> current_entry_indexes
;
625 RenderViewHost
* render_view_host
=
626 main_window_
->web_contents()->GetRenderViewHost();
628 for (std::vector
<Shell
*>::iterator window
= Shell::windows().begin();
629 window
!= Shell::windows().end();
631 WebContents
* web_contents
= (*window
)->web_contents();
632 // Only capture the history from windows in the same process as the main
633 // window. During layout tests, we only use two processes when an
634 // devtools window is open.
635 if (render_view_host
->GetProcess() !=
636 web_contents
->GetRenderViewHost()->GetProcess()) {
639 routing_ids
.push_back(web_contents
->GetRenderViewHost()->GetRoutingID());
640 current_entry_indexes
.push_back(
641 web_contents
->GetController().GetCurrentEntryIndex());
642 std::vector
<PageState
> history
;
643 for (int entry
= 0; entry
< web_contents
->GetController().GetEntryCount();
645 PageState state
= web_contents
->GetController().GetEntryAtIndex(entry
)->
647 if (!state
.IsValid()) {
648 state
= PageState::CreateFromURL(
649 web_contents
->GetController().GetEntryAtIndex(entry
)->GetURL());
651 history
.push_back(state
);
653 session_histories
.push_back(history
);
656 Send(new ShellViewMsg_SessionHistory(render_view_host
->GetRoutingID(),
659 current_entry_indexes
));
662 void BlinkTestController::OnCloseRemainingWindows() {
663 DevToolsAgentHost::DetachAllClients();
664 std::vector
<Shell
*> open_windows(Shell::windows());
665 Shell
* devtools_shell
= devtools_frontend_
?
666 devtools_frontend_
->frontend_shell() : NULL
;
667 for (size_t i
= 0; i
< open_windows
.size(); ++i
) {
668 if (open_windows
[i
] != main_window_
&& open_windows
[i
] != devtools_shell
)
669 open_windows
[i
]->Close();
671 base::MessageLoop::current()->RunUntilIdle();
674 void BlinkTestController::OnResetDone() {
675 if (is_leak_detection_enabled_
) {
676 if (main_window_
&& main_window_
->web_contents()) {
677 RenderViewHost
* render_view_host
=
678 main_window_
->web_contents()->GetRenderViewHost();
679 render_view_host
->Send(
680 new ShellViewMsg_TryLeakDetection(render_view_host
->GetRoutingID()));
685 base::ThreadTaskRunnerHandle::Get()->PostTask(
686 FROM_HERE
, base::MessageLoop::QuitClosure());
689 void BlinkTestController::OnLeakDetectionDone(
690 const LeakDetectionResult
& result
) {
691 if (!result
.leaked
) {
692 base::ThreadTaskRunnerHandle::Get()->PostTask(
693 FROM_HERE
, base::MessageLoop::QuitClosure());
697 printer_
->AddErrorMessage(
698 base::StringPrintf("#LEAK - renderer pid %d (%s)", current_pid_
,
699 result
.detail
.c_str()));
700 CHECK(!crash_when_leak_found_
);
705 } // namespace content