Class: Applitools::Connectivity::ServerConnector

Inherits:
Object
  • Object
show all
Extended by:
Helpers
Defined in:
lib/applitools/connectivity/server_connector.rb

Constant Summary collapse

DEFAULT_SERVER_URL =
'https://eyessdk.applitools.com'.freeze
SSL_CERT =
File.join(File.dirname(File.expand_path(__FILE__)), '../../../certs/cacert.pem').to_s.freeze
DEFAULT_TIMEOUT =
300
API_SESSIONS =
'/api/sessions'.freeze
API_SESSIONS_RUNNING =
API_SESSIONS + '/running/'.freeze
API_SINGLE_TEST =
API_SESSIONS + '/'.freeze
RENDER_INFO_PATH =
API_SESSIONS + "/renderinfo".freeze
RENDER =
'/render'.freeze
RESOURCES_SHA_256 =
'/resources/sha256/'.freeze
RENDER_STATUS =
'/render-status'.freeze
HTTP_STATUS_CODES =
{
  created: 201,
  accepted: 202,
  ok: 200,
  gone: 410
}.freeze
RETRY_DELAY =
0.5
RETRY_STEP_FACTOR =
1.5
RETRY_MAX_DELAY =
5

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

abstract_attr_accessor, abstract_method, environment_attribute, environment_variables

Constructor Details

#initialize(url = nil) ⇒ ServerConnector

Returns a new instance of ServerConnector.



38
39
40
# File 'lib/applitools/connectivity/server_connector.rb', line 38

def initialize(url = nil)
  self.server_url = url
end

Instance Attribute Details

#endpoint_urlObject (readonly)

Returns the value of attribute endpoint_url.



34
35
36
# File 'lib/applitools/connectivity/server_connector.rb', line 34

def endpoint_url
  @endpoint_url
end

#proxyObject

Returns the value of attribute proxy.



35
36
37
# File 'lib/applitools/connectivity/server_connector.rb', line 35

def proxy
  @proxy
end

#server_urlObject

Returns the value of attribute server_url.



33
34
35
# File 'lib/applitools/connectivity/server_connector.rb', line 33

def server_url
  @server_url
end

Instance Method Details

#download_resource(url) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/applitools/connectivity/server_connector.rb', line 97

def download_resource(url)
  Applitools::EyesLogger.debug "Fetching #{url}..."
  resp_proc = proc do |u|
    Faraday::Connection.new(
      u,
      ssl: { ca_file: SSL_CERT },
      proxy: @proxy.nil? ? nil : @proxy.to_hash
    ).send(:get) do |req|
      req.options.timeout = DEFAULT_TIMEOUT
      req.headers['Accept-Encoding'] = 'identity'
    end
  end
  response = resp_proc.call(url)
  redirect_count = 10
  while response.status == 301 && redirect_count > 0 do
    redirect_count -= 1
    response = resp_proc.call(response.headers['location'])
  end
  Applitools::EyesLogger.debug 'Done!'
  response
end

#match_single_window(data) ⇒ Object



185
186
187
188
# File 'lib/applitools/connectivity/server_connector.rb', line 185

def match_single_window(data)
  res = match_single_window_data(data)
  Applitools::TestResults.new Oj.load(res.body)
end

#match_single_window_data(data) ⇒ Object

Raises:

  • (Applitools::EyesError)


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/applitools/connectivity/server_connector.rb', line 157

def match_single_window_data(data)
  # Notice that this does not include the screenshot.
  json_data = Oj.dump(data.to_hash).force_encoding('BINARY')
  body = [json_data.length].pack('L>') + json_data + data.screenshot
  # Applitools::EyesLogger.debug json_data
  begin
    Applitools::EyesLogger.debug 'Sending match data...'
    res = long_post(
      @single_check_endpoint_url,
      content_type: 'application/octet-stream',
      body: body,
      query: { agent_id: data.agent_id }
    )
  rescue Errno::EWOULDBLOCK, Faraday::ConnectionFailed
    @delays ||= request_delay(RETRY_DELAY, RETRY_STEP_FACTOR, RETRY_MAX_DELAY)
    begin
      sleep @delays.next
    rescue StopIteration
      raise Applitools::UnknownNetworkStackError.new('Unknown network stack error')
    end
    res = match_single_window_data(data)
  ensure
    @delays = nil
  end
  raise Applitools::EyesError.new("Request failed: #{res.status} #{res.headers} #{res.body}") unless res.success?
  res
end

#match_window(session, data) ⇒ Object

Raises:

  • (Applitools::EyesError)


141
142
143
144
145
146
147
148
149
150
151
# File 'lib/applitools/connectivity/server_connector.rb', line 141

def match_window(session, data)
  # Notice that this does not include the screenshot.
  json_data = Oj.dump(Applitools::Utils.camelcase_hash_keys(data.to_hash)).force_encoding('BINARY')
  body = [json_data.length].pack('L>') + json_data + data.screenshot
  Applitools::EyesLogger.debug 'Sending match data...'
  #Applitools::EyesLogger.debug json_data
  res = long_post(URI.join(endpoint_url, session.id.to_s), content_type: 'application/octet-stream', body: body)
  raise Applitools::EyesError.new("Request failed: #{res.status} #{res.headers}") unless res.success?
  # puts Oj.load(res.body)
  Applitools::MatchResult.new Oj.load(res.body)
end

#post_dom_json(dom_data) ⇒ Object

Raises:

  • (Applitools::EyesError)


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/applitools/connectivity/server_connector.rb', line 211

def post_dom_json(dom_data)
  # Applitools::EyesLogger.debug 'About to send captured DOM...'
  request_body = Oj.dump(dom_data)
  # Applitools::EyesLogger.debug request_body
  processed_request_body = yield(request_body) if block_given?
  res = post(
    endpoint_url + 'data',
    body: processed_request_body.nil? ? request_body : processed_request_body,
    content_type: 'application/octet-stream'
  )

  Applitools::EyesLogger.debug 'Done!'
  raise Applitools::EyesError.new("Request failed: #{res.status} #{res.body}") unless res.success?
  Applitools::EyesLogger.debug  'Server response headers:'
  Applitools::EyesLogger.debug  res.headers.inspect
  res.headers['location']
end

#render(service_url, access_key, requests) ⇒ Object

Raises:

  • (Applitools::EyesError)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/applitools/connectivity/server_connector.rb', line 48

def render(service_url, access_key, requests)
  uri = URI(service_url)
  uri.path = RENDER
  response = dummy_post(
    uri,
    body: requests.json,
    headers: {
      'X-Auth-Token' => access_key
    },
    timeout: 10
  )
  raise Applitools::EyesError, "Error render processing (#{response.status}, #{response.body})" unless response.status == HTTP_STATUS_CODES[:ok]
  Oj.load response.body
end

#render_put_resource(service_url, access_key, resource, render) ⇒ Object

Raises:

  • (Applitools::EyesError)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/applitools/connectivity/server_connector.rb', line 63

def render_put_resource(service_url, access_key, resource, render)
  uri = URI(service_url)
  uri.path = RESOURCES_SHA_256 + resource.hash
  Applitools::EyesLogger.debug("PUT resource: #{uri}")
  # Applitools::EyesLogger.debug("Resource content: #{resource.content}")
  response = dummy_put(
    uri,
    body: resource.content,
    content_type: resource.content_type,
    headers: {
      'X-Auth-Token' => access_key
    },
    query: {'render-id' => render['renderId']}
  )
  raise Applitools::EyesError, "Error putting resource: #{response.status}, #{response.body}" unless response.status == HTTP_STATUS_CODES[:ok]
  resource.hash
end

#render_status_by_id(service_url, access_key, running_renders_json) ⇒ Object

Raises:

  • (Applitools::EyesError)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/applitools/connectivity/server_connector.rb', line 81

def render_status_by_id(service_url, access_key, running_renders_json)
  uri = URI(service_url)
  uri.path = RENDER_STATUS
  response = dummy_post(
    uri,
    body: running_renders_json,
    content_type: 'application/json',
    headers: {
        'X-Auth-Token' => access_key
    },
    timeout: 2
  )
  raise Applitools::EyesError, "Error getting server status, #{response.status} #{response.body}" unless response.status == HTTP_STATUS_CODES[:ok]
  Oj.load(response.body)
end

#rendering_infoObject

Raises:

  • (Applitools::EyesError)


42
43
44
45
46
# File 'lib/applitools/connectivity/server_connector.rb', line 42

def rendering_info
  response = get(server_url + RENDER_INFO_PATH, content_type: 'application/json')
  raise Applitools::EyesError, "Error getting render info (#{response.status}})" unless response.status == HTTP_STATUS_CODES[:ok]
  Oj.load response.body
end

#set_proxy(uri, user = nil, password = nil) ⇒ Object



129
130
131
# File 'lib/applitools/connectivity/server_connector.rb', line 129

def set_proxy(uri, user = nil, password = nil)
  self.proxy = Proxy.new uri, user, password
end

#start_session(session_start_info) ⇒ Object

Raises:

  • (Applitools::EyesError)


190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/applitools/connectivity/server_connector.rb', line 190

def start_session(session_start_info)
  request_body = Oj.dump(
    startInfo: Applitools::Utils.camelcase_hash_keys(session_start_info.to_hash)
  )
  res = post(
    endpoint_url, body: request_body
  )
  raise Applitools::EyesError.new("Request failed: #{res.status} #{res.body} #{request_body}") unless res.success?

  response = Oj.load(res.body)
  Applitools::Session.new(response['id'], response['url'], res.status == HTTP_STATUS_CODES[:created])
end

#stop_session(session, aborted = nil, save = false) ⇒ Object

Raises:

  • (Applitools::EyesError)


203
204
205
206
207
208
209
# File 'lib/applitools/connectivity/server_connector.rb', line 203

def stop_session(session, aborted = nil, save = false)
  res = long_delete(URI.join(endpoint_url, session.id.to_s), query: { aborted: aborted, updateBaseline: save })
  raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?

  response = Oj.load(res.body)
  Applitools::TestResults.new(response)
end