webkit_test_runner.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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/renderer/webkit_test_runner.h" 6 7#include <algorithm> 8#include <clocale> 9#include <cmath> 10 11#include "base/base64.h" 12#include "base/command_line.h" 13#include "base/debug/debugger.h" 14#include "base/files/file_path.h" 15#include "base/md5.h" 16#include "base/memory/scoped_ptr.h" 17#include "base/message_loop/message_loop.h" 18#include "base/strings/string_util.h" 19#include "base/strings/stringprintf.h" 20#include "base/strings/sys_string_conversions.h" 21#include "base/strings/utf_string_conversions.h" 22#include "base/time/time.h" 23#include "content/public/common/content_switches.h" 24#include "content/public/common/url_constants.h" 25#include "content/public/common/web_preferences.h" 26#include "content/public/renderer/render_view.h" 27#include "content/public/renderer/render_view_visitor.h" 28#include "content/public/test/layouttest_support.h" 29#include "content/shell/common/shell_messages.h" 30#include "content/shell/common/shell_switches.h" 31#include "content/shell/common/webkit_test_helpers.h" 32#include "content/shell/renderer/gc_controller.h" 33#include "content/shell/renderer/leak_detector.h" 34#include "content/shell/renderer/shell_render_process_observer.h" 35#include "content/shell/renderer/test_runner/WebTask.h" 36#include "content/shell/renderer/test_runner/WebTestInterfaces.h" 37#include "content/shell/renderer/test_runner/mock_screen_orientation_client.h" 38#include "content/shell/renderer/test_runner/web_test_proxy.h" 39#include "content/shell/renderer/test_runner/web_test_runner.h" 40#include "net/base/filename_util.h" 41#include "net/base/net_errors.h" 42#include "skia/ext/platform_canvas.h" 43#include "third_party/WebKit/public/platform/Platform.h" 44#include "third_party/WebKit/public/platform/WebCString.h" 45#include "third_party/WebKit/public/platform/WebPoint.h" 46#include "third_party/WebKit/public/platform/WebRect.h" 47#include "third_party/WebKit/public/platform/WebSize.h" 48#include "third_party/WebKit/public/platform/WebString.h" 49#include "third_party/WebKit/public/platform/WebURL.h" 50#include "third_party/WebKit/public/platform/WebURLError.h" 51#include "third_party/WebKit/public/platform/WebURLRequest.h" 52#include "third_party/WebKit/public/platform/WebURLResponse.h" 53#include "third_party/WebKit/public/web/WebArrayBufferView.h" 54#include "third_party/WebKit/public/web/WebContextMenuData.h" 55#include "third_party/WebKit/public/web/WebDataSource.h" 56#include "third_party/WebKit/public/web/WebDevToolsAgent.h" 57#include "third_party/WebKit/public/web/WebDocument.h" 58#include "third_party/WebKit/public/web/WebElement.h" 59#include "third_party/WebKit/public/web/WebHistoryItem.h" 60#include "third_party/WebKit/public/web/WebKit.h" 61#include "third_party/WebKit/public/web/WebLeakDetector.h" 62#include "third_party/WebKit/public/web/WebLocalFrame.h" 63#include "third_party/WebKit/public/web/WebScriptSource.h" 64#include "third_party/WebKit/public/web/WebTestingSupport.h" 65#include "third_party/WebKit/public/web/WebView.h" 66#include "ui/gfx/rect.h" 67 68using blink::Platform; 69using blink::WebArrayBufferView; 70using blink::WebContextMenuData; 71using blink::WebDevToolsAgent; 72using blink::WebDeviceMotionData; 73using blink::WebDeviceOrientationData; 74using blink::WebElement; 75using blink::WebLocalFrame; 76using blink::WebGamepads; 77using blink::WebHistoryItem; 78using blink::WebLocalFrame; 79using blink::WebPoint; 80using blink::WebRect; 81using blink::WebScriptSource; 82using blink::WebSize; 83using blink::WebString; 84using blink::WebURL; 85using blink::WebURLError; 86using blink::WebURLRequest; 87using blink::WebScreenOrientationType; 88using blink::WebTestingSupport; 89using blink::WebVector; 90using blink::WebView; 91 92namespace content { 93 94namespace { 95 96void InvokeTaskHelper(void* context) { 97 WebTask* task = reinterpret_cast<WebTask*>(context); 98 task->run(); 99 delete task; 100} 101 102class SyncNavigationStateVisitor : public RenderViewVisitor { 103 public: 104 SyncNavigationStateVisitor() {} 105 virtual ~SyncNavigationStateVisitor() {} 106 107 virtual bool Visit(RenderView* render_view) OVERRIDE { 108 SyncNavigationState(render_view); 109 return true; 110 } 111 private: 112 DISALLOW_COPY_AND_ASSIGN(SyncNavigationStateVisitor); 113}; 114 115class ProxyToRenderViewVisitor : public RenderViewVisitor { 116 public: 117 explicit ProxyToRenderViewVisitor(WebTestProxyBase* proxy) 118 : proxy_(proxy), 119 render_view_(NULL) { 120 } 121 virtual ~ProxyToRenderViewVisitor() {} 122 123 RenderView* render_view() const { return render_view_; } 124 125 virtual bool Visit(RenderView* render_view) OVERRIDE { 126 WebKitTestRunner* test_runner = WebKitTestRunner::Get(render_view); 127 if (!test_runner) { 128 NOTREACHED(); 129 return true; 130 } 131 if (test_runner->proxy() == proxy_) { 132 render_view_ = render_view; 133 return false; 134 } 135 return true; 136 } 137 138 private: 139 WebTestProxyBase* proxy_; 140 RenderView* render_view_; 141 142 DISALLOW_COPY_AND_ASSIGN(ProxyToRenderViewVisitor); 143}; 144 145class NavigateAwayVisitor : public RenderViewVisitor { 146 public: 147 explicit NavigateAwayVisitor(RenderView* main_render_view) 148 : main_render_view_(main_render_view) {} 149 virtual ~NavigateAwayVisitor() {} 150 151 virtual bool Visit(RenderView* render_view) OVERRIDE { 152 if (render_view == main_render_view_) 153 return true; 154 render_view->GetWebView()->mainFrame()->loadRequest( 155 WebURLRequest(GURL(url::kAboutBlankURL))); 156 return true; 157 } 158 159 private: 160 RenderView* main_render_view_; 161 162 DISALLOW_COPY_AND_ASSIGN(NavigateAwayVisitor); 163}; 164 165class UseSynchronousResizeModeVisitor : public RenderViewVisitor { 166 public: 167 explicit UseSynchronousResizeModeVisitor(bool enable) : enable_(enable) {} 168 virtual ~UseSynchronousResizeModeVisitor() {} 169 170 virtual bool Visit(RenderView* render_view) OVERRIDE { 171 UseSynchronousResizeMode(render_view, enable_); 172 return true; 173 } 174 175 private: 176 bool enable_; 177}; 178 179} // namespace 180 181WebKitTestRunner::WebKitTestRunner(RenderView* render_view) 182 : RenderViewObserver(render_view), 183 RenderViewObserverTracker<WebKitTestRunner>(render_view), 184 proxy_(NULL), 185 focused_view_(NULL), 186 is_main_window_(false), 187 focus_on_next_commit_(false), 188 leak_detector_(new LeakDetector(this)) { 189} 190 191WebKitTestRunner::~WebKitTestRunner() { 192} 193 194// WebTestDelegate ----------------------------------------------------------- 195 196void WebKitTestRunner::clearEditCommand() { 197 render_view()->ClearEditCommands(); 198} 199 200void WebKitTestRunner::setEditCommand(const std::string& name, 201 const std::string& value) { 202 render_view()->SetEditCommandForNextKeyEvent(name, value); 203} 204 205void WebKitTestRunner::setGamepadProvider( 206 RendererGamepadProvider* provider) { 207 SetMockGamepadProvider(provider); 208} 209 210void WebKitTestRunner::setDeviceLightData(const double data) { 211 SetMockDeviceLightData(data); 212} 213 214void WebKitTestRunner::setDeviceMotionData(const WebDeviceMotionData& data) { 215 SetMockDeviceMotionData(data); 216} 217 218void WebKitTestRunner::setDeviceOrientationData( 219 const WebDeviceOrientationData& data) { 220 SetMockDeviceOrientationData(data); 221} 222 223void WebKitTestRunner::setScreenOrientation( 224 const WebScreenOrientationType& orientation) { 225 MockScreenOrientationClient* mock_client = 226 proxy()->GetScreenOrientationClientMock(); 227 mock_client->UpdateDeviceOrientation(render_view()->GetWebView()->mainFrame(), 228 orientation); 229} 230 231void WebKitTestRunner::resetScreenOrientation() { 232 MockScreenOrientationClient* mock_client = 233 proxy()->GetScreenOrientationClientMock(); 234 mock_client->ResetData(); 235} 236 237void WebKitTestRunner::didChangeBatteryStatus( 238 const blink::WebBatteryStatus& status) { 239 MockBatteryStatusChanged(status); 240} 241 242void WebKitTestRunner::printMessage(const std::string& message) { 243 Send(new ShellViewHostMsg_PrintMessage(routing_id(), message)); 244} 245 246void WebKitTestRunner::postTask(WebTask* task) { 247 Platform::current()->callOnMainThread(InvokeTaskHelper, task); 248} 249 250void WebKitTestRunner::postDelayedTask(WebTask* task, long long ms) { 251 base::MessageLoop::current()->PostDelayedTask( 252 FROM_HERE, 253 base::Bind(&WebTask::run, base::Owned(task)), 254 base::TimeDelta::FromMilliseconds(ms)); 255} 256 257WebString WebKitTestRunner::registerIsolatedFileSystem( 258 const blink::WebVector<blink::WebString>& absolute_filenames) { 259 std::vector<base::FilePath> files; 260 for (size_t i = 0; i < absolute_filenames.size(); ++i) 261 files.push_back(base::FilePath::FromUTF16Unsafe(absolute_filenames[i])); 262 std::string filesystem_id; 263 Send(new ShellViewHostMsg_RegisterIsolatedFileSystem( 264 routing_id(), files, &filesystem_id)); 265 return WebString::fromUTF8(filesystem_id); 266} 267 268long long WebKitTestRunner::getCurrentTimeInMillisecond() { 269 return base::TimeDelta(base::Time::Now() - 270 base::Time::UnixEpoch()).ToInternalValue() / 271 base::Time::kMicrosecondsPerMillisecond; 272} 273 274WebString WebKitTestRunner::getAbsoluteWebStringFromUTF8Path( 275 const std::string& utf8_path) { 276 base::FilePath path = base::FilePath::FromUTF8Unsafe(utf8_path); 277 if (!path.IsAbsolute()) { 278 GURL base_url = 279 net::FilePathToFileURL(test_config_.current_working_directory.Append( 280 FILE_PATH_LITERAL("foo"))); 281 net::FileURLToFilePath(base_url.Resolve(utf8_path), &path); 282 } 283 return path.AsUTF16Unsafe(); 284} 285 286WebURL WebKitTestRunner::localFileToDataURL(const WebURL& file_url) { 287 base::FilePath local_path; 288 if (!net::FileURLToFilePath(file_url, &local_path)) 289 return WebURL(); 290 291 std::string contents; 292 Send(new ShellViewHostMsg_ReadFileToString( 293 routing_id(), local_path, &contents)); 294 295 std::string contents_base64; 296 base::Base64Encode(contents, &contents_base64); 297 298 const char data_url_prefix[] = "data:text/css:charset=utf-8;base64,"; 299 return WebURL(GURL(data_url_prefix + contents_base64)); 300} 301 302WebURL WebKitTestRunner::rewriteLayoutTestsURL(const std::string& utf8_url) { 303 const char kPrefix[] = "file:///tmp/LayoutTests/"; 304 const int kPrefixLen = arraysize(kPrefix) - 1; 305 306 if (utf8_url.compare(0, kPrefixLen, kPrefix, kPrefixLen)) 307 return WebURL(GURL(utf8_url)); 308 309 base::FilePath replace_path = 310 ShellRenderProcessObserver::GetInstance()->webkit_source_dir().Append( 311 FILE_PATH_LITERAL("LayoutTests/")); 312#if defined(OS_WIN) 313 std::string utf8_path = base::WideToUTF8(replace_path.value()); 314#else 315 std::string utf8_path = 316 base::WideToUTF8(base::SysNativeMBToWide(replace_path.value())); 317#endif 318 std::string new_url = 319 std::string("file://") + utf8_path + utf8_url.substr(kPrefixLen); 320 return WebURL(GURL(new_url)); 321} 322 323TestPreferences* WebKitTestRunner::preferences() { 324 return &prefs_; 325} 326 327void WebKitTestRunner::applyPreferences() { 328 WebPreferences prefs = render_view()->GetWebkitPreferences(); 329 ExportLayoutTestSpecificPreferences(prefs_, &prefs); 330 render_view()->SetWebkitPreferences(prefs); 331 Send(new ShellViewHostMsg_OverridePreferences(routing_id(), prefs)); 332} 333 334std::string WebKitTestRunner::makeURLErrorDescription( 335 const WebURLError& error) { 336 std::string domain = error.domain.utf8(); 337 int code = error.reason; 338 339 if (domain == net::kErrorDomain) { 340 domain = "NSURLErrorDomain"; 341 switch (error.reason) { 342 case net::ERR_ABORTED: 343 code = -999; // NSURLErrorCancelled 344 break; 345 case net::ERR_UNSAFE_PORT: 346 // Our unsafe port checking happens at the network stack level, but we 347 // make this translation here to match the behavior of stock WebKit. 348 domain = "WebKitErrorDomain"; 349 code = 103; 350 break; 351 case net::ERR_ADDRESS_INVALID: 352 case net::ERR_ADDRESS_UNREACHABLE: 353 case net::ERR_NETWORK_ACCESS_DENIED: 354 code = -1004; // NSURLErrorCannotConnectToHost 355 break; 356 } 357 } else { 358 DLOG(WARNING) << "Unknown error domain"; 359 } 360 361 return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">", 362 domain.c_str(), code, error.unreachableURL.spec().data()); 363} 364 365void WebKitTestRunner::useUnfortunateSynchronousResizeMode(bool enable) { 366 UseSynchronousResizeModeVisitor visitor(enable); 367 RenderView::ForEach(&visitor); 368} 369 370void WebKitTestRunner::enableAutoResizeMode(const WebSize& min_size, 371 const WebSize& max_size) { 372 EnableAutoResizeMode(render_view(), min_size, max_size); 373} 374 375void WebKitTestRunner::disableAutoResizeMode(const WebSize& new_size) { 376 DisableAutoResizeMode(render_view(), new_size); 377 if (!new_size.isEmpty()) 378 ForceResizeRenderView(render_view(), new_size); 379} 380 381void WebKitTestRunner::clearDevToolsLocalStorage() { 382 Send(new ShellViewHostMsg_ClearDevToolsLocalStorage(routing_id())); 383} 384 385void WebKitTestRunner::showDevTools(const std::string& settings, 386 const std::string& frontend_url) { 387 Send(new ShellViewHostMsg_ShowDevTools( 388 routing_id(), settings, frontend_url)); 389} 390 391void WebKitTestRunner::closeDevTools() { 392 Send(new ShellViewHostMsg_CloseDevTools(routing_id())); 393 WebDevToolsAgent* agent = render_view()->GetWebView()->devToolsAgent(); 394 if (agent) 395 agent->detach(); 396} 397 398void WebKitTestRunner::evaluateInWebInspector(long call_id, 399 const std::string& script) { 400 WebDevToolsAgent* agent = render_view()->GetWebView()->devToolsAgent(); 401 if (agent) 402 agent->evaluateInWebInspector(call_id, WebString::fromUTF8(script)); 403} 404 405void WebKitTestRunner::clearAllDatabases() { 406 Send(new ShellViewHostMsg_ClearAllDatabases(routing_id())); 407} 408 409void WebKitTestRunner::setDatabaseQuota(int quota) { 410 Send(new ShellViewHostMsg_SetDatabaseQuota(routing_id(), quota)); 411} 412 413void WebKitTestRunner::setDeviceScaleFactor(float factor) { 414 SetDeviceScaleFactor(render_view(), factor); 415} 416 417void WebKitTestRunner::setDeviceColorProfile(const std::string& name) { 418 SetDeviceColorProfile(render_view(), name); 419} 420 421void WebKitTestRunner::setFocus(WebTestProxyBase* proxy, bool focus) { 422 ProxyToRenderViewVisitor visitor(proxy); 423 RenderView::ForEach(&visitor); 424 if (!visitor.render_view()) { 425 NOTREACHED(); 426 return; 427 } 428 429 // Check whether the focused view was closed meanwhile. 430 if (!WebKitTestRunner::Get(focused_view_)) 431 focused_view_ = NULL; 432 433 if (focus) { 434 if (focused_view_ != visitor.render_view()) { 435 if (focused_view_) 436 SetFocusAndActivate(focused_view_, false); 437 SetFocusAndActivate(visitor.render_view(), true); 438 focused_view_ = visitor.render_view(); 439 } 440 } else { 441 if (focused_view_ == visitor.render_view()) { 442 SetFocusAndActivate(visitor.render_view(), false); 443 focused_view_ = NULL; 444 } 445 } 446} 447 448void WebKitTestRunner::setAcceptAllCookies(bool accept) { 449 Send(new ShellViewHostMsg_AcceptAllCookies(routing_id(), accept)); 450} 451 452std::string WebKitTestRunner::pathToLocalResource(const std::string& resource) { 453#if defined(OS_WIN) 454 if (resource.find("/tmp/") == 0) { 455 // We want a temp file. 456 GURL base_url = net::FilePathToFileURL(test_config_.temp_path); 457 return base_url.Resolve(resource.substr(strlen("/tmp/"))).spec(); 458 } 459#endif 460 461 // Some layout tests use file://// which we resolve as a UNC path. Normalize 462 // them to just file:///. 463 std::string result = resource; 464 while (StringToLowerASCII(result).find("file:////") == 0) { 465 result = result.substr(0, strlen("file:///")) + 466 result.substr(strlen("file:////")); 467 } 468 return rewriteLayoutTestsURL(result).spec(); 469} 470 471void WebKitTestRunner::setLocale(const std::string& locale) { 472 setlocale(LC_ALL, locale.c_str()); 473} 474 475void WebKitTestRunner::testFinished() { 476 if (!is_main_window_) { 477 Send(new ShellViewHostMsg_TestFinishedInSecondaryWindow(routing_id())); 478 return; 479 } 480 WebTestInterfaces* interfaces = 481 ShellRenderProcessObserver::GetInstance()->test_interfaces(); 482 interfaces->setTestIsRunning(false); 483 if (interfaces->testRunner()->ShouldDumpBackForwardList()) { 484 SyncNavigationStateVisitor visitor; 485 RenderView::ForEach(&visitor); 486 Send(new ShellViewHostMsg_CaptureSessionHistory(routing_id())); 487 } else { 488 CaptureDump(); 489 } 490} 491 492void WebKitTestRunner::closeRemainingWindows() { 493 NavigateAwayVisitor visitor(render_view()); 494 RenderView::ForEach(&visitor); 495 Send(new ShellViewHostMsg_CloseRemainingWindows(routing_id())); 496} 497 498void WebKitTestRunner::deleteAllCookies() { 499 Send(new ShellViewHostMsg_DeleteAllCookies(routing_id())); 500} 501 502int WebKitTestRunner::navigationEntryCount() { 503 return GetLocalSessionHistoryLength(render_view()); 504} 505 506void WebKitTestRunner::goToOffset(int offset) { 507 Send(new ShellViewHostMsg_GoToOffset(routing_id(), offset)); 508} 509 510void WebKitTestRunner::reload() { 511 Send(new ShellViewHostMsg_Reload(routing_id())); 512} 513 514void WebKitTestRunner::loadURLForFrame(const WebURL& url, 515 const std::string& frame_name) { 516 Send(new ShellViewHostMsg_LoadURLForFrame( 517 routing_id(), url, frame_name)); 518} 519 520bool WebKitTestRunner::allowExternalPages() { 521 return test_config_.allow_external_pages; 522} 523 524std::string WebKitTestRunner::dumpHistoryForWindow(WebTestProxyBase* proxy) { 525 size_t pos = 0; 526 std::vector<int>::iterator id; 527 for (id = routing_ids_.begin(); id != routing_ids_.end(); ++id, ++pos) { 528 RenderView* render_view = RenderView::FromRoutingID(*id); 529 if (!render_view) { 530 NOTREACHED(); 531 continue; 532 } 533 if (WebKitTestRunner::Get(render_view)->proxy() == proxy) 534 break; 535 } 536 537 if (id == routing_ids_.end()) { 538 NOTREACHED(); 539 return std::string(); 540 } 541 return DumpBackForwardList(session_histories_[pos], 542 current_entry_indexes_[pos]); 543} 544 545// RenderViewObserver -------------------------------------------------------- 546 547void WebKitTestRunner::DidClearWindowObject(WebLocalFrame* frame) { 548 WebTestingSupport::injectInternalsObject(frame); 549 ShellRenderProcessObserver::GetInstance()->test_interfaces()->bindTo(frame); 550 GCController::Install(frame); 551} 552 553bool WebKitTestRunner::OnMessageReceived(const IPC::Message& message) { 554 bool handled = true; 555 IPC_BEGIN_MESSAGE_MAP(WebKitTestRunner, message) 556 IPC_MESSAGE_HANDLER(ShellViewMsg_SetTestConfiguration, 557 OnSetTestConfiguration) 558 IPC_MESSAGE_HANDLER(ShellViewMsg_SessionHistory, OnSessionHistory) 559 IPC_MESSAGE_HANDLER(ShellViewMsg_Reset, OnReset) 560 IPC_MESSAGE_HANDLER(ShellViewMsg_NotifyDone, OnNotifyDone) 561 IPC_MESSAGE_HANDLER(ShellViewMsg_TryLeakDetection, OnTryLeakDetection) 562 IPC_MESSAGE_UNHANDLED(handled = false) 563 IPC_END_MESSAGE_MAP() 564 565 return handled; 566} 567 568void WebKitTestRunner::Navigate(const GURL& url) { 569 focus_on_next_commit_ = true; 570 if (!is_main_window_ && 571 ShellRenderProcessObserver::GetInstance()->main_test_runner() == this) { 572 WebTestInterfaces* interfaces = 573 ShellRenderProcessObserver::GetInstance()->test_interfaces(); 574 interfaces->setTestIsRunning(true); 575 interfaces->configureForTestWithURL(GURL(), false); 576 ForceResizeRenderView(render_view(), WebSize(800, 600)); 577 } 578} 579 580void WebKitTestRunner::DidCommitProvisionalLoad(WebLocalFrame* frame, 581 bool is_new_navigation) { 582 if (!focus_on_next_commit_) 583 return; 584 focus_on_next_commit_ = false; 585 render_view()->GetWebView()->setFocusedFrame(frame); 586} 587 588void WebKitTestRunner::DidFailProvisionalLoad(WebLocalFrame* frame, 589 const WebURLError& error) { 590 focus_on_next_commit_ = false; 591} 592 593// Public methods - ----------------------------------------------------------- 594 595void WebKitTestRunner::Reset() { 596 // The proxy_ is always non-NULL, it is set right after construction. 597 proxy_->set_widget(render_view()->GetWebView()); 598 proxy_->Reset(); 599 prefs_.Reset(); 600 routing_ids_.clear(); 601 session_histories_.clear(); 602 current_entry_indexes_.clear(); 603 604 render_view()->ClearEditCommands(); 605 render_view()->GetWebView()->mainFrame()->setName(WebString()); 606 render_view()->GetWebView()->mainFrame()->clearOpener(); 607 render_view()->GetWebView()->setPageScaleFactorLimits(-1, -1); 608 render_view()->GetWebView()->setPageScaleFactor(1, WebPoint(0, 0)); 609 610 // Resetting the internals object also overrides the WebPreferences, so we 611 // have to sync them to WebKit again. 612 WebTestingSupport::resetInternalsObject( 613 render_view()->GetWebView()->mainFrame()->toWebLocalFrame()); 614 render_view()->SetWebkitPreferences(render_view()->GetWebkitPreferences()); 615} 616 617// Private methods ----------------------------------------------------------- 618 619void WebKitTestRunner::CaptureDump() { 620 WebTestInterfaces* interfaces = 621 ShellRenderProcessObserver::GetInstance()->test_interfaces(); 622 TRACE_EVENT0("shell", "WebKitTestRunner::CaptureDump"); 623 624 if (interfaces->testRunner()->ShouldDumpAsAudio()) { 625 std::vector<unsigned char> vector_data; 626 interfaces->testRunner()->GetAudioData(&vector_data); 627 Send(new ShellViewHostMsg_AudioDump(routing_id(), vector_data)); 628 } else { 629 Send(new ShellViewHostMsg_TextDump(routing_id(), 630 proxy()->CaptureTree(false))); 631 632 if (test_config_.enable_pixel_dumping && 633 interfaces->testRunner()->ShouldGeneratePixelResults()) { 634 CHECK(render_view()->GetWebView()->isAcceleratedCompositingActive()); 635 proxy()->CapturePixelsAsync(base::Bind( 636 &WebKitTestRunner::CaptureDumpPixels, base::Unretained(this))); 637 return; 638 } 639 } 640 641 CaptureDumpComplete(); 642} 643 644void WebKitTestRunner::CaptureDumpPixels(const SkBitmap& snapshot) { 645 DCHECK_NE(0, snapshot.info().fWidth); 646 DCHECK_NE(0, snapshot.info().fHeight); 647 648 SkAutoLockPixels snapshot_lock(snapshot); 649 base::MD5Digest digest; 650 base::MD5Sum(snapshot.getPixels(), snapshot.getSize(), &digest); 651 std::string actual_pixel_hash = base::MD5DigestToBase16(digest); 652 653 if (actual_pixel_hash == test_config_.expected_pixel_hash) { 654 SkBitmap empty_image; 655 Send(new ShellViewHostMsg_ImageDump( 656 routing_id(), actual_pixel_hash, empty_image)); 657 } else { 658 Send(new ShellViewHostMsg_ImageDump( 659 routing_id(), actual_pixel_hash, snapshot)); 660 } 661 662 CaptureDumpComplete(); 663} 664 665void WebKitTestRunner::CaptureDumpComplete() { 666 render_view()->GetWebView()->mainFrame()->stopLoading(); 667 668 base::MessageLoop::current()->PostTask( 669 FROM_HERE, 670 base::Bind(base::IgnoreResult(&WebKitTestRunner::Send), 671 base::Unretained(this), 672 new ShellViewHostMsg_TestFinished(routing_id()))); 673} 674 675void WebKitTestRunner::OnSetTestConfiguration( 676 const ShellTestConfiguration& params) { 677 test_config_ = params; 678 is_main_window_ = true; 679 680 ForceResizeRenderView( 681 render_view(), 682 WebSize(params.initial_size.width(), params.initial_size.height())); 683 setFocus(proxy_, true); 684 685 WebTestInterfaces* interfaces = 686 ShellRenderProcessObserver::GetInstance()->test_interfaces(); 687 interfaces->setTestIsRunning(true); 688 interfaces->configureForTestWithURL(params.test_url, 689 params.enable_pixel_dumping); 690} 691 692void WebKitTestRunner::OnSessionHistory( 693 const std::vector<int>& routing_ids, 694 const std::vector<std::vector<PageState> >& session_histories, 695 const std::vector<unsigned>& current_entry_indexes) { 696 routing_ids_ = routing_ids; 697 session_histories_ = session_histories; 698 current_entry_indexes_ = current_entry_indexes; 699 CaptureDump(); 700} 701 702void WebKitTestRunner::OnReset() { 703 ShellRenderProcessObserver::GetInstance()->test_interfaces()->resetAll(); 704 Reset(); 705 // Navigating to about:blank will make sure that no new loads are initiated 706 // by the renderer. 707 render_view()->GetWebView()->mainFrame()->loadRequest( 708 WebURLRequest(GURL(url::kAboutBlankURL))); 709 Send(new ShellViewHostMsg_ResetDone(routing_id())); 710} 711 712void WebKitTestRunner::OnNotifyDone() { 713 render_view()->GetWebView()->mainFrame()->executeScript( 714 WebScriptSource(WebString::fromUTF8("testRunner.notifyDone();"))); 715} 716 717void WebKitTestRunner::OnTryLeakDetection() { 718 WebLocalFrame* main_frame = 719 render_view()->GetWebView()->mainFrame()->toWebLocalFrame(); 720 DCHECK_EQ(GURL(url::kAboutBlankURL), GURL(main_frame->document().url())); 721 DCHECK(!main_frame->isLoading()); 722 723 leak_detector_->TryLeakDetection(main_frame); 724} 725 726void WebKitTestRunner::ReportLeakDetectionResult( 727 const LeakDetectionResult& report) { 728 Send(new ShellViewHostMsg_LeakDetectionDone(routing_id(), report)); 729} 730 731} // namespace content 732