web_performo 0.1
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.
- data/History.txt +4 -0
- data/Manifest.txt +12 -0
- data/README.rdoc +77 -0
- data/Rakefile +21 -0
- data/lib/web_performo.rb +55 -0
- data/lib/web_performo/result.rb +23 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/web_performo_results_spec.rb +26 -0
- data/spec/web_performo_spec.rb +47 -0
- data/tasks/test.rake +30 -0
- metadata +100 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= web_performo
|
2
|
+
|
3
|
+
* http://github.com/moowahaha/WebPerformoTheMagnificent
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Measures the time it takes a given web page to both return the first byte
|
8
|
+
and to render in a given browser.
|
9
|
+
|
10
|
+
== SYNOPSIS:
|
11
|
+
|
12
|
+
Getting the performance statistics of a given URL:
|
13
|
+
|
14
|
+
performo = WebPerformo.new('firefox')
|
15
|
+
performo.run('http://www.google.com')
|
16
|
+
|
17
|
+
# high precision seconds taken to return the first byte from the web server
|
18
|
+
performo.first_byte_speed
|
19
|
+
|
20
|
+
# high precision seconds taken to render the page in a browser
|
21
|
+
performo.render_speed
|
22
|
+
|
23
|
+
Compare the performance of two sites:
|
24
|
+
|
25
|
+
performo = WebPerformo.new('firefox')
|
26
|
+
|
27
|
+
google = performo.run('http://www.google.com')
|
28
|
+
bing = performo.run('http://www.bing.com')
|
29
|
+
|
30
|
+
if google > bing
|
31
|
+
puts "google is faster than bing"
|
32
|
+
end
|
33
|
+
|
34
|
+
Make an assertion about website performance
|
35
|
+
|
36
|
+
performo = WebPerformo.new('firefox')
|
37
|
+
|
38
|
+
rea = performo.run('http://www.realestate.com.au')
|
39
|
+
nest = performo.run('http://www.nestoria.com.au')
|
40
|
+
|
41
|
+
# ... assuming realestate.com.au is faster than nestoria...
|
42
|
+
nest.assert > rea #=> exception
|
43
|
+
rea.assert < nest #=> exception
|
44
|
+
|
45
|
+
|
46
|
+
== REQUIREMENTS:
|
47
|
+
|
48
|
+
* selenium-webdriver >= 0.0.18
|
49
|
+
|
50
|
+
== INSTALL:
|
51
|
+
|
52
|
+
* sudo gem install web_performo
|
53
|
+
|
54
|
+
== LICENSE:
|
55
|
+
|
56
|
+
Copyright (c) 2010 Stephen Hardisty
|
57
|
+
|
58
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
59
|
+
software and associated documentation files (the "Software"), to deal in the Software
|
60
|
+
without restriction, including without limitation the rights to use, copy, modify,
|
61
|
+
merge, publish,distribute, sublicense, and/or sell copies of the Software, and to
|
62
|
+
permit persons to whom the Software is furnished to do so, subject to the following
|
63
|
+
conditions:
|
64
|
+
|
65
|
+
The above copyright notice and this permission notice shall be included in all copies
|
66
|
+
or substantial portions of the Software. Except as contained in this notice, neither
|
67
|
+
the names of the above copyright holders nor sponsors in relation to the Software
|
68
|
+
(REA Group or its subsidiaries) shall be used in advertising or otherwise to promote
|
69
|
+
the sale, use or other dealings in the Software without prior written authorization.
|
70
|
+
|
71
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,
|
72
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
73
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
74
|
+
HOLDERS OR SPONSORS IN RELATION TO THE SOFTWARE (REA GROUP LIMITED OR ITS
|
75
|
+
SUBSIDIARIES) OR THEIR RELATED PERSONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
76
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
77
|
+
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
require './lib/web_performo'
|
6
|
+
|
7
|
+
Hoe.plugin :newgem
|
8
|
+
# Hoe.plugin :website
|
9
|
+
# Hoe.plugin :cucumberfeatures
|
10
|
+
|
11
|
+
# Generate all the Rake tasks
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
|
+
$hoe = Hoe.spec 'web_performo' do
|
14
|
+
self.developer 'Stephen Hardisty', 'moowahaha@hotmail.com'
|
15
|
+
self.rubyforge_name = self.name
|
16
|
+
self.extra_deps = [['selenium-webdriver','>= 0.0.18']]
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'newgem/tasks'
|
20
|
+
Dir['tasks/*.rake'].each { |t| load t }
|
21
|
+
|
data/lib/web_performo.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'web_performo', 'result')
|
2
|
+
require 'socket'
|
3
|
+
include Socket::Constants
|
4
|
+
require 'selenium-webdriver'
|
5
|
+
|
6
|
+
class WebPerformo
|
7
|
+
VERSION = '0.1'
|
8
|
+
|
9
|
+
def initialize browser = 'firefox'
|
10
|
+
@browser = browser.to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
def run url
|
14
|
+
WebPerformo::Result.new(
|
15
|
+
:url => url,
|
16
|
+
:first_byte_speed => time_first_byte(url),
|
17
|
+
:render_speed => time_render(url)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def time_first_byte url
|
24
|
+
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
|
25
|
+
sockaddr = Socket.sockaddr_in(80, url.downcase.gsub(/^https?:\/\//, ''))
|
26
|
+
|
27
|
+
begin
|
28
|
+
socket.connect_nonblock(sockaddr)
|
29
|
+
rescue Errno::EINPROGRESS
|
30
|
+
IO.select(nil, [socket])
|
31
|
+
end
|
32
|
+
|
33
|
+
timer(socket) do |socket|
|
34
|
+
socket.write( "GET / HTTP/1.0\r\n\r\n" )
|
35
|
+
socket.readchar
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def time_render url
|
40
|
+
selenium_driver = Selenium::WebDriver.for @browser
|
41
|
+
|
42
|
+
time_elapsed = timer(selenium_driver, url.downcase =~ /^http:/ ? url : "http://#{url}") do |driver, url|
|
43
|
+
driver.navigate.to(url)
|
44
|
+
end
|
45
|
+
|
46
|
+
selenium_driver.close
|
47
|
+
time_elapsed
|
48
|
+
end
|
49
|
+
|
50
|
+
def timer *params
|
51
|
+
before = Time.now.to_f
|
52
|
+
yield *params
|
53
|
+
Time.now.to_f - before
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'assertion')
|
2
|
+
|
3
|
+
class WebPerformo
|
4
|
+
class Result
|
5
|
+
attr_reader :first_byte_speed, :render_speed, :url
|
6
|
+
|
7
|
+
def initialize result
|
8
|
+
@url, @first_byte_speed, @render_speed = result[:url], result[:first_byte_speed], result[:render_speed]
|
9
|
+
end
|
10
|
+
|
11
|
+
def > candidate
|
12
|
+
self.first_byte_speed > candidate.first_byte_speed && self.render_speed > candidate.render_speed
|
13
|
+
end
|
14
|
+
|
15
|
+
def < candidate
|
16
|
+
self.first_byte_speed < candidate.first_byte_speed && self.render_speed < candidate.render_speed
|
17
|
+
end
|
18
|
+
|
19
|
+
def assert
|
20
|
+
WebPerformo::Assertion.new(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/web_performo.rb'}"
|
9
|
+
puts "Loading web_performo gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'web_performo', 'result')
|
2
|
+
|
3
|
+
describe WebPerformo::Result do
|
4
|
+
it "should allow us to fetch data we sat" do
|
5
|
+
result = WebPerformo::Result.new(:render_speed => 10, :first_byte_speed => 20, :url => 'bob')
|
6
|
+
|
7
|
+
result.render_speed.should == 10
|
8
|
+
result.first_byte_speed.should == 20
|
9
|
+
result.url.should == 'bob'
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'comparing' do
|
13
|
+
before do
|
14
|
+
@slow_result = WebPerformo::Result.new(:render_speed => 2, :first_byte_speed => 2, :url => 'slow')
|
15
|
+
@fast_result = WebPerformo::Result.new(:render_speed => 1, :first_byte_speed => 1, :url => 'fast')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should recognise results that are fast" do
|
19
|
+
@fast_result.should < @slow_result
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should recognise results that are slow" do
|
23
|
+
@slow_result.should > @fast_result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'web_performo')
|
2
|
+
|
3
|
+
describe WebPerformo do
|
4
|
+
it "should tell me what url a result is based on" do
|
5
|
+
result = WebPerformo.new.run('http://www.dcyder.com')
|
6
|
+
result.url.should == 'http://www.dcyder.com'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'first byte' do
|
10
|
+
it "should give me the first-byte speed of dcyder.com (what a site!)" do
|
11
|
+
fake_socket = stub('fake socket')
|
12
|
+
Socket.should_receive(:new).and_return(fake_socket)
|
13
|
+
|
14
|
+
fake_sockaddr = stub('fake socket address')
|
15
|
+
Socket.should_receive(:sockaddr_in).with(80, 'www.dcyder.com').and_return(fake_sockaddr)
|
16
|
+
fake_socket.should_receive(:connect_nonblock).with(fake_sockaddr)
|
17
|
+
|
18
|
+
fake_socket.should_receive(:write).with(/GET/)
|
19
|
+
fake_socket.should_receive(:readchar).and_return {sleep 0.5}
|
20
|
+
|
21
|
+
performo = WebPerformo.new
|
22
|
+
result = performo.run('http://www.dcyder.com')
|
23
|
+
|
24
|
+
result.first_byte_speed.should > 0.5
|
25
|
+
result.first_byte_speed.should < 0.7
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'rendering' do
|
30
|
+
it "should give me the render speed of dcyder.com (worth rendering, btw)" do
|
31
|
+
fake_driver = stub('fake browser')
|
32
|
+
Selenium::WebDriver.should_receive(:for).with(:fakeyfox).and_return(fake_driver)
|
33
|
+
|
34
|
+
fake_navigator = stub('fake selenium navigator')
|
35
|
+
fake_driver.should_receive(:navigate).and_return(fake_navigator)
|
36
|
+
fake_navigator.should_receive(:to).with('http://www.dcyder.com').and_return {sleep 0.5}
|
37
|
+
|
38
|
+
fake_driver.should_receive(:close)
|
39
|
+
|
40
|
+
performo = WebPerformo.new('fakeyfox')
|
41
|
+
result = performo.run('www.dcyder.com')
|
42
|
+
|
43
|
+
result.render_speed.should > 0.5
|
44
|
+
result.render_speed.should < 0.7
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/tasks/test.rake
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec/rake/spectask'
|
2
|
+
require 'spec/rake/verify_rcov'
|
3
|
+
|
4
|
+
task :test => ['test:covered']
|
5
|
+
|
6
|
+
namespace :test do
|
7
|
+
report_dir = "reports"
|
8
|
+
directory report_dir
|
9
|
+
|
10
|
+
spec_opts = ["--colour", "--format", "progress"]
|
11
|
+
|
12
|
+
rcov_opts = ["--include", "spec", "--exclude", "spec/*,gems/*,db/*,features/*,gremlin/lib/*,nagios_reporter/lib", "--rails"]
|
13
|
+
rcov_report_dir = report_dir + "/rcov"
|
14
|
+
|
15
|
+
desc "Run all specs in spec directory with RCov (excluding plugin specs)"
|
16
|
+
Spec::Rake::SpecTask.new(:all_with_reports => [report_dir]) do |t|
|
17
|
+
t.spec_opts = spec_opts + ["--format", "html:#{report_dir}/rspec/specs.html"]
|
18
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
19
|
+
t.rcov = true
|
20
|
+
t.rcov_dir = rcov_report_dir
|
21
|
+
t.rcov_opts = rcov_opts
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
RCov::VerifyTask.new(:covered => :all_with_reports) do |t|
|
26
|
+
t.threshold = 100.0
|
27
|
+
t.require_exact_threshold = false
|
28
|
+
t.index_html = "#{rcov_report_dir}/index.html"
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: web_performo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Hardisty
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-05-11 00:00:00 +10:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: selenium-webdriver
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.18
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rubyforge
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.4
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hoe
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.6.0
|
44
|
+
version:
|
45
|
+
description: |-
|
46
|
+
Measures the time it takes a given web page to both return the first byte
|
47
|
+
and to render in a given browser.
|
48
|
+
email:
|
49
|
+
- moowahaha@hotmail.com
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files:
|
55
|
+
- History.txt
|
56
|
+
- Manifest.txt
|
57
|
+
files:
|
58
|
+
- History.txt
|
59
|
+
- Manifest.txt
|
60
|
+
- README.rdoc
|
61
|
+
- Rakefile
|
62
|
+
- lib/web_performo.rb
|
63
|
+
- lib/web_performo/result.rb
|
64
|
+
- script/console
|
65
|
+
- script/destroy
|
66
|
+
- script/generate
|
67
|
+
- spec/web_performo_results_spec.rb
|
68
|
+
- spec/web_performo_spec.rb
|
69
|
+
- tasks/test.rake
|
70
|
+
has_rdoc: true
|
71
|
+
homepage: http://github.com/moowahaha/WebPerformoTheMagnificent
|
72
|
+
licenses: []
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options:
|
76
|
+
- --main
|
77
|
+
- README.rdoc
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
requirements: []
|
93
|
+
|
94
|
+
rubyforge_project: web_performo
|
95
|
+
rubygems_version: 1.3.5
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: Measures the time it takes a given web page to both return the first byte and to render in a given browser.
|
99
|
+
test_files: []
|
100
|
+
|