eyes_selenium 2.11.0 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/eyes_selenium/eyes/driver.rb +36 -31
- data/lib/eyes_selenium/eyes/eyes.rb +42 -5
- data/lib/eyes_selenium/eyes/match_window_task.rb +14 -18
- data/lib/eyes_selenium/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc78305202b75895bf7025658234b46d93645892
|
4
|
+
data.tar.gz: bade0478f3a690c4ba373ad74ebd8e9460ce73ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e649613d6a93955dad130ae4d305bd34dbc41205ea6603534dcc22032693c83c4d04414b3a4d3d2612eb1bf15416f824c855b39b0da5f98c490c55987f98b7b
|
7
|
+
data.tar.gz: 0a28cebf023e6724ed65d0bc27d85c6c29359364afcc8b0f9e96ea0714ff8e6955910e768d7d974637b6eef58d62b75465c1efe1556f9af15cd3e55096033cc6
|
@@ -4,27 +4,28 @@ require 'appium_lib'
|
|
4
4
|
|
5
5
|
class Applitools::Driver
|
6
6
|
|
7
|
-
# Prepares an image for being sent to the Eyes server (e.g., handling rotation, scaling etc.).
|
7
|
+
# Prepares an image (in place!) for being sent to the Eyes server (e.g., handling rotation, scaling etc.).
|
8
8
|
#
|
9
9
|
# +driver+:: +Applitools::Driver+ The driver which produced the screenshot.
|
10
10
|
# +image+:: +ChunkyPNG::Canvas+ The image to normalize.
|
11
|
+
# +rotation+:: +Integer+|+nil+ The degrees by which to rotate the image: positive values = clockwise rotation,
|
12
|
+
# negative values = counter-clockwise, 0 = force no rotation, +nil+ = rotate
|
13
|
+
# automatically when needed.
|
11
14
|
#
|
12
|
-
|
13
|
-
# +Integer+ The rotation of the screenshot we get from the webdriver (degrees).
|
14
|
-
def self.normalize_image!(driver, image, rotation=0)
|
15
|
+
def self.normalize_image!(driver, image, rotation)
|
15
16
|
EyesLogger.debug "#{__method__}()"
|
16
|
-
# Handling rotation
|
17
|
-
num_quadrants = 0
|
18
17
|
if rotation != 0
|
19
|
-
|
20
|
-
|
18
|
+
num_quadrants = 0
|
19
|
+
if !rotation.nil?
|
20
|
+
if rotation % 90 != 0
|
21
|
+
raise Applitools::EyesError.new(
|
22
|
+
"Currently only quadrant rotations are supported. Current rotation: #{rotation}")
|
23
|
+
end
|
24
|
+
num_quadrants = (rotation / 90).to_i
|
25
|
+
elsif rotation.nil? && driver.mobile_device? && driver.landscape_orientation? && image.height > image.width
|
26
|
+
# For Android, we need to rotate images to the right, and for iOS to the left.
|
27
|
+
num_quadrants = driver.android? ? 1 : -1
|
21
28
|
end
|
22
|
-
num_quadrants = (rotation / 90).to_i
|
23
|
-
elsif driver.mobile_device? && driver.landscape_orientation? && image.height > image.width
|
24
|
-
# For Android, we need to rotate images to the right, and for iOS to the left.
|
25
|
-
num_quadrants = driver.android? ? 1 : -1
|
26
|
-
end
|
27
|
-
if num_quadrants != 0
|
28
29
|
Applitools::Utils::ImageUtils.quadrant_rotate!(image, num_quadrants)
|
29
30
|
end
|
30
31
|
end
|
@@ -108,24 +109,28 @@ class Applitools::Driver
|
|
108
109
|
@is_mobile_device
|
109
110
|
end
|
110
111
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
112
|
+
# Return a PNG screenshot in the given format as a string
|
113
|
+
#
|
114
|
+
# +output_type+:: +Symbol+ The format of the screenshot. Accepted values are +:base64+ and +:png+.
|
115
|
+
# +rotation+:: +Integer+|+nil+ The degrees by which to rotate the image: positive values = clockwise rotation,
|
116
|
+
# negative values = counter-clockwise, 0 = force no rotation, +nil+ = rotate
|
117
|
+
# automatically when needed.
|
118
|
+
#
|
119
|
+
# Returns: +String+ A screenshot in the requested format.
|
120
|
+
def screenshot_as(output_type, rotation=nil)
|
121
|
+
# FIXME Check if screenshot_taker is still required
|
122
|
+
screenshot = screenshot_taker ? screenshot_taker.screenshot : driver.screenshot_as(:base64)
|
123
|
+
screenshot = Applitools::Utils::ImageUtils.png_image_from_base64(screenshot)
|
124
|
+
Applitools::Driver.normalize_image!(self, screenshot, rotation)
|
125
|
+
case output_type
|
126
|
+
when :base64
|
127
|
+
screenshot = Applitools::Utils::ImageUtils.base64_from_png_image(screenshot)
|
128
|
+
when :png
|
129
|
+
screenshot = Applitools::Utils::ImageUtils.bytes_from_png_image(screenshot)
|
130
|
+
else
|
131
|
+
raise Applitools::EyesError.new("Unsupported screenshot output type #{output_type.to_s}")
|
125
132
|
end
|
126
|
-
screenshot
|
127
|
-
Applitools::Driver.normalize_image!(self, screenshot)
|
128
|
-
Applitools::Utils::ImageUtils.base64_from_png_image(screenshot)
|
133
|
+
screenshot.force_encoding('BINARY')
|
129
134
|
end
|
130
135
|
|
131
136
|
def mouse
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Applitools::Eyes
|
2
2
|
|
3
|
-
DEFAULT_MATCH_TIMEOUT = 2.0
|
3
|
+
DEFAULT_MATCH_TIMEOUT = 2.0 # Seconds
|
4
4
|
BASE_AGENT_ID = 'eyes.selenium.ruby/' + Applitools::VERSION
|
5
5
|
DEFAULT_EYES_SERVER = 'https://eyessdk.applitools.com'
|
6
6
|
|
@@ -10,10 +10,47 @@ class Applitools::Eyes
|
|
10
10
|
:dont_get_title
|
11
11
|
|
12
12
|
public
|
13
|
+
#
|
14
|
+
# Attributes:
|
15
|
+
#
|
16
|
+
# +app_name+:: +String+ The application name which was provided as an argument to +open+.
|
17
|
+
# +test_name+:: +String+ The test name which was provided as an argument to +open+.
|
18
|
+
# +is_open+:: +boolean+ Is there an open session.
|
19
|
+
# +viewport_size+:: +Hash+ The viewport size which was provided as an argument to +open+. Should include +width+
|
20
|
+
# and +height+.
|
21
|
+
# +driver+:: +Applitools::Driver+ The driver instance wrapping the driver which was provided as an argument to +open+.
|
22
|
+
# +api_key+:: +String+ The user's API key.
|
23
|
+
# +match_timeout+:: +Float+ The default timeout for check_XXXX operations. (Seconds)
|
24
|
+
# +batch+:: +BatchInfo+ The current tests grouping, if any.
|
25
|
+
# +host_os+:: +String+ A string identifying the OS running the AUT. Set this if you wish to override Eyes' automatic
|
26
|
+
# inference.
|
27
|
+
# +host_app+:: +String+ A string identifying the container application running the AUT (e.g., Firefox). Set this if
|
28
|
+
# you wish to override Eyes' automatic inference.
|
29
|
+
# +branch_name+:: +String+ If set, names the branch in which the test should run.
|
30
|
+
# +parent_branch_name+:: +String+ If set, names the parent branch of the branch in which the test should run.
|
31
|
+
# +user_inputs+:: +Applitools::MouseTrigger+/+Applitools::KeyboardTrigger+ Mouse/Keyboard events which happened after
|
32
|
+
# the last visual validation.
|
33
|
+
# +save_new_tests+:: +boolean+ Whether or not new tests should be automatically accepted as baseline.
|
34
|
+
# +save_failed_tests+:: +boolean+ Whether or not failed tests should be automatically accepted as baseline.
|
35
|
+
# +match_level+:: +String+ The default match level for the entire session. See +Applitools::MatchLevel+.
|
36
|
+
# +baseline_name+:: +String+ A string identifying the baseline which the test will be compared against. Set this if
|
37
|
+
# you wish to override Eyes' automatic baseline inference.
|
38
|
+
# +is_disabled+:: +boolean+ Set to +true+ if you wish to disable Eyes without deleting code (Eyes' methods act as a
|
39
|
+
# mock, and will do nothing).
|
40
|
+
# +server_url+:: +String+ The Eyes' server. Set this if you wish to override the default Eyes server URL.
|
41
|
+
# +agent_id+:: +String+ An optional string identifying the current library using the SDK.
|
42
|
+
# +log_handler+:: +Logger+ The logger to which Eyes will send info/debug messages.
|
43
|
+
# +failure_reports+:: +String+ Whether the current test will report mismatches immediately or when it is finished.
|
44
|
+
# See +Applitools::FailureReports+.
|
45
|
+
# +rotation+:: +Integer+|+nil+ The degrees by which to rotate the screenshots received from the driver. Set this to
|
46
|
+
# override Eyes' automatic rotation inference. Positive values = clockwise rotation,
|
47
|
+
# negative values = counter-clockwise, 0 = force no rotation, +nil+ = use Eyes' automatic rotation
|
48
|
+
# inference.
|
49
|
+
#
|
13
50
|
attr_reader :app_name, :test_name, :is_open, :viewport_size, :driver
|
14
51
|
attr_accessor :match_timeout, :batch, :host_os, :host_app, :branch_name, :parent_branch_name, :user_inputs,
|
15
52
|
:save_new_tests, :save_failed_tests, :api_key, :is_disabled, :server_url, :agent_id, :log_handler,
|
16
|
-
:failure_reports, :match_level, :baseline_name
|
53
|
+
:failure_reports, :match_level, :baseline_name, :rotation
|
17
54
|
|
18
55
|
def log_handler
|
19
56
|
EyesLogger.log_handler
|
@@ -85,8 +122,8 @@ class Applitools::Eyes
|
|
85
122
|
|
86
123
|
if api_key.nil?
|
87
124
|
#noinspection RubyQuotedStringsInspection
|
88
|
-
raise Applitools::EyesError.new(
|
89
|
-
|
125
|
+
raise Applitools::EyesError.new(
|
126
|
+
"API key not set! Log in to https://applitools.com to obtain your API Key and use 'api_key' to set it.")
|
90
127
|
end
|
91
128
|
|
92
129
|
if driver.is_a?(Selenium::WebDriver::Driver)
|
@@ -341,7 +378,7 @@ class Applitools::Eyes
|
|
341
378
|
end
|
342
379
|
|
343
380
|
EyesLogger.debug 'Starting match task...'
|
344
|
-
as_expected = match_window_task.match_window(region, specific_timeout, tag, should_match_window_run_once_on_timeout)
|
381
|
+
as_expected = match_window_task.match_window(region, specific_timeout, tag, rotation, should_match_window_run_once_on_timeout)
|
345
382
|
EyesLogger.debug 'Match window done!'
|
346
383
|
unless as_expected
|
347
384
|
self.should_match_window_run_once_on_timeout = true
|
@@ -22,18 +22,18 @@ class Applitools::MatchWindowTask
|
|
22
22
|
@current_screenshot = nil # +ChunkyPNG::Canvas+
|
23
23
|
end
|
24
24
|
|
25
|
-
def match_window(region, retry_timeout, tag,run_once_after_wait=false)
|
25
|
+
def match_window(region, retry_timeout, tag, rotation, run_once_after_wait=false)
|
26
26
|
if retry_timeout < 0
|
27
27
|
retry_timeout = default_retry_timeout
|
28
28
|
end
|
29
29
|
EyesLogger.debug "Retry timeout set to: #{retry_timeout}"
|
30
30
|
start = Time.now
|
31
31
|
res = if retry_timeout.zero?
|
32
|
-
run(region, tag)
|
32
|
+
run(region, tag, rotation)
|
33
33
|
elsif run_once_after_wait
|
34
|
-
run(region, tag, retry_timeout)
|
34
|
+
run(region, tag, rotation, retry_timeout)
|
35
35
|
else
|
36
|
-
run_with_intervals(region, tag, retry_timeout)
|
36
|
+
run_with_intervals(region, tag, rotation, retry_timeout)
|
37
37
|
end
|
38
38
|
elapsed_time = Time.now - start
|
39
39
|
EyesLogger.debug "match_window(): Completed in #{format('%.2f', elapsed_time)} seconds"
|
@@ -43,21 +43,21 @@ class Applitools::MatchWindowTask
|
|
43
43
|
driver.eyes.clear_user_inputs and return res
|
44
44
|
end
|
45
45
|
|
46
|
-
def run(region, tag, wait_before_run=nil)
|
46
|
+
def run(region, tag, rotation, wait_before_run=nil)
|
47
47
|
EyesLogger.debug 'Trying matching once...'
|
48
48
|
if wait_before_run
|
49
49
|
EyesLogger.debug 'waiting before run...'
|
50
50
|
sleep(wait_before_run)
|
51
51
|
EyesLogger.debug 'waiting done!'
|
52
52
|
end
|
53
|
-
match(region, tag)
|
53
|
+
match(region, tag, rotation)
|
54
54
|
end
|
55
55
|
|
56
|
-
def run_with_intervals(region, tag, retry_timeout)
|
56
|
+
def run_with_intervals(region, tag, rotation, retry_timeout)
|
57
57
|
# We intentionally take the first screenshot before starting the timer, to allow the page
|
58
58
|
# just a tad more time to stabilize.
|
59
59
|
EyesLogger.debug 'Matching with intervals...'
|
60
|
-
data = prep_match_data(region, tag, true)
|
60
|
+
data = prep_match_data(region, tag, rotation, true)
|
61
61
|
start = Time.now
|
62
62
|
as_expected = agent_connector.match_window(session, data)
|
63
63
|
EyesLogger.debug "First call result: #{as_expected}"
|
@@ -68,13 +68,13 @@ class Applitools::MatchWindowTask
|
|
68
68
|
EyesLogger.debug 'Waiting before match...'
|
69
69
|
sleep(MATCH_INTERVAL)
|
70
70
|
EyesLogger.debug 'Done! Matching...'
|
71
|
-
return true if match(region, tag, true)
|
71
|
+
return true if match(region, tag, rotation, true)
|
72
72
|
match_retry = Time.now - start
|
73
73
|
EyesLogger.debug "Elapsed time: #{match_retry}"
|
74
74
|
end
|
75
75
|
## lets try one more time if we still don't have a match
|
76
76
|
EyesLogger.debug 'Last attempt to match...'
|
77
|
-
as_expected = match(region, tag)
|
77
|
+
as_expected = match(region, tag, rotation)
|
78
78
|
EyesLogger.debug "Match result: #{as_expected}"
|
79
79
|
as_expected
|
80
80
|
end
|
@@ -89,15 +89,11 @@ class Applitools::MatchWindowTask
|
|
89
89
|
Applitools::Region.new(left, top, width, height)
|
90
90
|
end
|
91
91
|
|
92
|
-
def prep_match_data(region, tag, ignore_mismatch)
|
92
|
+
def prep_match_data(region, tag, rotation, ignore_mismatch)
|
93
93
|
EyesLogger.debug 'Preparing match data...'
|
94
94
|
title = eyes.title
|
95
95
|
EyesLogger.debug 'Getting screenshot...'
|
96
|
-
|
97
|
-
# We need a reference to the raw bytes of the PNG, which is why we didn't
|
98
|
-
# use +Applitools::Utils::ImageUtils.image_from_base64+.
|
99
|
-
EyesLogger.debug 'Done! Decoding base64...'
|
100
|
-
current_screenshot_encoded = Base64.decode64(screenshot64)
|
96
|
+
current_screenshot_encoded = driver.screenshot_as(:png, rotation)
|
101
97
|
EyesLogger.debug 'Done! Creating image object from PNG...'
|
102
98
|
@current_screenshot = ChunkyPNG::Image.from_blob(current_screenshot_encoded)
|
103
99
|
EyesLogger.debug 'Done!'
|
@@ -176,9 +172,9 @@ class Applitools::MatchWindowTask
|
|
176
172
|
match_window_data_obj
|
177
173
|
end
|
178
174
|
|
179
|
-
def match(region, tag, ignore_mismatch=false)
|
175
|
+
def match(region, tag, rotation, ignore_mismatch=false)
|
180
176
|
EyesLogger.debug 'Match called...'
|
181
|
-
data = prep_match_data(region, tag, ignore_mismatch)
|
177
|
+
data = prep_match_data(region, tag, rotation, ignore_mismatch)
|
182
178
|
match_result = agent_connector.match_window(session, data)
|
183
179
|
EyesLogger.debug 'Match done!'
|
184
180
|
match_result
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eyes_selenium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Applitools team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: selenium-webdriver
|