OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "base/base64.h" | 8 #include "base/base64.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 #include "content/test/content_browser_test_utils_internal.h" | 42 #include "content/test/content_browser_test_utils_internal.h" |
43 #include "net/dns/mock_host_resolver.h" | 43 #include "net/dns/mock_host_resolver.h" |
44 #include "net/test/cert_test_util.h" | 44 #include "net/test/cert_test_util.h" |
45 #include "net/test/embedded_test_server/embedded_test_server.h" | 45 #include "net/test/embedded_test_server/embedded_test_server.h" |
46 #include "net/test/test_data_directory.h" | 46 #include "net/test/test_data_directory.h" |
47 #include "testing/gmock/include/gmock/gmock.h" | 47 #include "testing/gmock/include/gmock/gmock.h" |
48 #include "third_party/skia/include/core/SkBitmap.h" | 48 #include "third_party/skia/include/core/SkBitmap.h" |
49 #include "third_party/skia/include/core/SkColor.h" | 49 #include "third_party/skia/include/core/SkColor.h" |
50 #include "ui/base/layout.h" | 50 #include "ui/base/layout.h" |
51 #include "ui/compositor/compositor_switches.h" | 51 #include "ui/compositor/compositor_switches.h" |
52 #include "ui/gfx/codec/jpeg_codec.h" | |
52 #include "ui/gfx/codec/png_codec.h" | 53 #include "ui/gfx/codec/png_codec.h" |
53 #include "ui/gfx/geometry/rect.h" | 54 #include "ui/gfx/geometry/rect.h" |
54 #include "ui/gfx/geometry/size.h" | 55 #include "ui/gfx/geometry/size.h" |
55 #include "ui/gfx/skia_util.h" | 56 #include "ui/gfx/skia_util.h" |
57 #include "ui/snapshot/snapshot.h" | |
56 | 58 |
57 #define EXPECT_SIZE_EQ(expected, actual) \ | 59 #define EXPECT_SIZE_EQ(expected, actual) \ |
58 do { \ | 60 do { \ |
59 EXPECT_EQ((expected).width(), (actual).width()); \ | 61 EXPECT_EQ((expected).width(), (actual).width()); \ |
60 EXPECT_EQ((expected).height(), (actual).height()); \ | 62 EXPECT_EQ((expected).height(), (actual).height()); \ |
61 } while (false) | 63 } while (false) |
62 | 64 |
63 using testing::ElementsAre; | 65 using testing::ElementsAre; |
64 | 66 |
65 namespace content { | 67 namespace content { |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 namespace { | 459 namespace { |
458 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) { | 460 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) { |
459 std::string png_data; | 461 std::string png_data; |
460 if (!base::Base64Decode(base64_data, &png_data)) | 462 if (!base::Base64Decode(base64_data, &png_data)) |
461 return false; | 463 return false; |
462 return gfx::PNGCodec::Decode( | 464 return gfx::PNGCodec::Decode( |
463 reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), | 465 reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), |
464 bitmap); | 466 bitmap); |
465 } | 467 } |
466 | 468 |
469 std::unique_ptr<SkBitmap> DecodeJPEG(std::string base64_data) { | |
470 std::string jpeg_data; | |
471 if (!base::Base64Decode(base64_data, &jpeg_data)) | |
472 return nullptr; | |
473 return gfx::JPEGCodec::Decode( | |
474 reinterpret_cast<unsigned const char*>(jpeg_data.data()), | |
475 jpeg_data.size()); | |
476 } | |
477 | |
467 // Adapted from cc::ExactPixelComparator. | 478 // Adapted from cc::ExactPixelComparator. |
468 bool MatchesBitmap(const SkBitmap& expected_bmp, | 479 bool MatchesBitmap(const SkBitmap& expected_bmp, |
469 const SkBitmap& actual_bmp, | 480 const SkBitmap& actual_bmp, |
470 const gfx::Rect& matching_mask) { | 481 const gfx::Rect& matching_mask, |
482 int error_limit) { | |
471 // Number of pixels with an error | 483 // Number of pixels with an error |
472 int error_pixels_count = 0; | 484 int error_pixels_count = 0; |
473 | 485 |
474 gfx::Rect error_bounding_rect = gfx::Rect(); | 486 gfx::Rect error_bounding_rect = gfx::Rect(); |
475 | 487 |
476 // Check that bitmaps have identical dimensions. | 488 // Check that bitmaps have identical dimensions. |
477 EXPECT_EQ(expected_bmp.width(), actual_bmp.width()); | 489 EXPECT_EQ(expected_bmp.width(), actual_bmp.width()); |
478 EXPECT_EQ(expected_bmp.height(), actual_bmp.height()); | 490 EXPECT_EQ(expected_bmp.height(), actual_bmp.height()); |
479 if (expected_bmp.width() != actual_bmp.width() || | 491 if (expected_bmp.width() != actual_bmp.width() || |
480 expected_bmp.height() != actual_bmp.height()) { | 492 expected_bmp.height() != actual_bmp.height()) { |
481 return false; | 493 return false; |
482 } | 494 } |
483 | 495 |
484 SkAutoLockPixels lock_actual_bmp(actual_bmp); | 496 SkAutoLockPixels lock_actual_bmp(actual_bmp); |
485 SkAutoLockPixels lock_expected_bmp(expected_bmp); | 497 SkAutoLockPixels lock_expected_bmp(expected_bmp); |
486 | 498 |
487 DCHECK(gfx::SkIRectToRect(actual_bmp.bounds()).Contains(matching_mask)); | 499 DCHECK(gfx::SkIRectToRect(actual_bmp.bounds()).Contains(matching_mask)); |
488 | 500 |
489 for (int x = matching_mask.x(); x < matching_mask.width(); ++x) { | 501 for (int x = matching_mask.x(); x < matching_mask.width(); ++x) { |
490 for (int y = matching_mask.y(); y < matching_mask.height(); ++y) { | 502 for (int y = matching_mask.y(); y < matching_mask.height(); ++y) { |
491 SkColor actual_color = actual_bmp.getColor(x, y); | 503 SkColor actual_color = actual_bmp.getColor(x, y); |
492 SkColor expected_color = expected_bmp.getColor(x, y); | 504 SkColor expected_color = expected_bmp.getColor(x, y); |
493 if (actual_color != expected_color) { | 505 if (std::abs(static_cast<int32_t>(actual_color) - |
506 static_cast<int32_t>(expected_color)) > error_limit) { | |
Avi (use Gerrit)
2017/01/09 16:57:33
An SkColor is a set of four 8-bit values packed in
Eric Seckler
2017/01/11 15:58:44
Uhh, yeah. Wasn't thinking here. Thank you for the
| |
494 if (error_pixels_count < 10) { | 507 if (error_pixels_count < 10) { |
495 LOG(ERROR) << "Pixel (" << x << "," << y << "): expected " | 508 LOG(ERROR) << "Pixel (" << x << "," << y << "): expected " |
496 << expected_color << " actual " << actual_color; | 509 << expected_color << " actual " << actual_color; |
497 } | 510 } |
498 error_pixels_count++; | 511 error_pixels_count++; |
499 error_bounding_rect.Union(gfx::Rect(x, y, 1, 1)); | 512 error_bounding_rect.Union(gfx::Rect(x, y, 1, 1)); |
500 } | 513 } |
501 } | 514 } |
502 } | 515 } |
503 | 516 |
504 if (error_pixels_count != 0) { | 517 if (error_pixels_count != 0) { |
505 LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count; | 518 LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count; |
506 LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString(); | 519 LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString(); |
507 return false; | 520 return false; |
508 } | 521 } |
509 | 522 |
510 return true; | 523 return true; |
511 } | 524 } |
512 } // namespace | 525 } // namespace |
513 | 526 |
514 class CaptureScreenshotTest : public DevToolsProtocolTest { | 527 class CaptureScreenshotTest : public DevToolsProtocolTest { |
515 protected: | 528 protected: |
516 void CaptureScreenshotAndCompareTo(const SkBitmap& expected_bitmap) { | 529 enum ScreenshotEncoding { ENCODING_PNG, ENCODING_JPEG }; |
517 SendCommand("Page.captureScreenshot", nullptr); | 530 void CaptureScreenshotAndCompareTo(const SkBitmap& expected_bitmap, |
531 ScreenshotEncoding encoding) { | |
532 std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); | |
533 params->SetString("format", encoding == ENCODING_PNG ? "png" : "jpeg"); | |
534 params->SetInteger("quality", 100); | |
535 SendCommand("Page.captureScreenshot", std::move(params)); | |
536 | |
518 std::string base64; | 537 std::string base64; |
519 EXPECT_TRUE(result_->GetString("data", &base64)); | 538 EXPECT_TRUE(result_->GetString("data", &base64)); |
520 SkBitmap result_bitmap; | 539 std::unique_ptr<SkBitmap> result_bitmap; |
521 EXPECT_TRUE(DecodePNG(base64, &result_bitmap)); | 540 int error_limit = 0; |
541 if (encoding == ENCODING_PNG) { | |
542 result_bitmap.reset(new SkBitmap()); | |
543 EXPECT_TRUE(DecodePNG(base64, result_bitmap.get())); | |
544 } else { | |
545 result_bitmap = DecodeJPEG(base64); | |
546 // Even with quality 100, jpeg isn't lossless. So, we allow some skew in | |
547 // pixel values. Not that this assumes that there is no skew in pixel | |
548 // positions, so will only work reliably if all pixels have equal values. | |
549 error_limit = 3; | |
550 } | |
551 EXPECT_TRUE(result_bitmap); | |
552 | |
522 gfx::Rect matching_mask(gfx::SkIRectToRect(expected_bitmap.bounds())); | 553 gfx::Rect matching_mask(gfx::SkIRectToRect(expected_bitmap.bounds())); |
523 #if defined(OS_MACOSX) | 554 #if defined(OS_MACOSX) |
524 // Mask out the corners, which may be drawn differently on Mac because of | 555 // Mask out the corners, which may be drawn differently on Mac because of |
525 // rounded corners. | 556 // rounded corners. |
526 matching_mask.Inset(4, 4, 4, 4); | 557 matching_mask.Inset(4, 4, 4, 4); |
527 #endif | 558 #endif |
528 EXPECT_TRUE(MatchesBitmap(expected_bitmap, result_bitmap, matching_mask)); | 559 EXPECT_TRUE(MatchesBitmap(expected_bitmap, *result_bitmap, matching_mask, |
560 error_limit)); | |
529 } | 561 } |
530 | 562 |
531 // Takes a screenshot of a colored box that is positioned inside the frame. | 563 // Takes a screenshot of a colored box that is positioned inside the frame. |
532 void PlaceAndCaptureBox(const gfx::Size& frame_size, | 564 void PlaceAndCaptureBox(const gfx::Size& frame_size, |
533 const gfx::Size& box_size, | 565 const gfx::Size& box_size, |
534 float screenshot_scale) { | 566 float screenshot_scale) { |
535 static const int kBoxOffsetHeight = 100; | 567 static const int kBoxOffsetHeight = 100; |
536 const gfx::Size scaled_box_size = | 568 const gfx::Size scaled_box_size = |
537 ScaleToFlooredSize(box_size, screenshot_scale); | 569 ScaleToFlooredSize(box_size, screenshot_scale); |
538 std::unique_ptr<base::DictionaryValue> params; | 570 std::unique_ptr<base::DictionaryValue> params; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 params->SetDouble("x", (frame_size.width() - box_size.width()) / 2.); | 609 params->SetDouble("x", (frame_size.width() - box_size.width()) / 2.); |
578 params->SetDouble("y", kBoxOffsetHeight); | 610 params->SetDouble("y", kBoxOffsetHeight); |
579 params->SetDouble("scale", screenshot_scale); | 611 params->SetDouble("scale", screenshot_scale); |
580 SendCommand("Emulation.forceViewport", std::move(params)); | 612 SendCommand("Emulation.forceViewport", std::move(params)); |
581 | 613 |
582 // Capture screenshot and verify that it is indeed blue. | 614 // Capture screenshot and verify that it is indeed blue. |
583 SkBitmap expected_bitmap; | 615 SkBitmap expected_bitmap; |
584 expected_bitmap.allocN32Pixels(scaled_box_size.width(), | 616 expected_bitmap.allocN32Pixels(scaled_box_size.width(), |
585 scaled_box_size.height()); | 617 scaled_box_size.height()); |
586 expected_bitmap.eraseColor(SkColorSetRGB(0x00, 0x00, 0xff)); | 618 expected_bitmap.eraseColor(SkColorSetRGB(0x00, 0x00, 0xff)); |
587 CaptureScreenshotAndCompareTo(expected_bitmap); | 619 CaptureScreenshotAndCompareTo(expected_bitmap, ENCODING_PNG); |
588 | 620 |
589 // Reset for next screenshot. | 621 // Reset for next screenshot. |
590 SendCommand("Emulation.resetViewport", nullptr); | 622 SendCommand("Emulation.resetViewport", nullptr); |
591 SendCommand("Emulation.clearDeviceMetricsOverride", nullptr); | 623 SendCommand("Emulation.clearDeviceMetricsOverride", nullptr); |
592 } | 624 } |
593 | 625 |
594 private: | 626 private: |
595 #if !defined(OS_ANDROID) | 627 #if !defined(OS_ANDROID) |
596 void SetUpCommandLine(base::CommandLine* command_line) override { | 628 void SetUpCommandLine(base::CommandLine* command_line) override { |
597 command_line->AppendSwitch(switches::kEnablePixelOutputInTests); | 629 command_line->AppendSwitch(switches::kEnablePixelOutputInTests); |
598 } | 630 } |
599 #endif | 631 #endif |
600 }; | 632 }; |
601 | 633 |
602 IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, CaptureScreenshot) { | 634 IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, CaptureScreenshot) { |
603 // This test fails consistently on low-end Android devices. | 635 // This test fails consistently on low-end Android devices. |
604 // See crbug.com/653637. | 636 // See crbug.com/653637. |
605 if (base::SysInfo::IsLowEndDevice()) return; | 637 if (base::SysInfo::IsLowEndDevice()) return; |
606 | 638 |
607 shell()->LoadURL(GURL("about:blank")); | 639 shell()->LoadURL( |
640 GURL("data:text/html,<body style='background:#123456'></body>")); | |
641 WaitForLoadStop(shell()->web_contents()); | |
608 Attach(); | 642 Attach(); |
609 EXPECT_TRUE( | |
610 content::ExecuteScript(shell()->web_contents()->GetRenderViewHost(), | |
611 "document.body.style.background = '#123456'")); | |
612 SkBitmap expected_bitmap; | 643 SkBitmap expected_bitmap; |
613 // We compare against the actual physical backing size rather than the | 644 // We compare against the actual physical backing size rather than the |
614 // view size, because the view size is stored adjusted for DPI and only in | 645 // view size, because the view size is stored adjusted for DPI and only in |
646 // integer precision. | |
647 gfx::Size view_size = static_cast<RenderWidgetHostViewBase*>( | |
648 shell()->web_contents()->GetRenderWidgetHostView()) | |
649 ->GetPhysicalBackingSize(); | |
650 expected_bitmap.allocN32Pixels(view_size.width(), view_size.height()); | |
651 expected_bitmap.eraseColor(SkColorSetRGB(0x12, 0x34, 0x56)); | |
652 CaptureScreenshotAndCompareTo(expected_bitmap, ENCODING_PNG); | |
653 } | |
654 | |
655 IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, CaptureScreenshotJpeg) { | |
656 // This test fails consistently on low-end Android devices. | |
657 // See crbug.com/653637. | |
Avi (use Gerrit)
2017/01/09 16:57:33
This bug is about mismatches in color. Do we want
Eric Seckler
2017/01/11 15:58:44
I'm actually not sure if this would still be happe
Avi (use Gerrit)
2017/01/11 17:09:20
SGTM!
| |
658 if (base::SysInfo::IsLowEndDevice()) | |
659 return; | |
660 | |
661 shell()->LoadURL( | |
662 GURL("data:text/html,<body style='background:#123456'></body>")); | |
663 WaitForLoadStop(shell()->web_contents()); | |
664 Attach(); | |
665 SkBitmap expected_bitmap; | |
666 // We compare against the actual physical backing size rather than the | |
667 // view size, because the view size is stored adjusted for DPI and only in | |
615 // integer precision. | 668 // integer precision. |
616 gfx::Size view_size = static_cast<RenderWidgetHostViewBase*>( | 669 gfx::Size view_size = static_cast<RenderWidgetHostViewBase*>( |
617 shell()->web_contents()->GetRenderWidgetHostView()) | 670 shell()->web_contents()->GetRenderWidgetHostView()) |
618 ->GetPhysicalBackingSize(); | 671 ->GetPhysicalBackingSize(); |
619 expected_bitmap.allocN32Pixels(view_size.width(), view_size.height()); | 672 expected_bitmap.allocN32Pixels(view_size.width(), view_size.height()); |
620 expected_bitmap.eraseColor(SkColorSetRGB(0x12, 0x34, 0x56)); | 673 expected_bitmap.eraseColor(SkColorSetRGB(0x12, 0x34, 0x56)); |
621 CaptureScreenshotAndCompareTo(expected_bitmap); | 674 CaptureScreenshotAndCompareTo(expected_bitmap, ENCODING_JPEG); |
622 } | 675 } |
623 | 676 |
624 // Setting frame size (through RWHV) is not supported on Android. | 677 // Setting frame size (through RWHV) is not supported on Android. |
625 #if defined(OS_ANDROID) | 678 #if defined(OS_ANDROID) |
626 #define MAYBE_CaptureScreenshotArea DISABLED_CaptureScreenshotArea | 679 #define MAYBE_CaptureScreenshotArea DISABLED_CaptureScreenshotArea |
627 #else | 680 #else |
628 #define MAYBE_CaptureScreenshotArea CaptureScreenshotArea | 681 #define MAYBE_CaptureScreenshotArea CaptureScreenshotArea |
629 #endif | 682 #endif |
630 IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, | 683 IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, |
631 MAYBE_CaptureScreenshotArea) { | 684 MAYBE_CaptureScreenshotArea) { |
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1507 EXPECT_EQ("polyglottal", value); | 1560 EXPECT_EQ("polyglottal", value); |
1508 found++; | 1561 found++; |
1509 } else { | 1562 } else { |
1510 FAIL(); | 1563 FAIL(); |
1511 } | 1564 } |
1512 } | 1565 } |
1513 EXPECT_EQ(2u, found); | 1566 EXPECT_EQ(2u, found); |
1514 } | 1567 } |
1515 | 1568 |
1516 } // namespace content | 1569 } // namespace content |
OLD | NEW |