susuwatari 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rvmrc +2 -0
- data/Gemfile +9 -0
- data/README.md +88 -0
- data/Rakefile +10 -0
- data/lib/susuwatari.rb +15 -0
- data/lib/susuwatari/client.rb +48 -0
- data/lib/susuwatari/error.rb +4 -0
- data/lib/susuwatari/result.rb +46 -0
- data/lib/susuwatari/version.rb +3 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/susuwatari_spec.rb +39 -0
- data/susuwatari.gemspec +26 -0
- metadata +106 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
Susuwatari
|
2
|
+
===
|
3
|
+
|
4
|
+
Susuwatari (ススワタリ lit. meaning "travelling soot") is the name of the dust bunnies featured in [Studio Ghibli](http://en.wikipedia.org/wiki/Studio_Ghibli) Animes _My Neighbour Totoro_ and _Spirited Away_.
|
5
|
+
|
6
|
+
|
7
|
+
An Introduction for the Impatient (tl;dr)
|
8
|
+
---
|
9
|
+
|
10
|
+
This gem allows you to use the API of Patrick Meenan excellent [webpagetest.org](http://www.webpagetest.org) and fetch scores, numbers and waterfall images.
|
11
|
+
|
12
|
+
require 'susuwatari'
|
13
|
+
|
14
|
+
mei = Susuwatari.new( url: 'google.com', k: '5566sdfdsf' )
|
15
|
+
mei.run
|
16
|
+
=> "aASFDasfdads2"
|
17
|
+
|
18
|
+
mei.status
|
19
|
+
=> :running
|
20
|
+
|
21
|
+
mei.status
|
22
|
+
=> :completed
|
23
|
+
|
24
|
+
mei.result.keys
|
25
|
+
=> [ "testId", "summary", "testUrl", "location", "connectivity",
|
26
|
+
"bwDown", "bwUp", "latency", "plr", "completed", "runs", "average",
|
27
|
+
"median", "run"]
|
28
|
+
|
29
|
+
mei.result.testId
|
30
|
+
=> "aASFDasfdads2"
|
31
|
+
|
32
|
+
mei.result.run.firstView.images.waterfall
|
33
|
+
=> "http://www.webpagetest.org/results/12/02/09/KG/35XV333/1_waterfall.png"
|
34
|
+
|
35
|
+
mei.result.run.firstView.results.score_cache
|
36
|
+
=> "98"
|
37
|
+
|
38
|
+
mei.result.run.firstView.results.requests
|
39
|
+
=> 12
|
40
|
+
|
41
|
+
You can check what a result looks like [here](https://sites.google.com/a/webpagetest.org/docs/advanced-features/webpagetest-restful-apis#TOC-Getting-test-results).
|
42
|
+
|
43
|
+
So why Susuwatari?
|
44
|
+
---
|
45
|
+
|
46
|
+
Premature optimization might be the root of all evil, but optimizing actual performance bottlenecks is uniquely satisfying.
|
47
|
+
|
48
|
+
Optimizing a web page from the end user perspective is even more satisfying, so we figured we need a way to monitor the web page speed on a regular basis.
|
49
|
+
|
50
|
+
This gem allows to you test your url using webpagetest.org and get all the relevant numbers (imho) in a structured form. Looking at the waterfall charts allows you to squash all those little nasty dust bunnies that will slow down your page.
|
51
|
+
|
52
|
+
![Squashing Susuwatari](http://dl.dropbox.com/u/3878602/ToShare/lk6r97NoeA1qzgeh8o1_500.gif "Squashing Susuwatari")
|
53
|
+
|
54
|
+
So how to use it?
|
55
|
+
---
|
56
|
+
You need an api key from webpagetest.org to use this gem. You can find more information about that on the [Developer Interfaces Documentation](https://sites.google.com/a/webpagetest.org/docs/advanced-features).
|
57
|
+
|
58
|
+
Once you've installed the gem, you can use it like this:
|
59
|
+
|
60
|
+
require 'susuwatari'
|
61
|
+
|
62
|
+
mei = Susuwatari.new( url: 'google.com', k: 'your-key', from: 'detroit', using: 'Chrome')
|
63
|
+
|
64
|
+
mei.run
|
65
|
+
=> 'aBd333'
|
66
|
+
|
67
|
+
|
68
|
+
# You can check the status.
|
69
|
+
mei.status
|
70
|
+
=> :running
|
71
|
+
|
72
|
+
mei.status
|
73
|
+
=> :completed
|
74
|
+
|
75
|
+
mei.result.keys
|
76
|
+
=> [ "testId", "summary", "testUrl", "location", "connectivity",
|
77
|
+
"bwDown", "bwUp", "latency", "plr", "completed", "runs", "average",
|
78
|
+
"median", "run"]
|
79
|
+
|
80
|
+
#You can access the results as a hash
|
81
|
+
mei.result["testId"]
|
82
|
+
=> 'aBd333'
|
83
|
+
|
84
|
+
#Or in a pseudo-object oriented fashion
|
85
|
+
mei.result.testId
|
86
|
+
=> 'aBd333'
|
87
|
+
|
88
|
+
|
data/Rakefile
ADDED
data/lib/susuwatari.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'hashie'
|
3
|
+
require 'rest_client'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
require 'susuwatari/version'
|
7
|
+
require 'susuwatari/error'
|
8
|
+
require "susuwatari/result"
|
9
|
+
require 'susuwatari/client'
|
10
|
+
|
11
|
+
module Susuwatari
|
12
|
+
def self.new(params)
|
13
|
+
Susuwatari::Client.new(params)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Susuwatari
|
2
|
+
class Client
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
attr_accessor :params, :response
|
6
|
+
|
7
|
+
def_delegator :@result, :status
|
8
|
+
|
9
|
+
TEST_URL = 'http://www.webpagetest.org/runtest.php'
|
10
|
+
|
11
|
+
def initialize( params = {} )
|
12
|
+
params.fetch(:k)
|
13
|
+
params.fetch(:url)
|
14
|
+
params[:f] = :json
|
15
|
+
params[:runs] ||= 1
|
16
|
+
params.delete(:r)
|
17
|
+
self.params = params
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
return status if @result
|
22
|
+
@result = Result.new(make_request)
|
23
|
+
@result.test_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def result
|
27
|
+
@result && @result.test_result || {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
@result && @result.status || :to_be_run
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def make_request
|
37
|
+
response = RestClient.get TEST_URL, :params => params, :accept => :json
|
38
|
+
raise_error "The requests was not completed, try again." unless response.code == 200
|
39
|
+
body = Hashie::Mash.new(JSON.parse(response.body))
|
40
|
+
raise_error(body.statusText) unless body.statusCode == 200
|
41
|
+
body
|
42
|
+
end
|
43
|
+
|
44
|
+
def raise_error(msg)
|
45
|
+
raise Error.new(msg)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_support/core_ext/hash/conversions'
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
|
5
|
+
module Susuwatari
|
6
|
+
class Result
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
STATUS_URL = 'http://www.webpagetest.org/testStatus.php'
|
10
|
+
RESULT_URL_PREFIX = 'http://www.webpagetest.org/xmlResult/'
|
11
|
+
|
12
|
+
attr_reader :test_id, :current_status, :test_result, :request_raw
|
13
|
+
|
14
|
+
def_delegators :@test_result, :average, :median
|
15
|
+
|
16
|
+
def initialize( request_response )
|
17
|
+
@request_raw = request_response
|
18
|
+
@test_id = request_raw.data.testId
|
19
|
+
end
|
20
|
+
|
21
|
+
def status
|
22
|
+
fetch_status unless current_status == :complete
|
23
|
+
current_status
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def fetch_status
|
29
|
+
status = Hashie::Mash.new(JSON.parse( RestClient.get STATUS_URL, :params => { :f => :json, :test => test_id }))
|
30
|
+
case status.data.statusCode.to_s
|
31
|
+
when /1../
|
32
|
+
@current_status = :running
|
33
|
+
when "200"
|
34
|
+
@current_status = :completed
|
35
|
+
fetch_result
|
36
|
+
when /4../
|
37
|
+
@current_status = :error
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def fetch_result
|
42
|
+
response = RestClient.get "#{RESULT_URL_PREFIX}/#{test_id}/"
|
43
|
+
@test_result = Hashie::Mash.new(Hash.from_xml(response.body)).response.data
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
require 'susuwatari'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
|
7
|
+
# Requires supporting files with custom matchers and macros, etc,
|
8
|
+
# in ./support/ and its subdirectories.
|
9
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Susuwatari do
|
4
|
+
let(:key){ "4dabc19c6d0a4c30a2a20b4a6448d085" }
|
5
|
+
let(:url){ "google.com"}
|
6
|
+
|
7
|
+
context 'run a simple test' do
|
8
|
+
specify do
|
9
|
+
stub_request(:get, "http://www.webpagetest.org/runtest.php?f=json&k=#{key}&runs=1&url=#{url}").
|
10
|
+
with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
11
|
+
to_return(:status => 200, :headers => {}, :body =>
|
12
|
+
{ "statusCode" => 200,
|
13
|
+
"statusText" => "Ok",
|
14
|
+
"data" => {
|
15
|
+
"testId" => "120116_KP_2WMG1",
|
16
|
+
"ownerKey" => "4dabc19c6d0a4c30a2a20b4a6448d085",
|
17
|
+
"jsonUrl" => "http://www.webpagetest.org/results.php?test=120116_KP_2WMG1&f=json",
|
18
|
+
"xmlUrl" => "http://www.webpagetest.org/xmlResult\/120116_KP_2WMG1/",
|
19
|
+
"userUrl" => "http://www.webpagetest.org/result\/120116_KP_2WMG1/",
|
20
|
+
"summaryCSV" => "http://www.webpagetest.org/result\/120116_KP_2WMG1/page_data.csv",
|
21
|
+
"detailCSV" => "http://www.webpagetest.org/result\/120116_KP_2WMG1/requests.csv" } }.to_json)
|
22
|
+
mei = Susuwatari.new( url: 'google.com', k: key )
|
23
|
+
mei.run
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises an error if the request could not be completed" do
|
27
|
+
url = "trollololo"
|
28
|
+
status_text = "Please enter a Valid URL. <b>trollololo</b> is not a valid Internet host name"
|
29
|
+
stub_request(:get, "http://www.webpagetest.org/runtest.php?f=json&k=#{key}&runs=1&url=#{url}").
|
30
|
+
with(:headers => {'Accept'=>'application/json', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
31
|
+
to_return(:status => 200, :headers => {}, :body =>
|
32
|
+
{ "statusCode"=>400,
|
33
|
+
"statusText"=>
|
34
|
+
status_text }.to_json )
|
35
|
+
mei = Susuwatari.new( url: url, k: key )
|
36
|
+
lambda{ mei.run }.should raise_error(Susuwatari::Error, status_text)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/susuwatari.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "susuwatari/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "susuwatari"
|
6
|
+
s.version = Susuwatari::VERSION
|
7
|
+
s.authors = ["Benjamin Krause", "Adolfo Builes"]
|
8
|
+
s.email = ["benjamin@moviepilot.com", "builes.adolfo@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/moviepilot/susuwatari"
|
10
|
+
s.summary = %q{Simple Wrapper around the API of webpagetest.org}
|
11
|
+
s.description = %q{Allows to schedule tests on webpagetest.org}
|
12
|
+
|
13
|
+
s.rubyforge_project = "susuwatari"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
# specify any dependencies here; for example:
|
21
|
+
# s.add_development_dependency "rspec"
|
22
|
+
s.add_runtime_dependency "activesupport", "~> 3.2.1"
|
23
|
+
s.add_runtime_dependency "json", "~> 1.6.5"
|
24
|
+
s.add_runtime_dependency "hashie", "~> 1.2.0"
|
25
|
+
s.add_runtime_dependency "rest-client", "~> 1.6.7"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: susuwatari
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Benjamin Krause
|
9
|
+
- Adolfo Builes
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-02-09 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
requirement: &2153083120 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.2.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2153083120
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: json
|
28
|
+
requirement: &2153082620 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.6.5
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2153082620
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: hashie
|
39
|
+
requirement: &2153082160 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.2.0
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2153082160
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rest-client
|
50
|
+
requirement: &2153111380 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.6.7
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2153111380
|
59
|
+
description: Allows to schedule tests on webpagetest.org
|
60
|
+
email:
|
61
|
+
- benjamin@moviepilot.com
|
62
|
+
- builes.adolfo@gmail.com
|
63
|
+
executables: []
|
64
|
+
extensions: []
|
65
|
+
extra_rdoc_files: []
|
66
|
+
files:
|
67
|
+
- .gitignore
|
68
|
+
- .rvmrc
|
69
|
+
- Gemfile
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- lib/susuwatari.rb
|
73
|
+
- lib/susuwatari/client.rb
|
74
|
+
- lib/susuwatari/error.rb
|
75
|
+
- lib/susuwatari/result.rb
|
76
|
+
- lib/susuwatari/version.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
- spec/susuwatari_spec.rb
|
79
|
+
- susuwatari.gemspec
|
80
|
+
homepage: https://github.com/moviepilot/susuwatari
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project: susuwatari
|
100
|
+
rubygems_version: 1.8.15
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: Simple Wrapper around the API of webpagetest.org
|
104
|
+
test_files:
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/susuwatari_spec.rb
|