-
Notifications
You must be signed in to change notification settings - Fork 147
/
image_assertion.rb
102 lines (80 loc) · 3.35 KB
/
image_assertion.rb
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
require 'open3'
require 'shellwords'
class ImageAssertion
MAX_ALLOWED_DIFF_VALUE = 1.0
DIFF_IMAGE_FOLDER_NAME = 'screens_diff'
def self.assert_image(test_output, ref_images_path, image_name, threshold)
return false unless (test_output && ref_images_path && image_name)
diff_images_path = File.join(test_output, DIFF_IMAGE_FOLDER_NAME)
Dir.mkdir(diff_images_path) unless File.directory?(diff_images_path)
image_file_name = image_name + '.png'
expected_path = File.join(ref_images_path, image_file_name)
diff_path = File.join(diff_images_path, image_file_name)
run_folder_name = find_last_folder(test_output)
received_path = File.join(run_folder_name, image_file_name)
print_status(create_status('started', "Asserting #{image_file_name}."))
if !File.exists?(received_path)
error = "No captured image file found at #{received_path}"
print_status(create_status('failed', error))
return false
elsif !File.exists?(expected_path)
error = "No reference image file found at #{expected_path}"
print_status(create_status('failed', error))
return false
else
result, exit_status = im_compare(expected_path, received_path, diff_path)
if exit_status == 0
return process_imagemagick_result(image_file_name, result, threshold)
elsif exit_status == 1
print_status(create_status('failed', "Images differ, check #{diff_images_path} for details. ImageMagick error: #{result}"))
else
print_status(create_status('failed', "ImageMagick comparison failed: #{result}"))
end
end
end
private
# Iterte through folders with name Run* and return with latests run number
def self.find_last_folder(test_output)
folder_mask = "#{test_output}/Run";
run_folders = Dir.glob("#{folder_mask}*")
return nil unless run_folders.length > 0
run_folders.sort do |x, y|
y.gsub(folder_mask, '').to_i <=> x.gsub(folder_mask, '').to_i
end[0]
end
def self.process_imagemagick_result(image_file_name, result, threshold)
result_status = 'failed'
result_message = "#{image_file_name} is not equal to the reference."
assertionResult = false
#imagemagick outputs floating point metrics value when succeeds
compare_succeed = ( result.match(/[0-9]*\.?[0-9]+/).length > 0 )
threshold ||= MAX_ALLOWED_DIFF_VALUE
if compare_succeed
if result.to_f < threshold
result_status = 'passed'
result_message = "#{image_file_name} asserted successfully."
assertionResult = true
else
print_status(create_status(result_status, "expected diff is smaller than #{threshold} but #{result.to_f}."))
end
else
result_message = result
end
print_status(create_status(result_status, result_message))
assertionResult
end
def self.create_status(status, message)
"#{Time.new} #{status}: #{message}"
end
def self.print_status(message)
$stderr.puts(message)
end
def self.im_compare(expected_path, received_path, diff_path)
command = '/usr/local/bin/compare -metric MAE '
command << Shellwords.escape(expected_path) + ' '
command << Shellwords.escape(received_path) + ' '
command << ( diff_path ? Shellwords.escape(diff_path) : 'null:' )
_, _, stderr, wait_thr = Open3.popen3(command)
[stderr.read, wait_thr.value.exitstatus]
end
end