1 // Copyright 2014 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/web_test_proxy.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/MockColorChooser.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/accessibility_controller.h" 21 #include "content/shell/renderer/test_runner/event_sender.h" 22 #include "content/shell/renderer/test_runner/mock_web_push_client.h" 23 #include "content/shell/renderer/test_runner/mock_web_user_media_client.h" 24 #include "content/shell/renderer/test_runner/test_runner.h" 25 #include "content/shell/renderer/test_runner/web_test_runner.h" 26 // FIXME: Including platform_canvas.h here is a layering violation. 27 #include "skia/ext/platform_canvas.h" 28 #include "third_party/WebKit/public/platform/WebCString.h" 29 #include "third_party/WebKit/public/platform/WebURLError.h" 30 #include "third_party/WebKit/public/platform/WebURLRequest.h" 31 #include "third_party/WebKit/public/platform/WebURLResponse.h" 32 #include "third_party/WebKit/public/web/WebAXEnums.h" 33 #include "third_party/WebKit/public/web/WebAXObject.h" 34 #include "third_party/WebKit/public/web/WebCachedURLRequest.h" 35 #include "third_party/WebKit/public/web/WebConsoleMessage.h" 36 #include "third_party/WebKit/public/web/WebDataSource.h" 37 #include "third_party/WebKit/public/web/WebDocument.h" 38 #include "third_party/WebKit/public/web/WebElement.h" 39 #include "third_party/WebKit/public/web/WebHistoryItem.h" 40 #include "third_party/WebKit/public/web/WebLocalFrame.h" 41 #include "third_party/WebKit/public/web/WebMIDIClientMock.h" 42 #include "third_party/WebKit/public/web/WebNode.h" 43 #include "third_party/WebKit/public/web/WebPluginParams.h" 44 #include "third_party/WebKit/public/web/WebPrintParams.h" 45 #include "third_party/WebKit/public/web/WebRange.h" 46 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 47 #include "third_party/WebKit/public/web/WebView.h" 48 49 namespace content { 50 51 namespace { 52 53 class HostMethodTask : public WebMethodTask<WebTestProxyBase> { 54 public: 55 typedef void (WebTestProxyBase::*CallbackMethodType)(); 56 HostMethodTask(WebTestProxyBase* object, CallbackMethodType callback) 57 : WebMethodTask<WebTestProxyBase>(object), callback_(callback) {} 58 59 virtual void runIfValid() OVERRIDE { (m_object->*callback_)(); } 60 61 private: 62 CallbackMethodType callback_; 63 }; 64 65 void PrintFrameDescription(WebTestDelegate* delegate, blink::WebFrame* frame) { 66 std::string name8 = frame->uniqueName().utf8(); 67 if (frame == frame->view()->mainFrame()) { 68 if (!name8.length()) { 69 delegate->printMessage("main frame"); 70 return; 71 } 72 delegate->printMessage(std::string("main frame \"") + name8 + "\""); 73 return; 74 } 75 if (!name8.length()) { 76 delegate->printMessage("frame (anonymous)"); 77 return; 78 } 79 delegate->printMessage(std::string("frame \"") + name8 + "\""); 80 } 81 82 void PrintFrameuserGestureStatus(WebTestDelegate* delegate, 83 blink::WebFrame* frame, 84 const char* msg) { 85 bool is_user_gesture = 86 blink::WebUserGestureIndicator::isProcessingUserGesture(); 87 delegate->printMessage(std::string("Frame with user gesture \"") + 88 (is_user_gesture ? "true" : "false") + "\"" + msg); 89 } 90 91 // Used to write a platform neutral file:/// URL by taking the 92 // filename and its directory. (e.g., converts 93 // "file:///tmp/foo/bar.txt" to just "bar.txt"). 94 std::string DescriptionSuitableForTestResult(const std::string& url) { 95 if (url.empty() || std::string::npos == url.find("file://")) 96 return url; 97 98 size_t pos = url.rfind('/'); 99 if (pos == std::string::npos || !pos) 100 return "ERROR:" + url; 101 pos = url.rfind('/', pos - 1); 102 if (pos == std::string::npos) 103 return "ERROR:" + url; 104 105 return url.substr(pos + 1); 106 } 107 108 void PrintResponseDescription(WebTestDelegate* delegate, 109 const blink::WebURLResponse& response) { 110 if (response.isNull()) { 111 delegate->printMessage("(null)"); 112 return; 113 } 114 std::string url = response.url().spec(); 115 char data[100]; 116 snprintf(data, sizeof(data), "%d", response.httpStatusCode()); 117 delegate->printMessage(std::string("<NSURLResponse ") + 118 DescriptionSuitableForTestResult(url) + 119 ", http status code " + data + ">"); 120 } 121 122 std::string URLDescription(const GURL& url) { 123 if (url.SchemeIs("file")) 124 return url.ExtractFileName(); 125 return url.possibly_invalid_spec(); 126 } 127 128 std::string PriorityDescription( 129 const blink::WebURLRequest::Priority& priority) { 130 switch (priority) { 131 case blink::WebURLRequest::PriorityVeryLow: 132 return "VeryLow"; 133 case blink::WebURLRequest::PriorityLow: 134 return "Low"; 135 case blink::WebURLRequest::PriorityMedium: 136 return "Medium"; 137 case blink::WebURLRequest::PriorityHigh: 138 return "High"; 139 case blink::WebURLRequest::PriorityVeryHigh: 140 return "VeryHigh"; 141 case blink::WebURLRequest::PriorityUnresolved: 142 default: 143 return "Unresolved"; 144 } 145 } 146 147 void BlockRequest(blink::WebURLRequest& request) { 148 request.setURL(GURL("255.255.255.255")); 149 } 150 151 bool IsLocalHost(const std::string& host) { 152 return host == "127.0.0.1" || host == "localhost"; 153 } 154 155 bool HostIsUsedBySomeTestsToGenerateError(const std::string& host) { 156 return host == "255.255.255.255"; 157 } 158 159 // Used to write a platform neutral file:/// URL by only taking the filename 160 // (e.g., converts "file:///tmp/foo.txt" to just "foo.txt"). 161 std::string URLSuitableForTestResult(const std::string& url) { 162 if (url.empty() || std::string::npos == url.find("file://")) 163 return url; 164 165 size_t pos = url.rfind('/'); 166 if (pos == std::string::npos) { 167 #ifdef WIN32 168 pos = url.rfind('\\'); 169 if (pos == std::string::npos) 170 pos = 0; 171 #else 172 pos = 0; 173 #endif 174 } 175 std::string filename = url.substr(pos + 1); 176 if (filename.empty()) 177 return "file:"; // A WebKit test has this in its expected output. 178 return filename; 179 } 180 181 // WebNavigationType debugging strings taken from PolicyDelegate.mm. 182 const char* kLinkClickedString = "link clicked"; 183 const char* kFormSubmittedString = "form submitted"; 184 const char* kBackForwardString = "back/forward"; 185 const char* kReloadString = "reload"; 186 const char* kFormResubmittedString = "form resubmitted"; 187 const char* kOtherString = "other"; 188 const char* kIllegalString = "illegal value"; 189 190 // Get a debugging string from a WebNavigationType. 191 const char* WebNavigationTypeToString(blink::WebNavigationType type) { 192 switch (type) { 193 case blink::WebNavigationTypeLinkClicked: 194 return kLinkClickedString; 195 case blink::WebNavigationTypeFormSubmitted: 196 return kFormSubmittedString; 197 case blink::WebNavigationTypeBackForward: 198 return kBackForwardString; 199 case blink::WebNavigationTypeReload: 200 return kReloadString; 201 case blink::WebNavigationTypeFormResubmitted: 202 return kFormResubmittedString; 203 case blink::WebNavigationTypeOther: 204 return kOtherString; 205 } 206 return kIllegalString; 207 } 208 209 std::string DumpFrameHeaderIfNeeded(blink::WebFrame* frame) { 210 std::string result; 211 212 // Add header for all but the main frame. Skip empty frames. 213 if (frame->parent() && !frame->document().documentElement().isNull()) { 214 result.append("\n--------\nFrame: '"); 215 result.append(frame->uniqueName().utf8().data()); 216 result.append("'\n--------\n"); 217 } 218 219 return result; 220 } 221 222 std::string DumpFramesAsMarkup(blink::WebFrame* frame, bool recursive) { 223 std::string result = DumpFrameHeaderIfNeeded(frame); 224 result.append(frame->contentAsMarkup().utf8()); 225 result.append("\n"); 226 227 if (recursive) { 228 for (blink::WebFrame* child = frame->firstChild(); child; 229 child = child->nextSibling()) 230 result.append(DumpFramesAsMarkup(child, recursive)); 231 } 232 233 return result; 234 } 235 236 std::string DumpDocumentText(blink::WebFrame* frame) { 237 // We use the document element's text instead of the body text here because 238 // not all documents have a body, such as XML documents. 239 blink::WebElement document_element = frame->document().documentElement(); 240 if (document_element.isNull()) 241 return std::string(); 242 return document_element.innerText().utf8(); 243 } 244 245 std::string DumpFramesAsText(blink::WebFrame* frame, bool recursive) { 246 std::string result = DumpFrameHeaderIfNeeded(frame); 247 result.append(DumpDocumentText(frame)); 248 result.append("\n"); 249 250 if (recursive) { 251 for (blink::WebFrame* child = frame->firstChild(); child; 252 child = child->nextSibling()) 253 result.append(DumpFramesAsText(child, recursive)); 254 } 255 256 return result; 257 } 258 259 std::string DumpFramesAsPrintedText(blink::WebFrame* frame, bool recursive) { 260 // Cannot do printed format for anything other than HTML 261 if (!frame->document().isHTMLDocument()) 262 return std::string(); 263 264 std::string result = DumpFrameHeaderIfNeeded(frame); 265 result.append( 266 frame->renderTreeAsText(blink::WebFrame::RenderAsTextPrinting).utf8()); 267 result.append("\n"); 268 269 if (recursive) { 270 for (blink::WebFrame* child = frame->firstChild(); child; 271 child = child->nextSibling()) 272 result.append(DumpFramesAsPrintedText(child, recursive)); 273 } 274 275 return result; 276 } 277 278 std::string DumpFrameScrollPosition(blink::WebFrame* frame, bool recursive) { 279 std::string result; 280 blink::WebSize offset = frame->scrollOffset(); 281 if (offset.width > 0 || offset.height > 0) { 282 if (frame->parent()) { 283 result = 284 std::string("frame '") + frame->uniqueName().utf8().data() + "' "; 285 } 286 char data[100]; 287 snprintf( 288 data, sizeof(data), "scrolled to %d,%d\n", offset.width, offset.height); 289 result += data; 290 } 291 292 if (!recursive) 293 return result; 294 for (blink::WebFrame* child = frame->firstChild(); child; 295 child = child->nextSibling()) 296 result += DumpFrameScrollPosition(child, recursive); 297 return result; 298 } 299 300 std::string DumpAllBackForwardLists(TestInterfaces* interfaces, 301 WebTestDelegate* delegate) { 302 std::string result; 303 const std::vector<WebTestProxyBase*>& window_list = interfaces->windowList(); 304 for (size_t i = 0; i < window_list.size(); ++i) 305 result.append(delegate->dumpHistoryForWindow(window_list.at(i))); 306 return result; 307 } 308 } 309 310 WebTestProxyBase::WebTestProxyBase() 311 : test_interfaces_(NULL), 312 delegate_(NULL), 313 web_widget_(NULL), 314 spellcheck_(new SpellCheckClient(this)), 315 chooser_count_(0) { 316 Reset(); 317 } 318 319 WebTestProxyBase::~WebTestProxyBase() { 320 test_interfaces_->windowClosed(this); 321 } 322 323 void WebTestProxyBase::SetInterfaces(WebTestInterfaces* interfaces) { 324 test_interfaces_ = interfaces->testInterfaces(); 325 test_interfaces_->windowOpened(this); 326 } 327 328 void WebTestProxyBase::SetDelegate(WebTestDelegate* delegate) { 329 delegate_ = delegate; 330 spellcheck_->setDelegate(delegate); 331 if (speech_recognizer_.get()) 332 speech_recognizer_->setDelegate(delegate); 333 } 334 335 blink::WebView* WebTestProxyBase::GetWebView() const { 336 DCHECK(web_widget_); 337 // TestRunner does not support popup widgets. So |web_widget|_ is always a 338 // WebView. 339 return static_cast<blink::WebView*>(web_widget_); 340 } 341 342 void WebTestProxyBase::Reset() { 343 animate_scheduled_ = false; 344 resource_identifier_map_.clear(); 345 log_console_output_ = true; 346 if (midi_client_.get()) 347 midi_client_->resetMock(); 348 accept_languages_ = ""; 349 } 350 351 blink::WebSpellCheckClient* WebTestProxyBase::GetSpellCheckClient() const { 352 return spellcheck_.get(); 353 } 354 355 blink::WebColorChooser* WebTestProxyBase::CreateColorChooser( 356 blink::WebColorChooserClient* client, 357 const blink::WebColor& color, 358 const blink::WebVector<blink::WebColorSuggestion>& suggestions) { 359 // This instance is deleted by WebCore::ColorInputType 360 return new MockColorChooser(client, delegate_, this); 361 } 362 363 bool WebTestProxyBase::RunFileChooser( 364 const blink::WebFileChooserParams& params, 365 blink::WebFileChooserCompletion* completion) { 366 delegate_->printMessage("Mock: Opening a file chooser.\n"); 367 // FIXME: Add ability to set file names to a file upload control. 368 return false; 369 } 370 371 void WebTestProxyBase::ShowValidationMessage( 372 const blink::WebRect& anchor_in_root_view, 373 const blink::WebString& message, 374 const blink::WebString& sub_message, 375 blink::WebTextDirection hint) { 376 delegate_->printMessage( 377 std::string("ValidationMessageClient: main-message=") + 378 std::string(message.utf8()) + " sub-message=" + 379 std::string(sub_message.utf8()) + "\n"); 380 } 381 382 std::string WebTestProxyBase::CaptureTree(bool debug_render_tree) { 383 bool should_dump_custom_text = 384 test_interfaces_->testRunner()->shouldDumpAsCustomText(); 385 bool should_dump_as_text = test_interfaces_->testRunner()->shouldDumpAsText(); 386 bool should_dump_as_markup = 387 test_interfaces_->testRunner()->shouldDumpAsMarkup(); 388 bool should_dump_as_printed = test_interfaces_->testRunner()->isPrinting(); 389 blink::WebFrame* frame = GetWebView()->mainFrame(); 390 std::string data_utf8; 391 if (should_dump_custom_text) { 392 // Append a newline for the test driver. 393 data_utf8 = test_interfaces_->testRunner()->customDumpText() + "\n"; 394 } else if (should_dump_as_text) { 395 bool recursive = 396 test_interfaces_->testRunner()->shouldDumpChildFramesAsText(); 397 data_utf8 = should_dump_as_printed ? 398 DumpFramesAsPrintedText(frame, recursive) : 399 DumpFramesAsText(frame, recursive); 400 } else if (should_dump_as_markup) { 401 bool recursive = 402 test_interfaces_->testRunner()->shouldDumpChildFramesAsMarkup(); 403 // Append a newline for the test driver. 404 data_utf8 = DumpFramesAsMarkup(frame, recursive); 405 } else { 406 bool recursive = 407 test_interfaces_->testRunner()->shouldDumpChildFrameScrollPositions(); 408 blink::WebFrame::RenderAsTextControls render_text_behavior = 409 blink::WebFrame::RenderAsTextNormal; 410 if (should_dump_as_printed) 411 render_text_behavior |= blink::WebFrame::RenderAsTextPrinting; 412 if (debug_render_tree) 413 render_text_behavior |= blink::WebFrame::RenderAsTextDebug; 414 data_utf8 = frame->renderTreeAsText(render_text_behavior).utf8(); 415 data_utf8 += DumpFrameScrollPosition(frame, recursive); 416 } 417 418 if (test_interfaces_->testRunner()->ShouldDumpBackForwardList()) 419 data_utf8 += DumpAllBackForwardLists(test_interfaces_, delegate_); 420 421 return data_utf8; 422 } 423 424 void WebTestProxyBase::DrawSelectionRect(SkCanvas* canvas) { 425 // See if we need to draw the selection bounds rect. Selection bounds 426 // rect is the rect enclosing the (possibly transformed) selection. 427 // The rect should be drawn after everything is laid out and painted. 428 if (!test_interfaces_->testRunner()->shouldDumpSelectionRect()) 429 return; 430 // If there is a selection rect - draw a red 1px border enclosing rect 431 blink::WebRect wr = GetWebView()->mainFrame()->selectionBoundsRect(); 432 if (wr.isEmpty()) 433 return; 434 // Render a red rectangle bounding selection rect 435 SkPaint paint; 436 paint.setColor(0xFFFF0000); // Fully opaque red 437 paint.setStyle(SkPaint::kStroke_Style); 438 paint.setFlags(SkPaint::kAntiAlias_Flag); 439 paint.setStrokeWidth(1.0f); 440 SkIRect rect; // Bounding rect 441 rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height); 442 canvas->drawIRect(rect, paint); 443 } 444 445 void WebTestProxyBase::didCompositeAndReadback(const SkBitmap& bitmap) { 446 TRACE_EVENT2("shell", 447 "WebTestProxyBase::didCompositeAndReadback", 448 "x", 449 bitmap.info().fWidth, 450 "y", 451 bitmap.info().fHeight); 452 SkCanvas canvas(bitmap); 453 DrawSelectionRect(&canvas); 454 DCHECK(!composite_and_readback_callbacks_.empty()); 455 composite_and_readback_callbacks_.front().Run(bitmap); 456 composite_and_readback_callbacks_.pop_front(); 457 } 458 459 void WebTestProxyBase::SetAcceptLanguages(const std::string& accept_languages) { 460 bool notify = accept_languages_ != accept_languages; 461 accept_languages_ = accept_languages; 462 463 if (notify) 464 GetWebView()->acceptLanguagesChanged(); 465 } 466 467 void WebTestProxyBase::CapturePixelsForPrinting( 468 const base::Callback<void(const SkBitmap&)>& callback) { 469 web_widget_->layout(); 470 471 blink::WebSize page_size_in_pixels = web_widget_->size(); 472 blink::WebFrame* web_frame = GetWebView()->mainFrame(); 473 474 int page_count = web_frame->printBegin(page_size_in_pixels); 475 int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1; 476 477 bool is_opaque = false; 478 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::TryCreateBitmapCanvas( 479 page_size_in_pixels.width, totalHeight, is_opaque))); 480 if (canvas) 481 web_frame->printPagesWithBoundaries(canvas.get(), page_size_in_pixels); 482 web_frame->printEnd(); 483 484 DrawSelectionRect(canvas.get()); 485 SkBaseDevice* device = skia::GetTopDevice(*canvas); 486 const SkBitmap& bitmap = device->accessBitmap(false); 487 callback.Run(bitmap); 488 } 489 490 void WebTestProxyBase::CapturePixelsAsync( 491 const base::Callback<void(const SkBitmap&)>& callback) { 492 TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync"); 493 494 DCHECK(web_widget_->isAcceleratedCompositingActive()); 495 DCHECK(!callback.is_null()); 496 497 if (test_interfaces_->testRunner()->isPrinting()) { 498 base::MessageLoopProxy::current()->PostTask( 499 FROM_HERE, 500 base::Bind(&WebTestProxyBase::CapturePixelsForPrinting, 501 base::Unretained(this), 502 callback)); 503 return; 504 } 505 506 composite_and_readback_callbacks_.push_back(callback); 507 web_widget_->compositeAndReadbackAsync(this); 508 } 509 510 void WebTestProxyBase::SetLogConsoleOutput(bool enabled) { 511 log_console_output_ = enabled; 512 } 513 514 void WebTestProxyBase::DidDisplayAsync(const base::Closure& callback, 515 const SkBitmap& bitmap) { 516 // Verify we actually composited. 517 CHECK_NE(0, bitmap.info().fWidth); 518 CHECK_NE(0, bitmap.info().fHeight); 519 if (!callback.is_null()) 520 callback.Run(); 521 } 522 523 void WebTestProxyBase::DisplayAsyncThen(const base::Closure& callback) { 524 TRACE_EVENT0("shell", "WebTestProxyBase::DisplayAsyncThen"); 525 526 CHECK(web_widget_->isAcceleratedCompositingActive()); 527 CapturePixelsAsync(base::Bind( 528 &WebTestProxyBase::DidDisplayAsync, base::Unretained(this), callback)); 529 } 530 531 blink::WebMIDIClientMock* WebTestProxyBase::GetMIDIClientMock() { 532 if (!midi_client_.get()) 533 midi_client_.reset(new blink::WebMIDIClientMock); 534 return midi_client_.get(); 535 } 536 537 MockWebSpeechRecognizer* WebTestProxyBase::GetSpeechRecognizerMock() { 538 if (!speech_recognizer_.get()) { 539 speech_recognizer_.reset(new MockWebSpeechRecognizer()); 540 speech_recognizer_->setDelegate(delegate_); 541 } 542 return speech_recognizer_.get(); 543 } 544 545 void WebTestProxyBase::ScheduleAnimation() { 546 if (!test_interfaces_->testRunner()->TestIsRunning()) 547 return; 548 549 if (!animate_scheduled_) { 550 animate_scheduled_ = true; 551 delegate_->postDelayedTask( 552 new HostMethodTask(this, &WebTestProxyBase::AnimateNow), 1); 553 } 554 } 555 556 void WebTestProxyBase::AnimateNow() { 557 if (animate_scheduled_) { 558 animate_scheduled_ = false; 559 web_widget_->animate(0.0); 560 web_widget_->layout(); 561 } 562 } 563 564 void WebTestProxyBase::PostAccessibilityEvent(const blink::WebAXObject& obj, 565 blink::WebAXEvent event) { 566 // Only hook the accessibility events occured during the test run. 567 // This check prevents false positives in WebLeakDetector. 568 // The pending tasks in browser/renderer message queue may trigger 569 // accessibility events, 570 // and AccessibilityController will hold on to their target nodes if we don't 571 // ignore them here. 572 if (!test_interfaces_->testRunner()->TestIsRunning()) 573 return; 574 575 if (event == blink::WebAXEventFocus) 576 test_interfaces_->accessibilityController()->SetFocusedElement(obj); 577 578 const char* event_name = NULL; 579 switch (event) { 580 case blink::WebAXEventActiveDescendantChanged: 581 event_name = "ActiveDescendantChanged"; 582 break; 583 case blink::WebAXEventAlert: 584 event_name = "Alert"; 585 break; 586 case blink::WebAXEventAriaAttributeChanged: 587 event_name = "AriaAttributeChanged"; 588 break; 589 case blink::WebAXEventAutocorrectionOccured: 590 event_name = "AutocorrectionOccured"; 591 break; 592 case blink::WebAXEventBlur: 593 event_name = "Blur"; 594 break; 595 case blink::WebAXEventCheckedStateChanged: 596 event_name = "CheckedStateChanged"; 597 break; 598 case blink::WebAXEventChildrenChanged: 599 event_name = "ChildrenChanged"; 600 break; 601 case blink::WebAXEventFocus: 602 event_name = "Focus"; 603 break; 604 case blink::WebAXEventHide: 605 event_name = "Hide"; 606 break; 607 case blink::WebAXEventInvalidStatusChanged: 608 event_name = "InvalidStatusChanged"; 609 break; 610 case blink::WebAXEventLayoutComplete: 611 event_name = "LayoutComplete"; 612 break; 613 case blink::WebAXEventLiveRegionChanged: 614 event_name = "LiveRegionChanged"; 615 break; 616 case blink::WebAXEventLoadComplete: 617 event_name = "LoadComplete"; 618 break; 619 case blink::WebAXEventLocationChanged: 620 event_name = "LocationChanged"; 621 break; 622 case blink::WebAXEventMenuListItemSelected: 623 event_name = "MenuListItemSelected"; 624 break; 625 case blink::WebAXEventMenuListValueChanged: 626 event_name = "MenuListValueChanged"; 627 break; 628 case blink::WebAXEventRowCollapsed: 629 event_name = "RowCollapsed"; 630 break; 631 case blink::WebAXEventRowCountChanged: 632 event_name = "RowCountChanged"; 633 break; 634 case blink::WebAXEventRowExpanded: 635 event_name = "RowExpanded"; 636 break; 637 case blink::WebAXEventScrollPositionChanged: 638 event_name = "ScrollPositionChanged"; 639 break; 640 case blink::WebAXEventScrolledToAnchor: 641 event_name = "ScrolledToAnchor"; 642 break; 643 case blink::WebAXEventSelectedChildrenChanged: 644 event_name = "SelectedChildrenChanged"; 645 break; 646 case blink::WebAXEventSelectedTextChanged: 647 event_name = "SelectedTextChanged"; 648 break; 649 case blink::WebAXEventShow: 650 event_name = "Show"; 651 break; 652 case blink::WebAXEventTextChanged: 653 event_name = "TextChanged"; 654 break; 655 case blink::WebAXEventTextInserted: 656 event_name = "TextInserted"; 657 break; 658 case blink::WebAXEventTextRemoved: 659 event_name = "TextRemoved"; 660 break; 661 case blink::WebAXEventValueChanged: 662 event_name = "ValueChanged"; 663 break; 664 default: 665 event_name = "Unknown"; 666 break; 667 } 668 669 test_interfaces_->accessibilityController()->NotificationReceived(obj, 670 event_name); 671 672 if (test_interfaces_->accessibilityController() 673 ->ShouldLogAccessibilityEvents()) { 674 std::string message("AccessibilityNotification - "); 675 message += event_name; 676 677 blink::WebNode node = obj.node(); 678 if (!node.isNull() && node.isElementNode()) { 679 blink::WebElement element = node.to<blink::WebElement>(); 680 if (element.hasAttribute("id")) { 681 message += " - id:"; 682 message += element.getAttribute("id").utf8().data(); 683 } 684 } 685 686 delegate_->printMessage(message + "\n"); 687 } 688 } 689 690 void WebTestProxyBase::StartDragging(blink::WebLocalFrame* frame, 691 const blink::WebDragData& data, 692 blink::WebDragOperationsMask mask, 693 const blink::WebImage& image, 694 const blink::WebPoint& point) { 695 // When running a test, we need to fake a drag drop operation otherwise 696 // Windows waits for real mouse events to know when the drag is over. 697 test_interfaces_->eventSender()->DoDragDrop(data, mask); 698 } 699 700 // The output from these methods in layout test mode should match that 701 // expected by the layout tests. See EditingDelegate.m in DumpRenderTree. 702 703 void WebTestProxyBase::DidChangeSelection(bool is_empty_callback) { 704 if (test_interfaces_->testRunner()->shouldDumpEditingCallbacks()) 705 delegate_->printMessage( 706 "EDITING DELEGATE: " 707 "webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n"); 708 } 709 710 void WebTestProxyBase::DidChangeContents() { 711 if (test_interfaces_->testRunner()->shouldDumpEditingCallbacks()) 712 delegate_->printMessage( 713 "EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n"); 714 } 715 716 bool WebTestProxyBase::CreateView(blink::WebLocalFrame* frame, 717 const blink::WebURLRequest& request, 718 const blink::WebWindowFeatures& features, 719 const blink::WebString& frame_name, 720 blink::WebNavigationPolicy policy, 721 bool suppress_opener) { 722 if (!test_interfaces_->testRunner()->canOpenWindows()) 723 return false; 724 if (test_interfaces_->testRunner()->shouldDumpCreateView()) 725 delegate_->printMessage(std::string("createView(") + 726 URLDescription(request.url()) + ")\n"); 727 return true; 728 } 729 730 blink::WebPlugin* WebTestProxyBase::CreatePlugin( 731 blink::WebLocalFrame* frame, 732 const blink::WebPluginParams& params) { 733 if (TestPlugin::isSupportedMimeType(params.mimeType)) 734 return TestPlugin::create(frame, params, delegate_); 735 return 0; 736 } 737 738 void WebTestProxyBase::SetStatusText(const blink::WebString& text) { 739 if (!test_interfaces_->testRunner()->shouldDumpStatusCallbacks()) 740 return; 741 delegate_->printMessage( 742 std::string("UI DELEGATE STATUS CALLBACK: setStatusText:") + 743 text.utf8().data() + "\n"); 744 } 745 746 void WebTestProxyBase::DidStopLoading() { 747 if (test_interfaces_->testRunner()->shouldDumpProgressFinishedCallback()) 748 delegate_->printMessage("postProgressFinishedNotification\n"); 749 } 750 751 void WebTestProxyBase::ShowContextMenu( 752 blink::WebLocalFrame* frame, 753 const blink::WebContextMenuData& context_menu_data) { 754 test_interfaces_->eventSender()->SetContextMenuData(context_menu_data); 755 } 756 757 blink::WebUserMediaClient* WebTestProxyBase::GetUserMediaClient() { 758 if (!user_media_client_.get()) 759 user_media_client_.reset(new MockWebUserMediaClient(delegate_)); 760 return user_media_client_.get(); 761 } 762 763 // Simulate a print by going into print mode and then exit straight away. 764 void WebTestProxyBase::PrintPage(blink::WebLocalFrame* frame) { 765 blink::WebSize page_size_in_pixels = web_widget_->size(); 766 if (page_size_in_pixels.isEmpty()) 767 return; 768 blink::WebPrintParams printParams(page_size_in_pixels); 769 frame->printBegin(printParams); 770 frame->printEnd(); 771 } 772 773 blink::WebNotificationPresenter* WebTestProxyBase::GetNotificationPresenter() { 774 return test_interfaces_->testRunner()->notification_presenter(); 775 } 776 777 blink::WebMIDIClient* WebTestProxyBase::GetWebMIDIClient() { 778 return GetMIDIClientMock(); 779 } 780 781 blink::WebSpeechRecognizer* WebTestProxyBase::GetSpeechRecognizer() { 782 return GetSpeechRecognizerMock(); 783 } 784 785 bool WebTestProxyBase::RequestPointerLock() { 786 return test_interfaces_->testRunner()->RequestPointerLock(); 787 } 788 789 void WebTestProxyBase::RequestPointerUnlock() { 790 test_interfaces_->testRunner()->RequestPointerUnlock(); 791 } 792 793 bool WebTestProxyBase::IsPointerLocked() { 794 return test_interfaces_->testRunner()->isPointerLocked(); 795 } 796 797 void WebTestProxyBase::DidFocus() { 798 delegate_->setFocus(this, true); 799 } 800 801 void WebTestProxyBase::DidBlur() { 802 delegate_->setFocus(this, false); 803 } 804 805 void WebTestProxyBase::SetToolTipText(const blink::WebString& text, 806 blink::WebTextDirection direction) { 807 test_interfaces_->testRunner()->setToolTipText(text); 808 } 809 810 void WebTestProxyBase::DidOpenChooser() { 811 chooser_count_++; 812 } 813 814 void WebTestProxyBase::DidCloseChooser() { 815 chooser_count_--; 816 } 817 818 bool WebTestProxyBase::IsChooserShown() { 819 return 0 < chooser_count_; 820 } 821 822 void WebTestProxyBase::LoadURLExternally( 823 blink::WebLocalFrame* frame, 824 const blink::WebURLRequest& request, 825 blink::WebNavigationPolicy policy, 826 const blink::WebString& suggested_name) { 827 if (test_interfaces_->testRunner()->shouldWaitUntilExternalURLLoad()) { 828 if (policy == blink::WebNavigationPolicyDownload) { 829 delegate_->printMessage( 830 std::string("Downloading URL with suggested filename \"") + 831 suggested_name.utf8() + "\"\n"); 832 } else { 833 delegate_->printMessage(std::string("Loading URL externally - \"") + 834 URLDescription(request.url()) + "\"\n"); 835 } 836 delegate_->testFinished(); 837 } 838 } 839 840 void WebTestProxyBase::DidStartProvisionalLoad(blink::WebLocalFrame* frame) { 841 if (!test_interfaces_->testRunner()->topLoadingFrame()) 842 test_interfaces_->testRunner()->setTopLoadingFrame(frame, false); 843 844 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 845 PrintFrameDescription(delegate_, frame); 846 delegate_->printMessage(" - didStartProvisionalLoadForFrame\n"); 847 } 848 849 if (test_interfaces_->testRunner() 850 ->shouldDumpUserGestureInFrameLoadCallbacks()) { 851 PrintFrameuserGestureStatus( 852 delegate_, frame, " - in didStartProvisionalLoadForFrame\n"); 853 } 854 } 855 856 void WebTestProxyBase::DidReceiveServerRedirectForProvisionalLoad( 857 blink::WebLocalFrame* frame) { 858 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 859 PrintFrameDescription(delegate_, frame); 860 delegate_->printMessage( 861 " - didReceiveServerRedirectForProvisionalLoadForFrame\n"); 862 } 863 } 864 865 bool WebTestProxyBase::DidFailProvisionalLoad(blink::WebLocalFrame* frame, 866 const blink::WebURLError& error) { 867 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 868 PrintFrameDescription(delegate_, frame); 869 delegate_->printMessage(" - didFailProvisionalLoadWithError\n"); 870 } 871 LocationChangeDone(frame); 872 return !frame->provisionalDataSource(); 873 } 874 875 void WebTestProxyBase::DidCommitProvisionalLoad( 876 blink::WebLocalFrame* frame, 877 const blink::WebHistoryItem& history_item, 878 blink::WebHistoryCommitType history_type) { 879 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 880 PrintFrameDescription(delegate_, frame); 881 delegate_->printMessage(" - didCommitLoadForFrame\n"); 882 } 883 } 884 885 void WebTestProxyBase::DidReceiveTitle(blink::WebLocalFrame* frame, 886 const blink::WebString& title, 887 blink::WebTextDirection direction) { 888 blink::WebCString title8 = title.utf8(); 889 890 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 891 PrintFrameDescription(delegate_, frame); 892 delegate_->printMessage(std::string(" - didReceiveTitle: ") + 893 title8.data() + "\n"); 894 } 895 896 if (test_interfaces_->testRunner()->shouldDumpTitleChanges()) 897 delegate_->printMessage(std::string("TITLE CHANGED: '") + title8.data() + 898 "'\n"); 899 } 900 901 void WebTestProxyBase::DidChangeIcon(blink::WebLocalFrame* frame, 902 blink::WebIconURL::Type icon_type) { 903 if (test_interfaces_->testRunner()->shouldDumpIconChanges()) { 904 PrintFrameDescription(delegate_, frame); 905 delegate_->printMessage(std::string(" - didChangeIcons\n")); 906 } 907 } 908 909 void WebTestProxyBase::DidFinishDocumentLoad(blink::WebLocalFrame* frame) { 910 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 911 PrintFrameDescription(delegate_, frame); 912 delegate_->printMessage(" - didFinishDocumentLoadForFrame\n"); 913 } else { 914 unsigned pendingUnloadEvents = frame->unloadListenerCount(); 915 if (pendingUnloadEvents) { 916 PrintFrameDescription(delegate_, frame); 917 char buffer[100]; 918 snprintf(buffer, 919 sizeof(buffer), 920 " - has %u onunload handler(s)\n", 921 pendingUnloadEvents); 922 delegate_->printMessage(buffer); 923 } 924 } 925 } 926 927 void WebTestProxyBase::DidHandleOnloadEvents(blink::WebLocalFrame* frame) { 928 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 929 PrintFrameDescription(delegate_, frame); 930 delegate_->printMessage(" - didHandleOnloadEventsForFrame\n"); 931 } 932 } 933 934 void WebTestProxyBase::DidFailLoad(blink::WebLocalFrame* frame, 935 const blink::WebURLError& error) { 936 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 937 PrintFrameDescription(delegate_, frame); 938 delegate_->printMessage(" - didFailLoadWithError\n"); 939 } 940 LocationChangeDone(frame); 941 } 942 943 void WebTestProxyBase::DidFinishLoad(blink::WebLocalFrame* frame) { 944 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) { 945 PrintFrameDescription(delegate_, frame); 946 delegate_->printMessage(" - didFinishLoadForFrame\n"); 947 } 948 LocationChangeDone(frame); 949 } 950 951 void WebTestProxyBase::DidDetectXSS(blink::WebLocalFrame* frame, 952 const blink::WebURL& insecure_url, 953 bool did_block_entire_page) { 954 if (test_interfaces_->testRunner()->shouldDumpFrameLoadCallbacks()) 955 delegate_->printMessage("didDetectXSS\n"); 956 } 957 958 void WebTestProxyBase::DidDispatchPingLoader(blink::WebLocalFrame* frame, 959 const blink::WebURL& url) { 960 if (test_interfaces_->testRunner()->shouldDumpPingLoaderCallbacks()) 961 delegate_->printMessage(std::string("PingLoader dispatched to '") + 962 URLDescription(url).c_str() + "'.\n"); 963 } 964 965 void WebTestProxyBase::WillRequestResource( 966 blink::WebLocalFrame* frame, 967 const blink::WebCachedURLRequest& request) { 968 if (test_interfaces_->testRunner()->shouldDumpResourceRequestCallbacks()) { 969 PrintFrameDescription(delegate_, frame); 970 delegate_->printMessage(std::string(" - ") + 971 request.initiatorName().utf8().data()); 972 delegate_->printMessage(std::string(" requested '") + 973 URLDescription(request.urlRequest().url()).c_str() + 974 "'\n"); 975 } 976 } 977 978 void WebTestProxyBase::WillSendRequest( 979 blink::WebLocalFrame* frame, 980 unsigned identifier, 981 blink::WebURLRequest& request, 982 const blink::WebURLResponse& redirect_response) { 983 // Need to use GURL for host() and SchemeIs() 984 GURL url = request.url(); 985 std::string request_url = url.possibly_invalid_spec(); 986 987 GURL main_document_url = request.firstPartyForCookies(); 988 989 if (redirect_response.isNull() && 990 (test_interfaces_->testRunner()->shouldDumpResourceLoadCallbacks() || 991 test_interfaces_->testRunner()->shouldDumpResourcePriorities())) { 992 DCHECK(resource_identifier_map_.find(identifier) == 993 resource_identifier_map_.end()); 994 resource_identifier_map_[identifier] = 995 DescriptionSuitableForTestResult(request_url); 996 } 997 998 if (test_interfaces_->testRunner()->shouldDumpResourceLoadCallbacks()) { 999 if (resource_identifier_map_.find(identifier) == 1000 resource_identifier_map_.end()) 1001 delegate_->printMessage("<unknown>"); 1002 else 1003 delegate_->printMessage(resource_identifier_map_[identifier]); 1004 delegate_->printMessage(" - willSendRequest <NSURLRequest URL "); 1005 delegate_->printMessage( 1006 DescriptionSuitableForTestResult(request_url).c_str()); 1007 delegate_->printMessage(", main document URL "); 1008 delegate_->printMessage(URLDescription(main_document_url).c_str()); 1009 delegate_->printMessage(", http method "); 1010 delegate_->printMessage(request.httpMethod().utf8().data()); 1011 delegate_->printMessage("> redirectResponse "); 1012 PrintResponseDescription(delegate_, redirect_response); 1013 delegate_->printMessage("\n"); 1014 } 1015 1016 if (test_interfaces_->testRunner()->shouldDumpResourcePriorities()) { 1017 delegate_->printMessage( 1018 DescriptionSuitableForTestResult(request_url).c_str()); 1019 delegate_->printMessage(" has priority "); 1020 delegate_->printMessage(PriorityDescription(request.priority())); 1021 delegate_->printMessage("\n"); 1022 } 1023 1024 if (test_interfaces_->testRunner()->httpHeadersToClear()) { 1025 const std::set<std::string>* clearHeaders = 1026 test_interfaces_->testRunner()->httpHeadersToClear(); 1027 for (std::set<std::string>::const_iterator header = clearHeaders->begin(); 1028 header != clearHeaders->end(); 1029 ++header) 1030 request.clearHTTPHeaderField(blink::WebString::fromUTF8(*header)); 1031 } 1032 1033 std::string host = url.host(); 1034 if (!host.empty() && (url.SchemeIs("http") || url.SchemeIs("https"))) { 1035 if (!IsLocalHost(host) && !HostIsUsedBySomeTestsToGenerateError(host) && 1036 ((!main_document_url.SchemeIs("http") && 1037 !main_document_url.SchemeIs("https")) || 1038 IsLocalHost(main_document_url.host())) && 1039 !delegate_->allowExternalPages()) { 1040 delegate_->printMessage(std::string("Blocked access to external URL ") + 1041 request_url + "\n"); 1042 BlockRequest(request); 1043 return; 1044 } 1045 } 1046 1047 // Set the new substituted URL. 1048 request.setURL(delegate_->rewriteLayoutTestsURL(request.url().spec())); 1049 } 1050 1051 void WebTestProxyBase::DidReceiveResponse( 1052 blink::WebLocalFrame* frame, 1053 unsigned identifier, 1054 const blink::WebURLResponse& response) { 1055 if (test_interfaces_->testRunner()->shouldDumpResourceLoadCallbacks()) { 1056 if (resource_identifier_map_.find(identifier) == 1057 resource_identifier_map_.end()) 1058 delegate_->printMessage("<unknown>"); 1059 else 1060 delegate_->printMessage(resource_identifier_map_[identifier]); 1061 delegate_->printMessage(" - didReceiveResponse "); 1062 PrintResponseDescription(delegate_, response); 1063 delegate_->printMessage("\n"); 1064 } 1065 if (test_interfaces_->testRunner()->shouldDumpResourceResponseMIMETypes()) { 1066 GURL url = response.url(); 1067 blink::WebString mime_type = response.mimeType(); 1068 delegate_->printMessage(url.ExtractFileName()); 1069 delegate_->printMessage(" has MIME type "); 1070 // Simulate NSURLResponse's mapping of empty/unknown MIME types to 1071 // application/octet-stream 1072 delegate_->printMessage(mime_type.isEmpty() ? "application/octet-stream" 1073 : mime_type.utf8().data()); 1074 delegate_->printMessage("\n"); 1075 } 1076 } 1077 1078 void WebTestProxyBase::DidChangeResourcePriority( 1079 blink::WebLocalFrame* frame, 1080 unsigned identifier, 1081 const blink::WebURLRequest::Priority& priority, 1082 int intra_priority_value) { 1083 if (test_interfaces_->testRunner()->shouldDumpResourcePriorities()) { 1084 if (resource_identifier_map_.find(identifier) == 1085 resource_identifier_map_.end()) 1086 delegate_->printMessage("<unknown>"); 1087 else 1088 delegate_->printMessage(resource_identifier_map_[identifier]); 1089 delegate_->printMessage(" changed priority to "); 1090 delegate_->printMessage(PriorityDescription(priority)); 1091 char buffer[64]; 1092 snprintf( 1093 buffer, sizeof(buffer), ", intra_priority %d", intra_priority_value); 1094 delegate_->printMessage(buffer); 1095 delegate_->printMessage("\n"); 1096 } 1097 } 1098 1099 void WebTestProxyBase::DidFinishResourceLoad(blink::WebLocalFrame* frame, 1100 unsigned identifier) { 1101 if (test_interfaces_->testRunner()->shouldDumpResourceLoadCallbacks()) { 1102 if (resource_identifier_map_.find(identifier) == 1103 resource_identifier_map_.end()) 1104 delegate_->printMessage("<unknown>"); 1105 else 1106 delegate_->printMessage(resource_identifier_map_[identifier]); 1107 delegate_->printMessage(" - didFinishLoading\n"); 1108 } 1109 resource_identifier_map_.erase(identifier); 1110 } 1111 1112 void WebTestProxyBase::DidAddMessageToConsole( 1113 const blink::WebConsoleMessage& message, 1114 const blink::WebString& source_name, 1115 unsigned source_line) { 1116 // This matches win DumpRenderTree's UIDelegate.cpp. 1117 if (!log_console_output_) 1118 return; 1119 std::string level; 1120 switch (message.level) { 1121 case blink::WebConsoleMessage::LevelDebug: 1122 level = "DEBUG"; 1123 break; 1124 case blink::WebConsoleMessage::LevelLog: 1125 level = "MESSAGE"; 1126 break; 1127 case blink::WebConsoleMessage::LevelInfo: 1128 level = "INFO"; 1129 break; 1130 case blink::WebConsoleMessage::LevelWarning: 1131 level = "WARNING"; 1132 break; 1133 case blink::WebConsoleMessage::LevelError: 1134 level = "ERROR"; 1135 break; 1136 } 1137 delegate_->printMessage(std::string("CONSOLE ") + level + ": "); 1138 if (source_line) { 1139 char buffer[40]; 1140 snprintf(buffer, sizeof(buffer), "line %d: ", source_line); 1141 delegate_->printMessage(buffer); 1142 } 1143 if (!message.text.isEmpty()) { 1144 std::string new_message; 1145 new_message = message.text.utf8(); 1146 size_t file_protocol = new_message.find("file://"); 1147 if (file_protocol != std::string::npos) { 1148 new_message = new_message.substr(0, file_protocol) + 1149 URLSuitableForTestResult(new_message.substr(file_protocol)); 1150 } 1151 delegate_->printMessage(new_message); 1152 } 1153 delegate_->printMessage(std::string("\n")); 1154 } 1155 1156 void WebTestProxyBase::LocationChangeDone(blink::WebFrame* frame) { 1157 if (frame != test_interfaces_->testRunner()->topLoadingFrame()) 1158 return; 1159 test_interfaces_->testRunner()->setTopLoadingFrame(frame, true); 1160 } 1161 1162 blink::WebNavigationPolicy WebTestProxyBase::DecidePolicyForNavigation( 1163 blink::WebLocalFrame* frame, 1164 blink::WebDataSource::ExtraData* data, 1165 const blink::WebURLRequest& request, 1166 blink::WebNavigationType type, 1167 blink::WebNavigationPolicy default_policy, 1168 bool is_redirect) { 1169 blink::WebNavigationPolicy result; 1170 if (!test_interfaces_->testRunner()->policyDelegateEnabled()) 1171 return default_policy; 1172 1173 delegate_->printMessage(std::string("Policy delegate: attempt to load ") + 1174 URLDescription(request.url()) + 1175 " with navigation type '" + 1176 WebNavigationTypeToString(type) + "'\n"); 1177 if (test_interfaces_->testRunner()->policyDelegateIsPermissive()) 1178 result = blink::WebNavigationPolicyCurrentTab; 1179 else 1180 result = blink::WebNavigationPolicyIgnore; 1181 1182 if (test_interfaces_->testRunner()->policyDelegateShouldNotifyDone()) 1183 test_interfaces_->testRunner()->policyDelegateDone(); 1184 return result; 1185 } 1186 1187 bool WebTestProxyBase::WillCheckAndDispatchMessageEvent( 1188 blink::WebLocalFrame* source_frame, 1189 blink::WebFrame* target_frame, 1190 blink::WebSecurityOrigin target, 1191 blink::WebDOMMessageEvent event) { 1192 if (test_interfaces_->testRunner()->shouldInterceptPostMessage()) { 1193 delegate_->printMessage("intercepted postMessage\n"); 1194 return true; 1195 } 1196 1197 return false; 1198 } 1199 1200 void WebTestProxyBase::PostSpellCheckEvent(const blink::WebString& event_name) { 1201 if (test_interfaces_->testRunner()->shouldDumpSpellCheckCallbacks()) { 1202 delegate_->printMessage(std::string("SpellCheckEvent: ") + 1203 event_name.utf8().data() + "\n"); 1204 } 1205 } 1206 1207 void WebTestProxyBase::ResetInputMethod() { 1208 // If a composition text exists, then we need to let the browser process 1209 // to cancel the input method's ongoing composition session. 1210 if (web_widget_) 1211 web_widget_->confirmComposition(); 1212 } 1213 1214 blink::WebString WebTestProxyBase::acceptLanguages() { 1215 return blink::WebString::fromUTF8(accept_languages_); 1216 } 1217 1218 MockWebPushClient* WebTestProxyBase::GetPushClientMock() { 1219 if (!push_client_.get()) 1220 push_client_.reset(new MockWebPushClient); 1221 return push_client_.get(); 1222 } 1223 1224 blink::WebPushClient* WebTestProxyBase::GetWebPushClient() { 1225 return GetPushClientMock(); 1226 } 1227 1228 } // namespace content 1229