Class: Zucchini::Screenshot

Inherits:
Object
  • Object
show all
Defined in:
lib/zucchini/screenshot.rb

Constant Summary collapse

FILE_NAME_PATTERN =
/^(?<sequence_number>\d\d)_(?<screenshot_name>[^\.]*)\.png$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_path, device, log, unmatched_pending = false) ⇒ Screenshot

Returns a new instance of Screenshot.



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
# File 'lib/zucchini/screenshot.rb', line 7

def initialize(file_path, device, log, unmatched_pending = false)
  @file_path = file_path
  @log = log
  @device = device
  
  @file_name = File.basename(@file_path)
  match = FILE_NAME_PATTERN.match(@file_name)
  raise "Illegal screenshot name #{file_path}" unless match

  @screenshot_name      = match[:screenshot_name]
  @sequence_number      = match[:sequence_number].to_i

  @file_name = File.basename(@file_path)

  unless unmatched_pending
    run_data_path      = File.dirname(@file_path)
    support_path       = File.join(run_data_path, '../../../support')

    if @log
           = @log.(@sequence_number)
      @orientation = [:orientation]
      @screen      = [:screen]
      @rotated     = [:rotated]
    end

    if @orientation && !@rotated
      rotate
      @log.mark_screenshot_as_rotated(@sequence_number)
      @log.save
    end

    @mask_paths = {
      :global   => mask_path(File.join(support_path,  'masks',         @device[:screen])),
      :specific => mask_path(File.join(run_data_path, '../../masks',   @device[:screen], @file_name.sub('.png', ''))),
      :screen   => mask_path(File.join(support_path,  'screens/masks', @device[:screen], @screen.to_s.underscore))
    }

    masked_path   = File.join(run_data_path, "../Masked/actual/#{@file_name}")
    @masked_paths = { :global => masked_path, :screen => masked_path, :specific => masked_path }

    @diff_path = "#{run_data_path}/../Diff/#{@file_name}"
  end
end

Instance Attribute Details

#diffObject

Returns the value of attribute diff.



5
6
7
# File 'lib/zucchini/screenshot.rb', line 5

def diff
  @diff
end

#diff_pathObject

Returns the value of attribute diff_path.



5
6
7
# File 'lib/zucchini/screenshot.rb', line 5

def diff_path
  @diff_path
end

#file_nameObject (readonly)

Returns the value of attribute file_name.



4
5
6
# File 'lib/zucchini/screenshot.rb', line 4

def file_name
  @file_name
end

#file_pathObject (readonly)

Returns the value of attribute file_path.



4
5
6
# File 'lib/zucchini/screenshot.rb', line 4

def file_path
  @file_path
end

#mask_pathsObject

Returns the value of attribute mask_paths.



5
6
7
# File 'lib/zucchini/screenshot.rb', line 5

def mask_paths
  @mask_paths
end

#masked_pathsObject

Returns the value of attribute masked_paths.



5
6
7
# File 'lib/zucchini/screenshot.rb', line 5

def masked_paths
  @masked_paths
end

#original_file_pathObject (readonly)

Returns the value of attribute original_file_path.



4
5
6
# File 'lib/zucchini/screenshot.rb', line 4

def original_file_path
  @original_file_path
end

#test_pathObject

Returns the value of attribute test_path.



5
6
7
# File 'lib/zucchini/screenshot.rb', line 5

def test_path
  @test_path
end

Class Method Details

.valid?(file_path) ⇒ Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/zucchini/screenshot.rb', line 107

def self.valid?(file_path)
  FILE_NAME_PATTERN =~ File.basename(file_path)
end

Instance Method Details

#compareObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/zucchini/screenshot.rb', line 64

def compare
  mask_reference

  if @test_path
    FileUtils.mkdir_p(File.dirname(@diff_path))

    compare_command = "compare -metric AE -fuzz 2% -dissimilarity-threshold 1 -subimage-search"
    out = `#{compare_command} \"#{@masked_paths[:specific]}\" \"#{@test_path}\" \"#{@diff_path}\" 2>&1`
    out.chomp!
    @diff = (out == '0') ? [:passed, nil] : [:failed, out]
    @diff = [:pending, @diff[1]] if @pending
  else
    @diff = [:failed, "no reference or pending screenshot for #{@device[:screen]}"]
  end
end

#maskObject



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/zucchini/screenshot.rb', line 51

def mask
  create_masked_paths_dirs
  masked_path = apply_mask(@file_path, :global)

  if mask_present?(:screen)
    masked_path = apply_mask(masked_path, :screen)
  end

  if mask_present?(:specific)
    apply_mask(masked_path, :specific)
  end
end

#mask_referenceObject



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/zucchini/screenshot.rb', line 88

def mask_reference
  run_data_path = File.dirname(@file_path)
  %W(reference pending).each do |reference_type|
    reference_file_path = "#{run_data_path}/../../#{reference_type}/#{@device[:screen]}/#{@file_name}"
    output_path         = "#{run_data_path}/../Masked/#{reference_type}/#{@file_name}"

    if File.exists?(reference_file_path)
      @test_path = output_path
      @pending   = (reference_type == "pending")
      FileUtils.mkdir_p(File.dirname(output_path))

      reference = Zucchini::Screenshot.new(reference_file_path, @device, @log)
      reference.mask_paths  = @mask_paths
      reference.masked_paths = { :global => output_path, :screen => output_path, :specific => output_path }
      reference.mask
    end
  end
end

#result_imagesObject



80
81
82
83
84
85
86
# File 'lib/zucchini/screenshot.rb', line 80

def result_images
  @result_images ||= {
    :actual     => @masked_paths && File.exists?(@masked_paths[:specific]) ? @masked_paths[:specific] : nil,
    :expected   => @test_path    && File.exists?(@test_path) ? @test_path : nil,
    :difference => @diff_path    && File.exists?(@diff_path) ? @diff_path : nil
  }
end