eyes_selenium 2.16.0 → 2.17.0

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
  SHA1:
3
- metadata.gz: 47b395b9cd5931cd1cdf51770296824d4123540e
4
- data.tar.gz: ed4cfaadc2824b1140d64abee6322e08a5a99e94
3
+ metadata.gz: 250fb34d1762517235653022b1912a310f725030
4
+ data.tar.gz: e72d68a5d5927ad9bf4deaef8375820cc5c8fe23
5
5
  SHA512:
6
- metadata.gz: a7f9f968f8be5d0108c768084e00213a575b946abdad64de5b389008439f8ffcc2ab24892ddf68f43229ba4d51202bb9ec509b478e87f94640ce7d108f7a09f6
7
- data.tar.gz: 5fa006f0a50e22a1e9e2e31a17b31d25c47f11f90e98f1ecb70c051473fb998561bb1ec2b0031cdb859fc651077de559c086d2e4374d12d08df540f49cc9d325
6
+ metadata.gz: 9e86ee6df164195fd10b9b66032ca7132fd53deadca423ce904672e553b76e92f55c8f99f195d90bcf5217ebecf695a01aa86c5d62afa4cd6f9559e7cfa7b436
7
+ data.tar.gz: 41c97cde1b72b9dee573fec079fc80f6a3823c1ea00e41e45778a48743c10fe7292222d2a4a77a761f5dbe9dcdcc659dcc3de3fedc857496a4f47bdfc0d7d6ce
data/.rubocop.yml ADDED
@@ -0,0 +1,54 @@
1
+ # Custom config for RuboCop static code analysis
2
+ Metrics/LineLength:
3
+ Max: 120
4
+
5
+ Metrics/MethodLength:
6
+ Enabled: false
7
+
8
+ Metrics/ClassLength:
9
+ Enabled: false
10
+
11
+ Metrics/ParameterLists:
12
+ Enabled: false
13
+
14
+ Metrics/CyclomaticComplexity:
15
+ Enabled: false
16
+
17
+ Metrics/PerceivedComplexity:
18
+ Enabled: false
19
+
20
+ Metrics/AbcSize:
21
+ Enabled: false
22
+
23
+ Metrics/BlockNesting:
24
+ Max: 4
25
+
26
+ Style/SignalException:
27
+ EnforcedStyle: only_raise
28
+
29
+ Style/RaiseArgs:
30
+ Enabled: false
31
+
32
+ Style/AlignParameters:
33
+ EnforcedStyle: with_fixed_indentation
34
+
35
+ Style/HashSyntax:
36
+ UseHashRocketsWithSymbolValues: true
37
+
38
+ Style/AlignHash:
39
+ Enabled: false
40
+
41
+ Style/MultilineOperationIndentation:
42
+ EnforcedStyle: indented
43
+
44
+ Style/IndentHash:
45
+ EnforcedStyle: consistent
46
+
47
+ Style/ClassAndModuleChildren:
48
+ Enabled: false
49
+
50
+ Style/Documentation:
51
+ Enabled: false
52
+
53
+ Style/ModuleFunction:
54
+ Enabled: false
data/.travis.yml CHANGED
@@ -14,3 +14,5 @@ sudo: false
14
14
  before_install:
15
15
  - "export DISPLAY=:99.0"
16
16
  - "sh -e /etc/init.d/xvfb start"
17
+ script:
18
+ - bundle exec rake rubocop
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env rake
2
2
  require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
4
5
 
5
6
  RSpec::Core::RakeTask.new('spec')
6
7
  Bundler::GemHelper.install_tasks
7
8
 
8
9
  task :default => :spec
10
+
11
+ RuboCop::RakeTask.new
@@ -13,13 +13,13 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://www.applitools.com'
14
14
  spec.license = 'Apache License, Version 2.0'
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ spec.files = `git ls-files`.split($RS)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_dependency 'selenium-webdriver', '>= 2.45.0'
22
- spec.add_dependency 'oily_png'
22
+ spec.add_dependency 'oily_png', '>= 1.2'
23
23
  spec.add_dependency 'faraday'
24
24
  spec.add_dependency 'oj'
25
25
 
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'rspec', '>= 3'
29
29
  spec.add_development_dependency 'watir-webdriver'
30
30
  spec.add_development_dependency 'appium_lib'
31
+ spec.add_development_dependency 'rubocop'
31
32
 
32
33
  # Exclude debugging support on Travis CI, due to its incompatibility with jruby and older rubies.
33
34
  unless ENV['TRAVIS']
@@ -0,0 +1,10 @@
1
+ module Applitools::Base
2
+ class ImagePosition
3
+ attr_accessor :image, :position
4
+
5
+ def initialize(image, position)
6
+ @image = image
7
+ @position = position
8
+ end
9
+ end
10
+ end
@@ -7,7 +7,7 @@ module Applitools::Base
7
7
  move: 'Move',
8
8
  down: 'Down',
9
9
  up: 'Up'
10
- }.freeze
10
+ }.freeze
11
11
 
12
12
  attr_reader :mouse_action, :control, :location
13
13
 
@@ -2,16 +2,29 @@ module Applitools::Base
2
2
  class Point
3
3
  attr_accessor :x, :y
4
4
 
5
+ alias_attribute :left, :x
6
+ alias_attribute :top, :y
7
+
5
8
  def initialize(x, y)
6
9
  @x = x
7
10
  @y = y
8
11
  end
9
12
 
10
- def to_hash
11
- {
12
- x: x,
13
- y: y
14
- }
13
+ TOP_LEFT = Point.new(0, 0)
14
+
15
+ def ==(other)
16
+ return super.==(other) unless other.is_a?(Point)
17
+ @x == other.x && @y == other.y
18
+ end
19
+
20
+ def hash
21
+ @x.hash & @y.hash
22
+ end
23
+
24
+ alias_method :eql?, :==
25
+
26
+ def to_hash(options = {})
27
+ options[:region] ? { left: left, top: top } : { x: x, y: y }
15
28
  end
16
29
 
17
30
  def values
@@ -9,7 +9,7 @@ module Applitools::Base
9
9
  @height = height.round
10
10
  end
11
11
 
12
- EMPTY = Applitools::Base::Region.new(0, 0, 0, 0)
12
+ EMPTY = Region.new(0, 0, 0, 0)
13
13
 
14
14
  def make_empty
15
15
  @left = EMPTY.left
@@ -19,7 +19,7 @@ module Applitools::Base
19
19
  end
20
20
 
21
21
  def empty?
22
- @left == EMPTY.left && @top == EMPTY.top && @width == EMPTY.width && @height == EMPTY.height
22
+ @left == EMPTY.left && @top == EMPTY.top && @width == EMPTY.width && @height == EMPTY.height
23
23
  end
24
24
 
25
25
  def right
@@ -31,14 +31,17 @@ module Applitools::Base
31
31
  end
32
32
 
33
33
  def intersecting?(other)
34
- ((left <= other.left && other.left <= right) || (other.left <= left && left <= other.right)) \
35
- && ((top <= other.top && other.top <= bottom) || (other.top <= top && top <=other.bottom))
34
+ ((left <= other.left && other.left <= right) || (other.left <= left && left <= other.right)) &&
35
+ ((top <= other.top && other.top <= bottom) || (other.top <= top && top <= other.bottom))
36
36
  end
37
37
 
38
38
  def intersect(other)
39
- if !intersecting?(other)
40
- make_empty and return
39
+ unless intersecting?(other)
40
+ make_empty
41
+
42
+ return
41
43
  end
44
+
42
45
  i_left = (left >= other.left) ? left : other.left
43
46
  i_right = (right <= other.right) ? right : other.right
44
47
  i_top = (top >= other.top) ? top : other.top
@@ -51,14 +54,46 @@ module Applitools::Base
51
54
  end
52
55
 
53
56
  def contains?(other_left, other_top)
54
- other_left >= left && other_left <= right && \
55
- other_top >= top && other_top <= bottom
57
+ other_left >= left && other_left <= right && other_top >= top && other_top <= bottom
56
58
  end
57
59
 
58
60
  def middle_offset
59
61
  mid_x = width / 2
60
62
  mid_y = height / 2
61
- Applitools::Base::Point.new(mid_x.round, mid_y.round)
63
+ Point.new(mid_x.round, mid_y.round)
64
+ end
65
+
66
+ def subregions(subregion_size)
67
+ [].tap do |subregions|
68
+ current_top = @top
69
+ bottom = @top + @height
70
+ right = @left + @width
71
+ subregion_width = [@width, subregion_size.width].min
72
+ subregion_height = [@height, subregion_size.height].min
73
+
74
+ while current_top < bottom
75
+ current_bottom = current_top + subregion_height
76
+ if current_bottom > bottom
77
+ current_bottom = bottom
78
+ current_top = current_bottom - subregion_height
79
+ end
80
+
81
+ current_left = @left
82
+ while current_left < right
83
+ current_right = current_left + subregion_width
84
+ if current_right > right
85
+ current_right = right
86
+ current_left = current_right - subregion_width
87
+ end
88
+
89
+ subregions << Region.new(current_left, current_top, subregion_width, subregion_height)
90
+
91
+ current_left += subregion_width
92
+ end
93
+
94
+ current_top += subregion_height
95
+ end
96
+ end
62
97
  end
63
98
 
64
99
  def to_hash
@@ -1,7 +1,7 @@
1
1
  require 'faraday'
2
2
 
3
3
  require 'oj'
4
- Oj.default_options = {:mode => :compat }
4
+ Oj.default_options = { :mode => :compat }
5
5
 
6
6
  require 'uri'
7
7
 
@@ -44,7 +44,8 @@ module Applitools::Base::ServerConnector
44
44
  end
45
45
 
46
46
  def start_session(session_start_info)
47
- res = post(endpoint_url, body: Oj.dump(startInfo: Applitools::Utils.camelcase_hash_keys(session_start_info.to_hash)))
47
+ res = post(endpoint_url, body: Oj.dump(startInfo:
48
+ Applitools::Utils.camelcase_hash_keys(session_start_info.to_hash)))
48
49
  raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?
49
50
 
50
51
  response = Oj.load(res.body)
@@ -52,7 +53,7 @@ module Applitools::Base::ServerConnector
52
53
  end
53
54
 
54
55
  def stop_session(session, aborted = nil, save = false)
55
- res = long_delete(URI.join(endpoint_url, session.id.to_s), query: {aborted: aborted, updateBaseline: save})
56
+ res = long_delete(URI.join(endpoint_url, session.id.to_s), query: { aborted: aborted, updateBaseline: save })
56
57
  raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?
57
58
 
58
59
  response = Oj.load(res.body)
@@ -82,11 +83,11 @@ module Applitools::Base::ServerConnector
82
83
  end
83
84
 
84
85
  def request(url, method, options = {})
85
- Faraday::Connection.new(url, ssl: {ca_file: SSL_CERT}).send(method) do |req|
86
+ Faraday::Connection.new(url, ssl: { ca_file: SSL_CERT }).send(method) do |req|
86
87
  req.options.timeout = DEFAULT_TIMEOUT
87
88
  req.headers = DEFAULT_HEADERS.merge(options[:headers] || {})
88
89
  req.headers['Content-Type'] = options[:content_type] if options.key?(:content_type)
89
- req.params = {apiKey: api_key}.merge(options[:query] || {})
90
+ req.params = { apiKey: api_key }.merge(options[:query] || {})
90
91
  req.body = options[:body]
91
92
  end
92
93
  end
@@ -95,7 +96,7 @@ module Applitools::Base::ServerConnector
95
96
  delay = LONG_REQUEST_DELAY
96
97
  (options[:headers] ||= {})['Eyes-Expect'] = '202-accepted'
97
98
 
98
- while true
99
+ loop do
99
100
  # Date should be in RFC 1123 format.
100
101
  options[:headers]['Eyes-Date'] = Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
101
102
 
@@ -2,7 +2,7 @@ module Applitools::Base
2
2
  class TestResults
3
3
  attr_accessor :is_new, :url
4
4
  attr_reader :steps, :matches, :mismatches, :missing, :exact_matches, :strict_matches, :content_matches,
5
- :layout_matches, :none_matches, :is_passed
5
+ :layout_matches, :none_matches
6
6
 
7
7
  def initialize(steps = 0, matches = 0, mismatches = 0, missing = 0, exact_matches = 0, strict_matches = 0,
8
8
  content_matches = 0, layout_matches = 0, none_matches = 0)
@@ -19,15 +19,14 @@ module Applitools::Base
19
19
  @url = nil
20
20
  end
21
21
 
22
- def is_passed
22
+ def passed?
23
23
  !is_new && mismatches == 0 && missing == 0
24
24
  end
25
+ alias_method :is_passed, :passed?
25
26
 
26
27
  def to_s
27
28
  is_new_str = ''
28
- unless is_new.nil?
29
- is_new_str = is_new ? 'New test' : 'Existing test'
30
- end
29
+ is_new_str = is_new ? 'New test' : 'Existing test' unless is_new.nil?
31
30
 
32
31
  "#{is_new_str} [ steps: #{steps}, matches: #{matches}, mismatches: #{mismatches}, missing: #{missing} ], "\
33
32
  "URL: #{url}"
@@ -0,0 +1,17 @@
1
+ class Module
2
+ def alias_attribute(new_name, old_name)
3
+ module_eval <<-STR, __FILE__, __LINE__ + 1
4
+ def #{new_name}
5
+ self.#{old_name}
6
+ end
7
+
8
+ def #{new_name}?
9
+ self.#{old_name}?
10
+ end
11
+
12
+ def #{new_name}=(v)
13
+ self.#{old_name}
14
+ end
15
+ STR
16
+ end
17
+ end
@@ -23,7 +23,9 @@ class Applitools::Eyes
23
23
  DEFAULT_MATCH_TIMEOUT = 2.0.freeze # Seconds
24
24
  BASE_AGENT_ID = ('eyes.selenium.ruby/' + Applitools::VERSION).freeze
25
25
 
26
- #
26
+ ANDROID = 'Android'.freeze
27
+ IOS = 'iOS'.freeze
28
+
27
29
  # Attributes:
28
30
  #
29
31
  # +app_name+:: +String+ The application name which was provided as an argument to +open+.
@@ -31,7 +33,8 @@ class Applitools::Eyes
31
33
  # +is_open+:: +boolean+ Is there an open session.
32
34
  # +viewport_size+:: +Hash+ The viewport size which was provided as an argument to +open+. Should include +width+
33
35
  # and +height+.
34
- # +driver+:: +Applitools::Selenium::Driver+ The driver instance wrapping the driver which was provided as an argument to +open+.
36
+ # +driver+:: +Applitools::Selenium::Driver+ The driver instance wrapping the driver which was provided as an argument
37
+ # to +open+.
35
38
  # +api_key+:: +String+ The user's API key.
36
39
  # +match_timeout+:: +Float+ The default timeout for check_XXXX operations. (Seconds)
37
40
  # +batch+:: +BatchInfo+ The current tests grouping, if any.
@@ -41,8 +44,8 @@ class Applitools::Eyes
41
44
  # you wish to override Eyes' automatic inference.
42
45
  # +branch_name+:: +String+ If set, names the branch in which the test should run.
43
46
  # +parent_branch_name+:: +String+ If set, names the parent branch of the branch in which the test should run.
44
- # +user_inputs+:: +Applitools::Base::MouseTrigger+/+Applitools::Selenium::KeyboardTrigger+ Mouse/Keyboard events which happened after
45
- # the last visual validation.
47
+ # +user_inputs+:: +Applitools::Base::MouseTrigger+/+Applitools::Selenium::KeyboardTrigger+ Mouse/Keyboard events which
48
+ # happened after the last visual validation.
46
49
  # +save_new_tests+:: +boolean+ Whether or not new tests should be automatically accepted as baseline.
47
50
  # +save_failed_tests+:: +boolean+ Whether or not failed tests should be automatically accepted as baseline.
48
51
  # +match_level+:: +String+ The default match level for the entire session. See +Applitools::Eyes::MATCH_LEVEL+.
@@ -58,10 +61,14 @@ class Applitools::Eyes
58
61
  # +rotation+:: +Integer+|+nil+ The degrees by which to rotate the screenshots received from the driver. Set this to
59
62
  # override Eyes' automatic rotation inference. Positive values = clockwise rotation, negative
60
63
  # values = counter-clockwise, 0 = force no rotation, +nil+ = use Eyes' automatic rotation inference.
64
+ # +force_fullpage_screenshot+:: +boolean+ Whether or not to force fullpage screenshot taking, if the browser doesn't
65
+ # support it explicitly.
66
+ # +hide_scrollbars+:: +boolean+ Whether or not hide scrollbars.
67
+ # +use_css_transition+:: +boolean+ Whether or not to perform CSS transition.
61
68
  attr_reader :app_name, :test_name, :is_open, :viewport_size, :driver
62
69
  attr_accessor :match_timeout, :batch, :host_os, :host_app, :branch_name, :parent_branch_name, :user_inputs,
63
70
  :save_new_tests, :save_failed_tests, :is_disabled, :server_url, :agent_id, :failure_reports, :match_level,
64
- :baseline_name, :rotation
71
+ :baseline_name, :rotation, :force_fullpage_screenshot, :hide_scrollbars, :use_css_transition
65
72
 
66
73
  def_delegators 'Applitools::EyesLogger', :log_handler, :log_handler=
67
74
  def_delegators 'Applitools::Base::ServerConnector', :api_key, :api_key=, :server_url, :server_url=
@@ -98,6 +105,9 @@ class Applitools::Eyes
98
105
  @save_new_tests = true
99
106
  @save_failed_tests = false
100
107
  @dont_get_title = false
108
+ @force_fullpage_screenshot = false
109
+ @hide_scrollbars = false
110
+ @use_css_transition = false
101
111
  end
102
112
 
103
113
  def open(options = {})
@@ -105,7 +115,7 @@ class Applitools::Eyes
105
115
  return driver if disabled?
106
116
 
107
117
  if api_key.nil?
108
- raise Applitools::EyesError.new("API key not set! Log in to https://applitools.com to obtain your API Key and "\
118
+ raise Applitools::EyesError.new('API key not set! Log in to https://applitools.com to obtain your API Key and '\
109
119
  "use 'api_key' to set it.")
110
120
  end
111
121
 
@@ -180,7 +190,7 @@ class Applitools::Eyes
180
190
  check_region_(Applitools::Base::Region::EMPTY, tag, specific_timeout)
181
191
  end
182
192
 
183
- def close(raise_ex=true)
193
+ def close(raise_ex = true)
184
194
  return if disabled?
185
195
  @is_open = false
186
196
 
@@ -217,7 +227,7 @@ class Applitools::Eyes
217
227
  return results
218
228
  end
219
229
 
220
- unless results.is_passed
230
+ unless results.passed?
221
231
  # Test failed
222
232
  Applitools::EyesLogger.info "--- Failed test ended. See details at #{session_results_url}"
223
233
 
@@ -246,15 +256,13 @@ class Applitools::Eyes
246
256
  # get "http://www.google.com"
247
257
  # check_window("initial")
248
258
  # end
249
- #noinspection RubyUnusedLocalVariable
250
- def test(options = {}, &block)
251
- begin
252
- open(options)
253
- yield(driver)
254
- close
255
- ensure
256
- abort_if_not_closed
257
- end
259
+ # noinspection RubyUnusedLocalVariable
260
+ def test(options = {}, &_block)
261
+ open(options)
262
+ yield(driver)
263
+ close
264
+ ensure
265
+ abort_if_not_closed
258
266
  end
259
267
 
260
268
  def abort_if_not_closed
@@ -266,7 +274,7 @@ class Applitools::Eyes
266
274
 
267
275
  begin
268
276
  Applitools::Base::ServerConnector.stop_session(@session, true, false)
269
- rescue Exception, Applitools::EyesError => e
277
+ rescue => e
270
278
  Applitools::EyesLogger.error "Failed to abort server session: #{e.message}!"
271
279
  ensure
272
280
  @session = nil
@@ -280,8 +288,8 @@ class Applitools::Eyes
280
288
  end
281
289
 
282
290
  def get_driver(options)
283
- # TODO remove the "browser" related block when possible. It's for backward compatibility.
284
- if options.has_key?(:browser)
291
+ # TODO: remove the "browser" related block when possible. It's for backward compatibility.
292
+ if options.key?(:browser)
285
293
  Applitools::EyesLogger.warn('"browser" key is deprecated, please use "driver" instead.')
286
294
 
287
295
  return options[:browser]
@@ -308,10 +316,10 @@ class Applitools::Eyes
308
316
  Applitools::EyesLogger.info 'Mobile device detected! Checking device type..'
309
317
  if driver.android?
310
318
  Applitools::EyesLogger.info 'Android detected.'
311
- platform_name = 'Android'
319
+ platform_name = ANDROID
312
320
  elsif driver.ios?
313
321
  Applitools::EyesLogger.info 'iOS detected.'
314
- platform_name = 'iOS'
322
+ platform_name = IOS
315
323
  else
316
324
  Applitools::EyesLogger.warn 'Unknown device type.'
317
325
  end
@@ -379,15 +387,15 @@ class Applitools::Eyes
379
387
  as_expected = @match_window_task.match_window(region, specific_timeout, tag, rotation,
380
388
  @should_match_window_run_once_on_timeout)
381
389
  Applitools::EyesLogger.debug 'Match window done!'
382
- unless as_expected
383
- @should_match_window_run_once_on_timeout = true
384
- unless @session.new_session?
385
- Applitools::EyesLogger.info %( mismatch #{ tag ? '' : "(#{tag})" } )
386
- if failure_reports.to_i == Applitools::Eyes::FAILURE_REPORTS[:immediate]
387
- raise Applitools::TestFailedError.new("Mismatch found in '#{@session_start_info.scenario_id_or_name}' "\
388
- "of '#{@session_start_info.app_id_or_name}'")
389
- end
390
- end
391
- end
390
+ return if as_expected
391
+
392
+ @should_match_window_run_once_on_timeout = true
393
+ return if @session.new_session?
394
+
395
+ Applitools::EyesLogger.info %( mismatch #{ tag ? '' : "(#{tag})" } )
396
+ return unless failure_reports.to_i == Applitools::Eyes::FAILURE_REPORTS[:immediate]
397
+
398
+ raise Applitools::TestFailedError.new("Mismatch found in '#{@session_start_info.scenario_id_or_name}' "\
399
+ "of '#{@session_start_info.app_id_or_name}'")
392
400
  end
393
401
  end