eyes_selenium 2.15.0 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.travis.yml +16 -0
  4. data/Gemfile +1 -1
  5. data/README.md +14 -4
  6. data/Rakefile +8 -1
  7. data/eyes_selenium.gemspec +26 -17
  8. data/lib/applitools/base/batch_info.rb +19 -0
  9. data/lib/applitools/base/dimension.rb +21 -0
  10. data/lib/applitools/base/environment.rb +19 -0
  11. data/lib/applitools/base/mouse_trigger.rb +33 -0
  12. data/lib/applitools/base/point.rb +21 -0
  13. data/lib/applitools/base/region.rb +77 -0
  14. data/lib/applitools/base/server_connector.rb +113 -0
  15. data/lib/applitools/base/session.rb +15 -0
  16. data/lib/applitools/base/start_info.rb +34 -0
  17. data/lib/applitools/base/test_results.rb +36 -0
  18. data/lib/applitools/base/text_trigger.rb +22 -0
  19. data/lib/applitools/eyes.rb +393 -0
  20. data/lib/applitools/eyes_logger.rb +40 -0
  21. data/lib/applitools/method_tracer.rb +22 -0
  22. data/lib/applitools/selenium/driver.rb +194 -0
  23. data/lib/applitools/selenium/element.rb +66 -0
  24. data/lib/applitools/selenium/keyboard.rb +27 -0
  25. data/lib/applitools/selenium/match_window_data.rb +24 -0
  26. data/lib/applitools/selenium/match_window_task.rb +190 -0
  27. data/lib/applitools/selenium/mouse.rb +62 -0
  28. data/lib/applitools/selenium/viewport_size.rb +128 -0
  29. data/lib/applitools/utils/image_delta_compressor.rb +150 -0
  30. data/lib/applitools/utils/image_utils.rb +63 -0
  31. data/lib/applitools/utils/utils.rb +52 -0
  32. data/lib/applitools/version.rb +3 -0
  33. data/lib/eyes_selenium.rb +9 -29
  34. data/spec/driver_passthrough_spec.rb +25 -25
  35. data/spec/spec_helper.rb +5 -8
  36. data/test/appium_example_script.rb +57 -0
  37. data/{test_script.rb → test/test_script.rb} +7 -9
  38. data/{watir_test.rb → test/watir_test_script.rb} +6 -4
  39. metadata +120 -48
  40. data/appium_eyes_example.rb +0 -56
  41. data/lib/eyes_selenium/capybara.rb +0 -21
  42. data/lib/eyes_selenium/eyes/agent_connector.rb +0 -76
  43. data/lib/eyes_selenium/eyes/batch_info.rb +0 -19
  44. data/lib/eyes_selenium/eyes/dimension.rb +0 -15
  45. data/lib/eyes_selenium/eyes/driver.rb +0 -266
  46. data/lib/eyes_selenium/eyes/element.rb +0 -78
  47. data/lib/eyes_selenium/eyes/environment.rb +0 -15
  48. data/lib/eyes_selenium/eyes/eyes.rb +0 -396
  49. data/lib/eyes_selenium/eyes/eyes_keyboard.rb +0 -25
  50. data/lib/eyes_selenium/eyes/eyes_mouse.rb +0 -60
  51. data/lib/eyes_selenium/eyes/failure_reports.rb +0 -4
  52. data/lib/eyes_selenium/eyes/match_level.rb +0 -8
  53. data/lib/eyes_selenium/eyes/match_window_data.rb +0 -18
  54. data/lib/eyes_selenium/eyes/match_window_task.rb +0 -182
  55. data/lib/eyes_selenium/eyes/mouse_trigger.rb +0 -23
  56. data/lib/eyes_selenium/eyes/region.rb +0 -72
  57. data/lib/eyes_selenium/eyes/screenshot_taker.rb +0 -18
  58. data/lib/eyes_selenium/eyes/session.rb +0 -14
  59. data/lib/eyes_selenium/eyes/start_info.rb +0 -32
  60. data/lib/eyes_selenium/eyes/test_results.rb +0 -32
  61. data/lib/eyes_selenium/eyes/text_trigger.rb +0 -19
  62. data/lib/eyes_selenium/eyes/viewport_size.rb +0 -105
  63. data/lib/eyes_selenium/eyes_logger.rb +0 -47
  64. data/lib/eyes_selenium/utils.rb +0 -6
  65. data/lib/eyes_selenium/utils/image_delta_compressor.rb +0 -149
  66. data/lib/eyes_selenium/utils/image_utils.rb +0 -76
  67. data/lib/eyes_selenium/version.rb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e5d8d5bd76a819da52f7fc72a1c81a923c9f9a97
4
- data.tar.gz: 1330ef8e52a1a9e0c772c6000dcb55303f8fc86c
3
+ metadata.gz: 47b395b9cd5931cd1cdf51770296824d4123540e
4
+ data.tar.gz: ed4cfaadc2824b1140d64abee6322e08a5a99e94
5
5
  SHA512:
6
- metadata.gz: c587d0a9605ca5547e0b17b561a4b243a25ffa4d1ec7d72f2b8de1fece7d7c576f5262122854d15581ec793439c75188d4132fa91eaa89537e38ec8604bd236d
7
- data.tar.gz: 5f9fbb8dbab7175f7cadaec99bc119a98772c5b56000015a347713a4b2dbfde93e09c786fab71bb6c06eac0cdacb5f52ed505959b3dda3d3f23e4060d6bc5094
6
+ metadata.gz: a7f9f968f8be5d0108c768084e00213a575b946abdad64de5b389008439f8ffcc2ab24892ddf68f43229ba4d51202bb9ec509b478e87f94640ce7d108f7a09f6
7
+ data.tar.gz: 5fa006f0a50e22a1e9e2e31a17b31d25c47f11f90e98f1ecb70c051473fb998561bb1ec2b0031cdb859fc651077de559c086d2e4374d12d08df540f49cc9d325
data/.gitignore CHANGED
@@ -15,6 +15,4 @@ rdoc
15
15
  .idea/
16
16
  .idea-*/
17
17
  spec/reports
18
- test/tmp
19
- test/version_tmp
20
18
  tmp
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.6
6
+ - 2.2.2
7
+ - ruby-head
8
+ - rbx-2
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: rbx-2
12
+ # Use the faster container based infrastructure.
13
+ sudo: false
14
+ before_install:
15
+ - "export DISPLAY=:99.0"
16
+ - "sh -e /etc/init.d/xvfb start"
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in applitools.gemspec
3
+ # Specify your gem's dependencies in eyes_selenium.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # Applitools [![Gem Version](https://badge.fury.io/rb/eyes_selenium.svg)](https://rubygems.org/gems/eyes_selenium)
1
+ # Applitools
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/eyes_selenium.svg)](http://badge.fury.io/rb/eyes_selenium)
4
+ [![Build Status](https://travis-ci.org/applitools/Eyes.Selenium.Ruby.svg)](https://travis-ci.org/applitools/Eyes.Selenium.Ruby)
5
+ [![Dependency Status](https://gemnasium.com/applitools/Eyes.Selenium.Ruby.svg)](https://gemnasium.com/applitools/Eyes.Selenium.Ruby)
2
6
 
3
7
  Applitools Ruby SDK.
4
8
 
@@ -6,15 +10,21 @@ Applitools Ruby SDK.
6
10
 
7
11
  Add this line to your application's Gemfile:
8
12
 
9
- gem 'eyes_selenium'
13
+ ```ruby
14
+ gem 'eyes_selenium'
15
+ ```
10
16
 
11
17
  And then execute:
12
18
 
13
- $ bundle
19
+ ```ruby
20
+ $ bundle
21
+ ```
14
22
 
15
23
  Or install it yourself as:
16
24
 
17
- $ gem install eyes_selenium
25
+ ```bash
26
+ gem install eyes_selenium
27
+ ```
18
28
 
19
29
  ## Usage
20
30
  Please check the applitools website for usage instructions: http://www.applitools.com
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
- require "bundler/gem_tasks"
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ task :default => :spec
@@ -1,30 +1,39 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'eyes_selenium/version'
4
+ require 'applitools/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "eyes_selenium"
7
+ spec.name = 'eyes_selenium'
8
8
  spec.version = Applitools::VERSION
9
- spec.authors = ["Applitools team"]
10
- spec.email = ["team@applitools.com"]
11
- spec.description = "Applitools Ruby SDK"
12
- spec.summary = "Applitools Ruby SDK"
13
- spec.homepage = "http://www.applitools.com"
14
- spec.license = "Apache License, Version 2.0"
9
+ spec.authors = ['Applitools Team']
10
+ spec.email = ['team@applitools.com']
11
+ spec.description = 'Applitools Ruby SDK'
12
+ spec.summary = 'Applitools Ruby SDK'
13
+ spec.homepage = 'https://www.applitools.com'
14
+ spec.license = 'Apache License, Version 2.0'
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
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
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency "selenium-webdriver", [">= 2.45.0"]
22
- spec.add_dependency "httparty"
23
- spec.add_dependency "oily_png", [">= 1.1.0"]
21
+ spec.add_dependency 'selenium-webdriver', '>= 2.45.0'
22
+ spec.add_dependency 'oily_png'
23
+ spec.add_dependency 'faraday'
24
+ spec.add_dependency 'oj'
24
25
 
25
- spec.add_development_dependency "bundler", "~> 1.3"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "rspec", [">= 2.2.0"]
28
- spec.add_development_dependency "capybara", [">= 2.1.0"]
29
- spec.add_development_dependency "sinatra"
26
+ spec.add_development_dependency 'bundler'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec', '>= 3'
29
+ spec.add_development_dependency 'watir-webdriver'
30
+ spec.add_development_dependency 'appium_lib'
31
+
32
+ # Exclude debugging support on Travis CI, due to its incompatibility with jruby and older rubies.
33
+ unless ENV['TRAVIS']
34
+ spec.add_development_dependency 'pry'
35
+ spec.add_development_dependency 'pry-byebug'
36
+ spec.add_development_dependency 'pry-doc'
37
+ spec.add_development_dependency 'pry-stack_explorer'
38
+ end
30
39
  end
@@ -0,0 +1,19 @@
1
+ require 'securerandom'
2
+
3
+ module Applitools::Base
4
+ class BatchInfo
5
+ def initialize(name = nil, started_at = Time.now)
6
+ @name = name
7
+ @started_at = started_at
8
+ @id = SecureRandom.uuid
9
+ end
10
+
11
+ def to_hash
12
+ {
13
+ id: @id,
14
+ name: @name,
15
+ started_at: @started_at.iso8601
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Applitools::Base
2
+ class Dimension
3
+ attr_accessor :width, :height
4
+
5
+ def initialize(width, height)
6
+ @width = width
7
+ @height = height
8
+ end
9
+
10
+ def to_hash
11
+ {
12
+ width: width,
13
+ height: height
14
+ }
15
+ end
16
+
17
+ def values
18
+ [width, height]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Applitools::Base
2
+ class Environment
3
+ def initialize(os = nil, hosting_app = nil, display_size = nil, inferred = nil)
4
+ @os = os
5
+ @hosting_app = hosting_app
6
+ @display_size = display_size
7
+ @inferred = inferred
8
+ end
9
+
10
+ def to_hash
11
+ {
12
+ os: @os,
13
+ hosting_app: @hosting_app,
14
+ display_size: @display_size.to_hash,
15
+ inferred: @inferred
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module Applitools::Base
2
+ class MouseTrigger
3
+ MOUSE_ACTION = {
4
+ click: 'Click',
5
+ right_click: 'RightClick',
6
+ double_click: 'DoubleClick',
7
+ move: 'Move',
8
+ down: 'Down',
9
+ up: 'Up'
10
+ }.freeze
11
+
12
+ attr_reader :mouse_action, :control, :location
13
+
14
+ def initialize(mouse_action, control, location)
15
+ @mouse_action = mouse_action
16
+ @control = control
17
+ @location = location
18
+ end
19
+
20
+ def to_hash
21
+ {
22
+ trigget_type: 'Mouse',
23
+ mouse_action: MOUSE_ACTION[mouse_action],
24
+ control: control.to_hash,
25
+ location: location.to_hash
26
+ }
27
+ end
28
+
29
+ def to_s
30
+ "#{mouse_action} [#{control}] #{location.x}, #{location.y}"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ module Applitools::Base
2
+ class Point
3
+ attr_accessor :x, :y
4
+
5
+ def initialize(x, y)
6
+ @x = x
7
+ @y = y
8
+ end
9
+
10
+ def to_hash
11
+ {
12
+ x: x,
13
+ y: y
14
+ }
15
+ end
16
+
17
+ def values
18
+ [x, y]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,77 @@
1
+ module Applitools::Base
2
+ class Region
3
+ attr_accessor :left, :top, :width, :height
4
+
5
+ def initialize(left, top, width, height)
6
+ @left = left.round
7
+ @top = top.round
8
+ @width = width.round
9
+ @height = height.round
10
+ end
11
+
12
+ EMPTY = Applitools::Base::Region.new(0, 0, 0, 0)
13
+
14
+ def make_empty
15
+ @left = EMPTY.left
16
+ @top = EMPTY.top
17
+ @width = EMPTY.width
18
+ @height = EMPTY.height
19
+ end
20
+
21
+ def empty?
22
+ @left == EMPTY.left && @top == EMPTY.top && @width == EMPTY.width && @height == EMPTY.height
23
+ end
24
+
25
+ def right
26
+ left + width
27
+ end
28
+
29
+ def bottom
30
+ top + height
31
+ end
32
+
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))
36
+ end
37
+
38
+ def intersect(other)
39
+ if !intersecting?(other)
40
+ make_empty and return
41
+ end
42
+ i_left = (left >= other.left) ? left : other.left
43
+ i_right = (right <= other.right) ? right : other.right
44
+ i_top = (top >= other.top) ? top : other.top
45
+ i_bottom = (bottom <= other.bottom) ? bottom : other.bottom
46
+
47
+ @left = i_left
48
+ @top = i_top
49
+ @width = i_right - i_left
50
+ @height = i_bottom - i_top
51
+ end
52
+
53
+ def contains?(other_left, other_top)
54
+ other_left >= left && other_left <= right && \
55
+ other_top >= top && other_top <= bottom
56
+ end
57
+
58
+ def middle_offset
59
+ mid_x = width / 2
60
+ mid_y = height / 2
61
+ Applitools::Base::Point.new(mid_x.round, mid_y.round)
62
+ end
63
+
64
+ def to_hash
65
+ {
66
+ left: left,
67
+ top: top,
68
+ height: height,
69
+ width: width
70
+ }
71
+ end
72
+
73
+ def to_s
74
+ "(#{left}, #{top}), #{width} x #{height}"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,113 @@
1
+ require 'faraday'
2
+
3
+ require 'oj'
4
+ Oj.default_options = {:mode => :compat }
5
+
6
+ require 'uri'
7
+
8
+ module Applitools::Base::ServerConnector
9
+ extend self
10
+
11
+ DEFAULT_SERVER_URL = 'https://eyessdk.applitools.com'.freeze
12
+
13
+ SSL_CERT = File.join(File.dirname(File.expand_path(__FILE__)), '../../../certs/cacert.pem').to_s.freeze
14
+ DEFAULT_TIMEOUT = 300.freeze
15
+
16
+ API_SESSIONS_RUNNING = '/api/sessions/running/'.freeze
17
+
18
+ HTTP_STATUS_CODES = {
19
+ created: 201,
20
+ accepted: 202
21
+ }.freeze
22
+
23
+ attr_accessor :server_url, :api_key
24
+ attr_reader :endpoint_url
25
+
26
+ def server_url=(url)
27
+ @server_url = url.nil? ? DEFAULT_SERVER_URL : url
28
+ @endpoint_url = URI.join(@server_url, API_SESSIONS_RUNNING).to_s
29
+ end
30
+
31
+ def match_window(session, data)
32
+ # Notice that this does not include the screenshot.
33
+ json_data = Oj.dump(Applitools::Utils.camelcase_hash_keys(data.to_hash)).force_encoding('BINARY')
34
+ body = [json_data.length].pack('L>') + json_data + data.screenshot
35
+
36
+ Applitools::EyesLogger.debug 'Sending match data...'
37
+
38
+ res = post(URI.join(endpoint_url, session.id.to_s), content_type: 'application/octet-stream', body: body)
39
+ raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?
40
+
41
+ Oj.load(res.body)['asExpected'].tap do |as_expected|
42
+ Applitools::EyesLogger.debug "Got response! #{as_expected}"
43
+ end
44
+ end
45
+
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)))
48
+ raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?
49
+
50
+ response = Oj.load(res.body)
51
+ Applitools::Base::Session.new(response['id'], response['url'], res.status == HTTP_STATUS_CODES[:created])
52
+ end
53
+
54
+ 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
+ raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?
57
+
58
+ response = Oj.load(res.body)
59
+ response.delete('$id')
60
+ Applitools::Base::TestResults.new(*response.values)
61
+ end
62
+
63
+ private
64
+
65
+ DEFAULT_HEADERS = {
66
+ 'Accept' => 'application/json',
67
+ 'Content-Type' => 'application/json'
68
+ }.freeze
69
+
70
+ LONG_REQUEST_DELAY = 2.freeze # seconds
71
+ MAX_LONG_REQUEST_DELAY = 10.freeze # seconds
72
+ LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR = 1.5.freeze
73
+
74
+ [:get, :post, :delete].each do |method|
75
+ define_method method do |url, options = {}|
76
+ request(url, method, options)
77
+ end
78
+
79
+ define_method "long_#{method}" do |url, options = {}|
80
+ long_request(url, method, options)
81
+ end
82
+ end
83
+
84
+ def request(url, method, options = {})
85
+ Faraday::Connection.new(url, ssl: {ca_file: SSL_CERT}).send(method) do |req|
86
+ req.options.timeout = DEFAULT_TIMEOUT
87
+ req.headers = DEFAULT_HEADERS.merge(options[:headers] || {})
88
+ req.headers['Content-Type'] = options[:content_type] if options.key?(:content_type)
89
+ req.params = {apiKey: api_key}.merge(options[:query] || {})
90
+ req.body = options[:body]
91
+ end
92
+ end
93
+
94
+ def long_request(url, method, options = {})
95
+ delay = LONG_REQUEST_DELAY
96
+ (options[:headers] ||= {})['Eyes-Expect'] = '202-accepted'
97
+
98
+ while true
99
+ # Date should be in RFC 1123 format.
100
+ options[:headers]['Eyes-Date'] = Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
101
+
102
+ res = request(url, method, options)
103
+ return res unless res.status == HTTP_STATUS_CODES[:accepted]
104
+
105
+ Applitools::EyesLogger.debug "Still running... retrying in #{delay}s"
106
+ sleep delay
107
+
108
+ delay = [MAX_LONG_REQUEST_DELAY, (delay * LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR).round].min
109
+ end
110
+ end
111
+
112
+ include Applitools::MethodTracer
113
+ end