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