browsermob-proxy 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -6,6 +6,8 @@ Ruby client for the BrowserMob Proxy 2.0 REST API.
6
6
  How to use with selenium-webdriver
7
7
  ----------------------------------
8
8
 
9
+ Manually:
10
+
9
11
  ``` ruby
10
12
  require 'selenium/webdriver'
11
13
  require 'browsermob/proxy'
@@ -16,21 +18,48 @@ server.start
16
18
  proxy = server.create_proxy #=> #<BrowserMob::Proxy::Client:0x0000010224bdc0 ...>
17
19
 
18
20
  profile = Selenium::WebDriver::Firefox::Profile.new #=> #<Selenium::WebDriver::Firefox::Profile:0x000001022bf748 ...>
19
- profile.proxy = client.selenium_proxy
21
+ profile.proxy = proxy.selenium_proxy
20
22
 
21
23
  driver = Selenium::WebDriver.for :firefox, :profile => profile
22
24
 
23
- proxy.new_har("google")
25
+ proxy.new_har "google"
24
26
  driver.get "http://google.com"
25
27
 
26
28
  har = proxy.har #=> #<HAR::Archive:0x-27066c42d7e75fa6>
27
- har.entries.first.request.url
29
+ har.entries.first.request.url #=> "http://google.com"
28
30
  har.save_to "/tmp/google.har"
29
31
 
30
32
  proxy.close
31
33
  driver.quit
32
34
  ```
33
35
 
36
+ With event listener:
37
+
38
+ ``` ruby
39
+ require 'selenium/webdriver'
40
+ require 'browsermob/proxy'
41
+ require 'browsermob/proxy/webdriver_listener'
42
+
43
+ # start server, set up proxy like above
44
+ proxy_listener = BrowserMob::Proxy::WebDriverListener.new(proxy)
45
+
46
+ driver = Selenium::WebDriver.for :firefox, :profile => profile, :listener => proxy_listener
47
+ # use driver
48
+ driver.quit
49
+
50
+ listener.hars #=> [#<HAR::Archive:0x-27066c42d7e75fa6>, #<HAR::Archive:0x-d7e75fa627066c42>]
51
+ proxy.close
52
+
53
+ ```
54
+
55
+
56
+ Viewing HARs
57
+ ------------
58
+
59
+ The HAR gem includes a HAR viewer. After running the code above, you can view the saved HAR by running
60
+
61
+ $ har /tmp/google.har
62
+
34
63
 
35
64
  See also
36
65
  --------
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency "har"
21
21
 
22
22
  s.add_development_dependency "rspec", ">= 2.5.0"
23
- s.add_development_dependency "selenium-webdriver", ">= 2.0.0"
23
+ s.add_development_dependency "selenium-webdriver", "~> 2.7"
24
24
 
25
25
  s.files = `git ls-files`.split("\n")
26
26
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -2,6 +2,8 @@ module BrowserMob
2
2
  module Proxy
3
3
 
4
4
  class Client
5
+ attr_reader :host, :port
6
+
5
7
  def self.from(server_url)
6
8
  port = JSON.parse(
7
9
  RestClient.post(URI.join(server_url, "proxy").to_s, '')
@@ -23,7 +25,7 @@ module BrowserMob
23
25
  previous = @resource["har"].put :initialPageRef => ref
24
26
  HAR::Archive.from_string(previous) unless previous.empty?
25
27
  end
26
-
28
+
27
29
  def new_page(ref)
28
30
  @resource['har/pageRef'].put :pageRef => ref
29
31
  end
@@ -37,6 +39,16 @@ module BrowserMob
37
39
  Selenium::WebDriver::Proxy.new(:http => "#{@host}:#{@port}")
38
40
  end
39
41
 
42
+ def whitelist(regexp, status_code)
43
+ regex = Regexp === regexp ? regexp.source : regexp.to_s
44
+ @resource['har/whitelist'].put :regex => regex, :status => status_code
45
+ end
46
+
47
+ def blacklist(regexp, status_code)
48
+ regex = Regexp === regexp ? regexp.source : regexp.to_s
49
+ @resource['har/blacklist'].put :regex => regex, :status => status_code
50
+ end
51
+
40
52
  def close
41
53
  @resource.delete
42
54
  end
@@ -27,6 +27,9 @@ module BrowserMob
27
27
  @process.start
28
28
  sleep 0.1 until listening?
29
29
 
30
+ pid = Process.pid
31
+ at_exit { stop if Process.pid == pid }
32
+
30
33
  self
31
34
  end
32
35
 
@@ -39,17 +42,7 @@ module BrowserMob
39
42
  end
40
43
 
41
44
  def stop
42
- return unless @process.alive?
43
-
44
- begin
45
- @process.poll_for_exit(5)
46
- rescue ChildProcess::TimeoutError
47
- @process.stop
48
- end
49
- rescue Errno::ECHILD
50
- # already dead
51
- ensure
52
- @process = nil
45
+ @process.stop if @process.alive?
53
46
  end
54
47
 
55
48
  private
@@ -1,5 +1,5 @@
1
1
  module BrowserMob
2
2
  module Proxy
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -0,0 +1,67 @@
1
+ require 'selenium/webdriver/support'
2
+
3
+ module BrowserMob
4
+ module Proxy
5
+
6
+ #
7
+ # WebDriver event listener that assumes the following:
8
+ #
9
+ # driver.get - new HAR
10
+ # driver.click - new page
11
+ # driver.navigate.back - new page
12
+ # driver.navigate.forward - new page
13
+ #
14
+
15
+ class WebDriverListener < Selenium::WebDriver::Support::AbstractEventListener
16
+ attr_reader :hars
17
+
18
+ def initialize(client)
19
+ @client = client
20
+ @hars = []
21
+ end
22
+
23
+ def reset
24
+ @hars.clear
25
+ end
26
+
27
+ def before_navigate_to(url, driver)
28
+ save_har unless @hars.empty? # first request
29
+ @client.new_har("navigate-to-#{url}")
30
+ end
31
+
32
+ def before_navigate_back(driver = nil)
33
+ name = "navigate-back"
34
+ name << "-from-#{driver.current_url}" if driver
35
+
36
+ @client.new_page name
37
+ end
38
+
39
+ def before_navigate_forward(driver = nil)
40
+ name = "navigate-forward"
41
+ name << "-from-#{driver.current_url}" if driver
42
+
43
+ @client.new_page name
44
+ end
45
+
46
+ def before_click(element, driver)
47
+ name = "click-element-#{identifier_for element}"
48
+ @client.new_page name
49
+ end
50
+
51
+ def before_quit(driver)
52
+ save_har
53
+ end
54
+
55
+ private
56
+
57
+ def save_har
58
+ @hars << @client.har
59
+ end
60
+
61
+ def identifier_for(element)
62
+ # can be ovverriden to provide more meaningful info
63
+ element.ref
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Proxy + WebDriverListener" do
4
+ let(:wait) { Selenium::WebDriver::Wait.new }
5
+ let(:listener) { BrowserMob::Proxy::WebDriverListener.new(proxy) }
6
+ let(:driver) { Selenium::WebDriver.for :firefox, :profile => profile, :listener => listener }
7
+ let(:proxy) { new_proxy }
8
+
9
+ let(:profile) {
10
+ pr = Selenium::WebDriver::Firefox::Profile.new
11
+ pr.proxy = proxy.selenium_proxy
12
+
13
+ pr
14
+ }
15
+
16
+ after {
17
+ proxy.close
18
+ }
19
+
20
+ it "should record events" do
21
+ driver.get url_for("1.html")
22
+ driver.find_element(:link_text => "2").click
23
+ driver.quit
24
+
25
+ hars = listener.hars
26
+ hars.size.should == 1
27
+
28
+ hars.first.pages.size.should == 2
29
+
30
+ hars.each_with_index { |e,i| e.save_to("/tmp/#{i}.har") }
31
+ end
32
+ end
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  describe "Proxy + WebDriver" do
4
4
  let(:driver) { Selenium::WebDriver.for :firefox, :profile => profile }
5
5
  let(:proxy) { new_proxy }
6
+
6
7
  let(:profile) {
7
8
  pr = Selenium::WebDriver::Firefox::Profile.new
8
9
  pr.proxy = proxy.selenium_proxy
@@ -10,16 +11,21 @@ describe "Proxy + WebDriver" do
10
11
  pr
11
12
  }
12
13
 
13
- after { driver.quit }
14
- after { proxy.close }
14
+ after {
15
+ driver.quit
16
+ proxy.close
17
+ }
15
18
 
16
19
  it "should fetch a HAR" do
17
- proxy.new_har
18
- driver.get "http://google.com"
20
+ proxy.new_har("1")
21
+ driver.get url_for("1.html")
22
+
23
+ proxy.new_page "2"
24
+ driver.get url_for("2.html")
19
25
 
20
26
  har = proxy.har
21
27
 
22
28
  har.should be_kind_of(HAR::Archive)
23
- har.pages.size.should == 1
29
+ har.pages.size.should == 2
24
30
  end
25
31
  end
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>1</title>
6
+ </head>
7
+ <body>
8
+ <a href="2.html">2</a>
9
+ </body>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>2</title>
6
+ </head>
7
+ <body>
8
+
9
+ </body>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Page Title</title>
6
+ </head>
7
+ <body>
8
+
9
+ </body>
10
+ </html>
@@ -1,5 +1,6 @@
1
1
  require 'browsermob/proxy'
2
2
  require 'selenium-webdriver'
3
+ require 'browsermob/proxy/webdriver_listener'
3
4
 
4
5
  RestClient.log = STDOUT
5
6
 
@@ -19,7 +20,15 @@ module BrowserMob
19
20
  end
20
21
 
21
22
  def fixture(name)
22
- File.read(File.join(File.expand_path("../", __FILE__), "fixtures", name))
23
+ File.read(fixture_path(name))
24
+ end
25
+
26
+ def url_for(page)
27
+ "file://#{fixture_path page}"
28
+ end
29
+
30
+ def fixture_path(name)
31
+ File.join(File.expand_path("../", __FILE__), "fixtures", name)
23
32
  end
24
33
 
25
34
  end
@@ -6,36 +6,60 @@ module BrowserMob
6
6
  describe Client do
7
7
  let(:resource) { mock(RestClient::Resource) }
8
8
  let(:client) { Client.new(resource, "localhost", 9091) }
9
- let(:har_resource) { mock("resource[har]") }
10
- let(:page_ref_resource) { mock("resource[har/pageRef]") }
11
9
 
12
10
  before do
13
- resource.stub!(:[]).with("har").and_return(har_resource)
14
- resource.stub!(:[]).with("har/pageRef").and_return(page_ref_resource)
11
+ {
12
+ "har" => mock("resource[har]"),
13
+ "har/pageRef" => mock("resource[har/pageRef]"),
14
+ "har/whitelist" => mock("resource[har/whitelist]"),
15
+ "har/blacklist" => mock("resource[har/blacklist]")
16
+ }.each do |path, mock|
17
+ resource.stub!(:[]).with(path).and_return(mock)
18
+ end
15
19
  end
16
20
 
17
21
  it "creates a new har" do
18
- har_resource.should_receive(:put).with(:initialPageRef => "foo").and_return('')
22
+ resource['har'].should_receive(:put).
23
+ with(:initialPageRef => "foo").
24
+ and_return('')
19
25
 
20
26
  client.new_har("foo").should be_nil
21
27
  end
22
28
 
23
29
  it "returns the previous archive if one exists" do
24
- har_resource.should_receive(:put).with(:initialPageRef => "foo").and_return(fixture("google.har"))
30
+ resource['har'].should_receive(:put).
31
+ with(:initialPageRef => "foo").
32
+ and_return(fixture("google.har"))
25
33
 
26
34
  client.new_har("foo").should be_kind_of(HAR::Archive)
27
35
  end
28
36
 
29
37
  it "gets the current har" do
30
- har_resource.should_receive(:get).and_return(fixture("google.har"))
38
+ resource['har'].should_receive(:get).
39
+ and_return(fixture("google.har"))
31
40
 
32
41
  client.har.should be_kind_of(HAR::Archive)
33
42
  end
34
-
43
+
35
44
  it "creates a new page" do
36
- page_ref_resource.should_receive(:put).with :pageRef => "foo"
37
-
38
- client.new_page("foo")
45
+ resource['har/pageRef'].should_receive(:put).
46
+ with :pageRef => "foo"
47
+
48
+ client.new_page "foo"
49
+ end
50
+
51
+ it "sets the blacklist" do
52
+ resource['har/blacklist'].should_receive(:put).
53
+ with(:regex => "http://example.com", :status => 401)
54
+
55
+ client.blacklist(%r[http://example.com], 401)
56
+ end
57
+
58
+ it "sets the whitelist" do
59
+ resource['har/whitelist'].should_receive(:put).
60
+ with(:regex => "http://example.com", :status => 401)
61
+
62
+ client.whitelist(%r[http://example.com], 401)
39
63
  end
40
64
  end
41
65
 
@@ -0,0 +1,49 @@
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
+
13
+ it 'creates a new har on navigate.to' do
14
+ url = "http://example.com"
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
+ end
48
+ end
49
+ end
metadata CHANGED
@@ -1,93 +1,89 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: browsermob-proxy
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
4
5
  prerelease:
5
- version: 0.0.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - jari.bakken
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-07-15 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: rest-client
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2161286300 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
24
22
  type: :runtime
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: childprocess
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2161286300
25
+ - !ruby/object:Gem::Dependency
26
+ name: childprocess
27
+ requirement: &2161279940 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
35
33
  type: :runtime
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: json
39
34
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2161279940
36
+ - !ruby/object:Gem::Dependency
37
+ name: json
38
+ requirement: &2161263620 !ruby/object:Gem::Requirement
41
39
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
46
44
  type: :runtime
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: har
50
45
  prerelease: false
51
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2161263620
47
+ - !ruby/object:Gem::Dependency
48
+ name: har
49
+ requirement: &2161262300 !ruby/object:Gem::Requirement
52
50
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
57
55
  type: :runtime
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
60
- name: rspec
61
56
  prerelease: false
62
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *2161262300
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &2161259040 !ruby/object:Gem::Requirement
63
61
  none: false
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
67
65
  version: 2.5.0
68
66
  type: :development
69
- version_requirements: *id005
70
- - !ruby/object:Gem::Dependency
71
- name: selenium-webdriver
72
67
  prerelease: false
73
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *2161259040
69
+ - !ruby/object:Gem::Dependency
70
+ name: selenium-webdriver
71
+ requirement: &2161253700 !ruby/object:Gem::Requirement
74
72
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- version: 2.0.0
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: '2.7'
79
77
  type: :development
80
- version_requirements: *id006
78
+ prerelease: false
79
+ version_requirements: *2161253700
81
80
  description: Ruby client for the BrowserMob Proxy REST API
82
- email:
81
+ email:
83
82
  - jari.bakken@gmail.com
84
83
  executables: []
85
-
86
84
  extensions: []
87
-
88
85
  extra_rdoc_files: []
89
-
90
- files:
86
+ files:
91
87
  - .gitignore
92
88
  - Gemfile
93
89
  - LICENSE
@@ -99,39 +95,47 @@ files:
99
95
  - lib/browsermob/proxy/client.rb
100
96
  - lib/browsermob/proxy/server.rb
101
97
  - lib/browsermob/proxy/version.rb
98
+ - lib/browsermob/proxy/webdriver_listener.rb
99
+ - spec/e2e/listener_spec.rb
102
100
  - spec/e2e/selenium_spec.rb
101
+ - spec/fixtures/1.html
102
+ - spec/fixtures/2.html
103
+ - spec/fixtures/3.html
103
104
  - spec/fixtures/google.har
104
105
  - spec/spec_helper.rb
105
106
  - spec/unit/client_spec.rb
107
+ - spec/unit/webdriver_listener_spec.rb
106
108
  homepage: http://github.com/jarib/browsermob-proxy-rb
107
109
  licenses: []
108
-
109
110
  post_install_message:
110
111
  rdoc_options: []
111
-
112
- require_paths:
112
+ require_paths:
113
113
  - lib
114
- required_ruby_version: !ruby/object:Gem::Requirement
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
115
  none: false
116
- requirements:
117
- - - ">="
118
- - !ruby/object:Gem::Version
119
- version: "0"
120
- required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  none: false
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: "0"
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
126
  requirements: []
127
-
128
127
  rubyforge_project: browsermob-proxy-rb
129
- rubygems_version: 1.8.5
128
+ rubygems_version: 1.8.10
130
129
  signing_key:
131
130
  specification_version: 3
132
131
  summary: Ruby client for the BrowserMob Proxy REST API
133
- test_files:
132
+ test_files:
133
+ - spec/e2e/listener_spec.rb
134
134
  - spec/e2e/selenium_spec.rb
135
+ - spec/fixtures/1.html
136
+ - spec/fixtures/2.html
137
+ - spec/fixtures/3.html
135
138
  - spec/fixtures/google.har
136
139
  - spec/spec_helper.rb
137
140
  - spec/unit/client_spec.rb
141
+ - spec/unit/webdriver_listener_spec.rb