| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/test_runner/web_test_proxy.h" | 5 #include "components/test_runner/web_test_proxy.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <cctype> | 10 #include <cctype> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "components/test_runner/mock_screen_orientation_client.h" | 24 #include "components/test_runner/mock_screen_orientation_client.h" |
| 25 #include "components/test_runner/mock_web_speech_recognizer.h" | 25 #include "components/test_runner/mock_web_speech_recognizer.h" |
| 26 #include "components/test_runner/spell_check_client.h" | 26 #include "components/test_runner/spell_check_client.h" |
| 27 #include "components/test_runner/test_common.h" | 27 #include "components/test_runner/test_common.h" |
| 28 #include "components/test_runner/test_interfaces.h" | 28 #include "components/test_runner/test_interfaces.h" |
| 29 #include "components/test_runner/test_plugin.h" | 29 #include "components/test_runner/test_plugin.h" |
| 30 #include "components/test_runner/test_runner.h" | 30 #include "components/test_runner/test_runner.h" |
| 31 #include "components/test_runner/web_test_delegate.h" | 31 #include "components/test_runner/web_test_delegate.h" |
| 32 #include "components/test_runner/web_test_interfaces.h" | 32 #include "components/test_runner/web_test_interfaces.h" |
| 33 #include "components/test_runner/web_test_runner.h" | 33 #include "components/test_runner/web_test_runner.h" |
| 34 // FIXME: Including platform_canvas.h here is a layering violation. | |
| 35 #include "skia/ext/platform_canvas.h" | |
| 36 #include "third_party/WebKit/public/platform/Platform.h" | |
| 37 #include "third_party/WebKit/public/platform/WebClipboard.h" | |
| 38 #include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallbac
k.h" | |
| 39 #include "third_party/WebKit/public/platform/WebLayoutAndPaintAsyncCallback.h" | 34 #include "third_party/WebKit/public/platform/WebLayoutAndPaintAsyncCallback.h" |
| 40 #include "third_party/WebKit/public/platform/WebURLError.h" | 35 #include "third_party/WebKit/public/platform/WebURLError.h" |
| 41 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 36 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| 42 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 37 #include "third_party/WebKit/public/platform/WebURLResponse.h" |
| 43 #include "third_party/WebKit/public/web/WebAXEnums.h" | 38 #include "third_party/WebKit/public/web/WebAXEnums.h" |
| 44 #include "third_party/WebKit/public/web/WebAXObject.h" | 39 #include "third_party/WebKit/public/web/WebAXObject.h" |
| 45 #include "third_party/WebKit/public/web/WebDocument.h" | 40 #include "third_party/WebKit/public/web/WebDocument.h" |
| 46 #include "third_party/WebKit/public/web/WebElement.h" | 41 #include "third_party/WebKit/public/web/WebElement.h" |
| 47 #include "third_party/WebKit/public/web/WebHistoryItem.h" | 42 #include "third_party/WebKit/public/web/WebHistoryItem.h" |
| 48 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 43 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 49 #include "third_party/WebKit/public/web/WebNode.h" | 44 #include "third_party/WebKit/public/web/WebNode.h" |
| 50 #include "third_party/WebKit/public/web/WebPagePopup.h" | 45 #include "third_party/WebKit/public/web/WebPagePopup.h" |
| 51 #include "third_party/WebKit/public/web/WebPluginParams.h" | 46 #include "third_party/WebKit/public/web/WebPluginParams.h" |
| 52 #include "third_party/WebKit/public/web/WebPrintParams.h" | 47 #include "third_party/WebKit/public/web/WebPrintParams.h" |
| 53 #include "third_party/WebKit/public/web/WebRange.h" | 48 #include "third_party/WebKit/public/web/WebRange.h" |
| 54 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 49 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
| 55 #include "third_party/WebKit/public/web/WebView.h" | 50 #include "third_party/WebKit/public/web/WebView.h" |
| 56 #include "third_party/WebKit/public/web/WebWidgetClient.h" | 51 #include "third_party/WebKit/public/web/WebWidgetClient.h" |
| 57 | 52 |
| 58 namespace test_runner { | 53 namespace test_runner { |
| 59 | 54 |
| 60 namespace { | 55 namespace { |
| 61 | 56 |
| 62 class CaptureCallback : public blink::WebCompositeAndReadbackAsyncCallback { | |
| 63 public: | |
| 64 CaptureCallback(const base::Callback<void(const SkBitmap&)>& callback); | |
| 65 virtual ~CaptureCallback(); | |
| 66 | |
| 67 void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; } | |
| 68 void set_popup_position(const gfx::Point& position) { | |
| 69 popup_position_ = position; | |
| 70 } | |
| 71 | |
| 72 // WebCompositeAndReadbackAsyncCallback implementation. | |
| 73 void didCompositeAndReadback(const SkBitmap& bitmap) override; | |
| 74 | |
| 75 private: | |
| 76 base::Callback<void(const SkBitmap&)> callback_; | |
| 77 SkBitmap main_bitmap_; | |
| 78 bool wait_for_popup_; | |
| 79 gfx::Point popup_position_; | |
| 80 }; | |
| 81 | |
| 82 class LayoutAndPaintCallback : public blink::WebLayoutAndPaintAsyncCallback { | 57 class LayoutAndPaintCallback : public blink::WebLayoutAndPaintAsyncCallback { |
| 83 public: | 58 public: |
| 84 LayoutAndPaintCallback(const base::Closure& callback) | 59 LayoutAndPaintCallback(const base::Closure& callback) |
| 85 : callback_(callback), wait_for_popup_(false) { | 60 : callback_(callback), wait_for_popup_(false) { |
| 86 } | 61 } |
| 87 virtual ~LayoutAndPaintCallback() { | 62 virtual ~LayoutAndPaintCallback() { |
| 88 } | 63 } |
| 89 | 64 |
| 90 void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; } | 65 void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; } |
| 91 | 66 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } | 120 } |
| 146 | 121 |
| 147 blink::WebView* WebTestProxyBase::GetWebView() const { | 122 blink::WebView* WebTestProxyBase::GetWebView() const { |
| 148 DCHECK(web_widget_); | 123 DCHECK(web_widget_); |
| 149 // TestRunner does not support popup widgets. So |web_widget|_ is always a | 124 // TestRunner does not support popup widgets. So |web_widget|_ is always a |
| 150 // WebView. | 125 // WebView. |
| 151 return static_cast<blink::WebView*>(web_widget_); | 126 return static_cast<blink::WebView*>(web_widget_); |
| 152 } | 127 } |
| 153 | 128 |
| 154 void WebTestProxyBase::Reset() { | 129 void WebTestProxyBase::Reset() { |
| 155 drag_image_.reset(); | |
| 156 animate_scheduled_ = false; | 130 animate_scheduled_ = false; |
| 157 } | 131 } |
| 158 | 132 |
| 159 blink::WebSpellCheckClient* WebTestProxyBase::GetSpellCheckClient() const { | 133 blink::WebSpellCheckClient* WebTestProxyBase::GetSpellCheckClient() const { |
| 160 return spellcheck_.get(); | 134 return spellcheck_.get(); |
| 161 } | 135 } |
| 162 | 136 |
| 163 bool WebTestProxyBase::RunFileChooser( | 137 bool WebTestProxyBase::RunFileChooser( |
| 164 const blink::WebFileChooserParams& params, | 138 const blink::WebFileChooserParams& params, |
| 165 blink::WebFileChooserCompletion* completion) { | 139 blink::WebFileChooserCompletion* completion) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 195 delegate_->PrintMessage("ValidationMessageClient: main-message=" + | 169 delegate_->PrintMessage("ValidationMessageClient: main-message=" + |
| 196 base::UTF16ToUTF8(wrapped_main_text) + | 170 base::UTF16ToUTF8(wrapped_main_text) + |
| 197 " sub-message=" + | 171 " sub-message=" + |
| 198 base::UTF16ToUTF8(wrapped_sub_text) + "\n"); | 172 base::UTF16ToUTF8(wrapped_sub_text) + "\n"); |
| 199 } | 173 } |
| 200 | 174 |
| 201 std::string WebTestProxyBase::DumpBackForwardLists() { | 175 std::string WebTestProxyBase::DumpBackForwardLists() { |
| 202 return DumpAllBackForwardLists(test_interfaces_, delegate_); | 176 return DumpAllBackForwardLists(test_interfaces_, delegate_); |
| 203 } | 177 } |
| 204 | 178 |
| 205 void WebTestProxyBase::DrawSelectionRect(SkCanvas* canvas) { | |
| 206 // See if we need to draw the selection bounds rect. Selection bounds | |
| 207 // rect is the rect enclosing the (possibly transformed) selection. | |
| 208 // The rect should be drawn after everything is laid out and painted. | |
| 209 if (!test_interfaces_->GetTestRunner()->shouldDumpSelectionRect()) | |
| 210 return; | |
| 211 // If there is a selection rect - draw a red 1px border enclosing rect | |
| 212 blink::WebRect wr = GetWebView()->mainFrame()->selectionBoundsRect(); | |
| 213 if (wr.isEmpty()) | |
| 214 return; | |
| 215 // Render a red rectangle bounding selection rect | |
| 216 SkPaint paint; | |
| 217 paint.setColor(0xFFFF0000); // Fully opaque red | |
| 218 paint.setStyle(SkPaint::kStroke_Style); | |
| 219 paint.setFlags(SkPaint::kAntiAlias_Flag); | |
| 220 paint.setStrokeWidth(1.0f); | |
| 221 SkIRect rect; // Bounding rect | |
| 222 rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height); | |
| 223 canvas->drawIRect(rect, paint); | |
| 224 } | |
| 225 | |
| 226 void WebTestProxyBase::CopyImageAtAndCapturePixels( | |
| 227 int x, int y, const base::Callback<void(const SkBitmap&)>& callback) { | |
| 228 DCHECK(!callback.is_null()); | |
| 229 uint64_t sequence_number = blink::Platform::current()->clipboard()-> | |
| 230 sequenceNumber(blink::WebClipboard::Buffer()); | |
| 231 GetWebView()->copyImageAt(blink::WebPoint(x, y)); | |
| 232 if (sequence_number == blink::Platform::current()->clipboard()-> | |
| 233 sequenceNumber(blink::WebClipboard::Buffer())) { | |
| 234 SkBitmap emptyBitmap; | |
| 235 callback.Run(emptyBitmap); | |
| 236 return; | |
| 237 } | |
| 238 | |
| 239 blink::WebData data = blink::Platform::current()->clipboard()->readImage( | |
| 240 blink::WebClipboard::Buffer()); | |
| 241 blink::WebImage image = blink::WebImage::fromData(data, blink::WebSize()); | |
| 242 const SkBitmap& bitmap = image.getSkBitmap(); | |
| 243 SkAutoLockPixels autoLock(bitmap); | |
| 244 callback.Run(bitmap); | |
| 245 } | |
| 246 | |
| 247 void WebTestProxyBase::CapturePixelsForPrinting( | |
| 248 const base::Callback<void(const SkBitmap&)>& callback) { | |
| 249 web_widget_->updateAllLifecyclePhases(); | |
| 250 | |
| 251 blink::WebSize page_size_in_pixels = web_widget_->size(); | |
| 252 blink::WebFrame* web_frame = GetWebView()->mainFrame(); | |
| 253 | |
| 254 int page_count = web_frame->printBegin(page_size_in_pixels); | |
| 255 int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1; | |
| 256 | |
| 257 bool is_opaque = false; | |
| 258 skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::TryCreateBitmapCanvas( | |
| 259 page_size_in_pixels.width, totalHeight, is_opaque))); | |
| 260 if (!canvas) { | |
| 261 callback.Run(SkBitmap()); | |
| 262 return; | |
| 263 } | |
| 264 web_frame->printPagesWithBoundaries(canvas.get(), page_size_in_pixels); | |
| 265 web_frame->printEnd(); | |
| 266 | |
| 267 DrawSelectionRect(canvas.get()); | |
| 268 const SkBitmap bitmap = skia::ReadPixels(canvas.get()); | |
| 269 callback.Run(bitmap); | |
| 270 } | |
| 271 | |
| 272 CaptureCallback::CaptureCallback( | |
| 273 const base::Callback<void(const SkBitmap&)>& callback) | |
| 274 : callback_(callback), wait_for_popup_(false) { | |
| 275 } | |
| 276 | |
| 277 CaptureCallback::~CaptureCallback() { | |
| 278 } | |
| 279 | |
| 280 void CaptureCallback::didCompositeAndReadback(const SkBitmap& bitmap) { | |
| 281 TRACE_EVENT2("shell", | |
| 282 "CaptureCallback::didCompositeAndReadback", | |
| 283 "x", | |
| 284 bitmap.info().width(), | |
| 285 "y", | |
| 286 bitmap.info().height()); | |
| 287 if (!wait_for_popup_) { | |
| 288 callback_.Run(bitmap); | |
| 289 delete this; | |
| 290 return; | |
| 291 } | |
| 292 if (main_bitmap_.isNull()) { | |
| 293 bitmap.deepCopyTo(&main_bitmap_); | |
| 294 return; | |
| 295 } | |
| 296 SkCanvas canvas(main_bitmap_); | |
| 297 canvas.drawBitmap(bitmap, popup_position_.x(), popup_position_.y()); | |
| 298 callback_.Run(main_bitmap_); | |
| 299 delete this; | |
| 300 } | |
| 301 | |
| 302 void WebTestProxyBase::CapturePixelsAsync( | |
| 303 const base::Callback<void(const SkBitmap&)>& callback) { | |
| 304 TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync"); | |
| 305 DCHECK(!callback.is_null()); | |
| 306 | |
| 307 if (test_interfaces_->GetTestRunner()->shouldDumpDragImage()) { | |
| 308 if (drag_image_.isNull()) { | |
| 309 // This means the test called dumpDragImage but did not initiate a drag. | |
| 310 // Return a blank image so that the test fails. | |
| 311 SkBitmap bitmap; | |
| 312 bitmap.allocN32Pixels(1, 1); | |
| 313 { | |
| 314 SkAutoLockPixels lock(bitmap); | |
| 315 bitmap.eraseColor(0); | |
| 316 } | |
| 317 callback.Run(bitmap); | |
| 318 return; | |
| 319 } | |
| 320 | |
| 321 callback.Run(drag_image_.getSkBitmap()); | |
| 322 return; | |
| 323 } | |
| 324 | |
| 325 if (test_interfaces_->GetTestRunner()->isPrinting()) { | |
| 326 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 327 FROM_HERE, base::Bind(&WebTestProxyBase::CapturePixelsForPrinting, | |
| 328 base::Unretained(this), callback)); | |
| 329 return; | |
| 330 } | |
| 331 | |
| 332 CaptureCallback* capture_callback = new CaptureCallback(base::Bind( | |
| 333 &WebTestProxyBase::DidCapturePixelsAsync, base::Unretained(this), | |
| 334 callback)); | |
| 335 web_widget_->compositeAndReadbackAsync(capture_callback); | |
| 336 if (blink::WebPagePopup* popup = web_widget_->pagePopup()) { | |
| 337 capture_callback->set_wait_for_popup(true); | |
| 338 capture_callback->set_popup_position( | |
| 339 delegate_->ConvertDIPToNative(popup->positionRelativeToOwner())); | |
| 340 popup->compositeAndReadbackAsync(capture_callback); | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 void WebTestProxyBase::DidCapturePixelsAsync( | |
| 345 const base::Callback<void(const SkBitmap&)>& callback, | |
| 346 const SkBitmap& bitmap) { | |
| 347 SkCanvas canvas(bitmap); | |
| 348 DrawSelectionRect(&canvas); | |
| 349 if (!callback.is_null()) | |
| 350 callback.Run(bitmap); | |
| 351 } | |
| 352 | |
| 353 void LayoutAndPaintCallback::didLayoutAndPaint() { | 179 void LayoutAndPaintCallback::didLayoutAndPaint() { |
| 354 TRACE_EVENT0("shell", "LayoutAndPaintCallback::didLayoutAndPaint"); | 180 TRACE_EVENT0("shell", "LayoutAndPaintCallback::didLayoutAndPaint"); |
| 355 if (wait_for_popup_) { | 181 if (wait_for_popup_) { |
| 356 wait_for_popup_ = false; | 182 wait_for_popup_ = false; |
| 357 return; | 183 return; |
| 358 } | 184 } |
| 359 | 185 |
| 360 if (!callback_.is_null()) | 186 if (!callback_.is_null()) |
| 361 callback_.Run(); | 187 callback_.Run(); |
| 362 delete this; | 188 delete this; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 popup->updateAllLifecyclePhases(); | 248 popup->updateAllLifecyclePhases(); |
| 423 } | 249 } |
| 424 } | 250 } |
| 425 } | 251 } |
| 426 | 252 |
| 427 void WebTestProxyBase::StartDragging(blink::WebLocalFrame* frame, | 253 void WebTestProxyBase::StartDragging(blink::WebLocalFrame* frame, |
| 428 const blink::WebDragData& data, | 254 const blink::WebDragData& data, |
| 429 blink::WebDragOperationsMask mask, | 255 blink::WebDragOperationsMask mask, |
| 430 const blink::WebImage& image, | 256 const blink::WebImage& image, |
| 431 const blink::WebPoint& point) { | 257 const blink::WebPoint& point) { |
| 432 if (test_interfaces_->GetTestRunner()->shouldDumpDragImage()) { | 258 test_interfaces_->GetTestRunner()->setDragImage(image); |
| 433 if (drag_image_.isNull()) | 259 |
| 434 drag_image_ = image; | |
| 435 } | |
| 436 // When running a test, we need to fake a drag drop operation otherwise | 260 // When running a test, we need to fake a drag drop operation otherwise |
| 437 // Windows waits for real mouse events to know when the drag is over. | 261 // Windows waits for real mouse events to know when the drag is over. |
| 438 test_interfaces_->GetEventSender()->DoDragDrop(data, mask); | 262 test_interfaces_->GetEventSender()->DoDragDrop(data, mask); |
| 439 } | 263 } |
| 440 | 264 |
| 441 // The output from these methods in layout test mode should match that | 265 // The output from these methods in layout test mode should match that |
| 442 // expected by the layout tests. See EditingDelegate.m in DumpRenderTree. | 266 // expected by the layout tests. See EditingDelegate.m in DumpRenderTree. |
| 443 | 267 |
| 444 void WebTestProxyBase::DidChangeContents() { | 268 void WebTestProxyBase::DidChangeContents() { |
| 445 if (test_interfaces_->GetTestRunner()->shouldDumpEditingCallbacks()) | 269 if (test_interfaces_->GetTestRunner()->shouldDumpEditingCallbacks()) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 if (web_widget_) | 347 if (web_widget_) |
| 524 web_widget_->confirmComposition(); | 348 web_widget_->confirmComposition(); |
| 525 } | 349 } |
| 526 | 350 |
| 527 blink::WebString WebTestProxyBase::acceptLanguages() { | 351 blink::WebString WebTestProxyBase::acceptLanguages() { |
| 528 return blink::WebString::fromUTF8( | 352 return blink::WebString::fromUTF8( |
| 529 test_interfaces_->GetTestRunner()->GetAcceptLanguages()); | 353 test_interfaces_->GetTestRunner()->GetAcceptLanguages()); |
| 530 } | 354 } |
| 531 | 355 |
| 532 } // namespace test_runner | 356 } // namespace test_runner |
| OLD | NEW |