lib/watir-performance.rb
require 'ostruct'
module Watir
# Adds helper for window.performance to Watir::Browser.
# @see http://dev.w3.org/2006/webapi/WebTiming/
class PerformanceHelper
def initialize(data)
@data = data
@hash = {}
end
def munge
OpenStruct.new(summarized_hash(data_to_hash))
end
def data_to_hash
@data.each_key do |key|
next if key == '__fxdriver_unwrapped'
@hash[key.to_sym] = {}
next unless @data[key].respond_to? :each
@data[key].each do |k, v|
next if k == '__fxdriver_unwrapped'
@hash[key.to_sym][underscored(k).to_sym] = v
end
end
@hash
end
def summarized_hash(hash)
hash[:summary] = {}
timing = hash[:timing]
hash[:summary][:redirect] = redirect_timer(timing)
hash[:summary][:app_cache] = app_cache(timing)
hash[:summary][:dns] = hash[:timing][:domain_lookup_end] -
hash[:timing][:domain_lookup_start] if hash[:timing][:domain_lookup_start] > 0
hash[:summary][:tcp_connection] = hash[:timing][:connect_end] -
hash[:timing][:connect_start] if hash[:timing][:connect_start] > 0
hash[:summary][:tcp_connection_secure] = hash[:timing][:connect_end] -
hash[:timing][:secure_connection_start] if
((hash[:timing][:secure_connection_start] != nil) and
(hash[:timing][:secure_connection_start] > 0))
hash[:summary][:request] = hash[:timing][:response_start] -
hash[:timing][:request_start] if hash[:timing][:request_start] > 0
hash[:summary][:response] = hash[:timing][:response_end] -
hash[:timing][:response_start] if hash[:timing][:response_start] > 0
hash[:summary][:dom_processing] = hash[:timing][:dom_content_loaded_event_start] -
hash[:timing][:dom_loading] if hash[:timing][:dom_loading] > 0
hash[:summary][:time_to_first_byte] = hash[:timing][:response_start] -
hash[:timing][:domain_lookup_start] if hash[:timing][:domain_lookup_start] > 0
hash[:summary][:time_to_last_byte] = hash[:timing][:response_end] -
hash[:timing][:domain_lookup_start] if hash[:timing][:domain_lookup_start] > 0
hash[:summary][:response_time] = latest_timestamp(hash) - earliest_timestamp(hash)
hash
end
private
def underscored(camel_cased_word)
word = camel_cased_word.to_s.dup
word.gsub!(/::/, '/')
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
word.tr!('-', '_')
word.downcase!
word
end
def timer_checks(timers, hash)
timers.each do |timer|
return hash[:timing][timer] if hash[:timing][timer] > 0
end
end
def timer_summerize(t_start, t_end, standard, hash)
case standard
when true
hash[t_end] - hash[t_start] if hash[t_end] > 0
else
hash[t_end] - hash[t_start] if hash[t_start] > 0
end
end
def redirect_timer(hash)
hash[:redirect_end] - hash[:redirect_start] if hash[:redirect_end] > 0
end
def app_cache(hash)
hash[:domain_lookup_start] - hash[:fetch_start] if hash[:fetch_start] > 0
end
def earliest_timestamp(hash)
timers = %i[navigation_start redirect_start redirect_end fetch_start]
timer_checks(timers, hash)
end
def latest_timestamp(hash)
timers = %i[load_event_end load_event_start dom_complete
dom_content_loaded_event_end dom_content_loaded_event_start
dom_interactive response_end]
timer_checks(timers, hash)
end
end
PERFORMS = 'return window.performance || window.webkitPerformance || '\
'window.mozPerformance || window.msPerformance;'.freeze
ERRORMESSAGE = 'Could not collect performance metrics from your current ' \
'browser. Please ensure the browser you are using supports ' \
'collecting performance metrics.'.freeze
# Extending Watir Browser
# See Documentation Here
# https://www.rubydoc.info/gems/watir/
class Browser
def performance
data = case driver.browser
when :internet_explorer
script = 'return JSON.stringify(window.performance.toJSON());'
cmd = driver.execute_script(script)
::Object::JSON.parse(cmd)
else
driver.execute_script(PERFORMS)
end
raise ERRORMESSAGE if data.nil?
PerformanceHelper.new(data).munge
end
def performance_supported?
driver.execute_script(PERFORMS)
end
alias performance_data performance_supported?
def with_performance
yield PerformanceHelper.new(performance_data).munge if performance_supported?
end
end
end