browsermob-proxy2 0.1.0
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.
- checksums.yaml +15 -0
- data/.gitignore +4 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/LICENSE +202 -0
- data/README.md +98 -0
- data/Rakefile +21 -0
- data/browsermob-proxy.gemspec +31 -0
- data/lib/browsermob-proxy.rb +1 -0
- data/lib/browsermob/proxy.rb +13 -0
- data/lib/browsermob/proxy/client.rb +134 -0
- data/lib/browsermob/proxy/server.rb +60 -0
- data/lib/browsermob/proxy/version.rb +5 -0
- data/lib/browsermob/proxy/webdriver_listener.rb +70 -0
- data/spec/e2e/listener_spec.rb +29 -0
- data/spec/e2e/selenium_spec.rb +72 -0
- data/spec/fixtures/1.html +11 -0
- data/spec/fixtures/2.html +10 -0
- data/spec/fixtures/3.html +10 -0
- data/spec/fixtures/google.har +612 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/unit/client_spec.rb +193 -0
- data/spec/unit/webdriver_listener_spec.rb +56 -0
- metadata +188 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'browsermob/proxy'
|
2
|
+
require 'selenium-webdriver'
|
3
|
+
require 'browsermob/proxy/webdriver_listener'
|
4
|
+
require 'rack'
|
5
|
+
|
6
|
+
RestClient.log = STDOUT
|
7
|
+
|
8
|
+
module BrowserMob
|
9
|
+
module Proxy
|
10
|
+
module SpecHelper
|
11
|
+
def self.httpd
|
12
|
+
@httpd ||= HttpServer.new(Rack::File.new(fixture_dir))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.fixture_dir
|
16
|
+
@fixture_dir ||= File.join(File.expand_path("../", __FILE__), "fixtures")
|
17
|
+
end
|
18
|
+
|
19
|
+
def server
|
20
|
+
$_bm_server ||= Server.new(
|
21
|
+
File.join(home, "bin", "browsermob-proxy"),
|
22
|
+
:port => Selenium::WebDriver::PortProber.above(3000),
|
23
|
+
:log => true
|
24
|
+
).start
|
25
|
+
end
|
26
|
+
|
27
|
+
def new_proxy
|
28
|
+
server.create_proxy
|
29
|
+
end
|
30
|
+
|
31
|
+
def home
|
32
|
+
ENV['BROWSERMOB_PROXY_HOME'] or raise "BROWSERMOB_PROXY_HOME not set"
|
33
|
+
end
|
34
|
+
|
35
|
+
def fixture(name)
|
36
|
+
File.read(fixture_path(name))
|
37
|
+
end
|
38
|
+
|
39
|
+
def url_for(page)
|
40
|
+
SpecHelper.httpd.url_for(page)
|
41
|
+
end
|
42
|
+
|
43
|
+
def fixture_path(name)
|
44
|
+
File.join(SpecHelper.fixture_dir, name)
|
45
|
+
end
|
46
|
+
|
47
|
+
class HttpServer
|
48
|
+
attr_reader :port
|
49
|
+
|
50
|
+
def initialize(app)
|
51
|
+
@port = Selenium::WebDriver::PortProber.above(3000)
|
52
|
+
|
53
|
+
pid = fork do
|
54
|
+
Rack::Server.new(:app => app, :Port => @port).start
|
55
|
+
end
|
56
|
+
|
57
|
+
at_exit { Process.kill 'TERM', pid }
|
58
|
+
|
59
|
+
poller = Selenium::WebDriver::SocketPoller.new("localhost", @port, 10)
|
60
|
+
|
61
|
+
unless poller.connected?
|
62
|
+
raise "unable to start web server in 5 seconds"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def url_for(page)
|
67
|
+
# use 0.0.0.0 to avoid default no-proxy rules on localhost
|
68
|
+
"http://0.0.0.0:#{@port}/#{page}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
RSpec.configure do |c|
|
77
|
+
c.include(BrowserMob::Proxy::SpecHelper)
|
78
|
+
c.after(:suite) { $_bm_server.stop if $_bm_server }
|
79
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BrowserMob
|
4
|
+
module Proxy
|
5
|
+
|
6
|
+
describe Client do
|
7
|
+
let(:resource) { mock(RestClient::Resource) }
|
8
|
+
let(:client) { Client.new(resource, "localhost", 9091) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
{
|
12
|
+
"har" => mock("resource[har]"),
|
13
|
+
"har/pageRef" => mock("resource[har/pageRef]"),
|
14
|
+
"whitelist" => mock("resource[whitelist]"),
|
15
|
+
"blacklist" => mock("resource[blacklist]"),
|
16
|
+
"limit" => mock("resource[limit]"),
|
17
|
+
"headers" => mock("resource[headers]"),
|
18
|
+
"hosts" => mock("rescource[hosts]"),
|
19
|
+
"rewrite" => mock("resource[rewrite]")
|
20
|
+
}.each do |path, mock|
|
21
|
+
resource.stub!(:[]).with(path).and_return(mock)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "creates a named har" do
|
26
|
+
resource['har'].should_receive(:put).
|
27
|
+
with(:initialPageRef => "foo").
|
28
|
+
and_return('')
|
29
|
+
|
30
|
+
client.new_har("foo").should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "creates a new har with no name" do
|
34
|
+
resource['har'].should_receive(:put).
|
35
|
+
with({}).
|
36
|
+
and_return('')
|
37
|
+
|
38
|
+
client.new_har.should be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns the previous archive if one exists" do
|
42
|
+
resource['har'].should_receive(:put).
|
43
|
+
with(:initialPageRef => "foo").
|
44
|
+
and_return(fixture("google.har"))
|
45
|
+
|
46
|
+
client.new_har("foo").should be_kind_of(HAR::Archive)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "turns on header capture when given a name" do
|
50
|
+
resource['har'].should_receive(:put).
|
51
|
+
with(:initialPageRef => "foo", :captureHeaders => true).
|
52
|
+
and_return('')
|
53
|
+
|
54
|
+
client.new_har("foo", :capture_headers => true).should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "turns on header capture when not given a name" do
|
58
|
+
resource['har'].should_receive(:put).
|
59
|
+
with(:captureHeaders => true).
|
60
|
+
and_return('')
|
61
|
+
|
62
|
+
client.new_har(:capture_headers => true).should be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it "gets the current har" do
|
66
|
+
resource['har'].should_receive(:get).
|
67
|
+
and_return(fixture("google.har"))
|
68
|
+
|
69
|
+
client.har.should be_kind_of(HAR::Archive)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "creates a new page" do
|
73
|
+
resource['har/pageRef'].should_receive(:put).
|
74
|
+
with :pageRef => "foo"
|
75
|
+
|
76
|
+
client.new_page "foo"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "sets the blacklist" do
|
80
|
+
resource['blacklist'].should_receive(:put).
|
81
|
+
with(:regex => "http://example.com", :status => 401)
|
82
|
+
|
83
|
+
client.blacklist(%r[http://example.com], 401)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "sets the whitelist" do
|
87
|
+
resource['whitelist'].should_receive(:put).
|
88
|
+
with(:regex => "http://example.com", :status => 401)
|
89
|
+
|
90
|
+
client.whitelist(%r[http://example.com], 401)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "sets the hosts list when adding new hosts" do
|
94
|
+
resource['hosts'].should_receive(:post).
|
95
|
+
with('{"www.example.com":"127.0.0.1"}',
|
96
|
+
:content_type => "application/json")
|
97
|
+
|
98
|
+
client.add_host('www.example.com', '127.0.0.1')
|
99
|
+
end
|
100
|
+
|
101
|
+
it "sets the hosts list when deleting hosts" do
|
102
|
+
resource['hosts'].should_receive(:post)
|
103
|
+
client.add_host('www.example.com', '127.0.0.1')
|
104
|
+
resource['hosts'].should_receive(:post)
|
105
|
+
client.add_host('subdomain.example.com', '192.168.1.1')
|
106
|
+
|
107
|
+
resource['hosts'].should_receive(:post).
|
108
|
+
with('{"subdomain.example.com":"192.168.1.1"}',
|
109
|
+
:content_type => "application/json")
|
110
|
+
|
111
|
+
client.remove_host('www.example.com')
|
112
|
+
end
|
113
|
+
|
114
|
+
it "sets the :downstream_kbps limit" do
|
115
|
+
resource['limit'].should_receive(:put).
|
116
|
+
with('downstreamKbps' => 100)
|
117
|
+
|
118
|
+
client.limit(:downstream_kbps => 100)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "sets the :upstream_kbps limit" do
|
122
|
+
resource['limit'].should_receive(:put).
|
123
|
+
with('upstreamKbps' => 100)
|
124
|
+
|
125
|
+
client.limit(:upstream_kbps => 100)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "sets the :latency limit" do
|
129
|
+
resource['limit'].should_receive(:put).
|
130
|
+
with('latency' => 100)
|
131
|
+
|
132
|
+
client.limit(:latency => 100)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "sets all limits" do
|
136
|
+
resource['limit'].should_receive(:put).
|
137
|
+
with('latency' => 100, 'downstreamKbps' => 200, 'upstreamKbps' => 300)
|
138
|
+
|
139
|
+
client.limit(:latency => 100, :downstream_kbps => 200, :upstream_kbps => 300)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "raises ArgumentError on invalid options" do
|
143
|
+
lambda { client.limit(:foo => 1) }.should raise_error(ArgumentError)
|
144
|
+
lambda { client.limit({}) }.should raise_error(ArgumentError)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "sets headers" do
|
148
|
+
resource['headers'].should_receive(:post).with('{"foo":"bar"}', :content_type => "application/json")
|
149
|
+
|
150
|
+
client.headers(:foo => "bar")
|
151
|
+
end
|
152
|
+
|
153
|
+
it "rewrites URLs" do
|
154
|
+
resource['rewrite'].should_receive(:put).with(:matchRegex => "foo.*", :replace => "bar")
|
155
|
+
|
156
|
+
client.rewrite(/foo.*/, "bar")
|
157
|
+
end
|
158
|
+
|
159
|
+
context "#selenium_proxy" do
|
160
|
+
it "defaults to HTTP proxy only" do
|
161
|
+
proxy = client.selenium_proxy
|
162
|
+
|
163
|
+
proxy.http.should == "#{client.host}:#{client.port}"
|
164
|
+
proxy.ssl.should be_nil
|
165
|
+
proxy.ftp.should be_nil
|
166
|
+
end
|
167
|
+
|
168
|
+
it "allows multiple protocols" do
|
169
|
+
proxy = client.selenium_proxy(:http, :ssl)
|
170
|
+
|
171
|
+
proxy.http.should == "#{client.host}:#{client.port}"
|
172
|
+
proxy.ssl.should == "#{client.host}:#{client.port}"
|
173
|
+
proxy.ftp.should be_nil
|
174
|
+
end
|
175
|
+
|
176
|
+
it "allows disabling HTTP proxy" do
|
177
|
+
proxy = client.selenium_proxy(:ssl)
|
178
|
+
|
179
|
+
proxy.ssl.should == "#{client.host}:#{client.port}"
|
180
|
+
proxy.http.should be_nil
|
181
|
+
proxy.ftp.should be_nil
|
182
|
+
end
|
183
|
+
|
184
|
+
it "raises an error when a bad protocol is used" do
|
185
|
+
lambda {
|
186
|
+
client.selenium_proxy(:htp)
|
187
|
+
}.should raise_error
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BrowserMob
|
4
|
+
module Proxy
|
5
|
+
|
6
|
+
describe WebDriverListener do
|
7
|
+
let(:client) { mock(Client) }
|
8
|
+
let(:driver) { mock(Selenium::WebDriver::Driver, :current_url => 'http://foo') }
|
9
|
+
let(:listener) { WebDriverListener.new(client) }
|
10
|
+
let(:element) { mock(Selenium::WebDriver::Element, :ref => "some-id")}
|
11
|
+
let(:har) { mock(HAR::Archive) }
|
12
|
+
let(:url) { "http://example.com" }
|
13
|
+
|
14
|
+
it 'creates a new har on navigate.to' do
|
15
|
+
client.should_receive(:new_har).with("navigate-to-http://example.com", {})
|
16
|
+
client.should_receive(:har).and_return(:har)
|
17
|
+
|
18
|
+
listener.before_navigate_to(url, driver)
|
19
|
+
listener.before_quit(driver)
|
20
|
+
listener.hars.size.should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'creates a new page on navigate.back' do
|
24
|
+
client.should_receive(:new_page).with(/^navigate-back/)
|
25
|
+
|
26
|
+
listener.before_navigate_back(driver)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'creates a new page on navigate.forward' do
|
30
|
+
client.should_receive(:new_page).with(/^navigate-forward/)
|
31
|
+
|
32
|
+
listener.before_navigate_forward(driver)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'creates a new page on click' do
|
36
|
+
client.should_receive(:new_page).with(/^click-element/)
|
37
|
+
|
38
|
+
listener.before_click(element, driver)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'saves har before quit' do
|
42
|
+
client.should_receive(:har).and_return(har)
|
43
|
+
|
44
|
+
listener.before_quit(driver)
|
45
|
+
listener.hars.size.should == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'passes the :capture_headers option' do
|
49
|
+
listener = WebDriverListener.new(client, :capture_headers => true)
|
50
|
+
client.should_receive(:new_har).with("navigate-to-http://example.com", :capture_headers => true)
|
51
|
+
|
52
|
+
listener.before_navigate_to(url, driver)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: browsermob-proxy2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pedro Pinheiro
|
8
|
+
- jari.bakken
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ! '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ! '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: childprocess
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: multi_json
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: har
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.5.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 2.5.0
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: selenium-webdriver
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '2.7'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ~>
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '2.7'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rake
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 0.9.2
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 0.9.2
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rack
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: Ruby client for the BrowserMob Proxy REST API
|
127
|
+
email:
|
128
|
+
- pdpinheiro@gmail.com
|
129
|
+
- jari.bakken@gmail.com
|
130
|
+
executables: []
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- .gitignore
|
135
|
+
- .travis.yml
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- browsermob-proxy.gemspec
|
141
|
+
- lib/browsermob-proxy.rb
|
142
|
+
- lib/browsermob/proxy.rb
|
143
|
+
- lib/browsermob/proxy/client.rb
|
144
|
+
- lib/browsermob/proxy/server.rb
|
145
|
+
- lib/browsermob/proxy/version.rb
|
146
|
+
- lib/browsermob/proxy/webdriver_listener.rb
|
147
|
+
- spec/e2e/listener_spec.rb
|
148
|
+
- spec/e2e/selenium_spec.rb
|
149
|
+
- spec/fixtures/1.html
|
150
|
+
- spec/fixtures/2.html
|
151
|
+
- spec/fixtures/3.html
|
152
|
+
- spec/fixtures/google.har
|
153
|
+
- spec/spec_helper.rb
|
154
|
+
- spec/unit/client_spec.rb
|
155
|
+
- spec/unit/webdriver_listener_spec.rb
|
156
|
+
homepage: http://github.com/pdpi/browsermob-proxy-rb
|
157
|
+
licenses: []
|
158
|
+
metadata: {}
|
159
|
+
post_install_message:
|
160
|
+
rdoc_options: []
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ! '>='
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ! '>='
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
requirements: []
|
174
|
+
rubyforge_project: browsermob-proxy-rb
|
175
|
+
rubygems_version: 2.0.3
|
176
|
+
signing_key:
|
177
|
+
specification_version: 4
|
178
|
+
summary: Ruby client for the BrowserMob Proxy REST API
|
179
|
+
test_files:
|
180
|
+
- spec/e2e/listener_spec.rb
|
181
|
+
- spec/e2e/selenium_spec.rb
|
182
|
+
- spec/fixtures/1.html
|
183
|
+
- spec/fixtures/2.html
|
184
|
+
- spec/fixtures/3.html
|
185
|
+
- spec/fixtures/google.har
|
186
|
+
- spec/spec_helper.rb
|
187
|
+
- spec/unit/client_spec.rb
|
188
|
+
- spec/unit/webdriver_listener_spec.rb
|