Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / shell / renderer / test_runner / WebTestProxy.cpp
1 // Copyright 2013 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/test_runner/WebTestProxy.h"
6
7 #include <cctype>
8
9 #include "base/callback_helpers.h"
10 #include "base/debug/trace_event.h"
11 #include "base/logging.h"
12 #include "content/shell/renderer/test_runner/event_sender.h"
13 #include "content/shell/renderer/test_runner/MockColorChooser.h"
14 #include "content/shell/renderer/test_runner/MockWebSpeechRecognizer.h"
15 #include "content/shell/renderer/test_runner/SpellCheckClient.h"
16 #include "content/shell/renderer/test_runner/TestCommon.h"
17 #include "content/shell/renderer/test_runner/TestInterfaces.h"
18 #include "content/shell/renderer/test_runner/TestPlugin.h"
19 #include "content/shell/renderer/test_runner/WebTestDelegate.h"
20 #include "content/shell/renderer/test_runner/WebTestInterfaces.h"
21 #include "content/shell/renderer/test_runner/WebTestRunner.h"
22 #include "content/shell/renderer/test_runner/WebUserMediaClientMock.h"
23 #include "content/shell/renderer/test_runner/accessibility_controller.h"
24 #include "content/shell/renderer/test_runner/test_runner.h"
25 // FIXME: Including platform_canvas.h here is a layering violation.
26 #include "skia/ext/platform_canvas.h"
27 #include "third_party/WebKit/public/platform/WebCString.h"
28 #include "third_party/WebKit/public/platform/WebURLError.h"
29 #include "third_party/WebKit/public/platform/WebURLRequest.h"
30 #include "third_party/WebKit/public/platform/WebURLResponse.h"
31 #include "third_party/WebKit/public/web/WebAXEnums.h"
32 #include "third_party/WebKit/public/web/WebAXObject.h"
33 #include "third_party/WebKit/public/web/WebCachedURLRequest.h"
34 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
35 #include "third_party/WebKit/public/web/WebDataSource.h"
36 #include "third_party/WebKit/public/web/WebDocument.h"
37 #include "third_party/WebKit/public/web/WebElement.h"
38 #include "third_party/WebKit/public/web/WebHistoryItem.h"
39 #include "third_party/WebKit/public/web/WebLocalFrame.h"
40 #include "third_party/WebKit/public/web/WebMIDIClientMock.h"
41 #include "third_party/WebKit/public/web/WebNode.h"
42 #include "third_party/WebKit/public/web/WebPluginParams.h"
43 #include "third_party/WebKit/public/web/WebPrintParams.h"
44 #include "third_party/WebKit/public/web/WebRange.h"
45 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
46 #include "third_party/WebKit/public/web/WebView.h"
47
48 using namespace blink;
49 using namespace std;
50
51 namespace content {
52
53 namespace {
54
55 class HostMethodTask : public WebMethodTask<WebTestProxyBase> {
56 public:
57     typedef void (WebTestProxyBase::*CallbackMethodType)();
58     HostMethodTask(WebTestProxyBase* object, CallbackMethodType callback)
59         : WebMethodTask<WebTestProxyBase>(object)
60         , m_callback(callback)
61     { }
62
63     virtual void runIfValid() OVERRIDE { (m_object->*m_callback)(); }
64
65 private:
66     CallbackMethodType m_callback;
67 };
68
69 class ClosureTask : public WebMethodTask<WebTestProxyBase> {
70  public:
71   ClosureTask(WebTestProxyBase* object, base::Closure callback)
72       : WebMethodTask<WebTestProxyBase>(object), m_callback(callback) {}
73
74   virtual void runIfValid() OVERRIDE {
75     if (!m_callback.is_null())
76       m_callback.Run();
77   }
78
79  private:
80   base::Closure m_callback;
81 };
82
83 void printFrameDescription(WebTestDelegate* delegate, WebFrame* frame)
84 {
85     string name8 = frame->uniqueName().utf8();
86     if (frame == frame->view()->mainFrame()) {
87         if (!name8.length()) {
88             delegate->printMessage("main frame");
89             return;
90         }
91         delegate->printMessage(string("main frame \"") + name8 + "\"");
92         return;
93     }
94     if (!name8.length()) {
95         delegate->printMessage("frame (anonymous)");
96         return;
97     }
98     delegate->printMessage(string("frame \"") + name8 + "\"");
99 }
100
101 void printFrameUserGestureStatus(WebTestDelegate* delegate, WebFrame* frame, const char* msg)
102 {
103     bool isUserGesture = WebUserGestureIndicator::isProcessingUserGesture();
104     delegate->printMessage(string("Frame with user gesture \"") + (isUserGesture ? "true" : "false") + "\"" + msg);
105 }
106
107 // Used to write a platform neutral file:/// URL by taking the
108 // filename and its directory. (e.g., converts
109 // "file:///tmp/foo/bar.txt" to just "bar.txt").
110 string descriptionSuitableForTestResult(const string& url)
111 {
112     if (url.empty() || string::npos == url.find("file://"))
113         return url;
114
115     size_t pos = url.rfind('/');
116     if (pos == string::npos || !pos)
117         return "ERROR:" + url;
118     pos = url.rfind('/', pos - 1);
119     if (pos == string::npos)
120         return "ERROR:" + url;
121
122     return url.substr(pos + 1);
123 }
124
125 void printResponseDescription(WebTestDelegate* delegate, const WebURLResponse& response)
126 {
127     if (response.isNull()) {
128         delegate->printMessage("(null)");
129         return;
130     }
131     string url = response.url().spec();
132     char data[100];
133     snprintf(data, sizeof(data), "%d", response. httpStatusCode());
134     delegate->printMessage(string("<NSURLResponse ") + descriptionSuitableForTestResult(url) + ", http status code " + data + ">");
135 }
136
137 string URLDescription(const GURL& url)
138 {
139     if (url.SchemeIs("file"))
140         return url.ExtractFileName();
141     return url.possibly_invalid_spec();
142 }
143
144 string PriorityDescription(const WebURLRequest::Priority& priority)
145 {
146     switch (priority) {
147     case WebURLRequest::PriorityVeryLow:
148         return "VeryLow";
149     case WebURLRequest::PriorityLow:
150         return "Low";
151     case WebURLRequest::PriorityMedium:
152         return "Medium";
153     case WebURLRequest::PriorityHigh:
154         return "High";
155     case WebURLRequest::PriorityVeryHigh:
156         return "VeryHigh";
157     case WebURLRequest::PriorityUnresolved:
158     default:
159         return "Unresolved";
160     }
161 }
162
163 void blockRequest(WebURLRequest& request)
164 {
165     request.setURL(GURL("255.255.255.255"));
166 }
167
168 bool isLocalhost(const string& host)
169 {
170     return host == "127.0.0.1" || host == "localhost";
171 }
172
173 bool hostIsUsedBySomeTestsToGenerateError(const string& host)
174 {
175     return host == "255.255.255.255";
176 }
177
178 // Used to write a platform neutral file:/// URL by only taking the filename
179 // (e.g., converts "file:///tmp/foo.txt" to just "foo.txt").
180 string urlSuitableForTestResult(const string& url)
181 {
182     if (url.empty() || string::npos == url.find("file://"))
183         return url;
184
185     size_t pos = url.rfind('/');
186     if (pos == string::npos) {
187 #ifdef WIN32
188         pos = url.rfind('\\');
189         if (pos == string::npos)
190             pos = 0;
191 #else
192         pos = 0;
193 #endif
194     }
195     string filename = url.substr(pos + 1);
196     if (filename.empty())
197         return "file:"; // A WebKit test has this in its expected output.
198     return filename;
199 }
200
201 // WebNavigationType debugging strings taken from PolicyDelegate.mm.
202 const char* linkClickedString = "link clicked";
203 const char* formSubmittedString = "form submitted";
204 const char* backForwardString = "back/forward";
205 const char* reloadString = "reload";
206 const char* formResubmittedString = "form resubmitted";
207 const char* otherString = "other";
208 const char* illegalString = "illegal value";
209
210 // Get a debugging string from a WebNavigationType.
211 const char* webNavigationTypeToString(WebNavigationType type)
212 {
213     switch (type) {
214     case blink::WebNavigationTypeLinkClicked:
215         return linkClickedString;
216     case blink::WebNavigationTypeFormSubmitted:
217         return formSubmittedString;
218     case blink::WebNavigationTypeBackForward:
219         return backForwardString;
220     case blink::WebNavigationTypeReload:
221         return reloadString;
222     case blink::WebNavigationTypeFormResubmitted:
223         return formResubmittedString;
224     case blink::WebNavigationTypeOther:
225         return otherString;
226     }
227     return illegalString;
228 }
229
230 string dumpDocumentText(WebFrame* frame)
231 {
232     // We use the document element's text instead of the body text here because
233     // not all documents have a body, such as XML documents.
234     WebElement documentElement = frame->document().documentElement();
235     if (documentElement.isNull())
236         return string();
237     return documentElement.innerText().utf8();
238 }
239
240 string dumpFramesAsText(WebFrame* frame, bool recursive)
241 {
242     string result;
243
244     // Add header for all but the main frame. Skip empty frames.
245     if (frame->parent() && !frame->document().documentElement().isNull()) {
246         result.append("\n--------\nFrame: '");
247         result.append(frame->uniqueName().utf8().data());
248         result.append("'\n--------\n");
249     }
250
251     result.append(dumpDocumentText(frame));
252     result.append("\n");
253
254     if (recursive) {
255         for (WebFrame* child = frame->firstChild(); child; child = child->nextSibling())
256             result.append(dumpFramesAsText(child, recursive));
257     }
258
259     return result;
260 }
261
262 string dumpFramesAsPrintedText(WebFrame* frame, bool recursive)
263 {
264     string result;
265
266     // Cannot do printed format for anything other than HTML
267     if (!frame->document().isHTMLDocument())
268         return string();
269
270     // Add header for all but the main frame. Skip empty frames.
271     if (frame->parent() && !frame->document().documentElement().isNull()) {
272         result.append("\n--------\nFrame: '");
273         result.append(frame->uniqueName().utf8().data());
274         result.append("'\n--------\n");
275     }
276
277     result.append(frame->renderTreeAsText(WebFrame::RenderAsTextPrinting).utf8());
278     result.append("\n");
279
280     if (recursive) {
281         for (WebFrame* child = frame->firstChild(); child; child = child->nextSibling())
282             result.append(dumpFramesAsPrintedText(child, recursive));
283     }
284
285     return result;
286 }
287
288 string dumpFrameScrollPosition(WebFrame* frame, bool recursive)
289 {
290     string result;
291     WebSize offset = frame->scrollOffset();
292     if (offset.width > 0 || offset.height > 0) {
293         if (frame->parent())
294             result = string("frame '") + frame->uniqueName().utf8().data() + "' ";
295         char data[100];
296         snprintf(data, sizeof(data), "scrolled to %d,%d\n", offset.width, offset.height);
297         result += data;
298     }
299
300     if (!recursive)
301         return result;
302     for (WebFrame* child = frame->firstChild(); child; child = child->nextSibling())
303         result += dumpFrameScrollPosition(child, recursive);
304     return result;
305 }
306
307 string dumpAllBackForwardLists(TestInterfaces* interfaces, WebTestDelegate* delegate)
308 {
309     string result;
310     const vector<WebTestProxyBase*>& windowList = interfaces->windowList();
311     for (unsigned i = 0; i < windowList.size(); ++i)
312         result.append(delegate->dumpHistoryForWindow(windowList.at(i)));
313     return result;
314 }
315
316 }
317
318 WebTestProxyBase::WebTestProxyBase()
319     : m_testInterfaces(0)
320     , m_delegate(0)
321     , m_webWidget(0)
322     , m_spellcheck(new SpellCheckClient(this))
323     , m_chooserCount(0)
324 {
325     reset();
326 }
327
328 WebTestProxyBase::~WebTestProxyBase()
329 {
330     m_testInterfaces->windowClosed(this);
331 }
332
333 void WebTestProxyBase::setInterfaces(WebTestInterfaces* interfaces)
334 {
335     m_testInterfaces = interfaces->testInterfaces();
336     m_testInterfaces->windowOpened(this);
337 }
338
339 void WebTestProxyBase::setDelegate(WebTestDelegate* delegate)
340 {
341     m_delegate = delegate;
342     m_spellcheck->setDelegate(delegate);
343     if (m_speechRecognizer.get())
344         m_speechRecognizer->setDelegate(delegate);
345 }
346
347 void WebTestProxyBase::setWidget(WebWidget* widget)
348 {
349     m_webWidget = widget;
350 }
351
352 WebWidget* WebTestProxyBase::webWidget()
353 {
354     return m_webWidget;
355 }
356
357 WebView* WebTestProxyBase::webView()
358 {
359     DCHECK(m_webWidget);
360     // TestRunner does not support popup widgets. So m_webWidget is always a WebView.
361     return static_cast<WebView*>(m_webWidget);
362 }
363
364 void WebTestProxyBase::didForceResize()
365 {
366     invalidateAll();
367     discardBackingStore();
368 }
369
370 void WebTestProxyBase::reset()
371 {
372     m_paintRect = WebRect();
373     m_canvas.reset();
374     m_isPainting = false;
375     m_animateScheduled = false;
376     m_resourceIdentifierMap.clear();
377     m_logConsoleOutput = true;
378     if (m_midiClient.get())
379         m_midiClient->resetMock();
380 }
381
382 WebSpellCheckClient* WebTestProxyBase::spellCheckClient() const
383 {
384     return m_spellcheck.get();
385 }
386
387 WebColorChooser* WebTestProxyBase::createColorChooser(WebColorChooserClient* client, const blink::WebColor& color, const blink::WebVector<blink::WebColorSuggestion>& suggestions)
388 {
389     // This instance is deleted by WebCore::ColorInputType
390     return new MockColorChooser(client, m_delegate, this);
391 }
392
393 bool WebTestProxyBase::runFileChooser(const blink::WebFileChooserParams&, blink::WebFileChooserCompletion*)
394 {
395     m_delegate->printMessage("Mock: Opening a file chooser.\n");
396     // FIXME: Add ability to set file names to a file upload control.
397     return false;
398 }
399
400 void WebTestProxyBase::showValidationMessage(const WebRect&, const WebString& message, const WebString& subMessage, WebTextDirection)
401 {
402     m_delegate->printMessage(std::string("ValidationMessageClient: main-message=") + std::string(message.utf8()) + " sub-message=" + std::string(subMessage.utf8()) + "\n");
403 }
404
405 void WebTestProxyBase::hideValidationMessage()
406 {
407 }
408
409 void WebTestProxyBase::moveValidationMessage(const WebRect&)
410 {
411 }
412
413 string WebTestProxyBase::captureTree(bool debugRenderTree)
414 {
415     bool shouldDumpCustomText = m_testInterfaces->testRunner()->shouldDumpAsCustomText();
416     bool shouldDumpAsText = m_testInterfaces->testRunner()->shouldDumpAsText();
417     bool shouldDumpAsMarkup = m_testInterfaces->testRunner()->shouldDumpAsMarkup();
418     bool shouldDumpAsPrinted = m_testInterfaces->testRunner()->isPrinting();
419     WebFrame* frame = webView()->mainFrame();
420     string dataUtf8;
421     if (shouldDumpCustomText) {
422         // Append a newline for the test driver.
423         dataUtf8 = m_testInterfaces->testRunner()->customDumpText() + "\n";
424     } else if (shouldDumpAsText) {
425         bool recursive = m_testInterfaces->testRunner()->shouldDumpChildFramesAsText();
426         dataUtf8 = shouldDumpAsPrinted ? dumpFramesAsPrintedText(frame, recursive) : dumpFramesAsText(frame, recursive);
427     } else if (shouldDumpAsMarkup) {
428         // Append a newline for the test driver.
429         dataUtf8 = frame->contentAsMarkup().utf8() + "\n";
430     } else {
431         bool recursive = m_testInterfaces->testRunner()->shouldDumpChildFrameScrollPositions();
432         WebFrame::RenderAsTextControls renderTextBehavior = WebFrame::RenderAsTextNormal;
433         if (shouldDumpAsPrinted)
434             renderTextBehavior |= WebFrame::RenderAsTextPrinting;
435         if (debugRenderTree)
436             renderTextBehavior |= WebFrame::RenderAsTextDebug;
437         dataUtf8 = frame->renderTreeAsText(renderTextBehavior).utf8();
438         dataUtf8 += dumpFrameScrollPosition(frame, recursive);
439     }
440
441     if (m_testInterfaces->testRunner()->shouldDumpBackForwardList())
442         dataUtf8 += dumpAllBackForwardLists(m_testInterfaces, m_delegate);
443
444     return dataUtf8;
445 }
446
447 SkCanvas* WebTestProxyBase::capturePixels()
448 {
449     TRACE_EVENT0("shell", "WebTestProxyBase::capturePixels");
450     webWidget()->layout();
451     if (m_testInterfaces->testRunner()->isPrinting())
452         paintPagesWithBoundaries();
453     else
454         paintInvalidatedRegion();
455
456     DrawSelectionRect(canvas());
457
458     return canvas();
459 }
460
461 void WebTestProxyBase::DrawSelectionRect(SkCanvas* canvas) {
462   // See if we need to draw the selection bounds rect. Selection bounds
463   // rect is the rect enclosing the (possibly transformed) selection.
464   // The rect should be drawn after everything is laid out and painted.
465   if (!m_testInterfaces->testRunner()->shouldDumpSelectionRect())
466     return;
467   // If there is a selection rect - draw a red 1px border enclosing rect
468   WebRect wr = webView()->mainFrame()->selectionBoundsRect();
469   if (wr.isEmpty())
470     return;
471   // Render a red rectangle bounding selection rect
472   SkPaint paint;
473   paint.setColor(0xFFFF0000);  // Fully opaque red
474   paint.setStyle(SkPaint::kStroke_Style);
475   paint.setFlags(SkPaint::kAntiAlias_Flag);
476   paint.setStrokeWidth(1.0f);
477   SkIRect rect;  // Bounding rect
478   rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
479   canvas->drawIRect(rect, paint);
480 }
481
482 void WebTestProxyBase::didCompositeAndReadback(const SkBitmap& bitmap) {
483   TRACE_EVENT2("shell",
484                "WebTestProxyBase::didCompositeAndReadback",
485                "x",
486                bitmap.info().fWidth,
487                "y",
488                bitmap.info().fHeight);
489   SkCanvas canvas(bitmap);
490   DrawSelectionRect(&canvas);
491   DCHECK(!m_compositeAndReadbackCallbacks.empty());
492   m_compositeAndReadbackCallbacks.front().Run(bitmap);
493   m_compositeAndReadbackCallbacks.pop_front();
494 }
495
496 void WebTestProxyBase::CapturePixelsAsync(
497     base::Callback<void(const SkBitmap&)> callback) {
498   TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync");
499
500   DCHECK(webWidget()->isAcceleratedCompositingActive());
501   DCHECK(!callback.is_null());
502   m_compositeAndReadbackCallbacks.push_back(callback);
503   webWidget()->compositeAndReadbackAsync(this);
504 }
505
506 void WebTestProxyBase::setLogConsoleOutput(bool enabled)
507 {
508     m_logConsoleOutput = enabled;
509 }
510
511 void WebTestProxyBase::paintRect(const WebRect& rect)
512 {
513     DCHECK(!m_isPainting);
514     DCHECK(canvas());
515     m_isPainting = true;
516     float deviceScaleFactor = webView()->deviceScaleFactor();
517     int scaledX = static_cast<int>(static_cast<float>(rect.x) * deviceScaleFactor);
518     int scaledY = static_cast<int>(static_cast<float>(rect.y) * deviceScaleFactor);
519     int scaledWidth = static_cast<int>(ceil(static_cast<float>(rect.width) * deviceScaleFactor));
520     int scaledHeight = static_cast<int>(ceil(static_cast<float>(rect.height) * deviceScaleFactor));
521     WebRect deviceRect(scaledX, scaledY, scaledWidth, scaledHeight);
522     webWidget()->paint(canvas(), deviceRect);
523     m_isPainting = false;
524 }
525
526 void WebTestProxyBase::paintInvalidatedRegion()
527 {
528     webWidget()->animate(0.0);
529     webWidget()->layout();
530     WebSize widgetSize = webWidget()->size();
531     WebRect clientRect(0, 0, widgetSize.width, widgetSize.height);
532
533     // Paint the canvas if necessary. Allow painting to generate extra rects
534     // for the first two calls. This is necessary because some WebCore rendering
535     // objects update their layout only when painted.
536     // Store the total area painted in total_paint. Then tell the gdk window
537     // to update that area after we're done painting it.
538     for (int i = 0; i < 3; ++i) {
539         // rect = intersect(m_paintRect , clientRect)
540         WebRect damageRect = m_paintRect;
541         int left = max(damageRect.x, clientRect.x);
542         int top = max(damageRect.y, clientRect.y);
543         int right = min(damageRect.x + damageRect.width, clientRect.x + clientRect.width);
544         int bottom = min(damageRect.y + damageRect.height, clientRect.y + clientRect.height);
545         WebRect rect;
546         if (left < right && top < bottom)
547             rect = WebRect(left, top, right - left, bottom - top);
548
549         m_paintRect = WebRect();
550         if (rect.isEmpty())
551             continue;
552         paintRect(rect);
553     }
554     DCHECK(m_paintRect.isEmpty());
555 }
556
557 void WebTestProxyBase::paintPagesWithBoundaries()
558 {
559     DCHECK(!m_isPainting);
560     DCHECK(canvas());
561     m_isPainting = true;
562
563     WebSize pageSizeInPixels = webWidget()->size();
564     WebFrame* webFrame = webView()->mainFrame();
565
566     int pageCount = webFrame->printBegin(pageSizeInPixels);
567     int totalHeight = pageCount * (pageSizeInPixels.height + 1) - 1;
568
569     SkCanvas* testCanvas = skia::TryCreateBitmapCanvas(pageSizeInPixels.width, totalHeight, false);
570     if (testCanvas) {
571         discardBackingStore();
572         m_canvas.reset(testCanvas);
573     } else {
574         webFrame->printEnd();
575         return;
576     }
577
578     webFrame->printPagesWithBoundaries(canvas(), pageSizeInPixels);
579     webFrame->printEnd();
580
581     m_isPainting = false;
582 }
583
584 SkCanvas* WebTestProxyBase::canvas()
585 {
586     if (m_canvas.get())
587         return m_canvas.get();
588     WebSize widgetSize = webWidget()->size();
589     float deviceScaleFactor = webView()->deviceScaleFactor();
590     int scaledWidth = static_cast<int>(ceil(static_cast<float>(widgetSize.width) * deviceScaleFactor));
591     int scaledHeight = static_cast<int>(ceil(static_cast<float>(widgetSize.height) * deviceScaleFactor));
592     // We're allocating the canvas to be non-opaque (third parameter), so we
593     // don't end up with uninitialized memory if a layout test doesn't damage
594     // the entire view.
595     m_canvas.reset(skia::CreateBitmapCanvas(scaledWidth, scaledHeight, false));
596     return m_canvas.get();
597 }
598
599 void WebTestProxyBase::DisplayForSoftwareMode(const base::Closure& callback) {
600   const blink::WebSize& size = webWidget()->size();
601   WebRect rect(0, 0, size.width, size.height);
602   m_paintRect = rect;
603   paintInvalidatedRegion();
604
605   if (!callback.is_null())
606     callback.Run();
607 }
608
609 void WebTestProxyBase::DidDisplayAsync(const base::Closure& callback,
610                                        const SkBitmap& bitmap) {
611   // Verify we actually composited.
612   CHECK_NE(0, bitmap.info().fWidth);
613   CHECK_NE(0, bitmap.info().fHeight);
614   if (!callback.is_null())
615     callback.Run();
616 }
617
618 void WebTestProxyBase::displayAsyncThen(base::Closure callback) {
619   TRACE_EVENT0("shell", "WebTestProxyBase::displayAsyncThen");
620
621   // TODO(danakj): Remove when we have kForceCompositingMode everywhere.
622   if (!webWidget()->isAcceleratedCompositingActive()) {
623     TRACE_EVENT0("shell",
624                  "WebTestProxyBase::displayAsyncThen "
625                  "isAcceleratedCompositingActive false");
626     m_delegate->postTask(
627         new ClosureTask(this,
628                         base::Bind(&WebTestProxyBase::DisplayForSoftwareMode,
629                                    base::Unretained(this),
630                                    callback)));
631     return;
632   }
633
634   CapturePixelsAsync(base::Bind(
635       &WebTestProxyBase::DidDisplayAsync, base::Unretained(this), callback));
636 }
637
638 void WebTestProxyBase::discardBackingStore()
639 {
640     m_canvas.reset();
641 }
642
643 WebMIDIClientMock* WebTestProxyBase::midiClientMock()
644 {
645     if (!m_midiClient.get())
646         m_midiClient.reset(new WebMIDIClientMock);
647     return m_midiClient.get();
648 }
649
650 MockWebSpeechRecognizer* WebTestProxyBase::speechRecognizerMock()
651 {
652     if (!m_speechRecognizer.get()) {
653         m_speechRecognizer.reset(new MockWebSpeechRecognizer());
654         m_speechRecognizer->setDelegate(m_delegate);
655     }
656     return m_speechRecognizer.get();
657 }
658
659 void WebTestProxyBase::didInvalidateRect(const WebRect& rect)
660 {
661     // m_paintRect = m_paintRect U rect
662     if (rect.isEmpty())
663         return;
664     if (m_paintRect.isEmpty()) {
665         m_paintRect = rect;
666         return;
667     }
668     int left = min(m_paintRect.x, rect.x);
669     int top = min(m_paintRect.y, rect.y);
670     int right = max(m_paintRect.x + m_paintRect.width, rect.x + rect.width);
671     int bottom = max(m_paintRect.y + m_paintRect.height, rect.y + rect.height);
672     m_paintRect = WebRect(left, top, right - left, bottom - top);
673 }
674
675 void WebTestProxyBase::didScrollRect(int, int, const WebRect& clipRect)
676 {
677     didInvalidateRect(clipRect);
678 }
679
680 void WebTestProxyBase::invalidateAll()
681 {
682     m_paintRect = WebRect(0, 0, INT_MAX, INT_MAX);
683 }
684
685 void WebTestProxyBase::scheduleComposite()
686 {
687     invalidateAll();
688 }
689
690 void WebTestProxyBase::scheduleAnimation()
691 {
692     if (!m_testInterfaces->testRunner()->TestIsRunning())
693         return;
694
695     if (!m_animateScheduled) {
696         m_animateScheduled = true;
697         m_delegate->postDelayedTask(new HostMethodTask(this, &WebTestProxyBase::animateNow), 1);
698     }
699 }
700
701 void WebTestProxyBase::animateNow()
702 {
703     if (m_animateScheduled) {
704         m_animateScheduled = false;
705         webWidget()->animate(0.0);
706         webWidget()->layout();
707     }
708 }
709
710 bool WebTestProxyBase::isCompositorFramePending() const
711 {
712     return m_animateScheduled || !m_paintRect.isEmpty();
713 }
714
715 void WebTestProxyBase::show(WebNavigationPolicy)
716 {
717     invalidateAll();
718 }
719
720 void WebTestProxyBase::setWindowRect(const WebRect& rect)
721 {
722     invalidateAll();
723     discardBackingStore();
724 }
725
726 void WebTestProxyBase::didAutoResize(const WebSize&)
727 {
728     invalidateAll();
729 }
730
731 void WebTestProxyBase::postAccessibilityEvent(const blink::WebAXObject& obj, blink::WebAXEvent event)
732 {
733     // Only hook the accessibility events occured during the test run.
734     // This check prevents false positives in WebLeakDetector.
735     // The pending tasks in browser/renderer message queue may trigger accessibility events,
736     // and AccessibilityController will hold on to their target nodes if we don't ignore them here.
737     if (!m_testInterfaces->testRunner()->TestIsRunning())
738         return;
739
740     if (event == blink::WebAXEventFocus)
741         m_testInterfaces->accessibilityController()->SetFocusedElement(obj);
742
743     const char* eventName = 0;
744     switch (event) {
745     case blink::WebAXEventActiveDescendantChanged:
746         eventName = "ActiveDescendantChanged";
747         break;
748     case blink::WebAXEventAlert:
749         eventName = "Alert";
750         break;
751     case blink::WebAXEventAriaAttributeChanged:
752         eventName = "AriaAttributeChanged";
753         break;
754     case blink::WebAXEventAutocorrectionOccured:
755         eventName = "AutocorrectionOccured";
756         break;
757     case blink::WebAXEventBlur:
758         eventName = "Blur";
759         break;
760     case blink::WebAXEventCheckedStateChanged:
761         eventName = "CheckedStateChanged";
762         break;
763     case blink::WebAXEventChildrenChanged:
764         eventName = "ChildrenChanged";
765         break;
766     case blink::WebAXEventFocus:
767         eventName = "Focus";
768         break;
769     case blink::WebAXEventHide:
770         eventName = "Hide";
771         break;
772     case blink::WebAXEventInvalidStatusChanged:
773         eventName = "InvalidStatusChanged";
774         break;
775     case blink::WebAXEventLayoutComplete:
776         eventName = "LayoutComplete";
777         break;
778     case blink::WebAXEventLiveRegionChanged:
779         eventName = "LiveRegionChanged";
780         break;
781     case blink::WebAXEventLoadComplete:
782         eventName = "LoadComplete";
783         break;
784     case blink::WebAXEventLocationChanged:
785         eventName = "LocationChanged";
786         break;
787     case blink::WebAXEventMenuListItemSelected:
788         eventName = "MenuListItemSelected";
789         break;
790     case blink::WebAXEventMenuListValueChanged:
791         eventName = "MenuListValueChanged";
792         break;
793     case blink::WebAXEventRowCollapsed:
794         eventName = "RowCollapsed";
795         break;
796     case blink::WebAXEventRowCountChanged:
797         eventName = "RowCountChanged";
798         break;
799     case blink::WebAXEventRowExpanded:
800         eventName = "RowExpanded";
801         break;
802     case blink::WebAXEventScrollPositionChanged:
803         eventName = "ScrollPositionChanged";
804         break;
805     case blink::WebAXEventScrolledToAnchor:
806         eventName = "ScrolledToAnchor";
807         break;
808     case blink::WebAXEventSelectedChildrenChanged:
809         eventName = "SelectedChildrenChanged";
810         break;
811     case blink::WebAXEventSelectedTextChanged:
812         eventName = "SelectedTextChanged";
813         break;
814     case blink::WebAXEventShow:
815         eventName = "Show";
816         break;
817     case blink::WebAXEventTextChanged:
818         eventName = "TextChanged";
819         break;
820     case blink::WebAXEventTextInserted:
821         eventName = "TextInserted";
822         break;
823     case blink::WebAXEventTextRemoved:
824         eventName = "TextRemoved";
825         break;
826     case blink::WebAXEventValueChanged:
827         eventName = "ValueChanged";
828         break;
829     default:
830         eventName = "Unknown";
831         break;
832     }
833
834     m_testInterfaces->accessibilityController()->NotificationReceived(obj, eventName);
835
836     if (m_testInterfaces->accessibilityController()->ShouldLogAccessibilityEvents()) {
837         string message("AccessibilityNotification - ");
838         message += eventName;
839
840         blink::WebNode node = obj.node();
841         if (!node.isNull() && node.isElementNode()) {
842             blink::WebElement element = node.to<blink::WebElement>();
843             if (element.hasAttribute("id")) {
844                 message += " - id:";
845                 message += element.getAttribute("id").utf8().data();
846             }
847         }
848
849         m_delegate->printMessage(message + "\n");
850     }
851 }
852
853 void WebTestProxyBase::startDragging(WebLocalFrame*, const WebDragData& data, WebDragOperationsMask mask, const WebImage&, const WebPoint&)
854 {
855     // When running a test, we need to fake a drag drop operation otherwise
856     // Windows waits for real mouse events to know when the drag is over.
857     m_testInterfaces->eventSender()->DoDragDrop(data, mask);
858 }
859
860 // The output from these methods in layout test mode should match that
861 // expected by the layout tests. See EditingDelegate.m in DumpRenderTree.
862
863 void WebTestProxyBase::didChangeSelection(bool isEmptySelection)
864 {
865     if (m_testInterfaces->testRunner()->shouldDumpEditingCallbacks())
866         m_delegate->printMessage("EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n");
867 }
868
869 void WebTestProxyBase::didChangeContents()
870 {
871     if (m_testInterfaces->testRunner()->shouldDumpEditingCallbacks())
872         m_delegate->printMessage("EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n");
873 }
874
875 bool WebTestProxyBase::createView(WebLocalFrame*, const WebURLRequest& request, const WebWindowFeatures&, const WebString&, WebNavigationPolicy, bool)
876 {
877     if (!m_testInterfaces->testRunner()->canOpenWindows())
878         return false;
879     if (m_testInterfaces->testRunner()->shouldDumpCreateView())
880         m_delegate->printMessage(string("createView(") + URLDescription(request.url()) + ")\n");
881     return true;
882 }
883
884 WebPlugin* WebTestProxyBase::createPlugin(WebLocalFrame* frame, const WebPluginParams& params)
885 {
886     if (TestPlugin::isSupportedMimeType(params.mimeType))
887         return TestPlugin::create(frame, params, m_delegate);
888     return 0;
889 }
890
891 void WebTestProxyBase::setStatusText(const WebString& text)
892 {
893     if (!m_testInterfaces->testRunner()->shouldDumpStatusCallbacks())
894         return;
895     m_delegate->printMessage(string("UI DELEGATE STATUS CALLBACK: setStatusText:") + text.utf8().data() + "\n");
896 }
897
898 void WebTestProxyBase::didStopLoading()
899 {
900     if (m_testInterfaces->testRunner()->shouldDumpProgressFinishedCallback())
901         m_delegate->printMessage("postProgressFinishedNotification\n");
902 }
903
904 void WebTestProxyBase::showContextMenu(WebLocalFrame*, const WebContextMenuData& contextMenuData)
905 {
906     m_testInterfaces->eventSender()->SetContextMenuData(contextMenuData);
907 }
908
909 WebUserMediaClient* WebTestProxyBase::userMediaClient()
910 {
911     if (!m_userMediaClient.get())
912         m_userMediaClient.reset(new WebUserMediaClientMock(m_delegate));
913     return m_userMediaClient.get();
914 }
915
916 // Simulate a print by going into print mode and then exit straight away.
917 void WebTestProxyBase::printPage(WebLocalFrame* frame)
918 {
919     WebSize pageSizeInPixels = webWidget()->size();
920     if (pageSizeInPixels.isEmpty())
921         return;
922     WebPrintParams printParams(pageSizeInPixels);
923     frame->printBegin(printParams);
924     frame->printEnd();
925 }
926
927 WebNotificationPresenter* WebTestProxyBase::notificationPresenter()
928 {
929     return m_testInterfaces->testRunner()->notification_presenter();
930 }
931
932 WebMIDIClient* WebTestProxyBase::webMIDIClient()
933 {
934     return midiClientMock();
935 }
936
937 WebSpeechRecognizer* WebTestProxyBase::speechRecognizer()
938 {
939     return speechRecognizerMock();
940 }
941
942 bool WebTestProxyBase::requestPointerLock()
943 {
944     return m_testInterfaces->testRunner()->RequestPointerLock();
945 }
946
947 void WebTestProxyBase::requestPointerUnlock()
948 {
949     m_testInterfaces->testRunner()->RequestPointerUnlock();
950 }
951
952 bool WebTestProxyBase::isPointerLocked()
953 {
954     return m_testInterfaces->testRunner()->isPointerLocked();
955 }
956
957 void WebTestProxyBase::didFocus()
958 {
959     m_delegate->setFocus(this, true);
960 }
961
962 void WebTestProxyBase::didBlur()
963 {
964     m_delegate->setFocus(this, false);
965 }
966
967 void WebTestProxyBase::setToolTipText(const WebString& text, WebTextDirection)
968 {
969     m_testInterfaces->testRunner()->setToolTipText(text);
970 }
971
972 void WebTestProxyBase::didOpenChooser()
973 {
974     m_chooserCount++;
975 }
976
977 void WebTestProxyBase::didCloseChooser()
978 {
979     m_chooserCount--;
980 }
981
982 bool WebTestProxyBase::isChooserShown()
983 {
984     return 0 < m_chooserCount;
985 }
986
987 void WebTestProxyBase::loadURLExternally(WebLocalFrame* frame, const WebURLRequest& request, WebNavigationPolicy policy, const WebString& suggested_name)
988 {
989     if (m_testInterfaces->testRunner()->shouldWaitUntilExternalURLLoad()) {
990         if (policy == WebNavigationPolicyDownload) {
991             m_delegate->printMessage(string("Downloading URL with suggested filename \"") + suggested_name.utf8() + "\"\n");
992         } else {
993             m_delegate->printMessage(string("Loading URL externally - \"") + URLDescription(request.url()) + "\"\n");
994         }
995         m_delegate->testFinished();
996     }
997 }
998
999 void WebTestProxyBase::didStartProvisionalLoad(WebLocalFrame* frame)
1000 {
1001     if (!m_testInterfaces->testRunner()->topLoadingFrame())
1002         m_testInterfaces->testRunner()->setTopLoadingFrame(frame, false);
1003
1004     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1005         printFrameDescription(m_delegate, frame);
1006         m_delegate->printMessage(" - didStartProvisionalLoadForFrame\n");
1007     }
1008
1009     if (m_testInterfaces->testRunner()->shouldDumpUserGestureInFrameLoadCallbacks())
1010         printFrameUserGestureStatus(m_delegate, frame, " - in didStartProvisionalLoadForFrame\n");
1011 }
1012
1013 void WebTestProxyBase::didReceiveServerRedirectForProvisionalLoad(WebLocalFrame* frame)
1014 {
1015     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1016         printFrameDescription(m_delegate, frame);
1017         m_delegate->printMessage(" - didReceiveServerRedirectForProvisionalLoadForFrame\n");
1018     }
1019 }
1020
1021 bool WebTestProxyBase::didFailProvisionalLoad(WebLocalFrame* frame, const WebURLError&)
1022 {
1023     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1024         printFrameDescription(m_delegate, frame);
1025         m_delegate->printMessage(" - didFailProvisionalLoadWithError\n");
1026     }
1027     locationChangeDone(frame);
1028     return !frame->provisionalDataSource();
1029 }
1030
1031 void WebTestProxyBase::didCommitProvisionalLoad(WebLocalFrame* frame, const WebHistoryItem&, blink::WebHistoryCommitType)
1032 {
1033     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1034         printFrameDescription(m_delegate, frame);
1035         m_delegate->printMessage(" - didCommitLoadForFrame\n");
1036     }
1037 }
1038
1039 void WebTestProxyBase::didReceiveTitle(WebLocalFrame* frame, const WebString& title, WebTextDirection direction)
1040 {
1041     WebCString title8 = title.utf8();
1042
1043     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1044         printFrameDescription(m_delegate, frame);
1045         m_delegate->printMessage(string(" - didReceiveTitle: ") + title8.data() + "\n");
1046     }
1047
1048     if (m_testInterfaces->testRunner()->shouldDumpTitleChanges())
1049         m_delegate->printMessage(string("TITLE CHANGED: '") + title8.data() + "'\n");
1050 }
1051
1052 void WebTestProxyBase::didChangeIcon(WebLocalFrame* frame, WebIconURL::Type)
1053 {
1054     if (m_testInterfaces->testRunner()->shouldDumpIconChanges()) {
1055         printFrameDescription(m_delegate, frame);
1056         m_delegate->printMessage(string(" - didChangeIcons\n"));
1057     }
1058 }
1059
1060 void WebTestProxyBase::didFinishDocumentLoad(WebLocalFrame* frame)
1061 {
1062     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1063         printFrameDescription(m_delegate, frame);
1064         m_delegate->printMessage(" - didFinishDocumentLoadForFrame\n");
1065     } else {
1066         unsigned pendingUnloadEvents = frame->unloadListenerCount();
1067         if (pendingUnloadEvents) {
1068             printFrameDescription(m_delegate, frame);
1069             char buffer[100];
1070             snprintf(buffer, sizeof(buffer), " - has %u onunload handler(s)\n", pendingUnloadEvents);
1071             m_delegate->printMessage(buffer);
1072         }
1073     }
1074 }
1075
1076 void WebTestProxyBase::didHandleOnloadEvents(WebLocalFrame* frame)
1077 {
1078     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1079         printFrameDescription(m_delegate, frame);
1080         m_delegate->printMessage(" - didHandleOnloadEventsForFrame\n");
1081     }
1082 }
1083
1084 void WebTestProxyBase::didFailLoad(WebLocalFrame* frame, const WebURLError&)
1085 {
1086     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1087         printFrameDescription(m_delegate, frame);
1088         m_delegate->printMessage(" - didFailLoadWithError\n");
1089     }
1090     locationChangeDone(frame);
1091 }
1092
1093 void WebTestProxyBase::didFinishLoad(WebLocalFrame* frame)
1094 {
1095     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1096         printFrameDescription(m_delegate, frame);
1097         m_delegate->printMessage(" - didFinishLoadForFrame\n");
1098     }
1099     locationChangeDone(frame);
1100 }
1101
1102 void WebTestProxyBase::didDetectXSS(WebLocalFrame*, const WebURL&, bool)
1103 {
1104     if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks())
1105         m_delegate->printMessage("didDetectXSS\n");
1106 }
1107
1108 void WebTestProxyBase::didDispatchPingLoader(WebLocalFrame*, const WebURL& url)
1109 {
1110     if (m_testInterfaces->testRunner()->shouldDumpPingLoaderCallbacks())
1111         m_delegate->printMessage(string("PingLoader dispatched to '") + URLDescription(url).c_str() + "'.\n");
1112 }
1113
1114 void WebTestProxyBase::willRequestResource(WebLocalFrame* frame, const blink::WebCachedURLRequest& request)
1115 {
1116     if (m_testInterfaces->testRunner()->shouldDumpResourceRequestCallbacks()) {
1117         printFrameDescription(m_delegate, frame);
1118         m_delegate->printMessage(string(" - ") + request.initiatorName().utf8().data());
1119         m_delegate->printMessage(string(" requested '") + URLDescription(request.urlRequest().url()).c_str() + "'\n");
1120     }
1121 }
1122
1123 void WebTestProxyBase::willSendRequest(WebLocalFrame*, unsigned identifier, blink::WebURLRequest& request, const blink::WebURLResponse& redirectResponse)
1124 {
1125     // Need to use GURL for host() and SchemeIs()
1126     GURL url = request.url();
1127     string requestURL = url.possibly_invalid_spec();
1128
1129     GURL mainDocumentURL = request.firstPartyForCookies();
1130
1131     if (redirectResponse.isNull() && (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks() || m_testInterfaces->testRunner()->shouldDumpResourcePriorities())) {
1132         DCHECK(m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end());
1133         m_resourceIdentifierMap[identifier] = descriptionSuitableForTestResult(requestURL);
1134     }
1135
1136     if (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks()) {
1137         if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1138             m_delegate->printMessage("<unknown>");
1139         else
1140             m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1141         m_delegate->printMessage(" - willSendRequest <NSURLRequest URL ");
1142         m_delegate->printMessage(descriptionSuitableForTestResult(requestURL).c_str());
1143         m_delegate->printMessage(", main document URL ");
1144         m_delegate->printMessage(URLDescription(mainDocumentURL).c_str());
1145         m_delegate->printMessage(", http method ");
1146         m_delegate->printMessage(request.httpMethod().utf8().data());
1147         m_delegate->printMessage("> redirectResponse ");
1148         printResponseDescription(m_delegate, redirectResponse);
1149         m_delegate->printMessage("\n");
1150     }
1151
1152     if (m_testInterfaces->testRunner()->shouldDumpResourcePriorities()) {
1153         m_delegate->printMessage(descriptionSuitableForTestResult(requestURL).c_str());
1154         m_delegate->printMessage(" has priority ");
1155         m_delegate->printMessage(PriorityDescription(request.priority()));
1156         m_delegate->printMessage("\n");
1157     }
1158
1159     if (m_testInterfaces->testRunner()->httpHeadersToClear()) {
1160         const set<string> *clearHeaders = m_testInterfaces->testRunner()->httpHeadersToClear();
1161         for (set<string>::const_iterator header = clearHeaders->begin(); header != clearHeaders->end(); ++header)
1162             request.clearHTTPHeaderField(WebString::fromUTF8(*header));
1163     }
1164
1165     string host = url.host();
1166     if (!host.empty() && (url.SchemeIs("http") || url.SchemeIs("https"))) {
1167         if (!isLocalhost(host) && !hostIsUsedBySomeTestsToGenerateError(host)
1168             && ((!mainDocumentURL.SchemeIs("http") && !mainDocumentURL.SchemeIs("https")) || isLocalhost(mainDocumentURL.host()))
1169             && !m_delegate->allowExternalPages()) {
1170             m_delegate->printMessage(string("Blocked access to external URL ") + requestURL + "\n");
1171             blockRequest(request);
1172             return;
1173         }
1174     }
1175
1176     // Set the new substituted URL.
1177     request.setURL(m_delegate->rewriteLayoutTestsURL(request.url().spec()));
1178 }
1179
1180 void WebTestProxyBase::didReceiveResponse(WebLocalFrame*, unsigned identifier, const blink::WebURLResponse& response)
1181 {
1182     if (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks()) {
1183         if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1184             m_delegate->printMessage("<unknown>");
1185         else
1186             m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1187         m_delegate->printMessage(" - didReceiveResponse ");
1188         printResponseDescription(m_delegate, response);
1189         m_delegate->printMessage("\n");
1190     }
1191     if (m_testInterfaces->testRunner()->shouldDumpResourceResponseMIMETypes()) {
1192         GURL url = response.url();
1193         WebString mimeType = response.mimeType();
1194         m_delegate->printMessage(url.ExtractFileName());
1195         m_delegate->printMessage(" has MIME type ");
1196         // Simulate NSURLResponse's mapping of empty/unknown MIME types to application/octet-stream
1197         m_delegate->printMessage(mimeType.isEmpty() ? "application/octet-stream" : mimeType.utf8().data());
1198         m_delegate->printMessage("\n");
1199     }
1200 }
1201
1202 void WebTestProxyBase::didChangeResourcePriority(WebLocalFrame*, unsigned identifier, const blink::WebURLRequest::Priority& priority, int intra_priority_value)
1203 {
1204     if (m_testInterfaces->testRunner()->shouldDumpResourcePriorities()) {
1205         if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1206             m_delegate->printMessage("<unknown>");
1207         else
1208             m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1209         m_delegate->printMessage(" changed priority to ");
1210         m_delegate->printMessage(PriorityDescription(priority));
1211         char buffer[64];
1212         snprintf(buffer, sizeof(buffer), ", intra_priority %d", intra_priority_value);
1213         m_delegate->printMessage(buffer);
1214         m_delegate->printMessage("\n");
1215     }
1216 }
1217
1218 void WebTestProxyBase::didFinishResourceLoad(WebLocalFrame*, unsigned identifier)
1219 {
1220     if (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks()) {
1221         if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1222             m_delegate->printMessage("<unknown>");
1223         else
1224             m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1225         m_delegate->printMessage(" - didFinishLoading\n");
1226     }
1227     m_resourceIdentifierMap.erase(identifier);
1228 }
1229
1230 void WebTestProxyBase::didAddMessageToConsole(const WebConsoleMessage& message, const WebString& sourceName, unsigned sourceLine)
1231 {
1232     // This matches win DumpRenderTree's UIDelegate.cpp.
1233     if (!m_logConsoleOutput)
1234         return;
1235     string level;
1236     switch (message.level) {
1237     case WebConsoleMessage::LevelDebug:
1238         level = "DEBUG";
1239         break;
1240     case WebConsoleMessage::LevelLog:
1241         level = "MESSAGE";
1242         break;
1243     case WebConsoleMessage::LevelInfo:
1244         level = "INFO";
1245         break;
1246     case WebConsoleMessage::LevelWarning:
1247         level = "WARNING";
1248         break;
1249     case WebConsoleMessage::LevelError:
1250         level = "ERROR";
1251         break;
1252     }
1253     m_delegate->printMessage(string("CONSOLE ") + level + ": ");
1254     if (sourceLine) {
1255         char buffer[40];
1256         snprintf(buffer, sizeof(buffer), "line %d: ", sourceLine);
1257         m_delegate->printMessage(buffer);
1258     }
1259     if (!message.text.isEmpty()) {
1260         string newMessage;
1261         newMessage = message.text.utf8();
1262         size_t fileProtocol = newMessage.find("file://");
1263         if (fileProtocol != string::npos) {
1264             newMessage = newMessage.substr(0, fileProtocol)
1265                 + urlSuitableForTestResult(newMessage.substr(fileProtocol));
1266         }
1267         m_delegate->printMessage(newMessage);
1268     }
1269     m_delegate->printMessage(string("\n"));
1270 }
1271
1272 void WebTestProxyBase::locationChangeDone(WebFrame* frame)
1273 {
1274     if (frame != m_testInterfaces->testRunner()->topLoadingFrame())
1275         return;
1276     m_testInterfaces->testRunner()->setTopLoadingFrame(frame, true);
1277 }
1278
1279 WebNavigationPolicy WebTestProxyBase::decidePolicyForNavigation(WebLocalFrame*, WebDataSource::ExtraData*, const WebURLRequest& request, WebNavigationType type, WebNavigationPolicy defaultPolicy, bool isRedirect)
1280 {
1281     WebNavigationPolicy result;
1282     if (!m_testInterfaces->testRunner()->policyDelegateEnabled())
1283         return defaultPolicy;
1284
1285     m_delegate->printMessage(string("Policy delegate: attempt to load ") + URLDescription(request.url()) + " with navigation type '" + webNavigationTypeToString(type) + "'\n");
1286     if (m_testInterfaces->testRunner()->policyDelegateIsPermissive())
1287         result = blink::WebNavigationPolicyCurrentTab;
1288     else
1289         result = blink::WebNavigationPolicyIgnore;
1290
1291     if (m_testInterfaces->testRunner()->policyDelegateShouldNotifyDone())
1292         m_testInterfaces->testRunner()->policyDelegateDone();
1293     return result;
1294 }
1295
1296 bool WebTestProxyBase::willCheckAndDispatchMessageEvent(WebLocalFrame*, WebFrame*, WebSecurityOrigin, WebDOMMessageEvent)
1297 {
1298     if (m_testInterfaces->testRunner()->shouldInterceptPostMessage()) {
1299         m_delegate->printMessage("intercepted postMessage\n");
1300         return true;
1301     }
1302
1303     return false;
1304 }
1305
1306 void WebTestProxyBase::postSpellCheckEvent(const WebString& eventName)
1307 {
1308     if (m_testInterfaces->testRunner()->shouldDumpSpellCheckCallbacks()) {
1309         m_delegate->printMessage(string("SpellCheckEvent: ") + eventName.utf8().data() + "\n");
1310     }
1311 }
1312
1313 void WebTestProxyBase::resetInputMethod()
1314 {
1315     // If a composition text exists, then we need to let the browser process
1316     // to cancel the input method's ongoing composition session.
1317     if (m_webWidget)
1318         m_webWidget->confirmComposition();
1319 }
1320
1321 }  // namespace content