[safe-browsing] Database full hash matches like prefix match.
[chromium-blink-merge.git] / content / shell / renderer / test_runner / WebTestProxy.cpp
blob7cc74a4ebfffafe65f856f014d1cb2b74380cac4
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.
5 #include "content/shell/renderer/test_runner/WebTestProxy.h"
7 #include <cctype>
9 #include "base/logging.h"
10 #include "content/shell/renderer/test_runner/event_sender.h"
11 #include "content/shell/renderer/test_runner/MockColorChooser.h"
12 #include "content/shell/renderer/test_runner/MockWebSpeechInputController.h"
13 #include "content/shell/renderer/test_runner/MockWebSpeechRecognizer.h"
14 #include "content/shell/renderer/test_runner/SpellCheckClient.h"
15 #include "content/shell/renderer/test_runner/TestCommon.h"
16 #include "content/shell/renderer/test_runner/TestInterfaces.h"
17 #include "content/shell/renderer/test_runner/TestPlugin.h"
18 #include "content/shell/renderer/test_runner/WebTestDelegate.h"
19 #include "content/shell/renderer/test_runner/WebTestInterfaces.h"
20 #include "content/shell/renderer/test_runner/WebTestRunner.h"
21 #include "content/shell/renderer/test_runner/WebUserMediaClientMock.h"
22 #include "content/shell/renderer/test_runner/accessibility_controller.h"
23 #include "content/shell/renderer/test_runner/test_runner.h"
24 // FIXME: Including platform_canvas.h here is a layering violation.
25 #include "skia/ext/platform_canvas.h"
26 #include "third_party/WebKit/public/platform/WebCString.h"
27 #include "third_party/WebKit/public/platform/WebURLError.h"
28 #include "third_party/WebKit/public/platform/WebURLRequest.h"
29 #include "third_party/WebKit/public/platform/WebURLResponse.h"
30 #include "third_party/WebKit/public/web/WebAXEnums.h"
31 #include "third_party/WebKit/public/web/WebAXObject.h"
32 #include "third_party/WebKit/public/web/WebCachedURLRequest.h"
33 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
34 #include "third_party/WebKit/public/web/WebDataSource.h"
35 #include "third_party/WebKit/public/web/WebDocument.h"
36 #include "third_party/WebKit/public/web/WebElement.h"
37 #include "third_party/WebKit/public/web/WebHistoryItem.h"
38 #include "third_party/WebKit/public/web/WebLocalFrame.h"
39 #include "third_party/WebKit/public/web/WebMIDIClientMock.h"
40 #include "third_party/WebKit/public/web/WebNode.h"
41 #include "third_party/WebKit/public/web/WebPluginParams.h"
42 #include "third_party/WebKit/public/web/WebPrintParams.h"
43 #include "third_party/WebKit/public/web/WebRange.h"
44 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
45 #include "third_party/WebKit/public/web/WebView.h"
47 using namespace WebTestRunner;
48 using namespace blink;
49 using namespace std;
51 namespace content {
53 namespace {
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 { }
63 virtual void runIfValid() OVERRIDE { (m_object->*m_callback)(); }
65 private:
66 CallbackMethodType m_callback;
69 class ClosureTask : public WebMethodTask<WebTestProxyBase> {
70 public:
71 ClosureTask(WebTestProxyBase* object, base::Closure callback)
72 : WebMethodTask<WebTestProxyBase>(object), m_callback(callback) {}
74 virtual void runIfValid() OVERRIDE {
75 if (!m_callback.is_null())
76 m_callback.Run();
79 private:
80 base::Closure m_callback;
83 void printFrameDescription(WebTestDelegate* delegate, WebFrame* frame)
85 string name8 = frame->uniqueName().utf8();
86 if (frame == frame->view()->mainFrame()) {
87 if (!name8.length()) {
88 delegate->printMessage("main frame");
89 return;
91 delegate->printMessage(string("main frame \"") + name8 + "\"");
92 return;
94 if (!name8.length()) {
95 delegate->printMessage("frame (anonymous)");
96 return;
98 delegate->printMessage(string("frame \"") + name8 + "\"");
101 void printFrameUserGestureStatus(WebTestDelegate* delegate, WebFrame* frame, const char* msg)
103 bool isUserGesture = WebUserGestureIndicator::isProcessingUserGesture();
104 delegate->printMessage(string("Frame with user gesture \"") + (isUserGesture ? "true" : "false") + "\"" + msg);
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)
112 if (url.empty() || string::npos == url.find("file://"))
113 return url;
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;
122 return url.substr(pos + 1);
125 void printResponseDescription(WebTestDelegate* delegate, const WebURLResponse& response)
127 if (response.isNull()) {
128 delegate->printMessage("(null)");
129 return;
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 + ">");
137 string URLDescription(const GURL& url)
139 if (url.SchemeIs("file"))
140 return url.ExtractFileName();
141 return url.possibly_invalid_spec();
144 string PriorityDescription(const WebURLRequest::Priority& priority)
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";
163 void blockRequest(WebURLRequest& request)
165 request.setURL(GURL("255.255.255.255"));
168 bool isLocalhost(const string& host)
170 return host == "127.0.0.1" || host == "localhost";
173 bool hostIsUsedBySomeTestsToGenerateError(const string& host)
175 return host == "255.255.255.255";
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)
182 if (url.empty() || string::npos == url.find("file://"))
183 return url;
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
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;
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";
210 // Get a debugging string from a WebNavigationType.
211 const char* webNavigationTypeToString(WebNavigationType type)
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;
227 return illegalString;
230 string dumpDocumentText(WebFrame* frame)
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();
240 string dumpFramesAsText(WebFrame* frame, bool recursive)
242 string result;
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");
251 result.append(dumpDocumentText(frame));
252 result.append("\n");
254 if (recursive) {
255 for (WebFrame* child = frame->firstChild(); child; child = child->nextSibling())
256 result.append(dumpFramesAsText(child, recursive));
259 return result;
262 string dumpFramesAsPrintedText(WebFrame* frame, bool recursive)
264 string result;
266 // Cannot do printed format for anything other than HTML
267 if (!frame->document().isHTMLDocument())
268 return string();
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");
277 result.append(frame->renderTreeAsText(WebFrame::RenderAsTextPrinting).utf8());
278 result.append("\n");
280 if (recursive) {
281 for (WebFrame* child = frame->firstChild(); child; child = child->nextSibling())
282 result.append(dumpFramesAsPrintedText(child, recursive));
285 return result;
288 string dumpFrameScrollPosition(WebFrame* frame, bool recursive)
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;
300 if (!recursive)
301 return result;
302 for (WebFrame* child = frame->firstChild(); child; child = child->nextSibling())
303 result += dumpFrameScrollPosition(child, recursive);
304 return result;
307 string dumpAllBackForwardLists(TestInterfaces* interfaces, WebTestDelegate* delegate)
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;
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)
325 reset();
328 WebTestProxyBase::~WebTestProxyBase()
330 m_testInterfaces->windowClosed(this);
333 void WebTestProxyBase::setInterfaces(WebTestInterfaces* interfaces)
335 m_testInterfaces = interfaces->testInterfaces();
336 m_testInterfaces->windowOpened(this);
339 void WebTestProxyBase::setDelegate(WebTestDelegate* delegate)
341 m_delegate = delegate;
342 m_spellcheck->setDelegate(delegate);
343 #if ENABLE_INPUT_SPEECH
344 if (m_speechInputController.get())
345 m_speechInputController->setDelegate(delegate);
346 #endif
347 if (m_speechRecognizer.get())
348 m_speechRecognizer->setDelegate(delegate);
351 void WebTestProxyBase::setWidget(WebWidget* widget)
353 m_webWidget = widget;
356 WebWidget* WebTestProxyBase::webWidget()
358 return m_webWidget;
361 WebView* WebTestProxyBase::webView()
363 DCHECK(m_webWidget);
364 // TestRunner does not support popup widgets. So m_webWidget is always a WebView.
365 return static_cast<WebView*>(m_webWidget);
368 void WebTestProxyBase::didForceResize()
370 invalidateAll();
371 discardBackingStore();
374 void WebTestProxyBase::reset()
376 m_paintRect = WebRect();
377 m_canvas.reset();
378 m_isPainting = false;
379 m_animateScheduled = false;
380 m_resourceIdentifierMap.clear();
381 m_logConsoleOutput = true;
382 if (m_midiClient.get())
383 m_midiClient->resetMock();
384 #if ENABLE_INPUT_SPEECH
385 if (m_speechInputController.get())
386 m_speechInputController->clearResults();
387 #endif
390 WebSpellCheckClient* WebTestProxyBase::spellCheckClient() const
392 return m_spellcheck.get();
395 WebColorChooser* WebTestProxyBase::createColorChooser(WebColorChooserClient* client, const blink::WebColor& color, const blink::WebVector<blink::WebColorSuggestion>& suggestions)
397 // This instance is deleted by WebCore::ColorInputType
398 return new MockColorChooser(client, m_delegate, this);
401 bool WebTestProxyBase::runFileChooser(const blink::WebFileChooserParams&, blink::WebFileChooserCompletion*)
403 m_delegate->printMessage("Mock: Opening a file chooser.\n");
404 // FIXME: Add ability to set file names to a file upload control.
405 return false;
408 void WebTestProxyBase::showValidationMessage(const WebRect&, const WebString& message, const WebString& subMessage, WebTextDirection)
410 m_delegate->printMessage(std::string("ValidationMessageClient: main-message=") + std::string(message.utf8()) + " sub-message=" + std::string(subMessage.utf8()) + "\n");
413 void WebTestProxyBase::hideValidationMessage()
417 void WebTestProxyBase::moveValidationMessage(const WebRect&)
421 string WebTestProxyBase::captureTree(bool debugRenderTree)
423 bool shouldDumpAsText = m_testInterfaces->testRunner()->shouldDumpAsText();
424 bool shouldDumpAsMarkup = m_testInterfaces->testRunner()->shouldDumpAsMarkup();
425 bool shouldDumpAsPrinted = m_testInterfaces->testRunner()->isPrinting();
426 WebFrame* frame = webView()->mainFrame();
427 string dataUtf8;
428 if (shouldDumpAsText) {
429 bool recursive = m_testInterfaces->testRunner()->shouldDumpChildFramesAsText();
430 dataUtf8 = shouldDumpAsPrinted ? dumpFramesAsPrintedText(frame, recursive) : dumpFramesAsText(frame, recursive);
431 } else if (shouldDumpAsMarkup) {
432 // Append a newline for the test driver.
433 dataUtf8 = frame->contentAsMarkup().utf8() + "\n";
434 } else {
435 bool recursive = m_testInterfaces->testRunner()->shouldDumpChildFrameScrollPositions();
436 WebFrame::RenderAsTextControls renderTextBehavior = WebFrame::RenderAsTextNormal;
437 if (shouldDumpAsPrinted)
438 renderTextBehavior |= WebFrame::RenderAsTextPrinting;
439 if (debugRenderTree)
440 renderTextBehavior |= WebFrame::RenderAsTextDebug;
441 dataUtf8 = frame->renderTreeAsText(renderTextBehavior).utf8();
442 dataUtf8 += dumpFrameScrollPosition(frame, recursive);
445 if (m_testInterfaces->testRunner()->shouldDumpBackForwardList())
446 dataUtf8 += dumpAllBackForwardLists(m_testInterfaces, m_delegate);
448 return dataUtf8;
451 SkCanvas* WebTestProxyBase::capturePixels()
453 webWidget()->layout();
454 if (m_testInterfaces->testRunner()->isPrinting())
455 paintPagesWithBoundaries();
456 else
457 paintInvalidatedRegion();
459 // See if we need to draw the selection bounds rect. Selection bounds
460 // rect is the rect enclosing the (possibly transformed) selection.
461 // The rect should be drawn after everything is laid out and painted.
462 if (m_testInterfaces->testRunner()->shouldDumpSelectionRect()) {
463 // If there is a selection rect - draw a red 1px border enclosing rect
464 WebRect wr = webView()->mainFrame()->selectionBoundsRect();
465 if (!wr.isEmpty()) {
466 // Render a red rectangle bounding selection rect
467 SkPaint paint;
468 paint.setColor(0xFFFF0000); // Fully opaque red
469 paint.setStyle(SkPaint::kStroke_Style);
470 paint.setFlags(SkPaint::kAntiAlias_Flag);
471 paint.setStrokeWidth(1.0f);
472 SkIRect rect; // Bounding rect
473 rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
474 canvas()->drawIRect(rect, paint);
478 return canvas();
481 void WebTestProxyBase::setLogConsoleOutput(bool enabled)
483 m_logConsoleOutput = enabled;
486 void WebTestProxyBase::paintRect(const WebRect& rect)
488 DCHECK(!m_isPainting);
489 DCHECK(canvas());
490 m_isPainting = true;
491 float deviceScaleFactor = webView()->deviceScaleFactor();
492 int scaledX = static_cast<int>(static_cast<float>(rect.x) * deviceScaleFactor);
493 int scaledY = static_cast<int>(static_cast<float>(rect.y) * deviceScaleFactor);
494 int scaledWidth = static_cast<int>(ceil(static_cast<float>(rect.width) * deviceScaleFactor));
495 int scaledHeight = static_cast<int>(ceil(static_cast<float>(rect.height) * deviceScaleFactor));
496 WebRect deviceRect(scaledX, scaledY, scaledWidth, scaledHeight);
497 webWidget()->paint(canvas(), deviceRect);
498 m_isPainting = false;
501 void WebTestProxyBase::paintInvalidatedRegion()
503 webWidget()->animate(0.0);
504 webWidget()->layout();
505 WebSize widgetSize = webWidget()->size();
506 WebRect clientRect(0, 0, widgetSize.width, widgetSize.height);
508 // Paint the canvas if necessary. Allow painting to generate extra rects
509 // for the first two calls. This is necessary because some WebCore rendering
510 // objects update their layout only when painted.
511 // Store the total area painted in total_paint. Then tell the gdk window
512 // to update that area after we're done painting it.
513 for (int i = 0; i < 3; ++i) {
514 // rect = intersect(m_paintRect , clientRect)
515 WebRect damageRect = m_paintRect;
516 int left = max(damageRect.x, clientRect.x);
517 int top = max(damageRect.y, clientRect.y);
518 int right = min(damageRect.x + damageRect.width, clientRect.x + clientRect.width);
519 int bottom = min(damageRect.y + damageRect.height, clientRect.y + clientRect.height);
520 WebRect rect;
521 if (left < right && top < bottom)
522 rect = WebRect(left, top, right - left, bottom - top);
524 m_paintRect = WebRect();
525 if (rect.isEmpty())
526 continue;
527 paintRect(rect);
529 DCHECK(m_paintRect.isEmpty());
532 void WebTestProxyBase::paintPagesWithBoundaries()
534 DCHECK(!m_isPainting);
535 DCHECK(canvas());
536 m_isPainting = true;
538 WebSize pageSizeInPixels = webWidget()->size();
539 WebFrame* webFrame = webView()->mainFrame();
541 int pageCount = webFrame->printBegin(pageSizeInPixels);
542 int totalHeight = pageCount * (pageSizeInPixels.height + 1) - 1;
544 SkCanvas* testCanvas = skia::TryCreateBitmapCanvas(pageSizeInPixels.width, totalHeight, false);
545 if (testCanvas) {
546 discardBackingStore();
547 m_canvas.reset(testCanvas);
548 } else {
549 webFrame->printEnd();
550 return;
553 webFrame->printPagesWithBoundaries(canvas(), pageSizeInPixels);
554 webFrame->printEnd();
556 m_isPainting = false;
559 SkCanvas* WebTestProxyBase::canvas()
561 if (m_canvas.get())
562 return m_canvas.get();
563 WebSize widgetSize = webWidget()->size();
564 float deviceScaleFactor = webView()->deviceScaleFactor();
565 int scaledWidth = static_cast<int>(ceil(static_cast<float>(widgetSize.width) * deviceScaleFactor));
566 int scaledHeight = static_cast<int>(ceil(static_cast<float>(widgetSize.height) * deviceScaleFactor));
567 // We're allocating the canvas to be non-opaque (third parameter), so we
568 // don't end up with uninitialized memory if a layout test doesn't damage
569 // the entire view.
570 m_canvas.reset(skia::CreateBitmapCanvas(scaledWidth, scaledHeight, false));
571 return m_canvas.get();
574 void WebTestProxyBase::display(base::Closure callback)
576 const blink::WebSize& size = webWidget()->size();
577 WebRect rect(0, 0, size.width, size.height);
578 m_paintRect = rect;
579 paintInvalidatedRegion();
581 if (!callback.is_null())
582 callback.Run();
585 void WebTestProxyBase::displayAsyncThen(base::Closure callback)
587 // TODO(enne): When compositing, this should invoke a real rAF, paint,
588 // and commit. For now, just make sure that displayAsync is actually
589 // async so that callers can't depend on synchronous behavior.
590 m_delegate->postTask(new ClosureTask(
591 this,
592 base::Bind(
593 &WebTestProxyBase::display, base::Unretained(this), callback)));
596 void WebTestProxyBase::discardBackingStore()
598 m_canvas.reset();
601 WebMIDIClientMock* WebTestProxyBase::midiClientMock()
603 if (!m_midiClient.get())
604 m_midiClient.reset(new WebMIDIClientMock);
605 return m_midiClient.get();
608 #if ENABLE_INPUT_SPEECH
609 MockWebSpeechInputController* WebTestProxyBase::speechInputControllerMock()
611 DCHECK(m_speechInputController.get());
612 return m_speechInputController.get();
614 #endif
616 MockWebSpeechRecognizer* WebTestProxyBase::speechRecognizerMock()
618 if (!m_speechRecognizer.get()) {
619 m_speechRecognizer.reset(new MockWebSpeechRecognizer());
620 m_speechRecognizer->setDelegate(m_delegate);
622 return m_speechRecognizer.get();
625 void WebTestProxyBase::didInvalidateRect(const WebRect& rect)
627 // m_paintRect = m_paintRect U rect
628 if (rect.isEmpty())
629 return;
630 if (m_paintRect.isEmpty()) {
631 m_paintRect = rect;
632 return;
634 int left = min(m_paintRect.x, rect.x);
635 int top = min(m_paintRect.y, rect.y);
636 int right = max(m_paintRect.x + m_paintRect.width, rect.x + rect.width);
637 int bottom = max(m_paintRect.y + m_paintRect.height, rect.y + rect.height);
638 m_paintRect = WebRect(left, top, right - left, bottom - top);
641 void WebTestProxyBase::didScrollRect(int, int, const WebRect& clipRect)
643 didInvalidateRect(clipRect);
646 void WebTestProxyBase::invalidateAll()
648 m_paintRect = WebRect(0, 0, INT_MAX, INT_MAX);
651 void WebTestProxyBase::scheduleComposite()
653 invalidateAll();
656 void WebTestProxyBase::scheduleAnimation()
658 if (!m_testInterfaces->testRunner()->TestIsRunning())
659 return;
661 if (!m_animateScheduled) {
662 m_animateScheduled = true;
663 m_delegate->postDelayedTask(new HostMethodTask(this, &WebTestProxyBase::animateNow), 1);
667 void WebTestProxyBase::animateNow()
669 if (m_animateScheduled) {
670 m_animateScheduled = false;
671 webWidget()->animate(0.0);
672 webWidget()->layout();
676 bool WebTestProxyBase::isCompositorFramePending() const
678 return m_animateScheduled || !m_paintRect.isEmpty();
681 void WebTestProxyBase::show(WebNavigationPolicy)
683 invalidateAll();
686 void WebTestProxyBase::setWindowRect(const WebRect& rect)
688 invalidateAll();
689 discardBackingStore();
692 void WebTestProxyBase::didAutoResize(const WebSize&)
694 invalidateAll();
697 void WebTestProxyBase::postAccessibilityEvent(const blink::WebAXObject& obj, blink::WebAXEvent event)
699 // Only hook the accessibility events occured during the test run.
700 // This check prevents false positives in WebLeakDetector.
701 // The pending tasks in browser/renderer message queue may trigger accessibility events,
702 // and AccessibilityController will hold on to their target nodes if we don't ignore them here.
703 if (!m_testInterfaces->testRunner()->TestIsRunning())
704 return;
706 if (event == blink::WebAXEventFocus)
707 m_testInterfaces->accessibilityController()->SetFocusedElement(obj);
709 const char* eventName = 0;
710 switch (event) {
711 case blink::WebAXEventActiveDescendantChanged:
712 eventName = "ActiveDescendantChanged";
713 break;
714 case blink::WebAXEventAlert:
715 eventName = "Alert";
716 break;
717 case blink::WebAXEventAriaAttributeChanged:
718 eventName = "AriaAttributeChanged";
719 break;
720 case blink::WebAXEventAutocorrectionOccured:
721 eventName = "AutocorrectionOccured";
722 break;
723 case blink::WebAXEventBlur:
724 eventName = "Blur";
725 break;
726 case blink::WebAXEventCheckedStateChanged:
727 eventName = "CheckedStateChanged";
728 break;
729 case blink::WebAXEventChildrenChanged:
730 eventName = "ChildrenChanged";
731 break;
732 case blink::WebAXEventFocus:
733 eventName = "Focus";
734 break;
735 case blink::WebAXEventHide:
736 eventName = "Hide";
737 break;
738 case blink::WebAXEventInvalidStatusChanged:
739 eventName = "InvalidStatusChanged";
740 break;
741 case blink::WebAXEventLayoutComplete:
742 eventName = "LayoutComplete";
743 break;
744 case blink::WebAXEventLiveRegionChanged:
745 eventName = "LiveRegionChanged";
746 break;
747 case blink::WebAXEventLoadComplete:
748 eventName = "LoadComplete";
749 break;
750 case blink::WebAXEventLocationChanged:
751 eventName = "LocationChanged";
752 break;
753 case blink::WebAXEventMenuListItemSelected:
754 eventName = "MenuListItemSelected";
755 break;
756 case blink::WebAXEventMenuListValueChanged:
757 eventName = "MenuListValueChanged";
758 break;
759 case blink::WebAXEventRowCollapsed:
760 eventName = "RowCollapsed";
761 break;
762 case blink::WebAXEventRowCountChanged:
763 eventName = "RowCountChanged";
764 break;
765 case blink::WebAXEventRowExpanded:
766 eventName = "RowExpanded";
767 break;
768 case blink::WebAXEventScrollPositionChanged:
769 eventName = "ScrollPositionChanged";
770 break;
771 case blink::WebAXEventScrolledToAnchor:
772 eventName = "ScrolledToAnchor";
773 break;
774 case blink::WebAXEventSelectedChildrenChanged:
775 eventName = "SelectedChildrenChanged";
776 break;
777 case blink::WebAXEventSelectedTextChanged:
778 eventName = "SelectedTextChanged";
779 break;
780 case blink::WebAXEventShow:
781 eventName = "Show";
782 break;
783 case blink::WebAXEventTextChanged:
784 eventName = "TextChanged";
785 break;
786 case blink::WebAXEventTextInserted:
787 eventName = "TextInserted";
788 break;
789 case blink::WebAXEventTextRemoved:
790 eventName = "TextRemoved";
791 break;
792 case blink::WebAXEventValueChanged:
793 eventName = "ValueChanged";
794 break;
795 default:
796 eventName = "Unknown";
797 break;
800 m_testInterfaces->accessibilityController()->NotificationReceived(obj, eventName);
802 if (m_testInterfaces->accessibilityController()->ShouldLogAccessibilityEvents()) {
803 string message("AccessibilityNotification - ");
804 message += eventName;
806 blink::WebNode node = obj.node();
807 if (!node.isNull() && node.isElementNode()) {
808 blink::WebElement element = node.to<blink::WebElement>();
809 if (element.hasAttribute("id")) {
810 message += " - id:";
811 message += element.getAttribute("id").utf8().data();
815 m_delegate->printMessage(message + "\n");
819 void WebTestProxyBase::startDragging(WebLocalFrame*, const WebDragData& data, WebDragOperationsMask mask, const WebImage&, const WebPoint&)
821 // When running a test, we need to fake a drag drop operation otherwise
822 // Windows waits for real mouse events to know when the drag is over.
823 m_testInterfaces->eventSender()->DoDragDrop(data, mask);
826 // The output from these methods in layout test mode should match that
827 // expected by the layout tests. See EditingDelegate.m in DumpRenderTree.
829 void WebTestProxyBase::didChangeSelection(bool isEmptySelection)
831 if (m_testInterfaces->testRunner()->shouldDumpEditingCallbacks())
832 m_delegate->printMessage("EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n");
835 void WebTestProxyBase::didChangeContents()
837 if (m_testInterfaces->testRunner()->shouldDumpEditingCallbacks())
838 m_delegate->printMessage("EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n");
841 bool WebTestProxyBase::createView(WebLocalFrame*, const WebURLRequest& request, const WebWindowFeatures&, const WebString&, WebNavigationPolicy, bool)
843 if (!m_testInterfaces->testRunner()->canOpenWindows())
844 return false;
845 if (m_testInterfaces->testRunner()->shouldDumpCreateView())
846 m_delegate->printMessage(string("createView(") + URLDescription(request.url()) + ")\n");
847 return true;
850 WebPlugin* WebTestProxyBase::createPlugin(WebLocalFrame* frame, const WebPluginParams& params)
852 if (TestPlugin::isSupportedMimeType(params.mimeType))
853 return TestPlugin::create(frame, params, m_delegate);
854 return 0;
857 void WebTestProxyBase::setStatusText(const WebString& text)
859 if (!m_testInterfaces->testRunner()->shouldDumpStatusCallbacks())
860 return;
861 m_delegate->printMessage(string("UI DELEGATE STATUS CALLBACK: setStatusText:") + text.utf8().data() + "\n");
864 void WebTestProxyBase::didStopLoading()
866 if (m_testInterfaces->testRunner()->shouldDumpProgressFinishedCallback())
867 m_delegate->printMessage("postProgressFinishedNotification\n");
870 void WebTestProxyBase::showContextMenu(WebLocalFrame*, const WebContextMenuData& contextMenuData)
872 m_testInterfaces->eventSender()->SetContextMenuData(contextMenuData);
875 WebUserMediaClient* WebTestProxyBase::userMediaClient()
877 if (!m_userMediaClient.get())
878 m_userMediaClient.reset(new WebUserMediaClientMock(m_delegate));
879 return m_userMediaClient.get();
882 // Simulate a print by going into print mode and then exit straight away.
883 void WebTestProxyBase::printPage(WebLocalFrame* frame)
885 WebSize pageSizeInPixels = webWidget()->size();
886 if (pageSizeInPixels.isEmpty())
887 return;
888 WebPrintParams printParams(pageSizeInPixels);
889 frame->printBegin(printParams);
890 frame->printEnd();
893 WebNotificationPresenter* WebTestProxyBase::notificationPresenter()
895 return m_testInterfaces->testRunner()->notification_presenter();
898 WebMIDIClient* WebTestProxyBase::webMIDIClient()
900 return midiClientMock();
903 WebSpeechInputController* WebTestProxyBase::speechInputController(WebSpeechInputListener* listener)
905 #if ENABLE_INPUT_SPEECH
906 if (!m_speechInputController.get()) {
907 m_speechInputController.reset(new MockWebSpeechInputController(listener));
908 m_speechInputController->setDelegate(m_delegate);
910 return m_speechInputController.get();
911 #else
912 DCHECK(listener);
913 return 0;
914 #endif
917 WebSpeechRecognizer* WebTestProxyBase::speechRecognizer()
919 return speechRecognizerMock();
922 bool WebTestProxyBase::requestPointerLock()
924 return m_testInterfaces->testRunner()->RequestPointerLock();
927 void WebTestProxyBase::requestPointerUnlock()
929 m_testInterfaces->testRunner()->RequestPointerUnlock();
932 bool WebTestProxyBase::isPointerLocked()
934 return m_testInterfaces->testRunner()->isPointerLocked();
937 void WebTestProxyBase::didFocus()
939 m_delegate->setFocus(this, true);
942 void WebTestProxyBase::didBlur()
944 m_delegate->setFocus(this, false);
947 void WebTestProxyBase::setToolTipText(const WebString& text, WebTextDirection)
949 m_testInterfaces->testRunner()->setToolTipText(text);
952 void WebTestProxyBase::didOpenChooser()
954 m_chooserCount++;
957 void WebTestProxyBase::didCloseChooser()
959 m_chooserCount--;
962 bool WebTestProxyBase::isChooserShown()
964 return 0 < m_chooserCount;
967 void WebTestProxyBase::loadURLExternally(WebLocalFrame* frame, const WebURLRequest& request, WebNavigationPolicy policy, const WebString& suggested_name)
969 if (m_testInterfaces->testRunner()->shouldWaitUntilExternalURLLoad()) {
970 if (policy == WebNavigationPolicyDownload) {
971 m_delegate->printMessage(string("Downloading URL with suggested filename \"") + suggested_name.utf8() + "\"\n");
972 } else {
973 m_delegate->printMessage(string("Loading URL externally - \"") + URLDescription(request.url()) + "\"\n");
975 m_delegate->testFinished();
979 void WebTestProxyBase::didStartProvisionalLoad(WebLocalFrame* frame)
981 if (!m_testInterfaces->testRunner()->topLoadingFrame())
982 m_testInterfaces->testRunner()->setTopLoadingFrame(frame, false);
984 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
985 printFrameDescription(m_delegate, frame);
986 m_delegate->printMessage(" - didStartProvisionalLoadForFrame\n");
989 if (m_testInterfaces->testRunner()->shouldDumpUserGestureInFrameLoadCallbacks())
990 printFrameUserGestureStatus(m_delegate, frame, " - in didStartProvisionalLoadForFrame\n");
993 void WebTestProxyBase::didReceiveServerRedirectForProvisionalLoad(WebLocalFrame* frame)
995 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
996 printFrameDescription(m_delegate, frame);
997 m_delegate->printMessage(" - didReceiveServerRedirectForProvisionalLoadForFrame\n");
1001 bool WebTestProxyBase::didFailProvisionalLoad(WebLocalFrame* frame, const WebURLError&)
1003 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1004 printFrameDescription(m_delegate, frame);
1005 m_delegate->printMessage(" - didFailProvisionalLoadWithError\n");
1007 locationChangeDone(frame);
1008 return !frame->provisionalDataSource();
1011 void WebTestProxyBase::didCommitProvisionalLoad(WebLocalFrame* frame, const WebHistoryItem&, blink::WebHistoryCommitType)
1013 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1014 printFrameDescription(m_delegate, frame);
1015 m_delegate->printMessage(" - didCommitLoadForFrame\n");
1019 void WebTestProxyBase::didReceiveTitle(WebLocalFrame* frame, const WebString& title, WebTextDirection direction)
1021 WebCString title8 = title.utf8();
1023 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1024 printFrameDescription(m_delegate, frame);
1025 m_delegate->printMessage(string(" - didReceiveTitle: ") + title8.data() + "\n");
1028 if (m_testInterfaces->testRunner()->shouldDumpTitleChanges())
1029 m_delegate->printMessage(string("TITLE CHANGED: '") + title8.data() + "'\n");
1032 void WebTestProxyBase::didChangeIcon(WebLocalFrame* frame, WebIconURL::Type)
1034 if (m_testInterfaces->testRunner()->shouldDumpIconChanges()) {
1035 printFrameDescription(m_delegate, frame);
1036 m_delegate->printMessage(string(" - didChangeIcons\n"));
1040 void WebTestProxyBase::didFinishDocumentLoad(WebLocalFrame* frame)
1042 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1043 printFrameDescription(m_delegate, frame);
1044 m_delegate->printMessage(" - didFinishDocumentLoadForFrame\n");
1045 } else {
1046 unsigned pendingUnloadEvents = frame->unloadListenerCount();
1047 if (pendingUnloadEvents) {
1048 printFrameDescription(m_delegate, frame);
1049 char buffer[100];
1050 snprintf(buffer, sizeof(buffer), " - has %u onunload handler(s)\n", pendingUnloadEvents);
1051 m_delegate->printMessage(buffer);
1056 void WebTestProxyBase::didHandleOnloadEvents(WebLocalFrame* frame)
1058 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1059 printFrameDescription(m_delegate, frame);
1060 m_delegate->printMessage(" - didHandleOnloadEventsForFrame\n");
1064 void WebTestProxyBase::didFailLoad(WebLocalFrame* frame, const WebURLError&)
1066 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1067 printFrameDescription(m_delegate, frame);
1068 m_delegate->printMessage(" - didFailLoadWithError\n");
1070 locationChangeDone(frame);
1073 void WebTestProxyBase::didFinishLoad(WebLocalFrame* frame)
1075 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks()) {
1076 printFrameDescription(m_delegate, frame);
1077 m_delegate->printMessage(" - didFinishLoadForFrame\n");
1079 locationChangeDone(frame);
1082 void WebTestProxyBase::didDetectXSS(WebLocalFrame*, const WebURL&, bool)
1084 if (m_testInterfaces->testRunner()->shouldDumpFrameLoadCallbacks())
1085 m_delegate->printMessage("didDetectXSS\n");
1088 void WebTestProxyBase::didDispatchPingLoader(WebLocalFrame*, const WebURL& url)
1090 if (m_testInterfaces->testRunner()->shouldDumpPingLoaderCallbacks())
1091 m_delegate->printMessage(string("PingLoader dispatched to '") + URLDescription(url).c_str() + "'.\n");
1094 void WebTestProxyBase::willRequestResource(WebLocalFrame* frame, const blink::WebCachedURLRequest& request)
1096 if (m_testInterfaces->testRunner()->shouldDumpResourceRequestCallbacks()) {
1097 printFrameDescription(m_delegate, frame);
1098 m_delegate->printMessage(string(" - ") + request.initiatorName().utf8().data());
1099 m_delegate->printMessage(string(" requested '") + URLDescription(request.urlRequest().url()).c_str() + "'\n");
1103 void WebTestProxyBase::willSendRequest(WebLocalFrame*, unsigned identifier, blink::WebURLRequest& request, const blink::WebURLResponse& redirectResponse)
1105 // Need to use GURL for host() and SchemeIs()
1106 GURL url = request.url();
1107 string requestURL = url.possibly_invalid_spec();
1109 GURL mainDocumentURL = request.firstPartyForCookies();
1111 if (redirectResponse.isNull() && (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks() || m_testInterfaces->testRunner()->shouldDumpResourcePriorities())) {
1112 DCHECK(m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end());
1113 m_resourceIdentifierMap[identifier] = descriptionSuitableForTestResult(requestURL);
1116 if (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks()) {
1117 if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1118 m_delegate->printMessage("<unknown>");
1119 else
1120 m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1121 m_delegate->printMessage(" - willSendRequest <NSURLRequest URL ");
1122 m_delegate->printMessage(descriptionSuitableForTestResult(requestURL).c_str());
1123 m_delegate->printMessage(", main document URL ");
1124 m_delegate->printMessage(URLDescription(mainDocumentURL).c_str());
1125 m_delegate->printMessage(", http method ");
1126 m_delegate->printMessage(request.httpMethod().utf8().data());
1127 m_delegate->printMessage("> redirectResponse ");
1128 printResponseDescription(m_delegate, redirectResponse);
1129 m_delegate->printMessage("\n");
1132 if (m_testInterfaces->testRunner()->shouldDumpResourcePriorities()) {
1133 m_delegate->printMessage(descriptionSuitableForTestResult(requestURL).c_str());
1134 m_delegate->printMessage(" has priority ");
1135 m_delegate->printMessage(PriorityDescription(request.priority()));
1136 m_delegate->printMessage("\n");
1139 if (m_testInterfaces->testRunner()->httpHeadersToClear()) {
1140 const set<string> *clearHeaders = m_testInterfaces->testRunner()->httpHeadersToClear();
1141 for (set<string>::const_iterator header = clearHeaders->begin(); header != clearHeaders->end(); ++header)
1142 request.clearHTTPHeaderField(WebString::fromUTF8(*header));
1145 string host = url.host();
1146 if (!host.empty() && (url.SchemeIs("http") || url.SchemeIs("https"))) {
1147 if (!isLocalhost(host) && !hostIsUsedBySomeTestsToGenerateError(host)
1148 && ((!mainDocumentURL.SchemeIs("http") && !mainDocumentURL.SchemeIs("https")) || isLocalhost(mainDocumentURL.host()))
1149 && !m_delegate->allowExternalPages()) {
1150 m_delegate->printMessage(string("Blocked access to external URL ") + requestURL + "\n");
1151 blockRequest(request);
1152 return;
1156 // Set the new substituted URL.
1157 request.setURL(m_delegate->rewriteLayoutTestsURL(request.url().spec()));
1160 void WebTestProxyBase::didReceiveResponse(WebLocalFrame*, unsigned identifier, const blink::WebURLResponse& response)
1162 if (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks()) {
1163 if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1164 m_delegate->printMessage("<unknown>");
1165 else
1166 m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1167 m_delegate->printMessage(" - didReceiveResponse ");
1168 printResponseDescription(m_delegate, response);
1169 m_delegate->printMessage("\n");
1171 if (m_testInterfaces->testRunner()->shouldDumpResourceResponseMIMETypes()) {
1172 GURL url = response.url();
1173 WebString mimeType = response.mimeType();
1174 m_delegate->printMessage(url.ExtractFileName());
1175 m_delegate->printMessage(" has MIME type ");
1176 // Simulate NSURLResponse's mapping of empty/unknown MIME types to application/octet-stream
1177 m_delegate->printMessage(mimeType.isEmpty() ? "application/octet-stream" : mimeType.utf8().data());
1178 m_delegate->printMessage("\n");
1182 void WebTestProxyBase::didChangeResourcePriority(WebLocalFrame*, unsigned identifier, const blink::WebURLRequest::Priority& priority, int intra_priority_value)
1184 if (m_testInterfaces->testRunner()->shouldDumpResourcePriorities()) {
1185 if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1186 m_delegate->printMessage("<unknown>");
1187 else
1188 m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1189 m_delegate->printMessage(" changed priority to ");
1190 m_delegate->printMessage(PriorityDescription(priority));
1191 char buffer[64];
1192 snprintf(buffer, sizeof(buffer), ", intra_priority %d", intra_priority_value);
1193 m_delegate->printMessage(buffer);
1194 m_delegate->printMessage("\n");
1198 void WebTestProxyBase::didFinishResourceLoad(WebLocalFrame*, unsigned identifier)
1200 if (m_testInterfaces->testRunner()->shouldDumpResourceLoadCallbacks()) {
1201 if (m_resourceIdentifierMap.find(identifier) == m_resourceIdentifierMap.end())
1202 m_delegate->printMessage("<unknown>");
1203 else
1204 m_delegate->printMessage(m_resourceIdentifierMap[identifier]);
1205 m_delegate->printMessage(" - didFinishLoading\n");
1207 m_resourceIdentifierMap.erase(identifier);
1210 void WebTestProxyBase::didAddMessageToConsole(const WebConsoleMessage& message, const WebString& sourceName, unsigned sourceLine)
1212 // This matches win DumpRenderTree's UIDelegate.cpp.
1213 if (!m_logConsoleOutput)
1214 return;
1215 string level;
1216 switch (message.level) {
1217 case WebConsoleMessage::LevelDebug:
1218 level = "DEBUG";
1219 break;
1220 case WebConsoleMessage::LevelLog:
1221 level = "MESSAGE";
1222 break;
1223 case WebConsoleMessage::LevelInfo:
1224 level = "INFO";
1225 break;
1226 case WebConsoleMessage::LevelWarning:
1227 level = "WARNING";
1228 break;
1229 case WebConsoleMessage::LevelError:
1230 level = "ERROR";
1231 break;
1233 m_delegate->printMessage(string("CONSOLE ") + level + ": ");
1234 if (sourceLine) {
1235 char buffer[40];
1236 snprintf(buffer, sizeof(buffer), "line %d: ", sourceLine);
1237 m_delegate->printMessage(buffer);
1239 if (!message.text.isEmpty()) {
1240 string newMessage;
1241 newMessage = message.text.utf8();
1242 size_t fileProtocol = newMessage.find("file://");
1243 if (fileProtocol != string::npos) {
1244 newMessage = newMessage.substr(0, fileProtocol)
1245 + urlSuitableForTestResult(newMessage.substr(fileProtocol));
1247 m_delegate->printMessage(newMessage);
1249 m_delegate->printMessage(string("\n"));
1252 void WebTestProxyBase::locationChangeDone(WebFrame* frame)
1254 if (frame != m_testInterfaces->testRunner()->topLoadingFrame())
1255 return;
1256 m_testInterfaces->testRunner()->setTopLoadingFrame(frame, true);
1259 WebNavigationPolicy WebTestProxyBase::decidePolicyForNavigation(WebLocalFrame*, WebDataSource::ExtraData*, const WebURLRequest& request, WebNavigationType type, WebNavigationPolicy defaultPolicy, bool isRedirect)
1261 WebNavigationPolicy result;
1262 if (!m_testInterfaces->testRunner()->policyDelegateEnabled())
1263 return defaultPolicy;
1265 m_delegate->printMessage(string("Policy delegate: attempt to load ") + URLDescription(request.url()) + " with navigation type '" + webNavigationTypeToString(type) + "'\n");
1266 if (m_testInterfaces->testRunner()->policyDelegateIsPermissive())
1267 result = blink::WebNavigationPolicyCurrentTab;
1268 else
1269 result = blink::WebNavigationPolicyIgnore;
1271 if (m_testInterfaces->testRunner()->policyDelegateShouldNotifyDone())
1272 m_testInterfaces->testRunner()->policyDelegateDone();
1273 return result;
1276 bool WebTestProxyBase::willCheckAndDispatchMessageEvent(WebLocalFrame*, WebFrame*, WebSecurityOrigin, WebDOMMessageEvent)
1278 if (m_testInterfaces->testRunner()->shouldInterceptPostMessage()) {
1279 m_delegate->printMessage("intercepted postMessage\n");
1280 return true;
1283 return false;
1286 void WebTestProxyBase::postSpellCheckEvent(const WebString& eventName)
1288 if (m_testInterfaces->testRunner()->shouldDumpSpellCheckCallbacks()) {
1289 m_delegate->printMessage(string("SpellCheckEvent: ") + eventName.utf8().data() + "\n");
1293 void WebTestProxyBase::resetInputMethod()
1295 // If a composition text exists, then we need to let the browser process
1296 // to cancel the input method's ongoing composition session.
1297 if (m_webWidget)
1298 m_webWidget->confirmComposition();
1301 } // namespace content