eyes_images 4.0.0.alpha → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of eyes_images might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: d57304fb9f70a31cdd54d4d858518da1bb743242300cb7f6b44fca409e0ee474
4
- data.tar.gz: 0a8912459d6a810501f61c7d33dfa5fb318832ab35d3ef962640b075950e4a72
2
+ SHA1:
3
+ metadata.gz: 71125b4f052c21e79a5b50b6e553c079c55ee792
4
+ data.tar.gz: 3fc0aa90e059f26fd13f82f8cd01f4399bc93665
5
5
  SHA512:
6
- metadata.gz: 026b9ed41e630373d5ce26a269f77a075789e28c5aef3842ccf4b6b07ec60900e8996b4f1fa7be2085be74fc1207f9476039daf5dbd893421b4743277ed55033
7
- data.tar.gz: b967d91e24a201491432165860f8c198a0f67ff43fc13b4a941754433c80a175a04c4233710885549360a7dc8964d4729c784395d85b390d29080a5fe6b05b94
6
+ metadata.gz: d89e69a8b1a86ecd33fc51e35dddc8a8cb70d95b7100ad821e4c804e954148ba461f0aa88feb9913e07c4520f27c47f9d69b300df5fabb7367050660ec8f20fd
7
+ data.tar.gz: f1925352ff32e967a17d8c8d0fd2be3b0e3db40c95bd6fe84c7e774c4a3c356ebf44cf95c51813735f79a037c4296a9cb642c88136dc45ea36d1d4e9bbff03a1
@@ -42,8 +42,7 @@ module Applitools::Images
42
42
  def open(options = {})
43
43
  Applitools::ArgumentGuard.hash options, 'open(options)', [:app_name, :test_name]
44
44
  options[:viewport_size] = Applitools::RectangleSize.from_any_argument options[:viewport_size]
45
- # options = Applitools::Utils.extract_options!(args)
46
- universal_open(options)
45
+ open_base options
47
46
  end
48
47
 
49
48
  # Opens eyes using passed options, yields the block and then closes eyes session.
@@ -94,9 +93,6 @@ module Applitools::Images
94
93
 
95
94
  def check_it(name, target, match_window_data)
96
95
  Applitools::ArgumentGuard.not_nil(name, 'name')
97
-
98
- return universal_check(name, target)
99
-
100
96
  region_provider = get_region_provider(target)
101
97
 
102
98
  match_window_data.tag = name
@@ -168,8 +164,8 @@ module Applitools::Images
168
164
  # eyes.check_image(image: my_image, tag: 'My Test', ignore_mismatch: true)
169
165
  def check_image(options)
170
166
  options = { tag: '', ignore_mismatch: false }.merge options
171
- # image = get_image_from_options(options)
172
- target = Applitools::Images::Target.any(options).ignore_mismatch(options[:ignore_mismatch])
167
+ image = get_image_from_options(options)
168
+ target = Applitools::Images::Target.any(image).ignore_mismatch(options[:ignore_mismatch])
173
169
  check(options[:tag], target)
174
170
  end
175
171
 
@@ -189,10 +185,10 @@ module Applitools::Images
189
185
  # @example Image is a +String+
190
186
  # eyes.check_region(image_bytes: string_represents_image, tag: 'My Test', region: my_region)
191
187
  def check_region(options)
192
- options = { tag: '', ignore_mismatch: false }.merge options
188
+ options = { tag: nil, ignore_mismatch: false }.merge options
193
189
  Applitools::ArgumentGuard.not_nil options[:region], 'options[:region] can\'t be nil!'
194
- # image = get_image_from_options options
195
- target = Applitools::Images::Target.any(options).ignore_mismatch(options[:ignore_mismatch])
190
+ image = get_image_from_options options
191
+ target = Applitools::Images::Target.any(image).ignore_mismatch(options[:ignore_mismatch])
196
192
  target.region(options[:region])
197
193
  logger.info "check_region(image, #{options[:region]}, #{options[:tag]}, #{options[:ignore_mismatch]})"
198
194
  check(options[:tag], target)
@@ -236,22 +232,22 @@ module Applitools::Images
236
232
  alias get_viewport_size vp_size
237
233
  alias set_viewport_size vp_size=
238
234
 
239
- # def get_image_from_options(options)
240
- # image = if options[:image].nil? || !options[:image].is_a?(Applitools::Screenshot)
241
- # # if options[:image].is_a? ChunkyPNG::Image
242
- # # Applitools::Screenshot.from_image options[:image]
243
- # # if !options[:image_path].nil? && !options[:image_path].empty?
244
- # # Applitools::Screenshot.from_datastream ChunkyPNG::Datastream.from_file(options[:image_path]).to_s
245
- # if !options[:image_bytes].nil? && !options[:image_bytes].empty?
246
- # Applitools::Screenshot.from_datastream options[:image_bytes]
247
- # end
248
- # else
249
- # options[:image]
250
- # end
251
- #
252
- # Applitools::ArgumentGuard.not_nil image, 'options[:image] can\'t be nil!'
253
- #
254
- # image
255
- # end
235
+ def get_image_from_options(options)
236
+ image = if options[:image].nil? || !options[:image].is_a?(Applitools::Screenshot)
237
+ if options[:image].is_a? ChunkyPNG::Image
238
+ Applitools::Screenshot.from_image options[:image]
239
+ elsif !options[:image_path].nil? && !options[:image_path].empty?
240
+ Applitools::Screenshot.from_datastream ChunkyPNG::Datastream.from_file(options[:image_path]).to_s
241
+ elsif !options[:image_bytes].nil? && !options[:image_bytes].empty?
242
+ Applitools::Screenshot.from_datastream options[:image_bytes]
243
+ end
244
+ else
245
+ options[:image]
246
+ end
247
+
248
+ Applitools::ArgumentGuard.not_nil image, 'options[:image] can\'t be nil!'
249
+
250
+ image
251
+ end
256
252
  end
257
253
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Applitools::Images
4
+ # @!visibility private
5
+ class EyesImagesScreenshot < ::Applitools::EyesScreenshot
6
+ SCREENSHOT_AS_IS = Applitools::EyesScreenshot::COORDINATE_TYPES[:screenshot_as_is].freeze
7
+ CONTEXT_RELATIVE = Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative].freeze
8
+
9
+ def initialize(image, options = {})
10
+ super image
11
+ return if (location = options[:location]).nil?
12
+ Applitools::ArgumentGuard.is_a? location, 'options[:location]', Applitools::Location
13
+ @bounds = Applitools::Region.new location.x, location.y, image.width, image.height
14
+ end
15
+
16
+ def convert_location(location, from, to)
17
+ Applitools::ArgumentGuard.not_nil location, 'location'
18
+ Applitools::ArgumentGuard.not_nil from, 'from'
19
+ Applitools::ArgumentGuard.not_nil to, 'to'
20
+
21
+ Applitools::ArgumentGuard.is_a? location, 'location', Applitools::Location
22
+
23
+ result = Applitools::Location.new location.x, location.y
24
+ return result if from == to
25
+
26
+ case from
27
+ when SCREENSHOT_AS_IS
28
+ raise "Coordinate type conversation error: #{from} -> #{to}" unless to == CONTEXT_RELATIVE
29
+ result.offset bounds
30
+ return result
31
+ when CONTEXT_RELATIVE
32
+ raise "Coordinate type conversation error: #{from} -> #{to}" unless to == SCREENSHOT_AS_IS
33
+ result.offset(Applitools::Location.new(-bounds.x, -bounds.y))
34
+ return result
35
+ else
36
+ raise "Coordinate type conversation error: #{from} -> #{to}"
37
+ end
38
+ end
39
+
40
+ def intersected_region(region, from, to = CONTEXT_RELATIVE)
41
+ Applitools::ArgumentGuard.not_nil region, 'region'
42
+ Applitools::ArgumentGuard.not_nil from, 'coordinates Type (from)'
43
+
44
+ return Applitools::Region.new(0, 0, 0, 0) if region.empty?
45
+
46
+ intersected_region = convert_region_location region, from, to
47
+ intersected_region.intersect bounds
48
+ return intersected_region if intersected_region.empty?
49
+
50
+ intersected_region.location = convert_location intersected_region.location, to, from
51
+ intersected_region
52
+ end
53
+
54
+ def location_in_screenshot(location, coordinates_type)
55
+ Applitools::ArgumentGuard.not_nil location, 'location'
56
+ Applitools::ArgumentGuard.not_nil coordinates_type, 'coordinates_type'
57
+ location = convert_location(location, coordinates_type, CONTEXT_RELATIVE)
58
+
59
+ unless bounds.contains? location.left, location.top
60
+ raise Applitools::OutOfBoundsException.new "Location #{location} is not available in screenshot!"
61
+ end
62
+
63
+ convert_location location, CONTEXT_RELATIVE, SCREENSHOT_AS_IS
64
+ end
65
+
66
+ def sub_screenshot(region, coordinates_type, throw_if_clipped = false, force_nil_if_clipped = false)
67
+ Applitools::ArgumentGuard.not_nil region, 'region'
68
+ Applitools::ArgumentGuard.not_nil coordinates_type, 'coordinates_type'
69
+
70
+ sub_screen_region = intersected_region region, coordinates_type, SCREENSHOT_AS_IS
71
+
72
+ if sub_screen_region.empty? || (throw_if_clipped && !region.size_equals?(sub_screen_region))
73
+ return nil if force_nil_if_clipped
74
+ Applitools::OutOfBoundsException.new "Region #{sub_screen_region} (#{coordinates_type}) is out of " \
75
+ " screenshot bounds #{bounds}"
76
+ end
77
+
78
+ sub_screenshot_image = Applitools::Screenshot.from_any_image(
79
+ image.crop(
80
+ sub_screen_region.left, sub_screen_region.top, sub_screen_region.width, sub_screen_region.height
81
+ ).to_datastream.to_blob
82
+ )
83
+
84
+ relative_sub_screenshot_region = convert_region_location(sub_screen_region, SCREENSHOT_AS_IS, CONTEXT_RELATIVE)
85
+
86
+ Applitools::Images::EyesImagesScreenshot.new sub_screenshot_image,
87
+ location: relative_sub_screenshot_region.location
88
+ end
89
+
90
+ private
91
+
92
+ def bounds
93
+ @bounds ||= Applitools::Region.new(0, 0, image.width, image.height)
94
+ end
95
+ end
96
+ end
@@ -6,20 +6,19 @@ module Applitools::Images
6
6
  class << self
7
7
  def path(path)
8
8
  raise Applitools::EyesIllegalArgument unless File.exist?(path)
9
- # new Applitools::Screenshot.from_image(ChunkyPNG::Image.from_file(path))
10
- new(path)
9
+ new Applitools::Screenshot.from_image(ChunkyPNG::Image.from_file(path))
11
10
  end
12
11
 
13
12
  def blob(blob_image)
14
13
  Applitools::ArgumentGuard.not_nil blob_image, 'blob_image'
15
14
  Applitools::ArgumentGuard.is_a? blob_image, 'blob_image', String
16
- new(blob_image)
15
+ new Applitools::Screenshot.from_datastream(blob_image)
17
16
  end
18
17
 
19
18
  def image(image)
20
19
  Applitools::ArgumentGuard.not_nil image, 'image'
21
- # Applitools::ArgumentGuard.is_a? image, 'image', ChunkyPNG::Image
22
- new(image)
20
+ Applitools::ArgumentGuard.is_a? image, 'image', ChunkyPNG::Image
21
+ new Applitools::Screenshot.from_image(image)
23
22
  end
24
23
 
25
24
  def screenshot(screenshot)
@@ -29,36 +28,28 @@ module Applitools::Images
29
28
  end
30
29
 
31
30
  def any(screenshot)
32
- new(screenshot)
31
+ case screenshot
32
+ when Applitools::Screenshot
33
+ screenshot(screenshot)
34
+ when ChunkyPNG::Image
35
+ image(screenshot)
36
+ when String
37
+ begin
38
+ blob(screenshot)
39
+ rescue ChunkyPNG::SignatureMismatch
40
+ path(screenshot)
41
+ end
42
+ else
43
+ raise Applitools::EyesIllegalArgument.new "Passed screenshot is not image type (#{screenshot.class})"
44
+ end
33
45
  end
34
46
  end
35
47
 
36
48
  attr_accessor :image, :options, :ignored_regions, :region_to_check, :floating_regions, :accessibility_regions
37
49
 
38
- def convert_image_arg(image_arg)
39
- if image_arg.is_a?(Applitools::Screenshot)
40
- Base64.strict_encode64(image_arg.to_blob).force_encoding('UTF-8')
41
- elsif image_arg.class.name === 'ChunkyPNG::Image'
42
- Base64.strict_encode64(image_arg.to_blob).force_encoding('UTF-8')
43
- elsif image_arg.is_a?(Hash) && !image_arg[:image_path].nil?
44
- image_arg[:image_path]
45
- elsif image_arg.is_a?(Hash) && !image_arg[:image].nil?
46
- Base64.strict_encode64(image_arg[:image]).force_encoding('UTF-8')
47
- elsif image_arg.is_a?(Hash)
48
- raise Applitools::EyesIllegalArgument.new "Image is unrecognized, try to use image_path: path_or_url or image: buffer"
49
- elsif image_arg.is_a?(String) && File.exist?(image_arg) # Path
50
- image_arg
51
- elsif image_arg.is_a?(String) # URL ? Buffer
52
- raise Applitools::EyesIllegalArgument.new "Passed image is not explicit, try to use image_path: path_or_url or image: buffer"
53
- else
54
- raise Applitools::EyesIllegalArgument.new "Passed image is unrecognized"
55
- end
56
- end
57
-
58
- def initialize(image_arg)
59
- image = convert_image_arg(image_arg)
50
+ def initialize(image)
60
51
  Applitools::ArgumentGuard.not_nil(image, 'image')
61
- Applitools::ArgumentGuard.is_a? image, 'image', String
52
+ Applitools::ArgumentGuard.is_a? image, 'image', Applitools::Screenshot
62
53
  self.image = image
63
54
  self.ignored_regions = []
64
55
  self.floating_regions = []
@@ -69,67 +60,47 @@ module Applitools::Images
69
60
  end
70
61
 
71
62
  def ignore(*args)
72
- region = region_from_args(args)
73
- ignored_regions << region if region
74
- self
75
- end
76
-
77
- def get_bounds(args)
78
- return args.pop.to_hash if args.last.is_a?(Applitools::FloatingBounds)
79
- last4 = args.last(4)
80
- if last4.size === 4 && last4.all? { |e| e.is_a?(Numeric) }
81
- FloatingBounds.new(*last4).to_hash
82
- else
83
- {}
84
- end
85
- end
86
-
87
- def region_from_args(args)
88
- options = Applitools::Utils.extract_options!(args)
89
- padding = options && options[:padding]
90
- requested_padding = get_requested_padding(padding, args)
91
- value = convert_to_universal(args)
92
- value = { type: args[0], selector: args[1] } if value.nil?
93
- value = value[:selector] if value.is_a?(Hash) && (value[:type].to_s === 'id')
94
- return nil if value === {selector: nil, type: nil}
95
- region = { region: value }
96
- region.merge!(padding: requested_padding) if requested_padding != {}
97
- region.merge!(regionId: options[:region_id]) if options[:region_id]
98
- region
99
- end
100
-
101
- def get_requested_padding(padding, args)
102
- return padding.to_hash if padding && padding.is_a?(Applitools::PaddingBounds)
103
- return padding if padding && (padding.is_a?(Hash) || padding.is_a?(Numeric))
104
- if args.last.is_a? Applitools::PaddingBounds
105
- args.pop
106
- # elsif args.last.is_a?(Applitools::FloatingBounds)
107
- # args.pop.to_hash
63
+ requested_padding = if args.last.is_a? Applitools::PaddingBounds
64
+ args.pop
65
+ else
66
+ Applitools::PaddingBounds::PIXEL_PADDING
67
+ end
68
+ region = args.shift
69
+ if region
70
+ Applitools::ArgumentGuard.is_a? region, 'region', Applitools::Region
71
+ ignored_regions << region.padding(requested_padding)
108
72
  else
109
- {}
73
+ self.ignored_regions = []
110
74
  end
75
+ self
111
76
  end
112
77
 
113
78
  def floating(*args)
114
- options = Applitools::Utils.extract_options!(args)
115
- padding = options && options[:padding]
116
- requested_padding = get_requested_padding(padding, args)
117
- bounds = get_bounds(args)
118
- value = convert_to_universal(args)
119
- value = { type: args[0], selector: args[1] } if value.nil?
120
- value = value[:selector] if value.is_a?(Hash) && (value[:type].to_s === 'id')
121
- region = { region: value }
122
- region.merge!(bounds) if bounds != {}
123
- region.merge!(padding: requested_padding) if requested_padding != {}
124
- region.merge!(regionId: options[:region_id]) if options[:region_id]
125
- floating_regions << region
79
+ requested_padding = if args.last.is_a? Applitools::PaddingBounds
80
+ args.pop
81
+ else
82
+ Applitools::PaddingBounds::PIXEL_PADDING
83
+ end
84
+
85
+ value = case args.first
86
+ when Applitools::FloatingRegion
87
+ proc { args.first.padding(requested_padding) }
88
+ when Applitools::Region
89
+ proc do
90
+ region = args.shift
91
+ Applitools::FloatingRegion.any(region, *args).padding(requested_padding)
92
+ end
93
+ else
94
+ self.floating_regions = []
95
+ end
96
+ floating_regions << value
126
97
  self
127
98
  end
128
99
 
129
100
  def region(region = nil)
130
101
  if region
131
102
  Applitools::ArgumentGuard.is_a? region, 'region', Applitools::Region
132
- self.region_to_check = region.to_hash
103
+ self.region_to_check = region
133
104
  else
134
105
  self.region_to_check = nil
135
106
  end
@@ -148,60 +119,5 @@ module Applitools::Images
148
119
  Applitools::AccessibilityRegion.new(region, accessibility_region_type)
149
120
  end
150
121
  end
151
-
152
-
153
-
154
- private # dupl
155
-
156
- def is_element?(el)
157
- el.is_a?(::Selenium::WebDriver::Element) || (el.is_a?(Applitools::Selenium::Element) && el.respond_to?(:ref))
158
- end
159
-
160
- def is_region?(region)
161
- region.is_a?(Applitools::FloatingRegion) || region.is_a?(Applitools::Region) # || region.is_a?(Applitools::Selenium::Element)
162
- end
163
-
164
- def is_finder?(finders)
165
- return false unless finders.is_a?(Array)
166
- return false unless finders[1]
167
- return true if [:uiautomator, :predicate, :accessibility_id].include?(finders[0].to_sym)
168
- Applitools::Selenium::Driver::FINDERS.has_key?(finders[0].to_sym)
169
- end
170
-
171
- def convert_to_universal(args)
172
- if is_element?(args.first)
173
- ref = args.first.ref
174
- ref = args.first.ref[1] if ref.is_a?(Array) && ref[0] === :element
175
- return { elementId: ref }
176
- end
177
- return args.first.to_hash if is_region?(args.first)
178
- if is_finder?(args)
179
- if Applitools::Selenium::Driver::FINDERS.has_key?(args[0])
180
- selector = args[1]
181
- selector = "##{args[1]}" if args[0] === :id && !args[1].start_with?('#') && instance_of?(Applitools::Selenium::Target)
182
- return {type: Applitools::Selenium::Driver::FINDERS[args[0]], selector: selector}
183
- end
184
- case args[0]
185
- when :uiautomator # ANDROID_UI_AUTOMATOR: '-android uiautomator'
186
- return {type: '-android uiautomator', selector: args[1]}
187
- when :predicate # IOS_PREDICATE: '-ios predicate string',
188
- return {type: '-ios predicate string', selector: args[1]}
189
- when :accessibility_id
190
- return {type: 'accessibility id', selector: args[1]}
191
- end
192
- end
193
- if args.first.is_a?(String)
194
- return proc { |driver| driver.find_element(name_or_id: args.first) }
195
- end
196
- if args.first.is_a?(Hash) && args.first.has_key?('selector')
197
- if args.first.has_key?('shadow')
198
- return {selector: args.first['selector'], shadow: args.first['shadow']}
199
- else
200
- return {selector: args.first['selector']}
201
- end
202
- end
203
- nil
204
- end
205
-
206
122
  end
207
123
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Applitools
4
- VERSION = '4.5.0.beta'.freeze
5
- IMAGES_VERSION = '4.0.0.alpha'.freeze
6
- UNIVERSAL_VERSION = '3.0.2'.freeze
4
+ VERSION = '4.0.0'.freeze
5
+ UNIVERSAL_VERSION = '1.0.6'.freeze
7
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eyes_images
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.alpha
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Applitools Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-28 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eyes_core
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 4.5.0.beta
19
+ version: 4.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 4.5.0.beta
26
+ version: 4.0.0
27
27
  description: Provides Images SDK for Applitools tests.
28
28
  email:
29
29
  - team@applitools.com
@@ -32,6 +32,7 @@ extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - lib/applitools/images/eyes.rb
35
+ - lib/applitools/images/eyes_images_screenshot.rb
35
36
  - lib/applitools/images/target.rb
36
37
  - lib/applitools/version.rb
37
38
  - lib/eyes_images.rb
@@ -51,11 +52,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
51
52
  version: '0'
52
53
  required_rubygems_version: !ruby/object:Gem::Requirement
53
54
  requirements:
54
- - - ">"
55
+ - - ">="
55
56
  - !ruby/object:Gem::Version
56
- version: 1.3.1
57
+ version: '0'
57
58
  requirements: []
58
- rubygems_version: 3.3.14
59
+ rubyforge_project:
60
+ rubygems_version: 2.6.14.3
59
61
  signing_key:
60
62
  specification_version: 4
61
63
  summary: Applitools Ruby Images SDK