eyes_core 3.17.16 → 3.17.21

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: f493e2e676266fe3171fdcc71969df85850857c4cdfcdb76075ecc17c83d6947
4
- data.tar.gz: 1e1f1e972549d21dd82cf636fa2430a2854032b11e3aca4394a6881a7d967390
3
+ metadata.gz: 5f5de232cfebace23a11b460e49b9d345bace6aaae97c3348694f7ae55bb94a5
4
+ data.tar.gz: 95e1815deed07620bcaec68b0de6e2938b7c6d8b87aafb8b5f0e16abfbe247bf
5
5
  SHA512:
6
- metadata.gz: ef157b03cd73e0b56ccb8b30f2ca37dbaef94b9274218285fb21a3e91b3578b87b1c70ae0327888613159d12685e96914dcf8d244aa614de543f43b7d184353c
7
- data.tar.gz: 1ca941fb0dd570fbf7b2cd7312d8cdd4b5e0b0e54f5e6152fb31fa0d12ddecbd7d2c878e8575467a894f2c46f224f077e417550428402b4f22508974884aeee0
6
+ metadata.gz: e1bc1a7f731af8f0e78164246e039dac0967adc00c66dc343a51c15e3355ca826874b534ab77ba16e1eb6dad159cb026536c7ded50c9405a008c6b499710614a
7
+ data.tar.gz: 9e848677e2e2a2edda3e6ecd45ff4421a9dc6f0c4706982cd9f103e07efd6f228b66acdbf31a5dbb9fffeef4e9f234b9c7a738a4901c735477006d8db9601c6a
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'region_provider'
4
+ module Applitools
5
+ module Appium
6
+ class AndroidRegionProvider < ::Applitools::Appium::RegionProvider
7
+ private
8
+
9
+ def convert_element_coordinates
10
+ Applitools::Region.from_location_size(eye_region.location, eye_region.size)
11
+ end
12
+
13
+ def convert_viewport_rect_coordinates
14
+ region = viewport_rect
15
+ Applitools::Region.new(
16
+ region['left'],
17
+ region['top'],
18
+ region['width'],
19
+ region['height']
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
4
4
  attr_accessor :status_bar_height
5
+
5
6
  def perform_driver_settings_for_appium_driver
6
7
  self.region_visibility_strategy = Applitools::Selenium::NopRegionVisibilityStrategy.new
7
8
  self.force_driver_resolution_as_viewport_size = true
@@ -51,7 +52,7 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
51
52
 
52
53
  eyes_element = target_to_check.region_to_check.call(driver)
53
54
  self.eyes_element_to_check = eyes_element
54
- region_provider = Applitools::Appium::RegionProvider.new(driver, eyes_element)
55
+ region_provider = region_provider_class.new(driver, eyes_element)
55
56
  match_data.read_target(target_to_check, driver)
56
57
 
57
58
  check_window_base(
@@ -119,16 +120,19 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
119
120
 
120
121
  def viewport_screenshot
121
122
  logger.info 'Viewport screenshot requested...'
122
-
123
- self.screenshot = screenshot_class.new(
124
- Applitools::Screenshot.from_datastream(driver.screenshot_as(:png))
125
- )
123
+ obtain_viewport_screenshot
126
124
  end
127
125
 
128
126
  def element_screenshot
129
127
  logger.info 'Element screenshot requested...'
128
+ obtain_viewport_screenshot
129
+ end
130
+
131
+ def obtain_viewport_screenshot
130
132
  self.screenshot = screenshot_class.new(
131
- Applitools::Screenshot.from_datastream(driver.element_screenshot_as(eyes_element_to_check, :png))
133
+ Applitools::Screenshot.from_datastream(driver.screenshot_as(:png)),
134
+ status_bar_height: Applitools::Utils::EyesSeleniumUtils.status_bar_height(driver),
135
+ device_pixel_ratio: Applitools::Utils::EyesSeleniumUtils.device_pixel_ratio(driver)
132
136
  )
133
137
  end
134
138
 
@@ -137,4 +141,10 @@ class Applitools::Appium::Eyes < Applitools::Selenium::SeleniumEyes
137
141
  return Applitools::Appium::AndroidScreenshot if Applitools::Utils::EyesSeleniumUtils.android?(Applitools::Appium::Driver::AppiumLib)
138
142
  raise Applitools::EyesError, 'Unknown device type'
139
143
  end
144
+
145
+ def region_provider_class
146
+ return Applitools::Appium::IosRegionProvider if Applitools::Utils::EyesSeleniumUtils.ios?(Applitools::Appium::Driver::AppiumLib)
147
+ return Applitools::Appium::AndroidRegionProvider if Applitools::Utils::EyesSeleniumUtils.android?(Applitools::Appium::Driver::AppiumLib)
148
+ raise Applitools::EyesError, 'Unknown device type'
149
+ end
140
150
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require_relative 'region_provider'
4
+ module Applitools
5
+ module Appium
6
+ class IosRegionProvider < ::Applitools::Appium::RegionProvider
7
+ private
8
+
9
+ def convert_element_coordinates
10
+ Applitools::Region.from_location_size(eye_region.location, eye_region.size).
11
+ scale_it!(scale_factor)
12
+ end
13
+
14
+ def convert_viewport_rect_coordinates
15
+ region = viewport_rect
16
+ Applitools::Region.new(
17
+ region['left'],
18
+ region['top'],
19
+ region['width'],
20
+ region['height']
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
@@ -3,23 +3,48 @@
3
3
  module Applitools
4
4
  module Appium
5
5
  class RegionProvider
6
- attr_accessor :driver, :eye_region, :coordinate_type
6
+ attr_accessor :driver, :eye_region, :region_to_check
7
7
 
8
8
  def initialize(driver, eye_region)
9
9
  self.driver = driver
10
10
  self.eye_region = eye_region
11
+ self.region_to_check = Applitools::Region::EMPTY
12
+ convert_region_coordinates
11
13
  end
12
14
 
13
15
  def region
14
- return Applitools::Region::EMPTY if
15
- [::Selenium::WebDriver::Element, Applitools::Selenium::Element].include? eye_region.class
16
- region = driver.session_capabilities['viewportRect']
17
- Applitools::Region.new(
18
- region['left'],
19
- region['top'],
20
- region['width'],
21
- region['height']
22
- )
16
+ region_to_check
17
+ end
18
+
19
+ def coordinate_type
20
+ nil
21
+ end
22
+
23
+ private
24
+
25
+ def viewport_rect
26
+ Applitools::Utils::EyesSeleniumUtils.viewport_rect(driver)
27
+ end
28
+
29
+ def convert_region_coordinates
30
+ self.region_to_check = case eye_region
31
+ when ::Selenium::WebDriver::Element, Applitools::Selenium::Element
32
+ convert_element_coordinates
33
+ else
34
+ convert_viewport_rect_coordinates
35
+ end
36
+ end
37
+
38
+ def convert_element_coordinates
39
+ raise Applitools::AbstractMethodCalled.new(:convert_region_coordinates, 'Applitools::Appium::RegionProvider')
40
+ end
41
+
42
+ def convert_viewport_rect_coordinates
43
+ raise Applitools::AbstractMethodCalled.new(:convert_viewport_rect_coordinates, 'Applitools::Appium::RegionProvider')
44
+ end
45
+
46
+ def scale_factor
47
+ Applitools::Utils::EyesSeleniumUtils.device_pixel_ratio(driver)
23
48
  end
24
49
  end
25
50
  end
@@ -28,7 +28,7 @@ module Applitools::Appium
28
28
  def device_pixel_ratio(executor)
29
29
  session_info = session_capabilities(executor)
30
30
  return session_info['pixelRatio'].to_f if session_info['pixelRatio']
31
- Applitools::Selenium::Eyes::UNKNOWN_DEVICE_PIXEL_RATIO
31
+ 1
32
32
  end
33
33
 
34
34
  def status_bar_height(executor)
@@ -37,6 +37,17 @@ module Applitools::Appium
37
37
  0
38
38
  end
39
39
 
40
+ def viewport_rect(executor)
41
+ session_info = session_capabilities(executor)
42
+ return session_info['viewportRect'] if session_info['viewportRect']
43
+ {
44
+ 'left' => 0,
45
+ 'top' => 0,
46
+ 'width' => 0,
47
+ 'height' => 0
48
+ }
49
+ end
50
+
40
51
  def session_capabilities(executor)
41
52
  executor.session_capabilities if executor.respond_to? :session_capabilities
42
53
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Applitools
4
4
  class AppOutput
5
- attr_reader :title, :screenshot64, :location
5
+ attr_reader :title, :screenshot64, :location, :screenshot_url_getter, :dom_url_getter
6
6
 
7
7
  attr_accessor :dom_url, :screenshot_url, :visual_viewport
8
8
 
@@ -10,6 +10,8 @@ module Applitools
10
10
  @title = title
11
11
  @screenshot64 = screenshot64
12
12
  @location = Applitools::Location::TOP_LEFT
13
+ @screenshot_url_getter = nil
14
+ @dom_url_getter = nil
13
15
  end
14
16
 
15
17
  def location=(value)
@@ -17,12 +19,24 @@ module Applitools
17
19
  @location = value
18
20
  end
19
21
 
22
+ def on_need_screenshot_url(&block)
23
+ @screenshot_url_getter = block if block_given?
24
+ end
25
+
26
+ def on_need_dom_url(&block)
27
+ @dom_url_getter = block if block_given?
28
+ end
29
+
30
+ def dom_url
31
+ @dom_url ||= (@dom_url_getter && @dom_url_getter.call)
32
+ end
33
+
20
34
  def to_hash
21
35
  result = {
22
36
  Title: title,
23
37
  Screenshot64: nil,
24
38
  Location: location.to_hash,
25
- ScreenshotUrl: screenshot_url
39
+ ScreenshotUrl: screenshot_url || (screenshot_url_getter && screenshot_url_getter.call)
26
40
  }
27
41
  result[:DomUrl] = dom_url if dom_url
28
42
  result[:visualViewport] = visual_viewport if visual_viewport
@@ -6,17 +6,19 @@ require_relative 'helpers'
6
6
  module Applitools
7
7
  class BatchInfo
8
8
  extend Helpers
9
- attr_accessor :started_at, :id
9
+ attr_accessor :started_at, :id, :notify_on_completion
10
10
 
11
11
  environment_attribute :name, 'APPLITOOLS_BATCH_NAME'
12
12
  environment_attribute :id, 'APPLITOOLS_BATCH_ID'
13
13
  environment_attribute :sequence_name, 'APPLITOOLS_BATCH_SEQUENCE'
14
- environment_attribute :notify_on_completion, 'APPLITOOLS_BATCH_NOTIFY'
14
+ environment_attribute :env_notify_on_completion, 'APPLITOOLS_BATCH_NOTIFY'
15
+
15
16
 
16
17
  def initialize(name = nil, started_at = Time.now)
17
18
  self.name = name if name
18
19
  @started_at = started_at
19
20
  self.id = SecureRandom.uuid unless id
21
+ self.notify_on_completion = 'true'.casecmp(env_notify_on_completion || '') == 0 ? true : false
20
22
  end
21
23
 
22
24
  def json_data
@@ -25,7 +27,7 @@ module Applitools
25
27
  'name' => name,
26
28
  'startedAt' => @started_at.iso8601,
27
29
  'batchSequenceName' => sequence_name,
28
- 'notifyOnCompletion' => 'true'.casecmp(notify_on_completion || '') == 0 ? true : false
30
+ 'notifyOnCompletion' => notify_on_completion
29
31
  }
30
32
  end
31
33
 
@@ -280,7 +280,6 @@ module Applitools
280
280
  self.last_screenshot = result.screenshot
281
281
  end
282
282
 
283
- self.should_match_window_run_once_on_timeout = true
284
283
  self.failed = true
285
284
  logger.info "Mistmatch! #{tag}" unless running_session.new_session?
286
285
 
@@ -614,27 +613,7 @@ module Applitools
614
613
  end
615
614
 
616
615
  def get_app_output_with_screenshot(region_provider, _last_screenshot)
617
- dom_url = ''
618
616
  captured_dom_data = dom_data
619
- unless captured_dom_data.empty?
620
- begin
621
- logger.info 'Processing DOM..'
622
- dom_url = server_connector.post_dom_json(captured_dom_data, runner.rendering_info(server_connector)) do |json|
623
- io = StringIO.new
624
- gz = Zlib::GzipWriter.new(io)
625
- gz.write(json.encode('UTF-8'))
626
- gz.close
627
- result = io.string
628
- io.close
629
- result
630
- end
631
- logger.info 'Done'
632
- logger.info dom_url
633
- rescue Applitools::EyesError => e
634
- logger.warn e.message
635
- dom_url = nil
636
- end
637
- end
638
617
  logger.info 'Getting screenshot...'
639
618
  screenshot = capture_screenshot
640
619
  logger.info 'Done getting screenshot!'
@@ -646,21 +625,41 @@ module Applitools
646
625
 
647
626
  screenshot = yield(screenshot) if block_given?
648
627
 
649
- if screenshot
650
- self.screenshot_url = server_connector.put_screenshot(
651
- runner.rendering_info(server_connector),
652
- screenshot
653
- )
654
- end
655
-
656
628
  logger.info 'Getting title...'
657
629
  a_title = title
658
630
  logger.info 'Done!'
659
631
  Applitools::AppOutputWithScreenshot.new(
660
632
  Applitools::AppOutput.new(a_title, screenshot).tap do |o|
661
633
  o.location = region.location unless region.empty?
662
- o.dom_url = dom_url unless dom_url && dom_url.empty?
663
- o.screenshot_url = screenshot_url if respond_to?(:screenshot_url) && !screenshot_url.nil?
634
+ o.on_need_screenshot_url do
635
+ return unless screenshot
636
+ server_connector.put_screenshot(
637
+ runner.rendering_info(server_connector),
638
+ screenshot
639
+ )
640
+ end
641
+ o.on_need_dom_url do
642
+ unless captured_dom_data.empty?
643
+ begin
644
+ logger.info 'Processing DOM..'
645
+ dom_url = server_connector.post_dom_json(captured_dom_data, runner.rendering_info(server_connector)) do |json|
646
+ io = StringIO.new
647
+ gz = Zlib::GzipWriter.new(io)
648
+ gz.write(json.encode('UTF-8'))
649
+ gz.close
650
+ result = io.string
651
+ io.close
652
+ result
653
+ end
654
+ logger.info 'Done'
655
+ logger.info dom_url
656
+ rescue Applitools::EyesError => e
657
+ logger.warn e.message
658
+ dom_url = nil
659
+ end
660
+ dom_url
661
+ end
662
+ end
664
663
  end,
665
664
  screenshot,
666
665
  allow_empty_screenshot
@@ -24,6 +24,7 @@ module Applitools
24
24
  'ForceMismatch' => false,
25
25
  'IgnoreMatch' => false,
26
26
  'IgnoreMismatch' => false,
27
+ 'ReplaceLast' => false,
27
28
  'Trim' => {
28
29
  'Enabled' => false
29
30
  },
@@ -313,6 +314,15 @@ module Applitools
313
314
  current_data['IgnoreMismatch']
314
315
  end
315
316
 
317
+ def replace_last
318
+ current_data['Options']['ReplaceLast']
319
+ end
320
+
321
+ def replace_last=(value)
322
+ Applitools::ArgumentGuard.one_of?(value, 'value', [TrueClass, FalseClass])
323
+ current_data['Options']['ReplaceLast'] = value
324
+ end
325
+
316
326
  def tag
317
327
  current_data['Tag']
318
328
  end
@@ -48,10 +48,11 @@ module Applitools
48
48
  match_window_data.convert_strict_regions_coordinates
49
49
  match_window_data.convert_content_regions_coordinates
50
50
  match_window_data.convert_accessibility_regions_coordinates
51
+ match_window_data.replace_last = false
51
52
  match_result = perform_match(match_window_data)
52
53
  else
53
- passed_ignore_mismatch = match_window_data.ignore_mismatch
54
54
  app_output = app_output_provider.app_output(region_provider, last_screenshot)
55
+ last_image_digest = app_output.screenshot.image.sha256
55
56
  match_window_data.app_output = app_output
56
57
  match_window_data.convert_ignored_regions_coordinates
57
58
  match_window_data.convert_floating_regions_coordinates
@@ -59,44 +60,37 @@ module Applitools
59
60
  match_window_data.convert_strict_regions_coordinates
60
61
  match_window_data.convert_content_regions_coordinates
61
62
  match_window_data.convert_accessibility_regions_coordinates
62
- match_window_data.ignore_mismatch = true
63
- start = Time.now
63
+ match_window_data.replace_last = false
64
64
  match_result = perform_match(match_window_data)
65
- retry_time = Time.now - start
66
65
 
67
66
  block_retry = if block_given?
68
67
  yield(match_result)
69
68
  else
70
69
  false
71
70
  end
71
+ start = Time.now
72
+ retry_time = 0
72
73
 
73
74
  while retry_time < retry_timeout && !(block_retry || match_result.as_expected?)
74
75
  sleep MATCH_INTERVAL
75
76
  app_output = app_output_provider.app_output(region_provider, last_screenshot)
76
- match_window_data.app_output = app_output
77
- match_window_data.convert_ignored_regions_coordinates
78
- match_window_data.convert_floating_regions_coordinates
79
- match_window_data.convert_layout_regions_coordinates
80
- match_window_data.convert_strict_regions_coordinates
81
- match_window_data.convert_content_regions_coordinates
82
- match_window_data.convert_accessibility_regions_coordinates
83
- match_window_data.ignore_mismatch = true
84
- match_result = perform_match(match_window_data)
77
+ image_digest = app_output.screenshot.image.sha256
78
+ if image_digest == last_image_digest
79
+ logger.info('Got the same screenshot in retry. Not sending to the server.')
80
+ else
81
+ match_window_data.app_output = app_output
82
+ match_window_data.convert_ignored_regions_coordinates
83
+ match_window_data.convert_floating_regions_coordinates
84
+ match_window_data.convert_layout_regions_coordinates
85
+ match_window_data.convert_strict_regions_coordinates
86
+ match_window_data.convert_content_regions_coordinates
87
+ match_window_data.convert_accessibility_regions_coordinates
88
+ match_window_data.replace_last = true
89
+ match_result = perform_match(match_window_data)
90
+ end
91
+ last_image_digest = image_digest
85
92
  retry_time = Time.now - start
86
93
  end
87
-
88
- unless block_retry || match_result.as_expected?
89
- app_output = app_output_provider.app_output(region_provider, last_screenshot)
90
- match_window_data.app_output = app_output
91
- match_window_data.convert_ignored_regions_coordinates
92
- match_window_data.convert_floating_regions_coordinates
93
- match_window_data.convert_layout_regions_coordinates
94
- match_window_data.convert_strict_regions_coordinates
95
- match_window_data.convert_content_regions_coordinates
96
- match_window_data.convert_accessibility_regions_coordinates
97
- match_window_data.ignore_mismatch = passed_ignore_mismatch
98
- match_result = perform_match(match_window_data)
99
- end
100
94
  end
101
95
 
102
96
  logger.info "Completed in #{format('%.2f', Time.now - elapsed_time_start)} seconds"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require 'digest'
2
3
 
3
4
  module Applitools
4
5
  class Screenshot < Delegator
@@ -91,6 +92,10 @@ module Applitools
91
92
  def restore
92
93
  ::ChunkyPNG::Image.from_datastream @datastream
93
94
  end
95
+
96
+ def sha256
97
+ Digest::SHA2.new(256).hexdigest(@datastream.to_s)
98
+ end
94
99
  end
95
100
 
96
101
  class Image < self
@@ -115,6 +120,10 @@ module Applitools
115
120
  def __setobj__(obj)
116
121
  @image = obj
117
122
  end
123
+
124
+ def sha256
125
+ Digest::SHA2.new(256).hexdigest(@image.to_datastream.to_s)
126
+ end
118
127
  end
119
128
  end
120
129
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Applitools
4
- VERSION = '3.17.16'.freeze
4
+ VERSION = '3.17.21'.freeze
5
5
  end
@@ -0,0 +1,4 @@
1
+ module Applitools
2
+ JS_PATH = 'lib/applitools/selenium/scripts/node_modules'.freeze
3
+ SCRIPT_TEMPLATES_PATH = 'lib/applitools/selenium/scripts'.freeze
4
+ end
@@ -4,6 +4,7 @@ require 'forwardable'
4
4
  require 'delegate'
5
5
  require 'time'
6
6
  require_relative 'require_utils'
7
+ require_relative 'eyes_consts'
7
8
 
8
9
  module Applitools
9
10
  extend Applitools::RequireUtils
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.17.16
4
+ version: 3.17.21
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-07-18 00:00:00.000000000 Z
11
+ date: 2020-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oily_png
@@ -260,11 +260,13 @@ 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_region_provider.rb
263
264
  - lib/applitools/appium/android_screenshot.rb
264
265
  - lib/applitools/appium/driver.rb
265
266
  - lib/applitools/appium/eyes.rb
266
267
  - lib/applitools/appium/initialize_1.9.rb
267
268
  - lib/applitools/appium/initialize_2.0.rb
269
+ - lib/applitools/appium/ios_region_provider.rb
268
270
  - lib/applitools/appium/ios_screenshot.rb
269
271
  - lib/applitools/appium/region_provider.rb
270
272
  - lib/applitools/appium/screenshot.rb
@@ -362,6 +364,7 @@ files:
362
364
  - lib/applitools/utils/image_utils.rb
363
365
  - lib/applitools/utils/utils.rb
364
366
  - lib/applitools/version.rb
367
+ - lib/eyes_consts.rb
365
368
  - lib/eyes_core.rb
366
369
  - lib/eyes_rspec.rb
367
370
  - lib/require_utils.rb