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 +5 -5
- data/lib/applitools/images/eyes.rb +23 -27
- data/lib/applitools/images/eyes_images_screenshot.rb +96 -0
- data/lib/applitools/images/target.rb +50 -134
- data/lib/applitools/version.rb +2 -3
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 71125b4f052c21e79a5b50b6e553c079c55ee792
|
4
|
+
data.tar.gz: 3fc0aa90e059f26fd13f82f8cd01f4399bc93665
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
172
|
-
target = Applitools::Images::Target.any(
|
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:
|
188
|
+
options = { tag: nil, ignore_mismatch: false }.merge options
|
193
189
|
Applitools::ArgumentGuard.not_nil options[:region], 'options[:region] can\'t be nil!'
|
194
|
-
|
195
|
-
target = Applitools::Images::Target.any(
|
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
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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',
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
value =
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
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
|
data/lib/applitools/version.rb
CHANGED
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
|
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
|
+
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.
|
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.
|
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:
|
57
|
+
version: '0'
|
57
58
|
requirements: []
|
58
|
-
|
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
|