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
@@ -0,0 +1,15 @@
1
+ module Applitools::Base
2
+ class Session
3
+ attr_reader :id, :url
4
+
5
+ def initialize(session_id, session_url, new_session)
6
+ @id = session_id
7
+ @url = session_url
8
+ @new_session = new_session
9
+ end
10
+
11
+ def new_session?
12
+ @new_session
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ module Applitools::Base
2
+ class StartInfo
3
+ attr_accessor :app_id_or_name, :scenario_id_or_name
4
+
5
+ def initialize(agent_id, app_id_or_name, scenario_id_or_name, batch_info, env_name, environment, match_level,
6
+ ver_id = nil, branch_name = nil, parent_branch_name = nil)
7
+ @agent_id = agent_id
8
+ @app_id_or_name = app_id_or_name
9
+ @ver_id = ver_id
10
+ @scenario_id_or_name = scenario_id_or_name
11
+ @batch_info = batch_info
12
+ @env_name = env_name
13
+ @environment = environment
14
+ @match_level = match_level
15
+ @branch_name = branch_name
16
+ @parent_branch_name = parent_branch_name
17
+ end
18
+
19
+ def to_hash
20
+ {
21
+ agent_id: @agent_id,
22
+ app_id_or_name: @app_id_or_name,
23
+ ver_id: @ver_id,
24
+ scenario_id_or_name: @scenario_id_or_name,
25
+ batch_info: @batch_info.to_hash,
26
+ env_name: @env_name,
27
+ environment: @environment.to_hash,
28
+ match_level: @match_level,
29
+ branch_name: @branch_name,
30
+ parent_branch_name: @parent_branch_name
31
+ }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ module Applitools::Base
2
+ class TestResults
3
+ attr_accessor :is_new, :url
4
+ attr_reader :steps, :matches, :mismatches, :missing, :exact_matches, :strict_matches, :content_matches,
5
+ :layout_matches, :none_matches, :is_passed
6
+
7
+ def initialize(steps = 0, matches = 0, mismatches = 0, missing = 0, exact_matches = 0, strict_matches = 0,
8
+ content_matches = 0, layout_matches = 0, none_matches = 0)
9
+ @steps = steps
10
+ @matches = matches
11
+ @mismatches = mismatches
12
+ @missing = missing
13
+ @exact_matches = exact_matches
14
+ @strict_matches = strict_matches
15
+ @content_matches = content_matches
16
+ @layout_matches = layout_matches
17
+ @none_matches = none_matches
18
+ @is_new = nil
19
+ @url = nil
20
+ end
21
+
22
+ def is_passed
23
+ !is_new && mismatches == 0 && missing == 0
24
+ end
25
+
26
+ def to_s
27
+ is_new_str = ''
28
+ unless is_new.nil?
29
+ is_new_str = is_new ? 'New test' : 'Existing test'
30
+ end
31
+
32
+ "#{is_new_str} [ steps: #{steps}, matches: #{matches}, mismatches: #{mismatches}, missing: #{missing} ], "\
33
+ "URL: #{url}"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ module Applitools::Base
2
+ class TextTrigger
3
+ attr_reader :text, :control
4
+
5
+ def initialize(text, control)
6
+ @text = text
7
+ @control = control
8
+ end
9
+
10
+ def to_hash
11
+ {
12
+ trigget_type: 'Text',
13
+ text: text,
14
+ control: control.to_hash
15
+ }
16
+ end
17
+
18
+ def to_s
19
+ "Text [#{@control}] #{@text}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,393 @@
1
+ require_relative 'version'
2
+ require_relative 'eyes_logger'
3
+
4
+ require 'forwardable'
5
+
6
+ class Applitools::Eyes
7
+ extend Forwardable
8
+
9
+ FAILURE_REPORTS = {
10
+ immediate: 'Immediate',
11
+ on_close: 'OnClose'
12
+ }.freeze
13
+
14
+ MATCH_LEVEL = {
15
+ none: 'None',
16
+ layout: 'Layout',
17
+ layout2: 'Layout2',
18
+ content: 'Content',
19
+ strict: 'Strict',
20
+ exact: 'Exact'
21
+ }.freeze
22
+
23
+ DEFAULT_MATCH_TIMEOUT = 2.0.freeze # Seconds
24
+ BASE_AGENT_ID = ('eyes.selenium.ruby/' + Applitools::VERSION).freeze
25
+
26
+ #
27
+ # Attributes:
28
+ #
29
+ # +app_name+:: +String+ The application name which was provided as an argument to +open+.
30
+ # +test_name+:: +String+ The test name which was provided as an argument to +open+.
31
+ # +is_open+:: +boolean+ Is there an open session.
32
+ # +viewport_size+:: +Hash+ The viewport size which was provided as an argument to +open+. Should include +width+
33
+ # and +height+.
34
+ # +driver+:: +Applitools::Selenium::Driver+ The driver instance wrapping the driver which was provided as an argument to +open+.
35
+ # +api_key+:: +String+ The user's API key.
36
+ # +match_timeout+:: +Float+ The default timeout for check_XXXX operations. (Seconds)
37
+ # +batch+:: +BatchInfo+ The current tests grouping, if any.
38
+ # +host_os+:: +String+ A string identifying the OS running the AUT. Set this if you wish to override Eyes' automatic
39
+ # inference.
40
+ # +host_app+:: +String+ A string identifying the container application running the AUT (e.g., Firefox). Set this if
41
+ # you wish to override Eyes' automatic inference.
42
+ # +branch_name+:: +String+ If set, names the branch in which the test should run.
43
+ # +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.
46
+ # +save_new_tests+:: +boolean+ Whether or not new tests should be automatically accepted as baseline.
47
+ # +save_failed_tests+:: +boolean+ Whether or not failed tests should be automatically accepted as baseline.
48
+ # +match_level+:: +String+ The default match level for the entire session. See +Applitools::Eyes::MATCH_LEVEL+.
49
+ # +baseline_name+:: +String+ A string identifying the baseline which the test will be compared against. Set this if
50
+ # you wish to override Eyes' automatic baseline inference.
51
+ # +is_disabled+:: +boolean+ Set to +true+ if you wish to disable Eyes without deleting code (Eyes' methods act as a
52
+ # mock, and will do nothing).
53
+ # +server_url+:: +String+ The Eyes' server. Set this if you wish to override the default Eyes server URL.
54
+ # +agent_id+:: +String+ An optional string identifying the current library using the SDK.
55
+ # +log_handler+:: +Logger+ The logger to which Eyes will send info/debug messages.
56
+ # +failure_reports+:: +String+ Whether the current test will report mismatches immediately or when it is finished.
57
+ # See +Applitools::Eyes::FAILURE_REPORTS+.
58
+ # +rotation+:: +Integer+|+nil+ The degrees by which to rotate the screenshots received from the driver. Set this to
59
+ # override Eyes' automatic rotation inference. Positive values = clockwise rotation, negative
60
+ # values = counter-clockwise, 0 = force no rotation, +nil+ = use Eyes' automatic rotation inference.
61
+ attr_reader :app_name, :test_name, :is_open, :viewport_size, :driver
62
+ attr_accessor :match_timeout, :batch, :host_os, :host_app, :branch_name, :parent_branch_name, :user_inputs,
63
+ :save_new_tests, :save_failed_tests, :is_disabled, :server_url, :agent_id, :failure_reports, :match_level,
64
+ :baseline_name, :rotation
65
+
66
+ def_delegators 'Applitools::EyesLogger', :log_handler, :log_handler=
67
+ def_delegators 'Applitools::Base::ServerConnector', :api_key, :api_key=, :server_url, :server_url=
68
+
69
+ def full_agent_id
70
+ @full_agent_id ||= agent_id.nil? ? BASE_AGENT_ID : "#{agent_id} [#{BASE_AGENT_ID}]"
71
+ end
72
+
73
+ def title
74
+ unless @dont_get_title
75
+ begin
76
+ return driver.title
77
+ rescue
78
+ @dont_get_title = true
79
+ end
80
+ end
81
+
82
+ ''
83
+ end
84
+
85
+ def initialize(options = {})
86
+ @is_disabled = false
87
+
88
+ return if disabled?
89
+
90
+ @api_key = nil
91
+ @user_inputs = []
92
+
93
+ Applitools::Base::ServerConnector.server_url = options[:server_url]
94
+
95
+ @match_timeout = DEFAULT_MATCH_TIMEOUT
96
+ @match_level = Applitools::Eyes::MATCH_LEVEL[:exact]
97
+ @failure_reports = Applitools::Eyes::FAILURE_REPORTS[:on_close]
98
+ @save_new_tests = true
99
+ @save_failed_tests = false
100
+ @dont_get_title = false
101
+ end
102
+
103
+ def open(options = {})
104
+ @driver = get_driver(options)
105
+ return driver if disabled?
106
+
107
+ 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 "\
109
+ "use 'api_key' to set it.")
110
+ end
111
+
112
+ if driver.is_a?(Selenium::WebDriver::Driver)
113
+ @driver = Applitools::Selenium::Driver.new(self, driver: driver)
114
+ elsif defined?(Appium::Driver) && driver.is_a?(Appium::Driver)
115
+ @driver = Applitools::Selenium::Driver.new(self, driver: driver.driver, is_mobile_device: true)
116
+ elsif defined?(Watir::Browser) && driver.is_a?(Watir::Browser)
117
+ @driver = Applitools::Selenium::Driver.new(self, driver: driver.driver)
118
+ else
119
+ unless driver.is_a?(Applitools::Selenium::Driver)
120
+ raise Applitools::EyesError.new("Driver is not a Selenium::WebDriver::Driver (#{driver.class.name})!")
121
+ end
122
+ end
123
+
124
+ if open?
125
+ abort_if_not_closed
126
+ msg = 'a test is already running'
127
+ Applitools::EyesLogger.warn(msg)
128
+
129
+ raise Applitools::EyesError.new(msg)
130
+ end
131
+
132
+ @user_inputs = []
133
+ @app_name = options.fetch(:app_name)
134
+ @test_name = options.fetch(:test_name)
135
+ @viewport_size = options.fetch(:viewport_size, nil)
136
+
137
+ @is_open = true
138
+
139
+ driver
140
+ end
141
+
142
+ def open?
143
+ is_open
144
+ end
145
+
146
+ def clear_user_inputs
147
+ user_inputs.clear
148
+ end
149
+
150
+ def check_region(how, what, tag = nil, specific_timeout = -1)
151
+ Applitools::EyesLogger.debug 'check_region called'
152
+ return if disabled?
153
+
154
+ # We have to start the session if it's not started, since we want the viewport size to be set before getting the
155
+ # element's position and size
156
+ raise Applitools::EyesError.new('Eyes not open') unless open?
157
+
158
+ unless @session
159
+ Applitools::EyesLogger.debug 'Starting session...'
160
+ start_session
161
+ Applitools::EyesLogger.debug 'Done! Creating match window task...'
162
+ @match_window_task = Applitools::Selenium::MatchWindowTask.new(self, @session, driver, match_timeout)
163
+ Applitools::EyesLogger.debug 'Done!'
164
+ end
165
+
166
+ Applitools::EyesLogger.debug 'Finding element...'
167
+ element_to_check = driver.find_element(how, what)
168
+ Applitools::EyesLogger.debug 'Done! Getting element location...'
169
+ location = element_to_check.location
170
+ Applitools::EyesLogger.debug 'Done! Getting element size...'
171
+ size = element_to_check.size
172
+ Applitools::EyesLogger.debug 'Done! Creating region...'
173
+ region = Applitools::Base::Region.new(location.x, location.y, size.width, size.height)
174
+ Applitools::EyesLogger.debug 'Done! Checking region...'
175
+ check_region_(region, tag, specific_timeout)
176
+ Applitools::EyesLogger.debug 'Done!'
177
+ end
178
+
179
+ def check_window(tag = nil, specific_timeout = -1)
180
+ check_region_(Applitools::Base::Region::EMPTY, tag, specific_timeout)
181
+ end
182
+
183
+ def close(raise_ex=true)
184
+ return if disabled?
185
+ @is_open = false
186
+
187
+ # If there's no running session, the test was never started (never reached check_window).
188
+ unless @session
189
+ Applitools::EyesLogger.debug 'Server session was not started'
190
+ Applitools::EyesLogger.info '--- Empty test ended.'
191
+
192
+ return Applitools::Base::TestResults.new
193
+ end
194
+
195
+ session_results_url = @session.url
196
+ new_session = @session.new_session?
197
+ Applitools::EyesLogger.debug 'Ending server session...'
198
+ save = (new_session && save_new_tests) || (!new_session && save_failed_tests)
199
+ results = Applitools::Base::ServerConnector.stop_session(@session, false, save)
200
+ results.is_new = new_session
201
+ results.url = session_results_url
202
+ Applitools::EyesLogger.debug "Results: #{results}"
203
+
204
+ @session = nil
205
+
206
+ if new_session
207
+ instructions = "Please approve the new baseline at #{session_results_url}"
208
+ Applitools::EyesLogger.info "--- New test ended. #{instructions}"
209
+
210
+ if raise_ex
211
+ message = "'#{@session_start_info.scenario_id_or_name}' of '#{@session_start_info.app_id_or_name}'. "\
212
+ "#{instructions}"
213
+
214
+ raise Applitools::NewTestError.new(message, results)
215
+ end
216
+
217
+ return results
218
+ end
219
+
220
+ unless results.is_passed
221
+ # Test failed
222
+ Applitools::EyesLogger.info "--- Failed test ended. See details at #{session_results_url}"
223
+
224
+ if raise_ex
225
+ message = "'#{@session_start_info.scenario_id_or_name}' of '#{@session_start_info.app_id_or_name}'. see "\
226
+ "details at #{session_results_url}"
227
+
228
+ raise Applitools::TestFailedError.new(message, results)
229
+ end
230
+
231
+ return results
232
+ end
233
+
234
+ # Test passed
235
+ Applitools::EyesLogger.info "--- Test passed. See details at #{session_results_url}"
236
+
237
+ results
238
+ end
239
+
240
+ ## Use this method to perform seamless testing with selenium through eyes driver.
241
+ ## Using Selenium methods inside the 'test' block will send the messages to Selenium
242
+ ## after creating the Eyes triggers for them.
243
+ ##
244
+ ## Example:
245
+ # eyes.test(app_name: 'my app1', test_name: 'my test') do |d|
246
+ # get "http://www.google.com"
247
+ # check_window("initial")
248
+ # 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
258
+ end
259
+
260
+ def abort_if_not_closed
261
+ return if disabled?
262
+
263
+ @is_open = false
264
+
265
+ return unless @session
266
+
267
+ begin
268
+ Applitools::Base::ServerConnector.stop_session(@session, true, false)
269
+ rescue Exception, Applitools::EyesError => e
270
+ Applitools::EyesLogger.error "Failed to abort server session: #{e.message}!"
271
+ ensure
272
+ @session = nil
273
+ end
274
+ end
275
+
276
+ private
277
+
278
+ def disabled?
279
+ is_disabled
280
+ end
281
+
282
+ def get_driver(options)
283
+ # TODO remove the "browser" related block when possible. It's for backward compatibility.
284
+ if options.has_key?(:browser)
285
+ Applitools::EyesLogger.warn('"browser" key is deprecated, please use "driver" instead.')
286
+
287
+ return options[:browser]
288
+ end
289
+
290
+ options.fetch(:driver, nil)
291
+ end
292
+
293
+ def inferred_environment
294
+ user_agent = driver.user_agent
295
+ "useragent:#{user_agent}" if user_agent
296
+ end
297
+
298
+ # Application environment is the environment (e.g., the host OS) which runs the application under test.
299
+ #
300
+ # Returns:
301
+ # +Applitools::Base::Environment+ The application environment.
302
+ def app_environment
303
+ os = host_os
304
+ if os.nil?
305
+ Applitools::EyesLogger.info 'No OS set, checking for mobile OS...'
306
+ if driver.mobile_device?
307
+ platform_name = nil
308
+ Applitools::EyesLogger.info 'Mobile device detected! Checking device type..'
309
+ if driver.android?
310
+ Applitools::EyesLogger.info 'Android detected.'
311
+ platform_name = 'Android'
312
+ elsif driver.ios?
313
+ Applitools::EyesLogger.info 'iOS detected.'
314
+ platform_name = 'iOS'
315
+ else
316
+ Applitools::EyesLogger.warn 'Unknown device type.'
317
+ end
318
+ # We only set the OS if we identified the device type.
319
+ unless platform_name.nil?
320
+ platform_version = driver.platform_version
321
+ if platform_version.nil?
322
+ os = platform_name
323
+ else
324
+ # Notice that Ruby's +split+ function's +limit+ is the number of elements, whereas in Python it is the
325
+ # maximum splits performed (which is why they are set differently).
326
+ major_version = platform_version.split('.', 2)[0]
327
+ os = "#{platform_name} #{major_version}"
328
+ end
329
+ Applitools::EyesLogger.info "Setting OS: #{os}"
330
+ end
331
+ else
332
+ Applitools::EyesLogger.info 'No mobile OS detected.'
333
+ end
334
+ end
335
+
336
+ # Create and return the environment object.
337
+ Applitools::Base::Environment.new(os, host_app, viewport_size, inferred_environment)
338
+ end
339
+
340
+ def start_session
341
+ assign_viewport_size
342
+ @batch ||= Applitools::Base::BatchInfo.new
343
+ app_env = app_environment
344
+
345
+ @session_start_info = Applitools::Base::StartInfo.new(full_agent_id, app_name, test_name, batch, baseline_name,
346
+ app_env, match_level, nil, branch_name, parent_branch_name)
347
+ @session = Applitools::Base::ServerConnector.start_session(@session_start_info)
348
+ @should_match_window_run_once_on_timeout = @session.new_session?
349
+ end
350
+
351
+ def viewport_size?
352
+ viewport_size
353
+ end
354
+
355
+ def assign_viewport_size
356
+ if viewport_size?
357
+ @viewport_size = Applitools::Selenium::ViewportSize.new(driver, viewport_size)
358
+ viewport_size.set
359
+ else
360
+ @viewport_size = Applitools::Selenium::ViewportSize.new(driver).extract_viewport_from_browser!
361
+ end
362
+ end
363
+
364
+ def check_region_(region, tag = nil, specific_timeout = -1)
365
+ return if disabled?
366
+ Applitools::EyesLogger.info "check_region_('#{tag}', #{specific_timeout})"
367
+ raise Applitools::EyesError.new('region cannot be nil!') if region.nil?
368
+ raise Applitools::EyesError.new('Eyes not open') unless open?
369
+
370
+ unless @session
371
+ Applitools::EyesLogger.debug 'Starting session...'
372
+ start_session
373
+ Applitools::EyesLogger.debug 'Done! Creating match window task...'
374
+ @match_window_task = Applitools::Selenium::MatchWindowTask.new(self, @session, driver, match_timeout)
375
+ Applitools::EyesLogger.debug 'Done!'
376
+ end
377
+
378
+ Applitools::EyesLogger.debug 'Starting match task...'
379
+ as_expected = @match_window_task.match_window(region, specific_timeout, tag, rotation,
380
+ @should_match_window_run_once_on_timeout)
381
+ 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
392
+ end
393
+ end