1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
import os
import re
import subprocess
import unittest
import sys
import selenium_utilities
import selenium_constants
class PDiffTest(unittest.TestCase):
"""A perceptual diff test class, for running perceptual diffs on any
number of screenshots."""
def __init__(self, name, num_screenshots, screenshot_name, pdiff_path,
gen_dir, ref_dir, options):
unittest.TestCase.__init__(self, name)
self.name = name
self.num_screenshots = num_screenshots
self.screenshot_name = screenshot_name
self.pdiff_path = pdiff_path
self.gen_dir = gen_dir
self.ref_dir = ref_dir
self.options = options
def shortDescription(self):
"""override unittest.TestCase shortDescription for our own descriptions."""
return "Screenshot comparison for: " + self.name
def PDiffTest(self):
"""Runs a generic Perceptual Diff test."""
# Get arguments for perceptual diff.
pixel_threshold = "10"
alpha_threshold = "1.0"
use_colorfactor = False
use_downsample = False
use_edge = True
edge_threshold = "5"
for opt in self.options:
if opt.startswith("pdiff_threshold"):
pixel_threshold = selenium_utilities.GetArgument(opt)
elif (opt.startswith("pdiff_threshold_mac") and
sys.platform == "darwin"):
pixel_threshold = selenium_utilities.GetArgument(opt)
elif (opt.startswith("pdiff_threshold_win") and
sys.platform == 'win32' or sys.platform == "cygwin"):
pixel_threshold = selenium_utilities.GetArgument(opt)
elif (opt.startswith("pdiff_threshold_linux") and
sys.platform[:5] == "linux"):
pixel_threshold = selenium_utilities.GetArgument(opt)
elif (opt.startswith("colorfactor")):
colorfactor = selenium_utilities.GetArgument(opt)
use_colorfactor = True
elif (opt.startswith("downsample")):
downsample_factor = selenium_utilities.GetArgument(opt)
use_downsample = True
elif (opt.startswith("pdiff_edge_ignore_off")):
use_edge = False
elif (opt.startswith("pdiff_edge_threshold")):
edge_threshold = selenium_utilities.GetArgument(opt)
results = []
# Loop over number of screenshots.
for screenshot_no in range(self.num_screenshots):
# Find reference image.
shotname = self.screenshot_name + str(screenshot_no + 1)
J = os.path.join
platform_img_path = J(self.ref_dir,
selenium_constants.PLATFORM_SCREENSHOT_DIR,
shotname + '_reference.png')
reg_img_path = J(self.ref_dir,
selenium_constants.DEFAULT_SCREENSHOT_DIR,
shotname + '_reference.png')
if os.path.exists(platform_img_path):
ref_img_path = platform_img_path
elif os.path.exists(reg_img_path):
ref_img_path = reg_img_path
else:
self.fail('Reference image for ' + shotname + ' not found.')
# Find generated image.
gen_img_path = J(self.gen_dir, shotname + '.png')
diff_img_path = J(self.gen_dir, 'cmp_' + shotname + '.png')
self.assertTrue(os.path.exists(gen_img_path),
'Generated screenshot for ' + shotname + ' not found.\n')
# Run perceptual diff
arguments = [self.pdiff_path,
ref_img_path,
gen_img_path,
"-output", diff_img_path,
"-fov", "45",
"-alphaThreshold", alpha_threshold,
# Turn on verbose output for the percetual diff so we
# can see how far off we are on the threshold.
"-verbose",
# Set the threshold to zero so we can get a count
# of the different pixels. This causes the program
# to return failure for most images, but we can compare
# the values ourselves below.
"-threshold", "0"]
if use_colorfactor:
arguments += ["-colorfactor", colorfactor]
if use_downsample:
arguments += ["-downsample", downsample_factor]
if use_edge:
arguments += ["-ignoreEdges", edge_threshold]
pdiff_pipe = subprocess.Popen(arguments,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(pdiff_stdout, pdiff_stderr) = pdiff_pipe.communicate()
result = pdiff_pipe.returncode
# Find out how many pixels were different by looking at the output.
pixel_re = re.compile("(\d+) pixels are different", re.DOTALL)
pixel_match = pixel_re.search(pdiff_stdout)
different_pixels = "0"
if pixel_match:
different_pixels = pixel_match.group(1)
results += [(shotname, int(different_pixels))]
all_tests_passed = True
msg = "Pixel threshold is %s. Failing screenshots:\n" % pixel_threshold
for name, pixels in results:
if pixels >= int(pixel_threshold):
all_tests_passed = False
msg += " %s, differing by %s\n" % (name, str(pixels))
self.assertTrue(all_tests_passed, msg)
|