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