eyes_selenium 2.11.0 → 2.12.0
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 +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
|