eyes_selenium 6.12.10 → 6.12.11

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/eyes_selenium.gemspec +2 -5
  4. data/lib/applitools/eyes_selenium/version.rb +1 -1
  5. data/lib/applitools/selenium/browsers_info.rb +2 -0
  6. data/lib/applitools/selenium/concerns/selenium_eyes.rb +0 -33
  7. data/lib/applitools/selenium/driver.rb +1 -1
  8. data/lib/applitools/selenium/eyes.rb +1 -5
  9. data/lib/applitools/selenium/selenium_eyes.rb +15 -315
  10. data/lib/applitools/selenium/visual_grid/visual_grid_runner.rb +33 -92
  11. data/lib/eyes_selenium.rb +0 -2
  12. metadata +9 -64
  13. data/lib/applitools/selenium/css_parser/find_embedded_resources.rb +0 -102
  14. data/lib/applitools/selenium/dom_capture/dom_capture.rb +0 -172
  15. data/lib/applitools/selenium/dom_capture/dom_capture_script.rb +0 -611
  16. data/lib/applitools/selenium/external_css_resources.rb +0 -32
  17. data/lib/applitools/selenium/visual_grid/dom_snapshot_script.rb +0 -198
  18. data/lib/applitools/selenium/visual_grid/eyes_connector.rb +0 -170
  19. data/lib/applitools/selenium/visual_grid/render_info.rb +0 -24
  20. data/lib/applitools/selenium/visual_grid/render_request.rb +0 -24
  21. data/lib/applitools/selenium/visual_grid/render_requests.rb +0 -12
  22. data/lib/applitools/selenium/visual_grid/render_task.rb +0 -311
  23. data/lib/applitools/selenium/visual_grid/resource_cache.rb +0 -69
  24. data/lib/applitools/selenium/visual_grid/running_test.rb +0 -271
  25. data/lib/applitools/selenium/visual_grid/thread_pool.rb +0 -95
  26. data/lib/applitools/selenium/visual_grid/vg_match_window_data.rb +0 -187
  27. data/lib/applitools/selenium/visual_grid/vg_region.rb +0 -16
  28. data/lib/applitools/selenium/visual_grid/vg_resource.rb +0 -77
  29. data/lib/applitools/selenium/visual_grid/vg_task.rb +0 -53
  30. data/lib/applitools/selenium/visual_grid/visual_grid_eyes.rb +0 -494
  31. data/lib/applitools/selenium/visual_grid/web_element_region.rb +0 -16
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'thread'
3
-
4
- module Applitools
5
- module Selenium
6
- class VGThreadPool
7
- extend Forwardable
8
- attr_accessor :concurrency
9
- def_delegator 'Applitools::EyesLogger', :logger
10
-
11
- def initialize(concurrency = 10)
12
- self.concurrency = concurrency
13
- @stopped = true
14
- @thread_group = ThreadGroup.new
15
- @semaphore = Mutex.new
16
- @next_task_block = nil
17
- @watchdog = nil
18
- end
19
-
20
- def on_next_task_needed(&block)
21
- @next_task_block = block if block_given?
22
- end
23
-
24
- def start
25
- @semaphore.synchronize { @stopped = false }
26
- init_or_renew_threads
27
- @watchdog = Thread.new do
28
- catch(:exit) do
29
- loop do
30
- throw :exit if stopped?
31
- sleep 5
32
- init_or_renew_threads
33
- end
34
- end
35
- end
36
- end
37
-
38
- def stop
39
- @watchdog.exit
40
- @semaphore.synchronize do
41
- @stopped = true
42
- end
43
- @thread_group.list.each(&:join)
44
- stopped?
45
- end
46
-
47
- def stopped?
48
- @semaphore.synchronize { @stopped }
49
- end
50
-
51
- private
52
-
53
- def next_task
54
- @semaphore.synchronize do
55
- return @next_task_block.call if @next_task_block && @next_task_block.respond_to?(:call)
56
- end
57
- nil
58
- end
59
-
60
- def init_or_renew_threads
61
- one_concurrency = 1 # Thread's moved to universal server
62
- (one_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
- Applitools::EyesLogger.logger.info 'Worker is stopped'
85
- rescue => e
86
- Applitools::EyesLogger.logger.error "Failed to execute task - #{task_to_run.name}"
87
- Applitools::EyesLogger.logger.error e.message
88
- Applitools::EyesLogger.logger.error e.backtrace.join(' ')
89
- end
90
- end
91
- @thread_group.add thread
92
- end
93
- end
94
- end
95
- end
@@ -1,187 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Applitools
4
- module Selenium
5
- class VgMatchWindowData < Applitools::MatchWindowData
6
- CONVERT_COORDINATES = proc do |region, selector_regions|
7
- begin
8
- offset_region = selector_regions.last
9
- new_location = region.location.offset_negative(Applitools::Location.new(offset_region['x'].to_i, offset_region['y'].to_i))
10
- region.location = new_location
11
- rescue
12
- Applitools::EyesLogger.error("Failed to convert coordinates for #{region}")
13
- end
14
- end
15
- class RegionCoordinatesError < ::Applitools::EyesError
16
- attr_accessor :region
17
- def initialize(region, message)
18
- super(message)
19
- self.region = region
20
- end
21
- end
22
- attr_accessor :target, :selector_regions
23
- def read_target(target, driver, selector_regions)
24
- self.target = target
25
- self.selector_regions = selector_regions
26
- # options
27
- target_options_to_read.each do |field|
28
- a_value = target.options[field.to_sym]
29
- send("#{field}=", a_value) unless a_value.nil?
30
- end
31
- # ignored regions
32
- if target.respond_to? :ignored_regions
33
- target.ignored_regions.each do |r|
34
- @need_convert_ignored_regions_coordinates = true unless @need_convert_ignored_regions_coordinates
35
- case r
36
- when Proc
37
- region, padding_proc = r.call(driver, true)
38
- region = selector_regions[target.regions[region]]
39
- retrieved_region = Applitools::Region.new(region['x'], region['y'], region['width'], region['height'])
40
- @ignored_regions << padding_proc.call(retrieved_region) if padding_proc.is_a? Proc
41
- when Applitools::Region
42
- @ignored_regions << r
43
- when Applitools::Selenium::VGRegion
44
- region = target.regions.key?(r.region) ? selector_regions[target.regions[r.region]] : r.region
45
- raise RegionCoordinatesError.new(r, region['error']) if region['error']
46
- retrieved_region = Applitools::Region.new(region['x'], region['y'], region['width'], region['height'])
47
- @ignored_regions << if r.padding_proc.is_a?(Proc)
48
- r.padding_proc.call(retrieved_region)
49
- else
50
- retrieved_region
51
- end
52
- end
53
- end
54
- end
55
-
56
- if target.respond_to? :layout_regions
57
- @layout_regions = obtain_regions_coordinates(target.layout_regions, driver)
58
- @need_convert_layout_regions_coordinates = true unless @layout_regions.empty?
59
- end
60
-
61
- if target.respond_to? :content_regions
62
- @content_regions = obtain_regions_coordinates(target.content_regions, driver)
63
- @need_convert_content_regions_coordinates = true unless @content_regions.empty?
64
- end
65
-
66
- if target.respond_to? :strict_regions
67
- @strict_regions = obtain_regions_coordinates(target.strict_regions, driver)
68
- @need_convert_strict_regions_coordinates = true unless @strict_regions.empty?
69
- end
70
-
71
- if target.respond_to? :accessibility_regions
72
- @accessibility_regions = obtain_regions_coordinates(target.accessibility_regions, driver)
73
- @need_convert_accessibility_regions_coordinates = true unless @accessibility_regions.empty?
74
- end
75
-
76
- # # floating regions
77
- return unless target.respond_to? :floating_regions
78
- target.floating_regions.each do |r|
79
- case r
80
- when Proc
81
- region, padding_proc = r.call(driver, true)
82
- region = selector_regions[target.regions[region]]
83
- retrieved_region = Applitools::Region.new(region['x'], region['y'], region['width'], region['height'])
84
- floating_region = padding_proc.call(retrieved_region) if padding_proc.is_a? Proc
85
- raise Applitools::EyesError.new "Wrong floating region: #{region.class}" unless
86
- floating_region.is_a? Applitools::FloatingRegion
87
- @floating_regions << floating_region
88
- @need_convert_floating_regions_coordinates = true
89
- when Applitools::FloatingRegion
90
- @floating_regions << r
91
- @need_convert_floating_regions_coordinates = true
92
- when Applitools::Selenium::VGRegion
93
- region = r.region
94
- region = selector_regions[target.regions[region]]
95
- raise RegionCoordinatesError.new(r, region['error']) if region['error']
96
- retrieved_region = Applitools::Region.new(region['x'], region['y'], region['width'], region['height'])
97
- floating_region = r.padding_proc.call(retrieved_region) if r.padding_proc.is_a? Proc
98
- raise Applitools::EyesError.new "Wrong floating region: #{region.class}" unless
99
- floating_region.is_a? Applitools::FloatingRegion
100
- @floating_regions << floating_region
101
- @need_convert_floating_regions_coordinates = true
102
- end
103
- end
104
- end
105
-
106
- def obtain_regions_coordinates(regions, driver)
107
- result = []
108
- regions.each do |r|
109
- case r
110
- when Proc
111
- region = r.call(driver)
112
- region = selector_regions[target.regions[region]]
113
- result << Applitools::Region.new(region['x'], region['y'], region['width'], region['height'])
114
- when Applitools::Region
115
- result << r
116
- when Applitools::Selenium::VGRegion
117
- region = r.region
118
- region = selector_regions[target.regions[region]]
119
- raise RegionCoordinatesError.new(r, region['error']) if region['error']
120
- retrieved_region = Applitools::Region.new(region['x'], region['y'], region['width'], region['height'])
121
- result_region = if r.padding_proc.is_a? Proc
122
- r.padding_proc.call(retrieved_region)
123
- else
124
- retrieved_region
125
- end
126
- result << result_region
127
- end
128
- end
129
- result
130
- end
131
-
132
- def convert_ignored_regions_coordinates
133
- return unless @need_convert_ignored_regions_coordinates
134
- if target.convert_coordinates_block.is_a?(Proc)
135
- @ignored_regions.each { |r| target.convert_coordinates_block.call(r, selector_regions)}
136
- end
137
- self.ignored_regions = @ignored_regions.map(&:with_padding).map(&:to_hash)
138
- @need_convert_ignored_regions_coordinates = false
139
- end
140
-
141
- def convert_floating_regions_coordinates
142
- return unless @need_convert_floating_regions_coordinates
143
- if target.convert_coordinates_block.is_a?(Proc)
144
- @floating_regions.each { |r| target.convert_coordinates_block.call(r, selector_regions)}
145
- end
146
- self.floating_regions = @floating_regions
147
- @need_convert_floating_regions_coordinates = false
148
- end
149
-
150
- def convert_layout_regions_coordinates
151
- return unless @need_convert_layout_regions_coordinates
152
- if target.convert_coordinates_block.is_a?(Proc)
153
- @layout_regions.each { |r| target.convert_coordinates_block.call(r, selector_regions)}
154
- end
155
- self.layout_regions = @layout_regions
156
- @need_convert_layout_regions_coordinates = false
157
- end
158
-
159
- def convert_strict_regions_coordinates
160
- return unless @need_convert_strict_regions_coordinates
161
- if target.convert_coordinates_block.is_a?(Proc)
162
- @strict_regions.each { |r| target.convert_coordinates_block.call(r, selector_regions)}
163
- end
164
- self.strict_regions = @strict_regions
165
- @need_convert_strict_regions_coordinates = false
166
- end
167
-
168
- def convert_content_regions_coordinates
169
- return unless @need_convert_content_regions_coordinates
170
- if target.convert_coordinates_block.is_a?(Proc)
171
- @content_regions.each { |r| target.convert_coordinates_block.call(r, selector_regions)}
172
- end
173
- self.content_regions = @content_regions
174
- @need_convert_content_regions_coordinates = false
175
- end
176
-
177
- def convert_accessibility_regions_coordinates
178
- return unless @need_convert_accessibility_regions_coordinates
179
- if target.convert_coordinates_block.is_a?(Proc)
180
- @accessibility_regions.each { |r| target.convert_coordinates_block.call(r, selector_regions)}
181
- end
182
- self.accessibility_regions = @accessibility_regions
183
- @need_convert_accessibility_regions_coordinates = false
184
- end
185
- end
186
- end
187
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
- module Applitools
3
- module Selenium
4
- class VGRegion
5
- attr_accessor :region, :padding_proc
6
- def initialize(region, padding_proc)
7
- self.region = region
8
- self.padding_proc = padding_proc
9
- end
10
-
11
- def to_s
12
- region.inspect
13
- end
14
- end
15
- end
16
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
- require 'digest'
5
- # require 'nokogiri'
6
-
7
- module Applitools
8
- module Selenium
9
- class VGResource
10
- include Applitools::Jsonable
11
- json_fields :contentType, :hash, :hashFormat, :errorStatusCode
12
- attr_accessor :url, :content, :handle_discovered_resources_block
13
- alias content_type contentType
14
- alias content_type= contentType=
15
-
16
- class << self
17
- def parse_blob_from_script(blob, options = {})
18
- return new(
19
- blob['url'],
20
- "application/X-error-response-#{blob['errorStatusCode']}",
21
- blob['value'] || ''
22
- ).tap {|r| r.error_status_code = blob['errorStatusCode']} if blob['errorStatusCode']
23
- content = Base64.decode64(blob['value'])
24
- new(blob['url'], blob['type'], content, options)
25
- end
26
-
27
- def parse_response(url, response, options = {})
28
- return new(url, 'application/empty-response', '') unless response.status == 200
29
- new(url, response.headers['Content-Type'], response.body, options)
30
- end
31
- end
32
-
33
- def initialize(url, content_type, content, options = {})
34
- self.handle_discovered_resources_block = options[:on_resources_fetched] if
35
- options[:on_resources_fetched].is_a? Proc
36
- self.url = URI(url)
37
- self.content_type = content_type
38
- self.content = content
39
- self.hash = Digest::SHA256.hexdigest(content)
40
- self.hashFormat = 'sha256'
41
- lookup_for_resources
42
- end
43
-
44
- def on_resources_fetched(block)
45
- self.handle_discovered_resources_block = block
46
- end
47
-
48
- def lookup_for_resources
49
- lookup_for_css_resources
50
- lookup_for_svg_resources
51
- end
52
-
53
- def lookup_for_css_resources
54
- return unless %r{^text/css}i =~ content_type && handle_discovered_resources_block
55
- parser = Applitools::Selenium::CssParser::FindEmbeddedResources.new(content)
56
- handle_discovered_resources_block.call(parser.imported_css + parser.fonts + parser.images, url)
57
- end
58
-
59
- def lookup_for_svg_resources
60
- return unless %r{^image/svg\+xml} =~ content_type && handle_discovered_resources_block
61
- attrs = []
62
- # attrs = Nokogiri::XML(content)
63
- # .xpath("//@*[namespace-uri(.) = 'http://www.w3.org/1999/xlink'] | //@href")
64
- # .select { |a| a.name == 'href' }
65
- # .map(&:value)
66
- # .select { |a| /^(?!#).*/.match(a) }
67
- handle_discovered_resources_block.call(attrs, url)
68
- end
69
-
70
- def stringify
71
- url.to_s + content_type.to_s + hash
72
- end
73
-
74
- private :lookup_for_svg_resources, :lookup_for_css_resources
75
- end
76
- end
77
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'securerandom'
3
- module Applitools
4
- module Selenium
5
- class VGTask
6
- attr_accessor :name, :uuid
7
- def initialize(name, &block)
8
- self.name = name
9
- @block_to_run = block if block_given?
10
- @callback = []
11
- @error_callback = []
12
- @completed_callback = []
13
- self.uuid = SecureRandom.uuid
14
- end
15
-
16
- def on_task_succeeded(&block)
17
- @callback.push block if block_given?
18
- self
19
- end
20
-
21
- def on_task_error(&block)
22
- @error_callback.push block if block_given?
23
- self
24
- end
25
-
26
- def on_task_completed(&block)
27
- @completed_callback.push block if block_given?
28
- self
29
- end
30
-
31
- def call
32
- return unless @block_to_run.respond_to? :call
33
- begin
34
- res = @block_to_run.call
35
- @callback.each do |cb|
36
- cb.call(res) if cb.respond_to? :call
37
- end
38
- rescue StandardError => e
39
- Applitools::EyesLogger.logger.error 'Failed to execute task!'
40
- Applitools::EyesLogger.logger.error e.message
41
- Applitools::EyesLogger.logger.error e.backtrace.join('\n\t')
42
- @error_callback.each do |ecb|
43
- ecb.call(e) if ecb.respond_to? :call
44
- end
45
- ensure
46
- @completed_callback.each do |ccb|
47
- ccb.call if ccb.respond_to? :call
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end