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