eyes_core 3.14.0 → 3.14.1
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.
- checksums.yaml +4 -4
- data/lib/applitools/calabash/calabash_element.rb +62 -0
- data/lib/applitools/calabash/calabash_screenshot_provider.rb +81 -0
- data/lib/applitools/calabash/environment_detector.rb +23 -0
- data/lib/applitools/calabash/eyes.rb +182 -0
- data/lib/applitools/calabash/eyes_calabash_android_screenshot.rb +56 -0
- data/lib/applitools/calabash/eyes_calabash_ios_screenshot.rb +28 -0
- data/lib/applitools/calabash/eyes_calabash_screenshot.rb +78 -0
- data/lib/applitools/calabash/eyes_hooks.rb +51 -0
- data/lib/applitools/calabash/eyes_settings.rb +43 -0
- data/lib/applitools/calabash/full_page_capture_algorithm.rb +24 -0
- data/lib/applitools/calabash/full_page_capture_algorithm/android_scroll_view.rb +85 -0
- data/lib/applitools/calabash/full_page_capture_algorithm/base.rb +49 -0
- data/lib/applitools/calabash/full_page_capture_algorithm/ios_ui_table_view.rb +148 -0
- data/lib/applitools/calabash/os_versions.rb +23 -0
- data/lib/applitools/calabash/rspec_matchers.rb +22 -0
- data/lib/applitools/calabash/steps/android_eyes_session.rb +35 -0
- data/lib/applitools/calabash/steps/android_matchers.rb +34 -0
- data/lib/applitools/calabash/steps/eyes_session.rb +40 -0
- data/lib/applitools/calabash/steps/eyes_settings.rb +57 -0
- data/lib/applitools/calabash/steps/ios_eyes_session.rb +13 -0
- data/lib/applitools/calabash/steps/ios_matchers.rb +15 -0
- data/lib/applitools/calabash/steps/matchers.rb +69 -0
- data/lib/applitools/calabash/target.rb +67 -0
- data/lib/applitools/calabash/utils.rb +72 -0
- data/lib/applitools/calabash_steps.rb +14 -0
- data/lib/applitools/chunky_png_patch.rb +1 -0
- data/lib/applitools/connectivity/server_connector.rb +5 -4
- data/lib/applitools/core/abstract_region.rb +16 -0
- data/lib/applitools/core/class_name.rb +7 -0
- data/lib/applitools/core/eyes_base.rb +2 -0
- data/lib/applitools/core/floating_region.rb +17 -4
- data/lib/applitools/core/fluent_interface.rb +8 -0
- data/lib/applitools/core/location.rb +7 -0
- data/lib/applitools/core/match_window_data.rb +1 -1
- data/lib/applitools/core/rectangle_size.rb +8 -2
- data/lib/applitools/core/region.rb +9 -1
- data/lib/applitools/rspec/target_matcher.rb +23 -0
- data/lib/applitools/utils/eyes_selenium_utils.rb +0 -2
- data/lib/applitools/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 345d3a061eb0bf58d16612a3d980272c7403f6c1
|
4
|
+
data.tar.gz: 9e1616f8250a11e3ea2f0e01c8e03f97a9b5616f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c89e9f459b886ae3d5e4925995b87284fd6eca7856da6732d8769533625674400500a19f38f1bbd03b7dad5b89341747cbeb9f2504088ec522dfaf144b80605
|
7
|
+
data.tar.gz: 0fdb85a76f80a5afd0809fc66356bb07e666ebb132b59f4f0464bcc4ffd641a64aee174b872b600074432d7491f1f02e1d27adbe4b44f60d402ff5e857fb7a50
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
class CalabashElement
|
4
|
+
extend Forwardable
|
5
|
+
attr_reader :original_element, :element_query
|
6
|
+
def_delegators :@original_element, :[], :keys, :values
|
7
|
+
|
8
|
+
def initialize(element, element_query)
|
9
|
+
raise Applitools::EyesIllegalArgument, "Invalid element passed! (#{element})" unless valid_element?(element)
|
10
|
+
@original_element = element
|
11
|
+
@element_query = element_query
|
12
|
+
end
|
13
|
+
|
14
|
+
def left
|
15
|
+
self['rect']['x']
|
16
|
+
end
|
17
|
+
|
18
|
+
alias x left
|
19
|
+
|
20
|
+
def top
|
21
|
+
self['rect']['y']
|
22
|
+
end
|
23
|
+
|
24
|
+
alias y top
|
25
|
+
|
26
|
+
def width
|
27
|
+
self['rect']['width']
|
28
|
+
end
|
29
|
+
|
30
|
+
def height
|
31
|
+
self['rect']['height']
|
32
|
+
end
|
33
|
+
|
34
|
+
def location
|
35
|
+
Applitools::Location.from_struct(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def size
|
39
|
+
Applitools::RectangleSize.from_struct(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def region
|
43
|
+
Applitools::Region.from_location_size(location, size)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
@original_element
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def valid_element?(element)
|
53
|
+
result = true
|
54
|
+
result &&= element.is_a?(Hash)
|
55
|
+
result &&= element.key?('rect')
|
56
|
+
result &&= (rect = element['rect']).is_a?(Hash)
|
57
|
+
result &&= (%w(height width y x center_x center_y) - rect.keys).empty?
|
58
|
+
result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
class CalabashScreenshotProvider
|
4
|
+
WAIT_BEFORE_SCREENSHOT = 1
|
5
|
+
attr_reader :density, :context, :debug_screenshot_provider
|
6
|
+
|
7
|
+
def initialize(_options = {})
|
8
|
+
@density = 1
|
9
|
+
end
|
10
|
+
|
11
|
+
def with_density(value)
|
12
|
+
@density = value
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def using_context(value)
|
17
|
+
@context = value
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_debug_screenshot_provider(value)
|
22
|
+
Applitools::ArgumentGuard.is_a?(
|
23
|
+
value,
|
24
|
+
'debug_screenshot_provider',
|
25
|
+
Applitools::DebugScreenshotProvider
|
26
|
+
)
|
27
|
+
@debug_screenshot_provider = value
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def save_debug_screenshot(screenshot, suffix)
|
34
|
+
suffix = suffix.join('_') if suffix.respond_to? :join
|
35
|
+
debug_screenshot_provider.save(screenshot, suffix || '') if debug_screenshot_provider
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class AndroidScreenshotProvider < CalabashScreenshotProvider
|
40
|
+
include Singleton
|
41
|
+
|
42
|
+
def capture_screenshot(options = {})
|
43
|
+
sleep WAIT_BEFORE_SCREENSHOT
|
44
|
+
result = nil
|
45
|
+
Applitools::Calabash::Utils.using_screenshot(context) do |screenshot_path|
|
46
|
+
screenshot = ::ChunkyPNG::Image.from_file(screenshot_path)
|
47
|
+
save_debug_screenshot(screenshot, ['original', options[:debug_suffix]])
|
48
|
+
viewport_size = Applitools::Calabash::EyesSettings.instance.viewport_size
|
49
|
+
screenshot.crop!(0, 0, viewport_size[:width], viewport_size[:height])
|
50
|
+
save_debug_screenshot(screenshot, ['cropped', options[:debug_suffix]])
|
51
|
+
result = Applitools::Calabash::EyesCalabashAndroidScreenshot.new(
|
52
|
+
Applitools::Screenshot.from_image(
|
53
|
+
screenshot
|
54
|
+
),
|
55
|
+
density: density
|
56
|
+
)
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class IosScreenshotProvider < CalabashScreenshotProvider
|
63
|
+
include Singleton
|
64
|
+
def capture_screenshot(options = {})
|
65
|
+
sleep WAIT_BEFORE_SCREENSHOT
|
66
|
+
result = nil
|
67
|
+
Applitools::Calabash::Utils.using_screenshot(context) do |screenshot_path|
|
68
|
+
screenshot = ::ChunkyPNG::Image.from_file(screenshot_path)
|
69
|
+
save_debug_screenshot(screenshot, options[:debug_suffix])
|
70
|
+
result = Applitools::Calabash::EyesCalabashIosScreenshot.new(
|
71
|
+
Applitools::Screenshot.from_image(
|
72
|
+
screenshot
|
73
|
+
),
|
74
|
+
scale_factor: density
|
75
|
+
)
|
76
|
+
end
|
77
|
+
result
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
module EnvironmentDetector
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def android?
|
7
|
+
return true if defined?(::Calabash::Android) == 'constant'
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def ios?
|
12
|
+
return true if defined?(::Calabash::Cucumber) == 'constant'
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def current_environment
|
17
|
+
return :android if android?
|
18
|
+
return :ios if ios?
|
19
|
+
raise Applitools::EyesError, 'No calabash environment found!'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
module Applitools
|
2
|
+
module Calabash
|
3
|
+
class Eyes < Applitools::EyesBase
|
4
|
+
attr_accessor :device_pixel_ratio, :full_page_capture_algorithm, :base_agent_id, :title,
|
5
|
+
:debug_screenshot, :debug_screenshot_provider, :tag_for_debug
|
6
|
+
attr_reader :context
|
7
|
+
|
8
|
+
def initialize(server_url = Applitools::Connectivity::ServerConnector::DEFAULT_SERVER_URL)
|
9
|
+
super
|
10
|
+
self.base_agent_id = "eyes.calabash.ruby/#{Applitools::VERSION}".freeze
|
11
|
+
self.debug_screenshot = true
|
12
|
+
self.debug_screenshot_provider = Applitools::DebugScreenshotProvider.new
|
13
|
+
.tag_access { tag_for_debug }
|
14
|
+
.debug_flag_access { debug_screenshot }
|
15
|
+
end
|
16
|
+
|
17
|
+
def open(options = {})
|
18
|
+
Applitools::ArgumentGuard.hash options, 'open(options)', [:app_name, :test_name]
|
19
|
+
# options[:viewport_size] = Applitools::RectangleSize.from_any_argument options[:viewport_size]
|
20
|
+
open_base options
|
21
|
+
end
|
22
|
+
|
23
|
+
def check(name, target)
|
24
|
+
self.tag_for_debug = get_tag_for_debug(name)
|
25
|
+
check_it(name, target, Applitools::MatchWindowData.new)
|
26
|
+
end
|
27
|
+
|
28
|
+
def inferred_environment
|
29
|
+
return @inferred_environment unless @inferred_environment.nil?
|
30
|
+
return unless device_pixel_ratio
|
31
|
+
"device pixel ratio: #{device_pixel_ratio}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_context(value)
|
35
|
+
@context = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def remove_context
|
39
|
+
@context = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def capture_screenshot
|
43
|
+
return screenshot_provider.capture_screenshot(debug_suffix: tag_for_debug) unless full_page_capture_algorithm
|
44
|
+
full_page_capture_algorithm.get_stitched_region
|
45
|
+
end
|
46
|
+
|
47
|
+
def screenshot_provider
|
48
|
+
env = Applitools::Calabash::EnvironmentDetector.current_environment
|
49
|
+
case env
|
50
|
+
when :android
|
51
|
+
Applitools::Calabash::AndroidScreenshotProvider.instance.with_density(device_pixel_ratio)
|
52
|
+
.using_context(context)
|
53
|
+
.with_debug_screenshot_provider(debug_screenshot_provider)
|
54
|
+
when :ios
|
55
|
+
Applitools::Calabash::IosScreenshotProvider.instance.with_density(device_pixel_ratio)
|
56
|
+
.using_context(context)
|
57
|
+
.with_debug_screenshot_provider(debug_screenshot_provider)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def check_it(name, target, match_window_data)
|
62
|
+
Applitools::ArgumentGuard.not_nil(name, 'name')
|
63
|
+
|
64
|
+
logger.info 'Full element requested' if target.options[:stitch_content]
|
65
|
+
|
66
|
+
self.full_page_capture_algorithm = target.options[:stitch_content] &&
|
67
|
+
get_full_page_capture_algorithm(target.region_to_check)
|
68
|
+
|
69
|
+
region_provider = if full_page_capture_algorithm
|
70
|
+
entire_screenshot_region
|
71
|
+
else
|
72
|
+
get_region_provider(target)
|
73
|
+
end
|
74
|
+
|
75
|
+
match_window_data.tag = name
|
76
|
+
update_default_settings(match_window_data)
|
77
|
+
match_window_data.read_target(target, nil)
|
78
|
+
|
79
|
+
self.viewport_size = Applitools::Calabash::EyesSettings.instance.viewport_size if viewport_size.nil?
|
80
|
+
|
81
|
+
if match_window_data.is_a? Applitools::MatchSingleCheckData
|
82
|
+
return check_single_base(
|
83
|
+
region_provider,
|
84
|
+
target.options[:timeout] || Applitools::EyesBase::USE_DEFAULT_TIMEOUT,
|
85
|
+
match_window_data
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
check_window_base(
|
90
|
+
region_provider,
|
91
|
+
target.options[:timeout] || Applitools::EyesBase::USE_DEFAULT_TIMEOUT,
|
92
|
+
match_window_data
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_region_provider(target)
|
97
|
+
if (region_to_check = target.region_to_check).nil?
|
98
|
+
entire_screenshot_region
|
99
|
+
else
|
100
|
+
region_for_element(region_to_check)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_app_output_with_screenshot(*args)
|
105
|
+
# super do |screenshot|
|
106
|
+
# screenshot.scale_it!
|
107
|
+
# end
|
108
|
+
super(*args, &:scale_it!)
|
109
|
+
end
|
110
|
+
|
111
|
+
def entire_screenshot_region
|
112
|
+
Object.new.tap do |prov|
|
113
|
+
prov.instance_eval do
|
114
|
+
define_singleton_method :region do
|
115
|
+
Applitools::Region::EMPTY
|
116
|
+
end
|
117
|
+
|
118
|
+
define_singleton_method :coordinate_type do
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def region_for_element(region_to_check)
|
126
|
+
Object.new.tap do |prov|
|
127
|
+
prov.instance_eval do
|
128
|
+
define_singleton_method :region do
|
129
|
+
case region_to_check
|
130
|
+
when Applitools::Calabash::CalabashElement
|
131
|
+
region_to_check.region
|
132
|
+
when Applitools::Region
|
133
|
+
region_to_check
|
134
|
+
else
|
135
|
+
raise Applitools::EyesError, "Incompatible region type: #{region_to_check.class}"
|
136
|
+
end
|
137
|
+
# region_to_check.respond_to?(:region) ? region_to_check.region : region_to_check
|
138
|
+
end
|
139
|
+
define_singleton_method :coordinate_type do
|
140
|
+
Applitools::Calabash::EyesCalabashScreenshot::DRIVER
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def vp_size
|
147
|
+
viewport_size
|
148
|
+
end
|
149
|
+
|
150
|
+
def vp_size=(value, skip_check_if_open = false)
|
151
|
+
unless skip_check_if_open || open?
|
152
|
+
raise Applitools::EyesNotOpenException.new 'set_viewport_size: Eyes not open!'
|
153
|
+
end
|
154
|
+
Applitools::ArgumentGuard.not_nil 'value', value
|
155
|
+
@viewport_size = Applitools::RectangleSize.for value
|
156
|
+
end
|
157
|
+
|
158
|
+
alias get_viewport_size vp_size
|
159
|
+
alias set_viewport_size vp_size=
|
160
|
+
|
161
|
+
def get_full_page_capture_algorithm(element)
|
162
|
+
logger.info "Trying to get full page capture algorithm for element #{element}..."
|
163
|
+
environment = Applitools::Calabash::EnvironmentDetector.current_environment
|
164
|
+
element_class = Applitools::Calabash::Utils.send("grub_#{environment}_class_name", context, element).first
|
165
|
+
logger.info "Trying to get FullPageCaptureAlgorithm for #{element_class}..."
|
166
|
+
algo = Applitools::Calabash::FullPageCaptureAlgorithm.get_algorithm_class(environment, element_class)
|
167
|
+
if algo
|
168
|
+
logger.info "Using #{algo}"
|
169
|
+
algo = algo.new(screenshot_provider, element, debug_screenshot_provider: debug_screenshot_provider)
|
170
|
+
else
|
171
|
+
logger.info "FullPageCaptureAlgorithm for #{element_class} not found. Continue with :check_region instead"
|
172
|
+
end
|
173
|
+
algo
|
174
|
+
end
|
175
|
+
|
176
|
+
def get_tag_for_debug(name)
|
177
|
+
return "#{current_app_name} #{test_name}" if name.empty?
|
178
|
+
"#{current_app_name} #{test_name} - #{name}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'eyes_calabash_screenshot'
|
2
|
+
module Applitools
|
3
|
+
module Calabash
|
4
|
+
class EyesCalabashAndroidScreenshot < ::Applitools::Calabash::EyesCalabashScreenshot
|
5
|
+
ANDROID_DENSITY = {
|
6
|
+
120 => 0.75,
|
7
|
+
160 => 1,
|
8
|
+
213 => 1.33,
|
9
|
+
240 => 1.5,
|
10
|
+
320 => 2,
|
11
|
+
480 => 3
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def initialize(*args)
|
15
|
+
options = if args.last.is_a? Hash
|
16
|
+
args.pop
|
17
|
+
else
|
18
|
+
{}
|
19
|
+
end
|
20
|
+
super(*args)
|
21
|
+
@scale_factor = nil
|
22
|
+
self.density = options[:density] if options[:density]
|
23
|
+
@scale_factor ||= options[:scale_factor]
|
24
|
+
@scale_factor = 1 unless @scale_factor
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert_region_location(region, from, to)
|
28
|
+
case from
|
29
|
+
when DRIVER
|
30
|
+
case to
|
31
|
+
when SCREENSHOT_AS_IS
|
32
|
+
region
|
33
|
+
else
|
34
|
+
raise Applitools::EyesError, "from: #{from}, to: #{to}"
|
35
|
+
end
|
36
|
+
when CONTEXT_RELATIVE
|
37
|
+
case to
|
38
|
+
when SCREENSHOT_AS_IS
|
39
|
+
region.scale_it!(1.to_f / scale_factor) # !!!!!!
|
40
|
+
region
|
41
|
+
else
|
42
|
+
raise Applitools::EyesError, "from: #{from}, to: #{to}"
|
43
|
+
end
|
44
|
+
else
|
45
|
+
raise Applitools::EyesError, "from: #{from}, to: #{to}"
|
46
|
+
end
|
47
|
+
region
|
48
|
+
end
|
49
|
+
|
50
|
+
def density=(value)
|
51
|
+
raise Applitools::EyesIllegalArgument, "Unknown density = #{value}" unless ANDROID_DENSITY[value.to_i]
|
52
|
+
@scale_factor = ANDROID_DENSITY[value.to_i]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'eyes_calabash_screenshot'
|
2
|
+
module Applitools
|
3
|
+
module Calabash
|
4
|
+
class EyesCalabashIosScreenshot < Applitools::Calabash::EyesCalabashScreenshot
|
5
|
+
def convert_region_location(region, from, to)
|
6
|
+
case from
|
7
|
+
when DRIVER
|
8
|
+
case to
|
9
|
+
when SCREENSHOT_AS_IS
|
10
|
+
region.scale_it!(scale_factor)
|
11
|
+
else
|
12
|
+
raise Applitools::EyesError, "from: #{from}, to: #{to}"
|
13
|
+
end
|
14
|
+
when CONTEXT_RELATIVE
|
15
|
+
case to
|
16
|
+
when SCREENSHOT_AS_IS
|
17
|
+
region
|
18
|
+
else
|
19
|
+
raise Applitools::EyesError, "from: #{from}, to: #{to}"
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise Applitools::EyesError, "from: #{from}, to: #{to}"
|
23
|
+
end
|
24
|
+
region
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|