browsermob-proxy 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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