eyes_images 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 84bf491952e354ad6a8bd5b1be3557471c590c9c
4
+ data.tar.gz: 544807f8ef98e2bdf44348a25d75fca8a7245369
5
+ SHA512:
6
+ metadata.gz: d8ff16ae3a07aa78b2a97bf018c72d1466debafd6568b68c7e9586845709cdbf395da3a73fd5a63ce3913b7042b2d884407a990e6625d9bbbb36aee8d55acfee
7
+ data.tar.gz: 3730cc602a76bf267f7e8cdcf2ca62909e5031f785d759b075b7fc4665947efd63e24e2eb94b317671733808ec44783b16134bdeb350dec8570209a75da73e28
@@ -0,0 +1,204 @@
1
+ require 'applitools/core/eyes_base'
2
+
3
+ # Eyes Images SDK
4
+ #
5
+ module Applitools::Images
6
+ # A class to perform visual validation on images. Allows to handle user data like +Mouse trigger+ and +Text trigger+
7
+ # @example
8
+ # eyes = Applitools::Images::Eyes.new
9
+ # eyes.open(app_name: 'App name', test_name: 'Test name')
10
+ # eyes.check_image(eyes.check_image(image_path: '~/test/some_screenshot.png', tag: 'My Test')
11
+ # eyes.close(true)
12
+ class Eyes < Applitools::EyesBase
13
+ # @!visibility private
14
+ attr_accessor :base_agent_id, :screenshot, :inferred_environment, :title
15
+
16
+ # @!visibility private
17
+ def capture_screenshot
18
+ @screenshot
19
+ end
20
+
21
+ # Creates a new eyes object
22
+ # @example
23
+ # eyes = Applitools::Images::Eyes.new
24
+ # @param server_url The Eyes Server URL
25
+ def initialize(server_url = Applitools::Connectivity::ServerConnector::DEFAULT_SERVER_URL)
26
+ super
27
+ self.base_agent_id = 'eyes.images.ruby/1.0.0'
28
+ end
29
+
30
+ # Starts a test.
31
+ # @param [Hash] options
32
+ # @option options [String] :app_name the name of the application under trest. Required.
33
+ # @option options [String] :test_name the test name. Required
34
+ # @option options [String | Hash] :viewport_size viewport size for the baseline, may be passed as a
35
+ # string (<tt>'800x600'</tt>) or as a hash (<tt>{width: 800, height: 600}</tt>).
36
+ # If ommited, the viewport size will be grabbed from the actual image size
37
+ # @example
38
+ # eyes.open app_name: 'my app', test_name: 'my test'
39
+ def open(options = {})
40
+ Applitools::ArgumentGuard.hash options, 'open(options)', [:app_name, :test_name]
41
+ options[:viewport_size] = Applitools::RectangleSize.from_any_argument options[:viewport_size]
42
+ open_base options
43
+ end
44
+
45
+ # Opens eyes using passed options, yields the block and then closes eyes session.
46
+ # Use Applitools::Images::Eyes method inside the block to perform the test. If the block throws an exception,
47
+ # eyes session will be closed correctly.
48
+ # @example
49
+ # eyes.test(app_name: 'Eyes.Java', test_name: 'home2') do
50
+ # eyes.check_image(image_path: './images/viber-home.png')
51
+ # eyes.check_image(image_path: './images/viber-bada.png')
52
+ # end
53
+ def test(options = {}, &_block)
54
+ open(options)
55
+ yield
56
+ close
57
+ ensure
58
+ abort_if_not_closed
59
+ end
60
+
61
+ # Matches the input image with the next expected image. Takes a hash as an argument. Returns +boolean+
62
+ # as result of matching.
63
+ # @param [Hash] options
64
+ # @option options [Applitools::Screenshot] :image
65
+ # @option options [String] :image_bytes image in PNG format. Can be obtained as ChunkyPNG::Image.to_blob()
66
+ # @option options [String] :image_path
67
+ # @option options [String] :tag An optional tag to be associated with the validation checkpoint.
68
+ # @option options [Boolean] :ignore_mismatch If set to +true+ the server should ignore a negative
69
+ # result for the visual validation. (+false+ by default)
70
+ # @example Image is a file
71
+ # eyes.check_image(image_path: '~/test/some_screenshot.png', tag: 'My Test')
72
+ # @example Image is a +Applitools::Screenshot+ instance
73
+ # eyes.check_image(image: my_image, tag: 'My Test')
74
+ # @example Image is a +String+
75
+ # eyes.check_image(image_bytes: string_represents_image, tag: 'My Test')
76
+ # @example Ignore mismatch
77
+ # eyes.check_image(image: my_image, tag: 'My Test', ignore_mismatch: true)
78
+ def check_image(options)
79
+ options = { tag: nil, ignore_mismatch: false }.merge options
80
+
81
+ if disabled?
82
+ logger.info "check_image(image, #{options[:tag]}, #{options[:ignore_mismatch]}): Ignored"
83
+ return false
84
+ end
85
+
86
+ image = get_image_from_options options
87
+
88
+ logger.info "check_image(image, #{options[:tag]}, #{options[:ignore_mismatch]})"
89
+ if image.is_a? Applitools::Screenshot
90
+ self.viewport_size = Applitools::RectangleSize.new image.width, image.height if viewport_size.nil?
91
+ self.screenshot = EyesImagesScreenshot.new image
92
+ end
93
+ self.title = options[:tag] || ''
94
+ region_provider = Object.new
95
+ region_provider.instance_eval do
96
+ define_singleton_method :region do
97
+ Applitools::Region::EMPTY
98
+ end
99
+
100
+ define_singleton_method :coordinate_type do
101
+ nil
102
+ end
103
+ end
104
+ mr = check_window_base region_provider, options[:tag], options[:ignore_mismatch],
105
+ Applitools::EyesBase::USE_DEFAULT_TIMEOUT
106
+ mr.as_expected?
107
+ end
108
+
109
+ # Performs visual validation for the current image.
110
+ # @param [Hash] options
111
+ # @option options [Applitools::Region] :region A region to validate within the image
112
+ # @option options [Applitools::Screenshot] :image Image to validate
113
+ # @option options [String] :image_bytes Image in +PNG+ format. Can be obtained as ChunkyPNG::Image.to_blob()
114
+ # @option options [String] :image_path Path to image file
115
+ # @option options [String] :tag An optional tag to be associated with the validation checkpoint.
116
+ # @option options [Boolean] :ignore_mismatch If set to +true+ the server would ignore a negative
117
+ # result for the visual validation
118
+ # @example Image is a file
119
+ # eyes.check_region(image_path: '~/test/some_screenshot.png', region: my_region, tag: 'My Test')
120
+ # @example Image is a Applitools::Screenshot instance
121
+ # eyes.check_region(image: my_image, tag: 'My Test', region: my_region)
122
+ # @example Image is a +String+
123
+ # eyes.check_region(image_bytes: string_represents_image, tag: 'My Test', region: my_region)
124
+ def check_region(options)
125
+ options = { tag: nil, ignore_mismatch: false }.merge options
126
+
127
+ if disabled?
128
+ logger.info "check_region(image, #{options[:tag]}, #{options[:ignore_mismatch]}): Ignored"
129
+ return false
130
+ end
131
+
132
+ Applitools::ArgumentGuard.not_nil options[:region], 'options[:region] can\'t be nil!'
133
+ image = get_image_from_options options
134
+
135
+ logger.info "check_region(image, #{options[:region]}, #{options[:tag]}, #{options[:ignore_mismatch]})"
136
+
137
+ if image.is_a? Applitools::Screenshot
138
+ self.viewport_size = Applitools::RectangleSize.new image.width, image.height if viewport_size.nil?
139
+ self.screenshot = EyesImagesScreenshot.new image
140
+ end
141
+ self.title = options[:tag] || ''
142
+
143
+ region_provider = Object.new
144
+ region_provider.instance_eval do
145
+ define_singleton_method :region do
146
+ options[:region]
147
+ end
148
+ define_singleton_method :coordinate_type do
149
+ Applitools::EyesScreenshot::COORDINATE_TYPES[:screenshot_as_is]
150
+ end
151
+ end
152
+ mr = check_window_base region_provider, options[:tag], options[:ignore_mismatch],
153
+ Applitools::EyesBase::USE_DEFAULT_TIMEOUT
154
+ mr.as_expected?
155
+ end
156
+
157
+ # Adds a mouse trigger
158
+ # @param [Symbol] action A mouse action. Can be one of +:click+, +:right_click+, +:double_click+, +:move+,
159
+ # +:down+, +:up+
160
+ # @param [Applitools::Region] control The control on which the trigger is activated
161
+ # (context relative coordinates).
162
+ # @param [Applitools::Location] cursor The cursor's position relative to the control.
163
+ def add_mouse_trigger(action, control, cursor)
164
+ add_mouse_trigger_base action, control, cursor
165
+ end
166
+
167
+ # Adds a keyboard trigger
168
+ # @param [Applitools::Region] control the control's context-relative region.
169
+ # @param text The trigger's text.
170
+ def add_text_trigger(control, text)
171
+ add_text_trigger_base control, text
172
+ end
173
+
174
+ private
175
+
176
+ def vp_size
177
+ viewport_size
178
+ end
179
+
180
+ def vp_size=(value)
181
+ Applitools::ArgumentGuard.not_nil 'value', value
182
+ @viewport_size = Applitools::RectangleSize.for value
183
+ end
184
+
185
+ alias get_viewport_size vp_size
186
+ alias set_viewport_size vp_size=
187
+
188
+ def get_image_from_options(options)
189
+ if options[:image].nil? && !options[:image].is_a?(Applitools::Screenshot)
190
+ if !options[:image_path].nil? && !options[:image_path].empty?
191
+ image = Applitools::Screenshot.new ChunkyPNG::Datastream.from_file(options[:image_path]).to_s
192
+ elsif options[:image_bytes].nil? && !options[:image_bytes].empty?
193
+ image = Applitools::Screenshot.new options[:image_bytes]
194
+ end
195
+ else
196
+ image = options[:image]
197
+ end
198
+
199
+ Applitools::ArgumentGuard.not_nil image, 'options[:image] can\'t be nil!'
200
+
201
+ image
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,102 @@
1
+ module Applitools::Images
2
+ # @!visibility private
3
+ class EyesImagesScreenshot < ::Applitools::EyesScreenshot
4
+ SCREENSHOT_AS_IS = Applitools::EyesScreenshot::COORDINATE_TYPES[:screenshot_as_is].freeze
5
+ CONTEXT_RELATIVE = Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative].freeze
6
+
7
+ def initialize(image, options = {})
8
+ super image
9
+ return if (location = options[:location]).nil?
10
+ Applitools::ArgumentGuard.is_a? location, 'options[:location]', Applitools::Location
11
+ @bounds = Applitools::Region.new location.x, location.y, image.width, image.height
12
+ end
13
+
14
+ def convert_location(location, from, to)
15
+ Applitools::ArgumentGuard.not_nil location, 'location'
16
+ Applitools::ArgumentGuard.not_nil from, 'from'
17
+ Applitools::ArgumentGuard.not_nil to, 'to'
18
+
19
+ Applitools::ArgumentGuard.is_a? location, 'location', Applitools::Location
20
+
21
+ result = Applitools::Location.new location.x, location.y
22
+ return result if from == to
23
+
24
+ case from
25
+ when SCREENSHOT_AS_IS
26
+ raise "Coordinate type conversation error: #{from} -> #{to}" unless to == CONTEXT_RELATIVE
27
+ result.offset bounds
28
+ return result
29
+ when CONTEXT_RELATIVE
30
+ raise "Coordinate type conversation error: #{from} -> #{to}" unless to == SCREENSHOT_AS_IS
31
+ result.offset(Applitools::Location.new(-bounds.x, -bounds.y))
32
+ return result
33
+ else
34
+ raise "Coordinate type conversation error: #{from} -> #{to}"
35
+ end
36
+ end
37
+
38
+ def convert_region_location(region, from, to)
39
+ Applitools::ArgumentGuard.not_nil region, 'region'
40
+ return Core::Region.new(0, 0, 0, 0) if region.empty?
41
+
42
+ Applitools::ArgumentGuard.not_nil from, 'from'
43
+ Applitools::ArgumentGuard.not_nil to, 'to'
44
+
45
+ updated_location = convert_location region.location, from, to
46
+
47
+ Applitools::Region.new updated_location.x, updated_location.y, region.width, region.height
48
+ end
49
+
50
+ def intersected_region(region, from, to = CONTEXT_RELATIVE)
51
+ Applitools::ArgumentGuard.not_nil region, 'region'
52
+ Applitools::ArgumentGuard.not_nil from, 'coordinates Type (from)'
53
+
54
+ return Applitools::Region.new(0, 0, 0, 0) if region.empty?
55
+
56
+ intersected_region = convert_region_location region, from, to
57
+ intersected_region.intersect bounds
58
+ return intersected_region if intersected_region.empty?
59
+
60
+ intersected_region.location = convert_location intersected_region.location, to, from
61
+ intersected_region
62
+ end
63
+
64
+ def location_in_screenshot(location, coordinates_type)
65
+ Applitools::ArgumentGuard.not_nil location, 'location'
66
+ Applitools::ArgumentGuard.not_nil coordinates_type, 'coordinates_type'
67
+ location = convert_location(location, coordinates_type, CONTEXT_RELATIVE)
68
+
69
+ unless bounds.contains? location.left, location.top
70
+ raise Applitools::OutOfBoundsException.new "Location #{location} is not available in screenshot!"
71
+ end
72
+
73
+ convert_location location, CONTEXT_RELATIVE, SCREENSHOT_AS_IS
74
+ end
75
+
76
+ def sub_screenshot(region, coordinates_type, throw_if_clipped)
77
+ Applitools::ArgumentGuard.not_nil region, 'region'
78
+ Applitools::ArgumentGuard.not_nil coordinates_type, 'coordinates_type'
79
+
80
+ sub_screen_region = intersected_region region, coordinates_type, SCREENSHOT_AS_IS
81
+
82
+ if sub_screen_region.empty? || (throw_if_clipped && !region.size_equals?(sub_screen_region))
83
+ Applitools::OutOfBoundsException.new "Region #{sub_screen_region} (#{coordinates_type}) is out of " \
84
+ " screenshot bounds #{bounds}"
85
+ end
86
+
87
+ sub_screenshot_image = Applitools::Screenshot.new image.crop(sub_screen_region.left, sub_screen_region.top,
88
+ sub_screen_region.width, sub_screen_region.height).to_datastream.to_blob
89
+
90
+ relative_sub_screenshot_region = convert_region_location(sub_screen_region, SCREENSHOT_AS_IS, CONTEXT_RELATIVE)
91
+
92
+ Applitools::Images::EyesImagesScreenshot.new sub_screenshot_image,
93
+ location: relative_sub_screenshot_region.location
94
+ end
95
+
96
+ private
97
+
98
+ def bounds
99
+ @bounds ||= Applitools::Region.new(0, 0, image.width, image.height)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,3 @@
1
+ module Applitools
2
+ VERSION = '3.0.4'.freeze
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'eyes_core'
2
+
3
+ module Applitools::Images
4
+ # @!visibility private
5
+ class << self
6
+ # @!visibility private
7
+ def require_dir(dir)
8
+ Dir[File.join(File.dirname(File.expand_path(__FILE__)), 'applitools', dir, '*.rb')].sort.each do |f|
9
+ require f
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Applitools::Images.require_dir 'images'
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eyes_images
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Applitools Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eyes_core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.4
27
+ description: Applitools Ruby Images SDK
28
+ email:
29
+ - team@applitools.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/applitools/images/eyes.rb
35
+ - lib/applitools/images/eyes_images_screenshot.rb
36
+ - lib/applitools/version.rb
37
+ - lib/eyes_images.rb
38
+ homepage: https://www.applitools.com
39
+ licenses:
40
+ - Apache License, Version 2.0
41
+ metadata:
42
+ yard.run: yri
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.6.8
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Applitools Ruby Images SDK
63
+ test_files: []