Class: Vizzly::Client
- Inherits:
-
Object
- Object
- Vizzly::Client
- Defined in:
- lib/vizzly.rb
Overview
rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#disabled ⇒ Object
readonly
Returns the value of attribute disabled.
-
#server_url ⇒ Object
readonly
Returns the value of attribute server_url.
Instance Method Summary collapse
-
#disable!(reason = 'disabled') ⇒ Object
Disable screenshot capture.
-
#disabled? ⇒ Boolean
Check if screenshot capture is disabled.
-
#flush ⇒ true
Wait for all queued screenshots to be processed (Simple client doesn’t need explicit flushing).
-
#info ⇒ Hash
Get client information.
-
#initialize(server_url: nil, fail_on_diff: nil) ⇒ Client
constructor
A new instance of Client.
-
#ready? ⇒ Boolean
Check if the client is ready to capture screenshots.
-
#screenshot(name, image_data, options = {}) ⇒ Hash?
Take a screenshot for visual regression testing.
Constructor Details
#initialize(server_url: nil, fail_on_diff: nil) ⇒ Client
Returns a new instance of Client.
18 19 20 21 22 23 24 |
# File 'lib/vizzly.rb', line 18 def initialize(server_url: nil, fail_on_diff: nil) @server_info = nil @configured_fail_on_diff = fail_on_diff @server_url = server_url || discover_server_url @disabled = ENV['VIZZLY_ENABLED'] == 'false' @warned = false end |
Instance Attribute Details
#disabled ⇒ Object (readonly)
Returns the value of attribute disabled.
16 17 18 |
# File 'lib/vizzly.rb', line 16 def disabled @disabled end |
#server_url ⇒ Object (readonly)
Returns the value of attribute server_url.
16 17 18 |
# File 'lib/vizzly.rb', line 16 def server_url @server_url end |
Instance Method Details
#disable!(reason = 'disabled') ⇒ Object
Disable screenshot capture
200 201 202 203 204 205 |
# File 'lib/vizzly.rb', line 200 def disable!(reason = 'disabled') @disabled = true return if reason == 'disabled' warn "Vizzly SDK disabled due to #{reason}. Screenshots will be skipped for the remainder of this session." end |
#disabled? ⇒ Boolean
Check if screenshot capture is disabled
210 211 212 |
# File 'lib/vizzly.rb', line 210 def disabled? @disabled end |
#flush ⇒ true
Wait for all queued screenshots to be processed (Simple client doesn’t need explicit flushing)
186 187 188 |
# File 'lib/vizzly.rb', line 186 def flush true end |
#info ⇒ Hash
Get client information
217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/vizzly.rb', line 217 def info { enabled: !disabled?, server_url: @server_url, serverUrl: @server_url, ready: ready?, build_id: ENV.fetch('VIZZLY_BUILD_ID', nil), buildId: ENV.fetch('VIZZLY_BUILD_ID', nil), disabled: disabled?, fail_on_diff: fail_on_diff?, failOnDiff: fail_on_diff? } end |
#ready? ⇒ Boolean
Check if the client is ready to capture screenshots
193 194 195 |
# File 'lib/vizzly.rb', line 193 def ready? !disabled? && !@server_url.nil? end |
#screenshot(name, image_data, options = {}) ⇒ Hash?
Take a screenshot for visual regression testing
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/vizzly.rb', line 53 def screenshot(name, image_data, = {}) return nil if disabled? unless @server_url warn_once('Vizzly client not initialized. Screenshots will be skipped.') disable! return nil end image_base64 = Base64.strict_encode64(image_data) = () normalized = () normalized[:warnings].each { |warning| warn warning[:message] } request_timeout = normalized[:request_timeout] request_timeout_seconds = request_timeout ? request_timeout.to_f / 1000.0 : 30 build_id = normalized[:build_id] || ENV.fetch('VIZZLY_BUILD_ID', nil) payload = { name: name, image: image_base64, type: 'base64', buildId: build_id, properties: normalized[:properties], warnings: normalized[:warnings] }.compact uri = URI("#{@server_url}/screenshot") begin response = Net::HTTP.start( uri.host, uri.port, use_ssl: uri.scheme == 'https', open_timeout: 10, read_timeout: request_timeout_seconds ) do |http| request = Net::HTTP::Post.new(uri) request['Content-Type'] = 'application/json' request.body = JSON.generate(payload) http.request(request) end unless response.is_a?(Net::HTTPSuccess) error_data = begin JSON.parse(response.body) rescue JSON::ParserError, StandardError {} end # In TDD mode with visual differences, log but don't raise if response.code == '422' && error_data['tddMode'] && error_data['comparison'] comp = error_data['comparison'] diff_percent = comp['diffPercentage']&.round(2) || 0.0 if fail_on_diff? raise Error, "Visual diff detected for \"#{comp['name'] || name}\" (#{comp['diffPercentage'] || 0}% difference)" end # Extract port from server_url port = begin @server_url.match(/:(\d+)/)[1] rescue StandardError DEFAULT_TDD_PORT.to_s end dashboard_url = "http://localhost:#{port}/dashboard" warn "⚠️ Visual diff: #{comp['name']} (#{diff_percent}%) → #{dashboard_url}" return { success: true, status: 'failed', name: comp['name'], diffPercentage: comp['diffPercentage'] } end raise Error, "Screenshot failed: #{response.code} #{response.} - #{error_data['error'] || 'Unknown error'}" end body = JSON.parse(response.body) if body['tddMode'] && %w[diff failed].include?(body['status']) && fail_on_diff? raise Error, "Visual diff detected for \"#{body['name'] || name}\" (#{body['diffPercentage'] || 0}% difference)" end body rescue Error => e # Re-raise Vizzly errors (like visual diffs) raise if e..include?('Visual diff') warn "Vizzly screenshot failed for #{name}: #{e.}" if e..include?('Connection refused') || e.is_a?(Errno::ECONNREFUSED) warn "Server URL: #{@server_url}/screenshot" warn 'This usually means the Vizzly server is not running or not accessible' warn 'Check that the server is started and the port is correct' elsif e..include?('404') || e..include?('Not Found') warn "Server URL: #{@server_url}/screenshot" warn 'The screenshot endpoint was not found - check server configuration' end # Disable the SDK after first failure to prevent spam disable!('failure') nil rescue Net::OpenTimeout warn "Vizzly connection timed out for #{name}: couldn't connect within 10s" warn "Server URL: #{@server_url}/screenshot" warn 'This usually means the server is unreachable (firewall, network issue, or wrong host)' disable!('failure') nil rescue Net::ReadTimeout warn "Vizzly request timed out for #{name}: no response within 30s" warn "Server URL: #{@server_url}/screenshot" warn 'The server may be overloaded or processing is taking too long' disable!('failure') nil rescue StandardError => e warn "Vizzly screenshot failed for #{name}: #{e.}" disable!('failure') nil end end |