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