eyes_selenium 3.14.10 → 3.15.0.beta
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/applitools/selenium/concerns/browser_types.rb +15 -0
- data/lib/applitools/selenium/concerns/browsers_info.rb +16 -0
- data/lib/applitools/selenium/concerns/external_css_resources.rb +31 -0
- data/lib/applitools/selenium/concerns/render_browser_info_fluent.rb +42 -0
- data/lib/applitools/selenium/concerns/render_resources.rb +15 -0
- data/lib/applitools/selenium/concerns/rgrid_dom.rb +46 -0
- data/lib/applitools/selenium/concerns/stitch_modes.rb +15 -0
- data/lib/applitools/selenium/concerns/test_list.rb +23 -0
- data/lib/applitools/selenium/eyes.rb +13 -854
- data/lib/applitools/selenium/scripts/process_page_and_serialize.rb +519 -0
- data/lib/applitools/selenium/selenium_configuration.rb +64 -0
- data/lib/applitools/selenium/selenium_eyes.rb +860 -0
- data/lib/applitools/selenium/target.rb +2 -2
- data/lib/applitools/selenium/visual_grid/eyes_connector.rb +170 -0
- data/lib/applitools/selenium/visual_grid/render_browser_info.rb +31 -0
- data/lib/applitools/selenium/visual_grid/render_info.rb +9 -0
- data/lib/applitools/selenium/visual_grid/render_request.rb +22 -0
- data/lib/applitools/selenium/visual_grid/render_requests.rb +11 -0
- data/lib/applitools/selenium/visual_grid/render_task.rb +171 -0
- data/lib/applitools/selenium/visual_grid/resource_cache.rb +51 -0
- data/lib/applitools/selenium/visual_grid/running_test.rb +198 -0
- data/lib/applitools/selenium/visual_grid/thread_pool.rb +94 -0
- data/lib/applitools/selenium/visual_grid/vg_resource.rb +37 -0
- data/lib/applitools/selenium/visual_grid/vg_task.rb +46 -0
- data/lib/applitools/selenium/visual_grid/visual_grid_eyes.rb +236 -0
- data/lib/applitools/selenium/visual_grid/visual_grid_runner.rb +57 -0
- data/lib/applitools/version.rb +1 -1
- data/lib/eyes_selenium.rb +3 -0
- metadata +46 -7
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'state_machine'
|
2
|
+
require 'digest'
|
3
|
+
|
4
|
+
module Applitools
|
5
|
+
module Selenium
|
6
|
+
class RunningTest
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators 'Applitools::EyesLogger', :logger, :log_handler, :log_handler=
|
9
|
+
|
10
|
+
state_machine :initial => :new do
|
11
|
+
state :new do
|
12
|
+
def close
|
13
|
+
becomes_completed
|
14
|
+
end
|
15
|
+
|
16
|
+
def score
|
17
|
+
0
|
18
|
+
end
|
19
|
+
|
20
|
+
def queue
|
21
|
+
Applitools::Selenium::VisualGridRunner::EMPTY_QUEUE
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
state :not_rendered do
|
26
|
+
def score
|
27
|
+
render_queue.length * 10
|
28
|
+
end
|
29
|
+
|
30
|
+
def queue
|
31
|
+
render_queue
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
state :opened do
|
36
|
+
def score
|
37
|
+
task_queue.length
|
38
|
+
end
|
39
|
+
|
40
|
+
def queue
|
41
|
+
return Applitools::Selenium::VisualGridRunner::EMPTY_QUEUE unless task_lock.nil?
|
42
|
+
self.task_lock = task_queue.last unless task_queue.last.nil?
|
43
|
+
task_queue
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
state :rendered do
|
48
|
+
def score
|
49
|
+
open_queue.length
|
50
|
+
end
|
51
|
+
|
52
|
+
def queue
|
53
|
+
open_queue
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
state :tested do
|
58
|
+
def score
|
59
|
+
close_queue.length
|
60
|
+
end
|
61
|
+
|
62
|
+
def queue
|
63
|
+
close_queue
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
state :completed do
|
68
|
+
def score
|
69
|
+
0
|
70
|
+
end
|
71
|
+
|
72
|
+
def queue
|
73
|
+
Applitools::Selenium::VisualGridRunner::EMPTY_QUEUE
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
state :new, :not_rendered, :opened, :rendered, :tested do
|
78
|
+
def close
|
79
|
+
self.test_result = nil
|
80
|
+
close_task = Applitools::Selenium::VGTask.new("close #{browser_info}") do
|
81
|
+
eyes.close(false)
|
82
|
+
end
|
83
|
+
close_task.on_task_succeeded do |task_result|
|
84
|
+
self.test_result = task_result
|
85
|
+
end.on_task_error do |e|
|
86
|
+
self.pending_exceptions << e
|
87
|
+
end.on_task_completed do
|
88
|
+
watch_close[close_task] = true
|
89
|
+
becomes_completed if all_tasks_completed?(watch_close)
|
90
|
+
end
|
91
|
+
close_queue << close_task
|
92
|
+
watch_close[close_task] = false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
event :becomes_not_rendered do
|
97
|
+
transition :new => :not_rendered
|
98
|
+
end
|
99
|
+
|
100
|
+
event :becomes_opened do
|
101
|
+
transition :rendered => :opened
|
102
|
+
end
|
103
|
+
|
104
|
+
event :becomes_rendered do
|
105
|
+
transition :not_rendered => :rendered
|
106
|
+
end
|
107
|
+
|
108
|
+
event :becomes_tested do
|
109
|
+
transition :opened => :tested
|
110
|
+
end
|
111
|
+
|
112
|
+
event :becomes_completed do
|
113
|
+
transition [:not_rendered, :rendered, :opened, :tested] => :completed
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
attr_accessor :open_queue, :task_queue, :render_queue, :close_queue, :watch_open, :watch_task, :watch_render, :watch_close
|
118
|
+
|
119
|
+
attr_accessor :eyes, :browser_info, :test_result, :pending_exceptions, :driver, :task_lock
|
120
|
+
|
121
|
+
def initialize(eyes, browser_info, driver)
|
122
|
+
Applitools::ArgumentGuard.is_a? eyes, 'eyes', Applitools::Selenium::EyesConnector
|
123
|
+
Applitools::ArgumentGuard.is_a? browser_info, 'browser_info', Applitools::Selenium::RenderBrowserInfo
|
124
|
+
|
125
|
+
self.eyes = eyes
|
126
|
+
self.browser_info = browser_info
|
127
|
+
self.driver = driver
|
128
|
+
|
129
|
+
self.open_queue = []
|
130
|
+
self.task_queue = []
|
131
|
+
self.render_queue = []
|
132
|
+
self.close_queue = []
|
133
|
+
|
134
|
+
self.watch_open = {}
|
135
|
+
self.watch_task = {}
|
136
|
+
self.watch_render = {}
|
137
|
+
self.watch_close = {}
|
138
|
+
|
139
|
+
self.task_lock = nil
|
140
|
+
|
141
|
+
self.pending_exceptions = []
|
142
|
+
super()
|
143
|
+
init
|
144
|
+
end
|
145
|
+
|
146
|
+
def init
|
147
|
+
open_task = Applitools::Selenium::VGTask.new("open #{browser_info}") { eyes.open(driver, browser_info) }
|
148
|
+
|
149
|
+
open_task.on_task_succeeded { watch_open[open_task] = true; becomes_opened if all_tasks_completed?(watch_open) }.
|
150
|
+
on_task_error { |e| pending_exceptions << e; becomes_completed }
|
151
|
+
open_queue << open_task
|
152
|
+
watch_open[open_task] = false
|
153
|
+
end
|
154
|
+
|
155
|
+
def check(tag, target, script_result, visual_grid_manager, mod = nil)
|
156
|
+
render_task = RenderTask.new(
|
157
|
+
"Render #{eyes.config.short_description} - #{tag}",
|
158
|
+
script_result,
|
159
|
+
self,
|
160
|
+
visual_grid_manager.resource_cache,
|
161
|
+
visual_grid_manager.put_cache,
|
162
|
+
visual_grid_manager.rendering_info(eyes.server_connector),
|
163
|
+
eyes.server_connector,
|
164
|
+
mod
|
165
|
+
)
|
166
|
+
|
167
|
+
check_task = VGTask.new("perform check #{tag} #{target}") do
|
168
|
+
eyes.check(tag, target, render_task.uuid)
|
169
|
+
end
|
170
|
+
|
171
|
+
check_task.on_task_completed do
|
172
|
+
watch_task[check_task] = true
|
173
|
+
self.task_lock = nil if task_lock.uuid == check_task.uuid
|
174
|
+
becomes_tested if all_tasks_completed?(watch_task)
|
175
|
+
end
|
176
|
+
|
177
|
+
task_queue.insert(0, check_task)
|
178
|
+
watch_task[check_task] = false
|
179
|
+
|
180
|
+
render_task.on_task_succeeded do |r|
|
181
|
+
eyes.render_status_for_task(render_task.uuid, r) if r
|
182
|
+
watch_render[render_task] = true
|
183
|
+
becomes_rendered if all_tasks_completed?(watch_render)
|
184
|
+
end.on_task_error do
|
185
|
+
becomes_completed
|
186
|
+
end
|
187
|
+
render_queue << render_task
|
188
|
+
watch_render[render_task] = false
|
189
|
+
end
|
190
|
+
|
191
|
+
def all_tasks_completed?(watch)
|
192
|
+
return true if state_name == :completed
|
193
|
+
uniq_values = watch.values.uniq
|
194
|
+
uniq_values.count == 1 && uniq_values.first == true
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Applitools
|
4
|
+
module Selenium
|
5
|
+
class VGThreadPool
|
6
|
+
extend Forwardable
|
7
|
+
attr_accessor :concurrency
|
8
|
+
def_delegator 'Applitools::EyesLogger', :logger
|
9
|
+
|
10
|
+
def initialize(concurrency = 10)
|
11
|
+
self.concurrency = concurrency
|
12
|
+
@stopped = true
|
13
|
+
@thread_group = ThreadGroup.new
|
14
|
+
@semaphore = Mutex.new
|
15
|
+
@next_task_block = nil
|
16
|
+
@watchdog = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_next_task_needed(&block)
|
20
|
+
@next_task_block = block if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
@semaphore.synchronize { @stopped = false }
|
25
|
+
init_or_renew_threads
|
26
|
+
@watchdog = Thread.new do
|
27
|
+
catch(:exit) do
|
28
|
+
loop do
|
29
|
+
throw :exit if stopped?
|
30
|
+
sleep 5
|
31
|
+
init_or_renew_threads
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def stop
|
38
|
+
@watchdog.exit
|
39
|
+
@semaphore.synchronize do
|
40
|
+
@stopped = true
|
41
|
+
end
|
42
|
+
@thread_group.list.each do |t|
|
43
|
+
t.join
|
44
|
+
end
|
45
|
+
stopped?
|
46
|
+
end
|
47
|
+
|
48
|
+
def stopped?
|
49
|
+
@semaphore.synchronize { @stopped }
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def next_task
|
55
|
+
@semaphore.synchronize do
|
56
|
+
return @next_task_block.call if @next_task_block && @next_task_block.respond_to?(:call)
|
57
|
+
end
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def init_or_renew_threads
|
62
|
+
(concurrency - @thread_group.list.count).times do
|
63
|
+
logger.debug 'starting new thread (task worker)'
|
64
|
+
next_thread
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def next_thread
|
69
|
+
thread = Thread.new do
|
70
|
+
begin
|
71
|
+
catch(:exit) do
|
72
|
+
loop do
|
73
|
+
throw :exit if stopped?
|
74
|
+
task_to_run = next_task
|
75
|
+
if task_to_run && task_to_run.respond_to?(:call)
|
76
|
+
logger.debug "Executing new task... #{task_to_run.name}"
|
77
|
+
task_to_run.call
|
78
|
+
logger.debug 'Done!'
|
79
|
+
else
|
80
|
+
sleep 0.5
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
rescue => e
|
85
|
+
Applitools::EyesLogger.logger.error "Failed to execute task - #{task_to_run.name}"
|
86
|
+
Applitools::EyesLogger.logger.error e.message
|
87
|
+
Applitools::EyesLogger.logger.error e.backtrace.join( ' ')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
@thread_group.add thread
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'digest'
|
3
|
+
module Applitools
|
4
|
+
module Selenium
|
5
|
+
class VGResource
|
6
|
+
include Applitools::Jsonable
|
7
|
+
json_fields :contentType, :hash, :hashFormat
|
8
|
+
attr_accessor :url, :content
|
9
|
+
alias :content_type :contentType
|
10
|
+
alias :content_type= :contentType=
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def parse_blob_from_script(blob)
|
14
|
+
content = Base64.decode64(blob["value"])
|
15
|
+
self.new blob["url"], blob["type"], content
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_response(url, response)
|
19
|
+
return self.new(url, 'application/empty-response', '') unless response.status == 200
|
20
|
+
self.new(url, response.headers['Content-Type'], response.body)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(url, content_type, content)
|
25
|
+
self.url = URI(url)
|
26
|
+
self.content_type = content_type
|
27
|
+
self.content = content
|
28
|
+
self.hash = Digest::SHA256.hexdigest(content)
|
29
|
+
self.hashFormat = 'sha256'
|
30
|
+
end
|
31
|
+
|
32
|
+
def stringify
|
33
|
+
url.to_s + content_type.to_s + hash
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
module Applitools
|
3
|
+
module Selenium
|
4
|
+
class VGTask
|
5
|
+
attr_accessor :name, :uuid
|
6
|
+
def initialize(name, &block)
|
7
|
+
self.name = name
|
8
|
+
@block_to_run = block if block_given?
|
9
|
+
@callback = nil
|
10
|
+
@error_callback = nil
|
11
|
+
@completed_callback = nil
|
12
|
+
self.uuid = SecureRandom.uuid
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_task_succeeded(&block)
|
16
|
+
@callback = block if block_given?
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_task_error(&block)
|
21
|
+
@error_callback = block if block_given?
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_task_completed(&block)
|
26
|
+
@completed_callback = block if block_given?
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def call
|
31
|
+
return unless @block_to_run.respond_to? :call
|
32
|
+
begin
|
33
|
+
res = @block_to_run.call
|
34
|
+
@callback.call(res) if @callback.respond_to? :call
|
35
|
+
rescue StandardError => e
|
36
|
+
Applitools::EyesLogger.logger.error 'Failed to execute task!'
|
37
|
+
Applitools::EyesLogger.logger.error e.message
|
38
|
+
Applitools::EyesLogger.logger.error e.backtrace.join('\n\t')
|
39
|
+
@error_callback.call(e) if @error_callback.respond_to? :call
|
40
|
+
ensure
|
41
|
+
@completed_callback.call if @completed_callback.respond_to? :call
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'applitools/selenium/selenium_configuration'
|
2
|
+
module Applitools
|
3
|
+
module Selenium
|
4
|
+
class VisualGridEyes
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators 'Applitools::EyesLogger', :logger, :log_handler, :log_handler=
|
8
|
+
|
9
|
+
attr_accessor :visual_grid_manager, :driver, :current_url, :current_config, :fetched_cache_map, :config
|
10
|
+
attr_accessor :test_list
|
11
|
+
|
12
|
+
attr_accessor :api_key, :server_url, :proxy, :opened
|
13
|
+
|
14
|
+
def_delegators 'config', *Applitools::Selenium::SeleniumConfiguration.methods_to_delegate
|
15
|
+
def_delegators 'config', *Applitools::EyesBaseConfiguration.methods_to_delegate
|
16
|
+
|
17
|
+
def initialize(visual_grid_manager, server_url = nil)
|
18
|
+
ensure_config
|
19
|
+
self.visual_grid_manager = visual_grid_manager
|
20
|
+
self.test_list = Applitools::Selenium::TestList.new
|
21
|
+
self.opened = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def ensure_config
|
25
|
+
self.config = Applitools::Selenium::SeleniumConfiguration.new
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def open(*args)
|
30
|
+
self.test_list = Applitools::Selenium::TestList.new
|
31
|
+
options = Applitools::Utils.extract_options!(args)
|
32
|
+
Applitools::ArgumentGuard.hash(options, 'options', [:driver])
|
33
|
+
|
34
|
+
# self.current_config = options.delete(:config)
|
35
|
+
# self.current_config = yield(Applitools::Selenium::SeleniumConfiguration.new) if block_given?
|
36
|
+
|
37
|
+
# Applitools::ArgumentGuard.is_a? options[:driver], 'options[:driver]', ::Selenium::WebDriver
|
38
|
+
# Applitools::ArgumentGuard.is_a? current_config, 'options[:config]', Applitools::Selenium::SeleniumConfiguration
|
39
|
+
|
40
|
+
# batch_info.name = config.app_name
|
41
|
+
self.driver = options.delete(:driver)
|
42
|
+
self.current_url = driver.current_url
|
43
|
+
|
44
|
+
visual_grid_manager.open(self)
|
45
|
+
|
46
|
+
logger.info("getting all browsers info...")
|
47
|
+
browsers_info_list = config.browsers_info
|
48
|
+
logger.info("creating test descriptors for each browser info...")
|
49
|
+
browsers_info_list.each do |bi|
|
50
|
+
test_list.push Applitools::Selenium::RunningTest.new(eyes_connector, bi, driver)
|
51
|
+
end
|
52
|
+
self.opened = true
|
53
|
+
driver
|
54
|
+
end
|
55
|
+
|
56
|
+
def eyes_connector
|
57
|
+
logger.info("creating VisualGridEyes server connector")
|
58
|
+
::Applitools::Selenium::EyesConnector.new(server_url).tap do |connector|
|
59
|
+
connector.batch = batch_info
|
60
|
+
connector.config = config.deep_clone
|
61
|
+
connector.proxy = proxy if proxy.is_a? Applitools::Connectivity::Proxy
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def check(tag, target)
|
66
|
+
script = <<-END
|
67
|
+
var callback = arguments[arguments.length - 1]; return (#{Applitools::Selenium::Scripts::PROCESS_RESOURCES})().then(JSON.stringify).then(callback, function(err) {callback(err.stack || err.toString())});
|
68
|
+
END
|
69
|
+
|
70
|
+
script_result = driver.execute_async_script(script).freeze
|
71
|
+
mod = Digest::SHA2.hexdigest(script_result)
|
72
|
+
test_list.each do |test|
|
73
|
+
test.check(tag, target, script_result.dup, visual_grid_manager, mod)
|
74
|
+
end
|
75
|
+
test_list.each { |t| t.becomes_not_rendered}
|
76
|
+
end
|
77
|
+
|
78
|
+
def close(throw_exception = true)
|
79
|
+
return false if test_list.empty?
|
80
|
+
test_list.each do |t|
|
81
|
+
t.close
|
82
|
+
end
|
83
|
+
|
84
|
+
while (!((states = test_list.map(&:state_name).uniq).count == 1 && states.first == :completed)) do
|
85
|
+
sleep 0.5
|
86
|
+
end
|
87
|
+
self.opened = false
|
88
|
+
|
89
|
+
test_list.select { |t| t.pending_exceptions && !t.pending_exceptions.empty? }.each do |t|
|
90
|
+
t.pending_exceptions.each do |e|
|
91
|
+
raise e
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
if throw_exception
|
96
|
+
test_list.map(&:test_result).compact.each do |r|
|
97
|
+
raise Applitools::NewTestError.new new_test_error_message(r), r if r.new?
|
98
|
+
raise Applitools::DiffsFoundError.new diffs_found_error_message(r), r if r.unresolved? && !r.new?
|
99
|
+
raise Applitools::TestFailedError.new test_failed_error_message(r), r if r.failed?
|
100
|
+
end
|
101
|
+
end
|
102
|
+
test_list.map(&:test_result).first
|
103
|
+
end
|
104
|
+
|
105
|
+
def open?
|
106
|
+
opened
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_all_test_results
|
110
|
+
test_list.map(&:test_result)
|
111
|
+
end
|
112
|
+
|
113
|
+
def new_test_error_message(result)
|
114
|
+
original_results = result.original_results
|
115
|
+
"New test '#{original_results['name']}' " \
|
116
|
+
"of '#{original_results['appName']}' " \
|
117
|
+
"Please approve the baseline at #{original_results['appUrls']['session']} "
|
118
|
+
end
|
119
|
+
|
120
|
+
def diffs_found_error_message(result)
|
121
|
+
original_results = result.original_results
|
122
|
+
"Test '#{original_results['name']}' " \
|
123
|
+
"of '#{original_results['appname']}' " \
|
124
|
+
"detected differences! See details at #{original_results['appUrls']['session']}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_failed_error_message(result)
|
128
|
+
original_results = result.original_results
|
129
|
+
"Test '#{original_results['name']}' of '#{original_results['appName']}' " \
|
130
|
+
"is failed! See details at #{original_results['appUrls']['session']}"
|
131
|
+
end
|
132
|
+
private :new_test_error_message, :diffs_found_error_message, :test_failed_error_message
|
133
|
+
|
134
|
+
# Takes a snapshot of the application under test and matches it with the expected output.
|
135
|
+
#
|
136
|
+
# @param [String] tag An optional tag to be assosiated with the snapshot.
|
137
|
+
# @param [Fixnum] match_timeout The amount of time to retry matching (seconds)
|
138
|
+
def check_window(tag = nil, match_timeout = USE_DEFAULT_MATCH_TIMEOUT)
|
139
|
+
target = Applitools::Selenium::Target.window.tap do |t|
|
140
|
+
t.timeout(match_timeout)
|
141
|
+
t.fully if force_full_page_screenshot
|
142
|
+
end
|
143
|
+
check(tag, target)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Takes a snapshot of the application under test and matches a region of
|
147
|
+
# a specific element with the expected region output.
|
148
|
+
#
|
149
|
+
# @param [Applitools::Selenium::Element] element Represents a region to check.
|
150
|
+
# @param [Symbol] how a finder, such :css or :id. Selects a finder will be used to find an element
|
151
|
+
# See Selenium::Webdriver::Element#find_element documentation for full list of possible finders.
|
152
|
+
# @param [String] what The value will be passed to a specified finder. If finder is :css it must be a css selector.
|
153
|
+
# @param [Hash] options
|
154
|
+
# @option options [String] :tag An optional tag to be associated with the snapshot.
|
155
|
+
# @option options [Fixnum] :match_timeout The amount of time to retry matching. (Seconds)
|
156
|
+
# @option options [Boolean] :stitch_content If set to true, will try to get full content of the element
|
157
|
+
# (including hidden content due overflow settings) by scrolling the element,
|
158
|
+
# taking and stitching partial screenshots.
|
159
|
+
# @example Check region by element
|
160
|
+
# check_region(element, tag: 'Check a region by element', match_timeout: 3, stitch_content: false)
|
161
|
+
# @example Check region by css selector
|
162
|
+
# check_region(:css, '.form-row .input#e_mail', tag: 'Check a region by element', match_timeout: 3,
|
163
|
+
# stitch_content: false)
|
164
|
+
# @!parse def check_region(element, how=nil, what=nil, options = {}); end
|
165
|
+
def check_region(*args)
|
166
|
+
options = { timeout: USE_DEFAULT_MATCH_TIMEOUT, tag: nil }.merge! Applitools::Utils.extract_options!(args)
|
167
|
+
target = Applitools::Selenium::Target.new.region(*args).timeout(options[:match_timeout])
|
168
|
+
target.fully if options[:stitch_content]
|
169
|
+
check(options[:tag], target)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Validates the contents of an iframe and matches it with the expected output.
|
173
|
+
#
|
174
|
+
# @param [Hash] options The specific parameters of the desired screenshot.
|
175
|
+
# @option options [Fixnum] :timeout The amount of time to retry matching. (Seconds)
|
176
|
+
# @option options [String] :tag An optional tag to be associated with the snapshot.
|
177
|
+
# @option options [String] :frame Frame element or frame name or frame id.
|
178
|
+
# @option options [String] :name_or_id The name or id of the target frame (deprecated. use :frame instead).
|
179
|
+
# @option options [String] :frame_element The frame element (deprecated. use :frame instead).
|
180
|
+
# @return [Applitools::MatchResult] The match results.
|
181
|
+
|
182
|
+
def check_frame(options = {})
|
183
|
+
options = { timeout: USE_DEFAULT_MATCH_TIMEOUT, tag: nil }.merge!(options)
|
184
|
+
frame = options[:frame] || options[:frame_element] || options[:name_or_id]
|
185
|
+
target = Applitools::Selenium::Target.frame(frame).timeout(options[:timeout]).fully
|
186
|
+
check(options[:tag], target)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Validates the contents of a region in an iframe and matches it with the expected output.
|
190
|
+
#
|
191
|
+
# @param [Hash] options The specific parameters of the desired screenshot.
|
192
|
+
# @option options [String] :name_or_id The name or id of the target frame (deprecated. use :frame instead).
|
193
|
+
# @option options [String] :frame_element The frame element (deprecated. use :frame instead).
|
194
|
+
# @option options [String] :frame Frame element or frame name or frame id.
|
195
|
+
# @option options [String] :tag An optional tag to be associated with the snapshot.
|
196
|
+
# @option options [Symbol] :by By which identifier to find the region (e.g :css, :id).
|
197
|
+
# @option options [Fixnum] :timeout The amount of time to retry matching. (Seconds)
|
198
|
+
# @option options [Boolean] :stitch_content Whether to stitch the content or not.
|
199
|
+
# @return [Applitools::MatchResult] The match results.
|
200
|
+
def check_region_in_frame(options = {})
|
201
|
+
options = { timeout: USE_DEFAULT_MATCH_TIMEOUT, tag: nil, stitch_content: false }.merge!(options)
|
202
|
+
Applitools::ArgumentGuard.not_nil options[:by], 'options[:by]'
|
203
|
+
Applitools::ArgumentGuard.is_a? options[:by], 'options[:by]', Array
|
204
|
+
|
205
|
+
how_what = options.delete(:by)
|
206
|
+
frame = options[:frame] || options[:frame_element] || options[:name_or_id]
|
207
|
+
|
208
|
+
target = Applitools::Selenium::Target.new.timeout(options[:timeout])
|
209
|
+
target.frame(frame) if frame
|
210
|
+
target.fully if options[:stitch_content]
|
211
|
+
target.region(*how_what)
|
212
|
+
|
213
|
+
check(options[:tag], target)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Use this method to perform seamless testing with selenium through eyes driver.
|
217
|
+
# It yields a block and passes to it an Applitools::Selenium::Driver instance, which wraps standard driver.
|
218
|
+
# Using Selenium methods inside the 'test' block will send the messages to Selenium
|
219
|
+
# after creating the Eyes triggers for them. Options are similar to {open}
|
220
|
+
# @yieldparam driver [Applitools::Selenium::Driver] Gives a driver to a block, which translates calls to a native
|
221
|
+
# Selemium::Driver instance
|
222
|
+
# @example
|
223
|
+
# eyes.test(app_name: 'my app', test_name: 'my test') do |driver|
|
224
|
+
# driver.get "http://www.google.com"
|
225
|
+
# driver.check_window("initial")
|
226
|
+
# end
|
227
|
+
def test(options = {}, &_block)
|
228
|
+
open(options)
|
229
|
+
yield(driver)
|
230
|
+
close
|
231
|
+
ensure
|
232
|
+
abort_if_not_closed
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|