Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4412)

Unified Diff: chrome/browser/chromeos/login/screenshot_tester.cc

Issue 433873002: Loading screenshots and simple 1-to-1 comparison of screenshots (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: LOGs replaced with CHECKs Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/login/screenshot_tester.h ('k') | chromeos/chromeos_switches.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/login/screenshot_tester.cc
diff --git a/chrome/browser/chromeos/login/screenshot_tester.cc b/chrome/browser/chromeos/login/screenshot_tester.cc
index 683f987d6d0f82c460edeaf1d1ef6841bf16722d..6f4e8e292236d0412fede1404ff3e22401e41d48 100644
--- a/chrome/browser/chromeos/login/screenshot_tester.cc
+++ b/chrome/browser/chromeos/login/screenshot_tester.cc
@@ -4,10 +4,13 @@
#include "chrome/browser/chromeos/login/screenshot_tester.h"
+#include <algorithm>
ygorshenin1 2014/07/31 17:28:18 Where are you using it?
Lisa Ignatyeva 2014/07/31 17:40:00 It was used before, but I've forgot to remove it :
+
#include "ash/shell.h"
#include "base/base_export.h"
#include "base/bind_internal.h"
#include "base/command_line.h"
+#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h"
@@ -15,13 +18,25 @@
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#include "content/public/browser/browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/compositor/compositor_switches.h"
+#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/snapshot/snapshot.h"
+namespace {
+// Sets test mode for screenshot testing.
ygorshenin1 2014/07/31 17:28:18 nit: add a blank line before comment.
Lisa Ignatyeva 2014/07/31 17:40:00 Done.
+const char kTestMode[] = "test";
+
+// Sets update mode for screenshot testing.
+const char kUpdateMode[] = "update;"
+} // namespace
ygorshenin1 2014/07/31 17:28:18 nit: add a blank line before "} // namespace"
Lisa Ignatyeva 2014/07/31 17:40:00 Done.
+
namespace chromeos {
-ScreenshotTester::ScreenshotTester() : weak_factory_(this) {
+ScreenshotTester::ScreenshotTester() : test_mode_(false), weak_factory_(this) {
}
ScreenshotTester::~ScreenshotTester() {
@@ -29,7 +44,7 @@ ScreenshotTester::~ScreenshotTester() {
bool ScreenshotTester::TryInitialize() {
CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (!command_line.HasSwitch(switches::kEnableScreenshotTesting))
+ if (!command_line.HasSwitch(switches::kEnableScreenshotTestingWithMode))
return false;
if (!command_line.HasSwitch(::switches::kEnablePixelOutputInTests) ||
!command_line.HasSwitch(::switches::kUIEnableImplSidePainting)) {
@@ -40,64 +55,173 @@ bool ScreenshotTester::TryInitialize() {
<< "screenshots";
return false;
}
- if (!command_line.HasSwitch(switches::kScreenshotDestinationDir)) {
- LOG(ERROR) << "No destination for screenshots specified";
- return false;
+
+ std::string mode = command_line.GetSwitchValueASCII(
+ switches::kEnableScreenshotTestingWithMode);
+ if (mode != kUpdateMode && mode != kTestMode) {
+ CHECK(false) << "Invalid mode for screenshot testing: " << mode;
+ }
ygorshenin1 2014/07/31 17:28:18 nit: curly braces are not needed here.
Lisa Ignatyeva 2014/07/31 17:40:00 But I can use them here, as I understand.
+
+ if (!command_line.HasSwitch(chromeos::switches::kGoldenScreenshotsDir)) {
ygorshenin1 2014/07/31 17:28:18 nit: curly braces are not needed here.
+ CHECK(false) << "No directory for golden screenshots specified";
+ }
+
+ golden_screenshots_dir_ =
+ command_line.GetSwitchValuePath(switches::kGoldenScreenshotsDir);
+
+ if (mode == kTestMode) {
+ test_mode_ = true;
+ if (!command_line.HasSwitch(switches::kArtifactsDir)) {
+ artifacts_dir_ = golden_screenshots_dir_;
+ LOG(WARNING)
+ << "No directory for artifact storing specified. Artifacts will be"
+ << "saved at golden screenshots directory.";
+ } else {
+ artifacts_dir_ = command_line.GetSwitchValuePath(switches::kArtifactsDir);
+ }
}
- screenshot_dest_ = command_line.GetSwitchValuePath(
- chromeos::switches::kScreenshotDestinationDir);
return true;
}
-void ScreenshotTester::Run(const std::string& file_name) {
- TakeScreenshot();
- PNGFile current_screenshot = screenshot_;
- UpdateGoldenScreenshot(file_name, current_screenshot);
+void ScreenshotTester::Run(const std::string& test_name) {
+ test_name_ = test_name;
+ PNGFile current_screenshot = TakeScreenshot();
+ if (test_mode_) {
+ PNGFile golden_screenshot = LoadGoldenScreenshot();
+ VLOG(0) << "Loaded golden screenshot";
+ CompareScreenshots(golden_screenshot, current_screenshot);
+ } else {
+ UpdateGoldenScreenshot(current_screenshot);
+ return;
ygorshenin1 2014/07/31 17:28:18 nit: return is redundant here.
Lisa Ignatyeva 2014/07/31 17:40:00 Done.
+ }
}
-void ScreenshotTester::UpdateGoldenScreenshot(const std::string& file_name,
- PNGFile png_data) {
+void ScreenshotTester::UpdateGoldenScreenshot(PNGFile png_data) {
+ DCHECK(SaveImage("golden_screenshot", golden_screenshots_dir_, png_data));
ygorshenin1 2014/07/31 17:28:18 Replace DCHECK() by CHECK(), otherwise in release
Lisa Ignatyeva 2014/07/31 17:40:00 Done.
+}
+
+bool ScreenshotTester::SaveImage(const std::string& file_name,
+ const base::FilePath& screenshot_dir,
+ PNGFile png_data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ base::FilePath screenshot_path =
+ screenshot_dir.AppendASCII(test_name_ + "_" + file_name + ".png");
if (!png_data) {
LOG(ERROR) << "Can't take a screenshot";
- return;
+ return false;
}
- base::FilePath golden_screenshot_path =
- screenshot_dest_.AppendASCII(file_name + ".png");
- if (!base::CreateDirectory(golden_screenshot_path.DirName())) {
- LOG(ERROR) << "Can't create a directory ";
- return;
+ if (!base::CreateDirectory(screenshot_path.DirName())) {
+ LOG(ERROR) << "Can't create a directory "
+ << screenshot_path.DirName().value();
+ return false;
}
if (static_cast<size_t>(
- base::WriteFile(golden_screenshot_path,
+ base::WriteFile(screenshot_path,
reinterpret_cast<char*>(&(png_data->data()[0])),
png_data->size())) != png_data->size()) {
- LOG(ERROR) << "Can't save screenshot";
+ LOG(ERROR) << "Can't save screenshot " << file_name;
+ return false;
}
- VLOG(0) << "Golden screenshot updated successfully";
+ VLOG(0) << "Screenshot " << file_name << ".png saved successfully to "
+ << screenshot_dir.value();
+ return true;
}
-void ScreenshotTester::ReturnScreenshot(PNGFile png_data) {
- // TODO(elizavetai): rewrite this function so that TakeScreenshot
- // could return a |PNGFile| -- current screenshot.
+void ScreenshotTester::ReturnScreenshot(const PNGFile& screenshot,
+ PNGFile png_data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- screenshot_ = png_data;
+ screenshot->data() = png_data->data();
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE, run_loop_quitter_);
}
-void ScreenshotTester::TakeScreenshot() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ScreenshotTester::PNGFile ScreenshotTester::TakeScreenshot() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
aura::Window* primary_window = ash::Shell::GetPrimaryRootWindow();
gfx::Rect rect = primary_window->bounds();
+ PNGFile screenshot = new base::RefCountedBytes;
ui::GrabWindowSnapshotAsync(primary_window,
rect,
content::BrowserThread::GetBlockingPool(),
base::Bind(&ScreenshotTester::ReturnScreenshot,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(),
+ screenshot));
base::RunLoop run_loop;
run_loop_quitter_ = run_loop.QuitClosure();
run_loop.Run();
+ return screenshot;
+}
+
+ScreenshotTester::PNGFile ScreenshotTester::LoadGoldenScreenshot() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ base::FilePath screenshot_path = golden_screenshots_dir_.AppendASCII(
+ test_name_ + "_golden_screenshot.png");
+ if (!base::PathExists(screenshot_path)) {
+ CHECK(false) << "Can't find a golden screenshot for this test";
+ }
ygorshenin1 2014/07/31 17:28:18 nit: curly braces are not needed here.
+
+ size_t golden_screenshot_size;
+ base::GetFileSize(screenshot_path,
+ reinterpret_cast<int64*>(&golden_screenshot_size));
+
+ if (golden_screenshot_size == -1) {
+ CHECK(false) << "Can't get golden screenshot size";
+ }
+ PNGFile png_data = new base::RefCountedBytes;
+ png_data->data().resize(golden_screenshot_size);
+ base::ReadFile(screenshot_path,
+ reinterpret_cast<char*>(&(png_data->data()[0])),
+ golden_screenshot_size);
+
+ return png_data;
+}
+
+void ScreenshotTester::CompareScreenshots(PNGFile model, PNGFile sample) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ ASSERT_TRUE(model.get());
+ ASSERT_TRUE(sample.get());
+
+ SkBitmap model_bitmap;
+ SkBitmap sample_bitmap;
+ gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&(model->data()[0])),
+ model->data().size(),
+ &model_bitmap);
+ gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&(sample->data()[0])),
+ sample->data().size(),
+ &sample_bitmap);
+
+ ASSERT_EQ(model_bitmap.config(), sample_bitmap.config());
+ ASSERT_EQ(model_bitmap.width(), sample_bitmap.width());
+ ASSERT_EQ(model_bitmap.height(), sample_bitmap.height());
+
+ bool screenshots_match = true;
+
+ SkCanvas diff_canvas(sample_bitmap);
+ for (int i = 0; i < model_bitmap.width(); i++)
+ for (int j = 0; j < model_bitmap.height(); j++) {
+ if (model_bitmap.getColor(i, j) == sample_bitmap.getColor(i, j)) {
+ diff_canvas.drawPoint(i, j, SK_ColorWHITE);
+ } else {
+ screenshots_match = false;
+ diff_canvas.drawPoint(i, j, SK_ColorRED);
+ }
+ }
+
+ if (!screenshots_match) {
+ DCHECK(SaveImage("failed_screenshot", artifacts_dir_, sample));
+ gfx::PNGCodec::EncodeBGRASkBitmap(sample_bitmap, false, &sample->data());
+ DCHECK(SaveImage("difference", artifacts_dir_, sample));
+ LOG(ERROR)
+ << "Screenshots testing failed. Screenshots differ in some pixels";
+ VLOG(0) << "Current screenshot and diff picture saved to "
+ << artifacts_dir_.value();
+ } else {
+ VLOG(0) << "Current screenshot matches the golden screenshot. Screenshot "
+ "testing passed.";
+ }
+ ASSERT_TRUE(screenshots_match);
}
} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/login/screenshot_tester.h ('k') | chromeos/chromeos_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698