eyes_core 3.17.16 → 3.17.21

Sign up to get free protection for your applications and to get access to all the features.
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