eyes_core 3.16.15 → 3.17.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e00bd1d272774a42a3cd33cebe385b3aa9a6e53cdb627f625f4503d7950fa822
4
- data.tar.gz: 6f7396c9774c8332c926dce7f62f0ba9573ad920294589af3c435a6588c3dc54
3
+ metadata.gz: c787872bfae6a5ebff57943e35298ec87694ddb2c981da7269d153c0070feab9
4
+ data.tar.gz: 3879aa521a421e7ad6ad454de14ded53873bf04fe931dcf5088c143e564a22cf
5
5
  SHA512:
6
- metadata.gz: 7a78447c0ca43e4e3905fd0ef3068dc754461283a2defa0551c5fdef9583e8d3f783904acb4c35c86fc31878e190bf2b3929dd536369de1ba455283966ff1256
7
- data.tar.gz: 4a854afdcf564e0aca48cace6f77368ac315730659d2e85b871bddfd290eaff665c3226f3e6f558dff384c8de5d7c5ff088c98203c6e0e8e81f7b560571d3951
6
+ metadata.gz: f75c0d8811e9d2dfe57af4e4c43122dc0f501db4fbf14024218fd2c8c0c5d6e654953c17b57d66913ce4eb7255ad73bdd74bc432c8de8233f20caccd6e553b63
7
+ data.tar.gz: cab966515a359bdccbb8e42dd43195624e9bd96ecc376ee29b3fddf17e5ed8520201b5a53221ed0dd8de7dc73c38418fdc4022ca2f8edc54dc0809f757c3eb46
@@ -0,0 +1,21 @@
1
+ require_relative './screenshot.rb'
2
+ module Applitools
3
+ module Appium
4
+ class AndroidScreenshot < Applitools::Appium::Screenshot
5
+ def convert_region_location(region, from, to)
6
+ # converted_size = region.size.dup.scale_it!(1 / device_pixel_ratio)
7
+ # converted_location = region.location.dup.offset_negative(Applitools::Location.new(0, status_bar_height)).scale_it!(1 / device_pixel_ratio)
8
+ # Applitools::Region.from_location_size(converted_location, converted_size)
9
+ Applitools::Region.from_location_size(
10
+ convert_location(region.location, nil, nil),
11
+ region.size
12
+ ).scale_it!(1.to_f / device_pixel_ratio)
13
+ end
14
+
15
+ def convert_location(location, _from, _to)
16
+ location.offset_negative(Applitools::Location.new(0, status_bar_height))
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -2,10 +2,11 @@
2
2
 
3
3
  module Applitools::Appium
4
4
  class Driver < Applitools::Selenium::Driver
5
- attr_accessor :appium_driver
6
5
  def initialize(eyes, options)
7
- self.appium_driver = options.delete(:appium_driver)
8
6
  super(eyes, options)
9
7
  end
8
+ module AppiumLib
9
+ extend self
10
+ end
10
11
  end
11
12
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
4
+ attr_accessor :status_bar_height
4
5
  def perform_driver_settings_for_appium_driver
5
6
  self.region_visibility_strategy = Applitools::Selenium::NopRegionVisibilityStrategy.new
6
7
  self.force_driver_resolution_as_viewport_size = true
@@ -11,6 +12,7 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
11
12
  self.dont_get_title = true
12
13
  self.runner = Applitools::ClassicRunner.new
13
14
  self.base_agent_id = "eyes.appium.ruby/#{Applitools::VERSION}".freeze
15
+ self.status_bar_height = 0
14
16
  end
15
17
 
16
18
  private :perform_driver_settings_for_appium_driver
@@ -76,7 +78,7 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
76
78
  result = super do |screenshot|
77
79
  if scale_provider
78
80
  scaled_image = scale_provider.scale_image(screenshot.image)
79
- self.screenshot = Applitools::Appium::Screenshot.new(
81
+ self.screenshot = screenshot_class.new(
80
82
  Applitools::Screenshot.from_image(
81
83
  case scaled_image
82
84
  when ChunkyPNG::Image
@@ -86,7 +88,9 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
86
88
  else
87
89
  raise Applitools::EyesError.new('Unknown image format after scale!')
88
90
  end
89
- )
91
+ ),
92
+ status_bar_height: Applitools::Utils::EyesSeleniumUtils.status_bar_height(driver),
93
+ device_pixel_ratio: Applitools::Utils::EyesSeleniumUtils.device_pixel_ratio(driver)
90
94
  )
91
95
  end
92
96
  end
@@ -115,17 +119,22 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
115
119
 
116
120
  def viewport_screenshot
117
121
  logger.info 'Viewport screenshot requested...'
118
- self.screenshot = Applitools::Appium::Screenshot.new(
122
+
123
+ self.screenshot = screenshot_class.new(
119
124
  Applitools::Screenshot.from_datastream(driver.screenshot_as(:png))
120
125
  )
121
126
  end
122
127
 
123
128
  def element_screenshot
124
129
  logger.info 'Element screenshot requested...'
125
- self.screenshot = Applitools::Appium::Screenshot.new(
126
- Applitools::Screenshot.from_datastream(
127
- driver.element_screenshot_as(eyes_element_to_check, :png)
128
- )
130
+ self.screenshot = screenshot_class.new(
131
+ Applitools::Screenshot.from_datastream(driver.element_screenshot_as(eyes_element_to_check, :png))
129
132
  )
130
133
  end
134
+
135
+ def screenshot_class
136
+ return Applitools::Appium::IosScreenshot if Applitools::Utils::EyesSeleniumUtils.ios?(Applitools::Appium::Driver::AppiumLib)
137
+ return Applitools::Appium::AndroidScreenshot if Applitools::Utils::EyesSeleniumUtils.android?(Applitools::Appium::Driver::AppiumLib)
138
+ raise Applitools::EyesError, 'Unknown device type'
139
+ end
131
140
  end
@@ -0,0 +1,10 @@
1
+ require_relative './screenshot.rb'
2
+ module Applitools
3
+ module Appium
4
+ class IosScreenshot < Applitools::Appium::Screenshot
5
+ def convert_location(location, _from, _to)
6
+ location.offset_negative(Applitools::Location.new(0, status_bar_height))
7
+ end
8
+ end
9
+ end
10
+ end
@@ -3,6 +3,16 @@
3
3
  module Applitools
4
4
  module Appium
5
5
  class Screenshot < Applitools::EyesScreenshot
6
+
7
+ attr_reader :status_bar_height, :device_pixel_ratio
8
+
9
+ def initialize(*args)
10
+ options = Applitools::Utils.extract_options!(args)
11
+ @status_bar_height = options[:status_bar_height] || 0
12
+ @device_pixel_ratio = options[:device_pixel_ratio] || 1
13
+ super
14
+ end
15
+
6
16
  def sub_screenshot(region, _coordinate_type, _throw_if_clipped = false, _force_nil_if_clipped = false)
7
17
  self.class.new(
8
18
  Applitools::Screenshot.from_image(
@@ -10,6 +20,11 @@ module Applitools
10
20
  )
11
21
  )
12
22
  end
23
+
24
+ def convert_location(location, _from, _to)
25
+ raise 'Applitools::Appium::Screenshot is an abstract class.' \
26
+ ' You should implement :convert_location method in a descendant class.'
27
+ end
13
28
  end
14
29
  end
15
30
  end
@@ -4,8 +4,7 @@ module Applitools
4
4
  module Appium
5
5
  class Target
6
6
  include Applitools::FluentInterface
7
-
8
- attr_accessor :region_to_check, :options
7
+ attr_accessor :region_to_check, :options, :ignored_regions, :floating_regions, :layout_regions, :content_regions, :strict_regions, :accessibility_regions
9
8
 
10
9
  class << self
11
10
  def window
@@ -19,6 +18,12 @@ module Applitools
19
18
 
20
19
  def initialize
21
20
  self.region_to_check = proc { Applitools::Region::EMPTY }
21
+ self.ignored_regions = []
22
+ self.floating_regions = []
23
+ self.layout_regions = []
24
+ self.content_regions = []
25
+ self.strict_regions = []
26
+ self.accessibility_regions = []
22
27
  self.options = {}
23
28
  end
24
29
 
@@ -34,9 +39,170 @@ module Applitools
34
39
  self
35
40
  end
36
41
 
42
+ def ignore(*args)
43
+ requested_padding = if args.last.is_a? Applitools::PaddingBounds
44
+ args.pop
45
+ else
46
+ Applitools::PaddingBounds::ZERO_PADDING
47
+ end
48
+ ignored_regions << case (first_argument = args.first)
49
+ when ::Selenium::WebDriver::Element
50
+ proc do
51
+ Applitools::Region
52
+ .from_location_size(first_argument.location, first_argument.size)
53
+ .padding(requested_padding)
54
+ end
55
+ when Applitools::Region
56
+ result = first_argument.padding(requested_padding)
57
+ if Applitools::Utils::EyesSeleniumUtils.ios?(Applitools::Appium::Driver::AppiumLib)
58
+ def result.converted?
59
+ true
60
+ end
61
+ end
62
+ result
63
+ else
64
+ proc do |driver|
65
+ element = driver.find_element(*args)
66
+ Applitools::Region
67
+ .from_location_size(element.location, element.size)
68
+ .padding(requested_padding)
69
+ end
70
+ end
71
+ self
72
+ end
73
+
74
+ def floating(*args)
75
+ value = case args.first
76
+ when Applitools::FloatingRegion
77
+ args.first
78
+ when Applitools::Region
79
+ result = Applitools::FloatingRegion.any(*args)
80
+ if Applitools::Utils::EyesSeleniumUtils.ios?(Applitools::Appium::Driver::AppiumLib)
81
+ def result.converted?
82
+ true
83
+ end
84
+ end
85
+ result
86
+ when ::Selenium::WebDriver::Element
87
+ args_dup = args.dup
88
+ Applitools::FloatingRegion.any(*args_dup)
89
+ else
90
+ proc do |driver|
91
+ args_dup = args.dup
92
+ region = driver.find_element(args_dup.shift, args_dup.shift)
93
+ Applitools::FloatingRegion.any(
94
+ region, *args_dup
95
+ )
96
+ end
97
+ end
98
+ floating_regions << value
99
+ self
100
+ end
101
+
102
+ def layout
103
+ return match_level(Applitools::MatchLevel::LAYOUT) if args.empty?
104
+ region = process_region(*args)
105
+ layout_regions << region
106
+ self
107
+
108
+ end
109
+
110
+ def content(*args)
111
+ return match_level(Applitools::MatchLevel::CONTENT) if args.empty?
112
+ region = process_region(*args)
113
+ content_regions << region
114
+ self
115
+ end
116
+
117
+ def strict(*args)
118
+ return match_level(Applitools::MatchLevel::STRICT) if args.empty?
119
+ region = process_region(*args)
120
+ strict_regions << region
121
+ self
122
+ end
123
+
124
+ def exact(*args)
125
+ match_level(Applitools::MatchLevel::EXACT, *args)
126
+ end
127
+
128
+ def accessibility(*args)
129
+ options = Applitools::Utils.extract_options! args
130
+ unless options[:type]
131
+ raise Applitools::EyesError,
132
+ 'You should call Target.accessibility(region, type: type). The region_type option is required'
133
+ end
134
+ unless Applitools::AccessibilityRegionType.enum_values.include?(options[:type])
135
+ raise Applitools::EyesIllegalArgument,
136
+ "The region type should be one of [#{Applitools::AccessibilityRegionType.enum_values.join(', ')}]"
137
+ end
138
+
139
+ accessibility_regions << case args.first
140
+ when ::Selenium::WebDriver::Element
141
+ element = args.first
142
+ Applitools::AccessibilityRegion.new(
143
+ element,
144
+ options[:type]
145
+ )
146
+ when Applitools::Region
147
+ result = Applitools::AccessibilityRegion.new(
148
+ args.first, options[:type]
149
+ )
150
+ if Applitools::Utils::EyesSeleniumUtils.ios?(Applitools::Appium::Driver::AppiumLib)
151
+ def result.converted?
152
+ true
153
+ end
154
+ end
155
+ result
156
+ when String
157
+ proc do |driver|
158
+ element = driver.find_element(name_or_id: args.first)
159
+ Applitools::AccessibilityRegion.new(
160
+ element,
161
+ options[:type]
162
+ )
163
+ end
164
+ else
165
+ proc do |driver|
166
+ elements = driver.find_elements(*args)
167
+ elements.map do |e|
168
+ Applitools::AccessibilityRegion.new(
169
+ e,
170
+ options[:type]
171
+ )
172
+ end
173
+ end
174
+ end
175
+ self
176
+ end
177
+
37
178
  def finalize
38
179
  self
39
180
  end
181
+
182
+ private
183
+
184
+ def process_region(*args)
185
+ r = args.first
186
+ case r
187
+ when ::Selenium::WebDriver::Element
188
+ proc do |driver|
189
+ Applitools::Region.from_location_size(r.location, r.size)
190
+ end
191
+ when Applitools::Region
192
+ if Applitools::Utils::EyesSeleniumUtils.ios?(Applitools::Appium::Driver::AppiumLib)
193
+ def r.converted?
194
+ true
195
+ end
196
+ end
197
+ r
198
+ else
199
+ proc do |driver|
200
+ element = driver.find_element(*args)
201
+ Applitools::Region.from_location_size(element.location, element.size)
202
+ end
203
+ end
204
+ end
205
+
40
206
  end
41
207
  end
42
208
  end
@@ -4,7 +4,9 @@ module Applitools::Appium
4
4
  module Utils
5
5
  # true if test is running on mobile device
6
6
  def mobile_device?(driver)
7
- defined?(Appium::Driver) && driver.respond_to?(:appium_driver) && driver.appium_driver
7
+ defined?(Appium::Driver) &&
8
+ defined?(Applitools::Appium::Driver::AppiumLib) &&
9
+ Applitools::Appium::Driver::AppiumLib
8
10
  end
9
11
 
10
12
  # true if test is running on Android device
@@ -19,18 +21,26 @@ module Applitools::Appium
19
21
 
20
22
  # @param [Applitools::Selenium::Driver] driver
21
23
  def platform_version(driver)
22
- driver.respond_to?(:caps) && driver.caps[:platformVersion]
24
+ driver.respond_to?(:platform_version) && driver.platform_version
23
25
  end
24
26
 
25
27
  # @param [Applitools::Selenium::Driver] executor
26
28
  def device_pixel_ratio(executor)
27
- if executor.respond_to? :session_capabilities
28
- session_info = executor.session_capabilities
29
- return session_info['pixelRatio'].to_f if session_info['pixelRatio']
30
- end
29
+ session_info = session_capabilities(executor)
30
+ return session_info['pixelRatio'].to_f if session_info['pixelRatio']
31
31
  Applitools::Selenium::Eyes::UNKNOWN_DEVICE_PIXEL_RATIO
32
32
  end
33
33
 
34
+ def status_bar_height(executor)
35
+ session_info = session_capabilities(executor)
36
+ return session_info['statBarHeight'].to_i if session_info['statBarHeight']
37
+ 0
38
+ end
39
+
40
+ def session_capabilities(executor)
41
+ executor.session_capabilities if executor.respond_to? :session_capabilities
42
+ end
43
+
34
44
  def current_scroll_position(driver)
35
45
  super
36
46
  rescue
@@ -279,9 +279,7 @@ module Applitools::Connectivity
279
279
  end
280
280
 
281
281
  def start_session(session_start_info)
282
- request_body = Oj.dump(
283
- startInfo: Applitools::Utils.camelcase_hash_keys(session_start_info.to_hash)
284
- )
282
+ request_body = session_start_info.json
285
283
  res = long_post(
286
284
  endpoint_url, body: request_body
287
285
  )
@@ -11,9 +11,11 @@ module Applitools
11
11
  def initialize
12
12
  @config_hash = {}
13
13
  self.validation_errors = {}
14
- default_config = self.class.default_config
15
- default_config.keys.each do |k|
16
- send "#{k}=", default_config[k]
14
+ if self.class.respond_to? :default_config
15
+ default_config = self.class.default_config
16
+ default_config.keys.each do |k|
17
+ send "#{k}=", default_config[k]
18
+ end
17
19
  end
18
20
  end
19
21
 
@@ -3,12 +3,44 @@
3
3
  module Applitools
4
4
  module AccessibilityLevel
5
5
  extend self
6
- NONE = 'None'
7
6
  AA = 'AA'
8
7
  AAA = 'AAA'
9
8
 
10
9
  def enum_values
11
- [NONE, AA, AAA]
10
+ [AA, AAA]
11
+ end
12
+ end
13
+
14
+ module AccessibilityGuidelinesVersion
15
+ extend self
16
+ WCAG_2_1 = 'WCAG_2_1'
17
+ WCAG_2_0 = 'WCAG_2_0'
18
+ def enum_values
19
+ [WCAG_2_0, WCAG_2_1]
20
+ end
21
+ end
22
+
23
+ class AccessibilitySettings
24
+ attr_reader :config_hash
25
+ attr_accessor :validation_errors
26
+ extend Applitools::EyesConfigurationDSL
27
+
28
+ enum_field :level, Applitools::AccessibilityLevel.enum_values
29
+ enum_field :version, Applitools::AccessibilityGuidelinesVersion.enum_values
30
+
31
+ def initialize(accessibility_level, guidelines_version)
32
+ @config_hash = {}
33
+ self.validation_errors = []
34
+ self.level = accessibility_level
35
+ self.version = guidelines_version
36
+ end
37
+
38
+ def to_h
39
+ @config_hash
40
+ end
41
+
42
+ def json_data
43
+ to_h
12
44
  end
13
45
  end
14
46
  end
@@ -4,7 +4,6 @@ module Applitools
4
4
  module AccessibilityRegionType
5
5
  extend self
6
6
 
7
- NONE = 'None'
8
7
  IGNORE_CONTRAST = 'IgnoreContrast'
9
8
  REGULAR_TEXT = 'RegularText'
10
9
  LARGE_TEXT = 'LargeText'
@@ -13,7 +12,6 @@ module Applitools
13
12
 
14
13
  def enum_values
15
14
  [
16
- NONE,
17
15
  IGNORE_CONTRAST,
18
16
  REGULAR_TEXT,
19
17
  LARGE_TEXT,
@@ -12,16 +12,20 @@ module Applitools
12
12
  self.device_info = options[:device_info]
13
13
  end
14
14
 
15
- def to_hash
15
+ def json_data
16
16
  {
17
- 'os' => os,
18
- 'hostingApp' => hosting_app,
19
- 'displaySize' => display_size && display_size.to_hash,
20
- 'inferred' => inferred_environment,
21
- 'deviceInfo' => device_info.nil? || device_info.empty? ? 'Desktop' : device_info + ' (Chrome emulation)'
17
+ 'os' => os,
18
+ 'hostingApp' => hosting_app,
19
+ 'displaySize' => display_size && display_size.to_hash,
20
+ 'inferred' => inferred_environment,
21
+ 'deviceInfo' => device_info.nil? || device_info.empty? ? 'Desktop' : device_info
22
22
  }
23
23
  end
24
24
 
25
+ def to_hash
26
+ json_data
27
+ end
28
+
25
29
  def to_s
26
30
  result = ''
27
31
  to_hash.each_pair do |k, v|
@@ -19,16 +19,20 @@ module Applitools
19
19
  self.id = SecureRandom.uuid unless id
20
20
  end
21
21
 
22
- def to_hash
22
+ def json_data
23
23
  {
24
- 'id' => id,
25
- 'name' => name,
26
- 'startedAt' => @started_at.iso8601,
27
- 'batchSequenceName' => sequence_name,
28
- 'notifyOnCompletion' => 'true'.casecmp(notify_on_completion || '') == 0 ? true : false
24
+ 'id' => id,
25
+ 'name' => name,
26
+ 'startedAt' => @started_at.iso8601,
27
+ 'batchSequenceName' => sequence_name,
28
+ 'notifyOnCompletion' => 'true'.casecmp(notify_on_completion || '') == 0 ? true : false
29
29
  }
30
30
  end
31
31
 
32
+ def to_hash
33
+ json_data
34
+ end
35
+
32
36
  def to_s
33
37
  to_hash.to_s
34
38
  end
@@ -87,7 +87,6 @@ module Applitools
87
87
  self.results = []
88
88
  self.allow_empty_screenshot = true
89
89
  @inferred_environment = nil
90
- @properties = []
91
90
  @server_scale = 0
92
91
  @server_remainder = 0
93
92
  get_app_output_method = ->(r, s) { get_app_output_with_screenshot r, s }
@@ -151,10 +150,6 @@ module Applitools
151
150
  running_session && running_session.new_session?
152
151
  end
153
152
 
154
- def add_property(name, value)
155
- @properties << { name: name, value: value }
156
- end
157
-
158
153
  def abort_if_not_closed
159
154
  if disabled?
160
155
  logger.info "#{__method__} Ignored"
@@ -319,11 +314,14 @@ module Applitools
319
314
 
320
315
  tag = '' if tag.nil?
321
316
 
322
- session_start_info = SessionStartInfo.new agent_id: base_agent_id, app_id_or_name: app_name,
323
- scenario_id_or_name: test_name, batch_info: batch,
324
- env_name: baseline_env_name, environment: app_environment,
325
- default_match_settings: default_match_settings.json_data,
326
- branch_name: branch_name, parent_branch_name: parent_branch_name, properties: properties
317
+ self.session_start_info = SessionStartInfo.new agent_id: base_agent_id, app_id_or_name: app_name,
318
+ scenario_id_or_name: test_name, batch_info: batch,
319
+ baseline_env_name: baseline_env_name, environment: app_env,
320
+ default_match_settings: default_match_settings,
321
+ environment_name: environment_name, session_type: session_type,
322
+ branch_name: branch_name, parent_branch_name: parent_branch_name,
323
+ baseline_branch_name: baseline_branch_name, save_diffs: save_diffs,
324
+ properties: properties
327
325
 
328
326
  match_window_data.start_info = session_start_info
329
327
  match_window_data.update_baseline_if_new = save_new_tests
@@ -481,7 +479,7 @@ module Applitools
481
479
  attr_accessor :running_session, :last_screenshot, :scale_provider, :session_start_info,
482
480
  :should_match_window_run_once_on_timeout, :app_output_provider, :failed
483
481
 
484
- attr_reader :user_inputs, :properties
482
+ attr_reader :user_inputs
485
483
 
486
484
  private :full_agent_id, :full_agent_id=
487
485
 
@@ -596,9 +594,11 @@ module Applitools
596
594
 
597
595
  self.session_start_info = SessionStartInfo.new agent_id: base_agent_id, app_id_or_name: app_name,
598
596
  scenario_id_or_name: test_name, batch_info: batch,
599
- env_name: baseline_env_name, environment: app_env,
600
- default_match_settings: default_match_settings.json_data,
597
+ baseline_env_name: baseline_env_name, environment: app_env,
598
+ default_match_settings: default_match_settings,
599
+ environment_name: environment_name, session_type: session_type,
601
600
  branch_name: branch_name, parent_branch_name: parent_branch_name,
601
+ baseline_branch_name: baseline_branch_name, save_diffs: save_diffs,
602
602
  properties: properties
603
603
 
604
604
  logger.info 'Starting server session...'
@@ -20,7 +20,9 @@ module Applitools
20
20
  ENV['bamboo_APPLITOOLS_SERVER_URL'] || Applitools::Connectivity::ServerConnector::DEFAULT_SERVER_URL,
21
21
  api_key: ENV['APPLITOOLS_API_KEY'] || ENV['bamboo_APPLITOOLS_API_KEY'] || '',
22
22
  save_new_tests: true,
23
- default_match_settings: Applitools::ImageMatchSettings.new
23
+ default_match_settings: Applitools::ImageMatchSettings.new,
24
+ accessibility_validation: nil,
25
+ properties: []
24
26
  }.freeze
25
27
 
26
28
  class << self
@@ -109,6 +111,8 @@ module Applitools
109
111
  int_field :scale
110
112
  int_field :remainder
111
113
  boolean_field :ignore_caret
114
+ object_field :accessibility_validation, Applitools::AccessibilitySettings, true
115
+ object_field :properties, Array
112
116
 
113
117
  methods_to_delegate.delete(:batch_info)
114
118
  methods_to_delegate.delete(:batch_info=)
@@ -161,6 +165,16 @@ module Applitools
161
165
  default_match_settings.ignore_caret = value
162
166
  end
163
167
 
168
+ def custom_setter_for_accessibility_validation(value)
169
+ # self.default_match_settings = self.parent.class.default_config[:default_match_settings] unless default_match_settings
170
+ default_match_settings.accessibility_validation = value
171
+ end
172
+
173
+ def add_property(name, value)
174
+ properties << { name: name, value: value } if name && value
175
+ end
176
+
164
177
  methods_to_delegate.push(:set_proxy)
178
+ methods_to_delegate.push(:add_property)
165
179
  end
166
180
  end
@@ -62,7 +62,7 @@ module Applitools
62
62
  end
63
63
  end
64
64
 
65
- def object_field(field_name, klass)
65
+ def object_field(field_name, klass, allow_nil = false)
66
66
  collect_method field_name
67
67
  define_method(field_name) do
68
68
  return send("custom_getter_for_#{field_name}", config_hash[field_name.to_sym]) if
@@ -71,11 +71,11 @@ module Applitools
71
71
  end
72
72
  define_method("#{field_name}=") do |*args|
73
73
  value = args.shift
74
- unless value.is_a? klass
74
+ unless value.is_a?(klass)
75
75
  raise(
76
76
  Applitools::EyesIllegalArgument,
77
77
  "Expected #{klass} but got #{value.class}"
78
- )
78
+ ) unless allow_nil && value.nil?
79
79
  end
80
80
  config_hash[field_name.to_sym] = value
81
81
  config_hash[field_name.to_sym] = send("custom_setter_for_#{field_name}", config_hash[field_name.to_sym]) if
@@ -123,7 +123,7 @@ module Applitools
123
123
  unless available_values_array.include? value
124
124
  raise(
125
125
  Applitools::EyesIllegalArgument,
126
- "Unknown #{field_name} #{value}. Allowed session types: " \
126
+ "Unknown #{field_name} #{value}. Allowed #{field_name} values: " \
127
127
  "#{available_values_array.join(', ')}"
128
128
  )
129
129
  end
@@ -6,12 +6,12 @@ module Applitools
6
6
  class ImageMatchSettings
7
7
  include Applitools::Jsonable
8
8
  include Applitools::MatchLevelSetter
9
- json_fields :accessibilityLevel, :MatchLevel, :IgnoreCaret, :IgnoreDisplacements, :Accessibility,
9
+ json_fields :accessibilitySettings, :MatchLevel, :IgnoreCaret, :IgnoreDisplacements, :Accessibility,
10
10
  :Ignore, :Floating, :Layout, :Strict, :Content, :Exact, :EnablePatterns, :UseDom,
11
11
  :SplitTopHeight, :SplitBottomHeight, :scale, :remainder
12
12
 
13
13
  def initialize
14
- self.accessibility_level = 'None'
14
+ self.accessibility_settings = nil
15
15
  self.match_level = Applitools::MatchLevel::STRICT
16
16
  self.split_top_height = 0
17
17
  self.split_bottom_height = 0
@@ -49,6 +49,15 @@ module Applitools
49
49
  cloned_value
50
50
  end
51
51
 
52
+ def accessibility_validation
53
+ accessibility_settings
54
+ end
55
+
56
+ def accessibility_validation=(value)
57
+ raise Applitools::EyesIllegalArgument, "Expected value to be an Applitools::AccessibilitySettings instance but got #{value.class}" unless value.nil? || value.is_a?(Applitools::AccessibilitySettings)
58
+ self.accessibility_settings = value
59
+ end
60
+
52
61
  class Exact
53
62
  include Applitools::Jsonable
54
63
  json_fields :MinDiffIntensity, :MinDiffWidth, :MinDiffHeight, :MatchThreshold
@@ -7,9 +7,10 @@ module Applitools
7
7
  base.extend ClassMethods
8
8
  base.class_eval do
9
9
  class << self
10
- attr_accessor :json_methods
10
+ attr_accessor :json_methods, :wrap_data_block
11
11
  end
12
12
  @json_methods = {}
13
+ @wrap_data_block = nil
13
14
  end
14
15
  end
15
16
 
@@ -34,10 +35,16 @@ module Applitools
34
35
  def json_fields(*args)
35
36
  args.each { |m| json_field m }
36
37
  end
38
+
39
+ def wrap_data(&block)
40
+ @wrap_data_block = block
41
+ end
37
42
  end
38
43
 
39
44
  def json_data
40
- self.class.json_methods.sort.map { |k, v| [k, json_value(send(v))] }.to_h
45
+ result = self.class.json_methods.sort.map { |k, v| [k, json_value(send(v))] }.to_h
46
+ result = self.class.wrap_data_block.call(result) if self.class.wrap_data_block.is_a? Proc
47
+ result
41
48
  end
42
49
 
43
50
  def json
@@ -4,6 +4,7 @@ module Applitools
4
4
  class MatchWindowData
5
5
  class << self
6
6
  def convert_coordinates(region, screenshot)
7
+ return region.with_padding.to_hash if region.respond_to?(:converted?) && region.converted?
7
8
  screenshot.convert_region_location(
8
9
  region.with_padding,
9
10
  Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative],
@@ -2,38 +2,36 @@
2
2
 
3
3
  module Applitools
4
4
  class SessionStartInfo
5
- attr_accessor :app_id_or_name, :scenario_id_or_name
5
+ include Applitools::Jsonable
6
+ json_fields :batchInfo, :agentId, :appIdOrName, :verId, :environment, :environmentName, :branchName, :defaultMatchSettings,
7
+ :scenarioIdOrName, :properties, :parentBranchName, :compareWithParentBranch, :baselineEnvName, :saveDiffs, :sessionType,
8
+ :baselineBranchName
9
+
10
+ wrap_data do |value|
11
+ { startInfo: value }
12
+ end
6
13
 
7
14
  def initialize(options = {})
8
- @agent_id = options[:agent_id]
9
- @app_id_or_name = options[:app_id_or_name]
10
- @ver_id = options[:ver_id]
11
- @scenario_id_or_name = options[:scenario_id_or_name]
12
- @batch_info = options[:batch_info]
13
- @env_name = options[:env_name]
14
- @environment = options[:environment]
15
- @default_match_settings = options[:default_match_settings]
16
- @branch_name = options[:branch_name]
17
- @parent_branch_name = options[:parent_branch_name]
18
- @properties = options[:properties]
19
- @compare_with_parent_branch = options[:compare_with_parent_branch]
15
+ self.agent_id = options[:agent_id]
16
+ self.app_id_or_name = options[:app_id_or_name]
17
+ self.ver_id = options[:ver_id]
18
+ self.scenario_id_or_name = options[:scenario_id_or_name]
19
+ self.batch_info = options[:batch_info]
20
+ self.environment_name = options[:environment_name]
21
+ self.baseline_env_name = options[:baseline_env_name]
22
+ self.environment = options[:environment]
23
+ self.default_match_settings = options[:default_match_settings]
24
+ self.branch_name = options[:branch_name]
25
+ self.parent_branch_name = options[:parent_branch_name]
26
+ self.properties = options[:properties]
27
+ self.compare_with_parent_branch = options[:compare_with_parent_branch]
28
+ self.save_diffs = options[:save_diffs]
29
+ self.session_type = options[:session_type]
30
+ self.baseline_branch_name = options[:baseline_branch_name]
20
31
  end
21
32
 
22
33
  def to_hash
23
- {
24
- agent_id: @agent_id,
25
- app_id_or_name: @app_id_or_name,
26
- ver_id: @ver_id,
27
- scenario_id_or_name: @scenario_id_or_name,
28
- batch_info: @batch_info && @batch_info.to_hash,
29
- env_name: @env_name,
30
- environment: @environment.to_hash,
31
- default_match_settings: @default_match_settings,
32
- branch_name: @branch_name,
33
- parent_branch_name: @parent_branch_name,
34
- compare_with_parent_branch: @compare_with_parent_branch,
35
- properties: @properties
36
- }
34
+ json_data
37
35
  end
38
36
  end
39
37
  end
@@ -4,6 +4,18 @@ require 'yaml'
4
4
 
5
5
  module Applitools
6
6
  class TestResults
7
+ class AccessibilityStatus
8
+ attr_accessor :status, :level, :version
9
+ def initialize(hash = {})
10
+ self.status = hash['status']
11
+ self.level = hash['level']
12
+ self.version = hash['version']
13
+ end
14
+
15
+ def failed?
16
+ status.downcase == 'Failed'.downcase
17
+ end
18
+ end
7
19
  attr_accessor :is_new, :url, :screenshot
8
20
  attr_reader :status, :steps, :matches, :mismatches, :missing, :original_results
9
21
 
@@ -50,6 +62,14 @@ module Applitools
50
62
  original_results['secretToken']
51
63
  end
52
64
 
65
+ def name
66
+ original_results['name']
67
+ end
68
+
69
+ def session_accessibility_status
70
+ @accessibility_status ||= original_results['accessibilityStatus'] && AccessibilityStatus.new(original_results['accessibilityStatus'] || {})
71
+ end
72
+
53
73
  def ==(other)
54
74
  if other.is_a? self.class
55
75
  result = true
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Applitools
4
- VERSION = '3.16.15'.freeze
4
+ VERSION = '3.17.3'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eyes_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.15
4
+ version: 3.17.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Applitools Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-24 00:00:00.000000000 Z
11
+ date: 2020-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oily_png
@@ -260,10 +260,12 @@ files:
260
260
  - ext/eyes_core/extconf.rb
261
261
  - ext/eyes_core/eyes_core.c
262
262
  - ext/eyes_core/eyes_core.h
263
+ - lib/applitools/appium/android_screenshot.rb
263
264
  - lib/applitools/appium/driver.rb
264
265
  - lib/applitools/appium/eyes.rb
265
266
  - lib/applitools/appium/initialize_1.9.rb
266
267
  - lib/applitools/appium/initialize_2.0.rb
268
+ - lib/applitools/appium/ios_screenshot.rb
267
269
  - lib/applitools/appium/region_provider.rb
268
270
  - lib/applitools/appium/screenshot.rb
269
271
  - lib/applitools/appium/target.rb