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"
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
;
55 class HostMethodTask
: public WebMethodTask
<WebTestProxyBase
> {
57 typedef void (WebTestProxyBase::*CallbackMethodType
)();
58 HostMethodTask(WebTestProxyBase
* object
, CallbackMethodType callback
)
59 : WebMethodTask
<WebTestProxyBase
>(object
)
60 , m_callback(callback
)
63 virtual void runIfValid() OVERRIDE
{ (m_object
->*m_callback
)(); }
66 CallbackMethodType m_callback
;
69 class ClosureTask
: public WebMethodTask
<WebTestProxyBase
> {
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())
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");
91 delegate
->printMessage(string("main frame \"") + name8
+ "\"");
94 if (!name8
.length()) {
95 delegate
->printMessage("frame (anonymous)");
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://"))
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)");
131 string url
= response
.url().spec();
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
)
147 case WebURLRequest::PriorityVeryLow
:
149 case WebURLRequest::PriorityLow
:
151 case WebURLRequest::PriorityMedium
:
153 case WebURLRequest::PriorityHigh
:
155 case WebURLRequest::PriorityVeryHigh
:
157 case WebURLRequest::PriorityUnresolved
:
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://"))
185 size_t pos
= url
.rfind('/');
186 if (pos
== string::npos
) {
188 pos
= url
.rfind('\\');
189 if (pos
== string::npos
)
195 string filename
= url
.substr(pos
+ 1);
196 if (filename
.empty())
197 return "file:"; // A WebKit test has this in its expected output.
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
)
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
:
222 case blink::WebNavigationTypeFormResubmitted
:
223 return formResubmittedString
;
224 case blink::WebNavigationTypeOther
:
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())
237 return documentElement
.innerText().utf8();
240 string
dumpFramesAsText(WebFrame
* frame
, bool recursive
)
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
));
255 for (WebFrame
* child
= frame
->firstChild(); child
; child
= child
->nextSibling())
256 result
.append(dumpFramesAsText(child
, recursive
));
262 string
dumpFramesAsPrintedText(WebFrame
* frame
, bool recursive
)
266 // Cannot do printed format for anything other than HTML
267 if (!frame
->document().isHTMLDocument())
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());
281 for (WebFrame
* child
= frame
->firstChild(); child
; child
= child
->nextSibling())
282 result
.append(dumpFramesAsPrintedText(child
, recursive
));
288 string
dumpFrameScrollPosition(WebFrame
* frame
, bool recursive
)
291 WebSize offset
= frame
->scrollOffset();
292 if (offset
.width
> 0 || offset
.height
> 0) {
294 result
= string("frame '") + frame
->uniqueName().utf8().data() + "' ";
296 snprintf(data
, sizeof(data
), "scrolled to %d,%d\n", offset
.width
, offset
.height
);
302 for (WebFrame
* child
= frame
->firstChild(); child
; child
= child
->nextSibling())
303 result
+= dumpFrameScrollPosition(child
, recursive
);
307 string
dumpAllBackForwardLists(TestInterfaces
* interfaces
, WebTestDelegate
* delegate
)
310 const vector
<WebTestProxyBase
*>& windowList
= interfaces
->windowList();
311 for (unsigned i
= 0; i
< windowList
.size(); ++i
)
312 result
.append(delegate
->dumpHistoryForWindow(windowList
.at(i
)));
318 WebTestProxyBase::WebTestProxyBase()
319 : m_testInterfaces(0)
322 , m_spellcheck(new SpellCheckClient(this))
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
);
347 if (m_speechRecognizer
.get())
348 m_speechRecognizer
->setDelegate(delegate
);
351 void WebTestProxyBase::setWidget(WebWidget
* widget
)
353 m_webWidget
= widget
;
356 WebWidget
* WebTestProxyBase::webWidget()
361 WebView
* WebTestProxyBase::webView()
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()
371 discardBackingStore();
374 void WebTestProxyBase::reset()
376 m_paintRect
= WebRect();
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();
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.
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();
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";
435 bool recursive
= m_testInterfaces
->testRunner()->shouldDumpChildFrameScrollPositions();
436 WebFrame::RenderAsTextControls renderTextBehavior
= WebFrame::RenderAsTextNormal
;
437 if (shouldDumpAsPrinted
)
438 renderTextBehavior
|= WebFrame::RenderAsTextPrinting
;
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
);
451 SkCanvas
* WebTestProxyBase::capturePixels()
453 webWidget()->layout();
454 if (m_testInterfaces
->testRunner()->isPrinting())
455 paintPagesWithBoundaries();
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();
466 // Render a red rectangle bounding selection rect
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
);
481 void WebTestProxyBase::setLogConsoleOutput(bool enabled
)
483 m_logConsoleOutput
= enabled
;
486 void WebTestProxyBase::paintRect(const WebRect
& rect
)
488 DCHECK(!m_isPainting
);
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
);
521 if (left
< right
&& top
< bottom
)
522 rect
= WebRect(left
, top
, right
- left
, bottom
- top
);
524 m_paintRect
= WebRect();
529 DCHECK(m_paintRect
.isEmpty());
532 void WebTestProxyBase::paintPagesWithBoundaries()
534 DCHECK(!m_isPainting
);
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);
546 discardBackingStore();
547 m_canvas
.reset(testCanvas
);
549 webFrame
->printEnd();
553 webFrame
->printPagesWithBoundaries(canvas(), pageSizeInPixels
);
554 webFrame
->printEnd();
556 m_isPainting
= false;
559 SkCanvas
* WebTestProxyBase::canvas()
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
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
);
579 paintInvalidatedRegion();
581 if (!callback
.is_null())
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(
593 &WebTestProxyBase::display
, base::Unretained(this), callback
)));
596 void WebTestProxyBase::discardBackingStore()
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();
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
630 if (m_paintRect
.isEmpty()) {
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()
656 void WebTestProxyBase::scheduleAnimation()
658 if (!m_testInterfaces
->testRunner()->TestIsRunning())
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
)
686 void WebTestProxyBase::setWindowRect(const WebRect
& rect
)
689 discardBackingStore();
692 void WebTestProxyBase::didAutoResize(const WebSize
&)
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())
706 if (event
== blink::WebAXEventFocus
)
707 m_testInterfaces
->accessibilityController()->SetFocusedElement(obj
);
709 const char* eventName
= 0;
711 case blink::WebAXEventActiveDescendantChanged
:
712 eventName
= "ActiveDescendantChanged";
714 case blink::WebAXEventAlert
:
717 case blink::WebAXEventAriaAttributeChanged
:
718 eventName
= "AriaAttributeChanged";
720 case blink::WebAXEventAutocorrectionOccured
:
721 eventName
= "AutocorrectionOccured";
723 case blink::WebAXEventBlur
:
726 case blink::WebAXEventCheckedStateChanged
:
727 eventName
= "CheckedStateChanged";
729 case blink::WebAXEventChildrenChanged
:
730 eventName
= "ChildrenChanged";
732 case blink::WebAXEventFocus
:
735 case blink::WebAXEventHide
:
738 case blink::WebAXEventInvalidStatusChanged
:
739 eventName
= "InvalidStatusChanged";
741 case blink::WebAXEventLayoutComplete
:
742 eventName
= "LayoutComplete";
744 case blink::WebAXEventLiveRegionChanged
:
745 eventName
= "LiveRegionChanged";
747 case blink::WebAXEventLoadComplete
:
748 eventName
= "LoadComplete";
750 case blink::WebAXEventLocationChanged
:
751 eventName
= "LocationChanged";
753 case blink::WebAXEventMenuListItemSelected
:
754 eventName
= "MenuListItemSelected";
756 case blink::WebAXEventMenuListValueChanged
:
757 eventName
= "MenuListValueChanged";
759 case blink::WebAXEventRowCollapsed
:
760 eventName
= "RowCollapsed";
762 case blink::WebAXEventRowCountChanged
:
763 eventName
= "RowCountChanged";
765 case blink::WebAXEventRowExpanded
:
766 eventName
= "RowExpanded";
768 case blink::WebAXEventScrollPositionChanged
:
769 eventName
= "ScrollPositionChanged";
771 case blink::WebAXEventScrolledToAnchor
:
772 eventName
= "ScrolledToAnchor";
774 case blink::WebAXEventSelectedChildrenChanged
:
775 eventName
= "SelectedChildrenChanged";
777 case blink::WebAXEventSelectedTextChanged
:
778 eventName
= "SelectedTextChanged";
780 case blink::WebAXEventShow
:
783 case blink::WebAXEventTextChanged
:
784 eventName
= "TextChanged";
786 case blink::WebAXEventTextInserted
:
787 eventName
= "TextInserted";
789 case blink::WebAXEventTextRemoved
:
790 eventName
= "TextRemoved";
792 case blink::WebAXEventValueChanged
:
793 eventName
= "ValueChanged";
796 eventName
= "Unknown";
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")) {
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())
845 if (m_testInterfaces
->testRunner()->shouldDumpCreateView())
846 m_delegate
->printMessage(string("createView(") + URLDescription(request
.url()) + ")\n");
850 WebPlugin
* WebTestProxyBase::createPlugin(WebLocalFrame
* frame
, const WebPluginParams
& params
)
852 if (TestPlugin::isSupportedMimeType(params
.mimeType
))
853 return TestPlugin::create(frame
, params
, m_delegate
);
857 void WebTestProxyBase::setStatusText(const WebString
& text
)
859 if (!m_testInterfaces
->testRunner()->shouldDumpStatusCallbacks())
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())
888 WebPrintParams
printParams(pageSizeInPixels
);
889 frame
->printBegin(printParams
);
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();
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()
957 void WebTestProxyBase::didCloseChooser()
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");
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");
1046 unsigned pendingUnloadEvents
= frame
->unloadListenerCount();
1047 if (pendingUnloadEvents
) {
1048 printFrameDescription(m_delegate
, frame
);
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>");
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
);
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>");
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>");
1188 m_delegate
->printMessage(m_resourceIdentifierMap
[identifier
]);
1189 m_delegate
->printMessage(" changed priority to ");
1190 m_delegate
->printMessage(PriorityDescription(priority
));
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>");
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
)
1216 switch (message
.level
) {
1217 case WebConsoleMessage::LevelDebug
:
1220 case WebConsoleMessage::LevelLog
:
1223 case WebConsoleMessage::LevelInfo
:
1226 case WebConsoleMessage::LevelWarning
:
1229 case WebConsoleMessage::LevelError
:
1233 m_delegate
->printMessage(string("CONSOLE ") + level
+ ": ");
1236 snprintf(buffer
, sizeof(buffer
), "line %d: ", sourceLine
);
1237 m_delegate
->printMessage(buffer
);
1239 if (!message
.text
.isEmpty()) {
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())
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
;
1269 result
= blink::WebNavigationPolicyIgnore
;
1271 if (m_testInterfaces
->testRunner()->policyDelegateShouldNotifyDone())
1272 m_testInterfaces
->testRunner()->policyDelegateDone();
1276 bool WebTestProxyBase::willCheckAndDispatchMessageEvent(WebLocalFrame
*, WebFrame
*, WebSecurityOrigin
, WebDOMMessageEvent
)
1278 if (m_testInterfaces
->testRunner()->shouldInterceptPostMessage()) {
1279 m_delegate
->printMessage("intercepted postMessage\n");
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.
1298 m_webWidget
->confirmComposition();
1301 } // namespace content