phantom_menace 0.0.1 → 0.0.2

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.
@@ -0,0 +1,7 @@
1
+ require 'autotest/restart'
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.add_mapping(/.*/) do |f, _|
5
+ at.files_matching(/.*.rb$/)
6
+ end
7
+ end
data/.rspec ADDED
File without changes
@@ -0,0 +1,9 @@
1
+ ## 0.0.2 (2012-06-10)
2
+
3
+ * Added Browser#find
4
+ * Added Browser#render
5
+
6
+ ## 0.0.1 (2012-06-08)
7
+
8
+ * First release
9
+ * Browser has methods #find_all_links and #goto
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # phantom-menace
1
+ # phantom_menace
2
2
 
3
3
  A real headless "browser." It uses phantomjs and provides an API like a
4
4
  real browser does. Much like poltergeist but decoupled from capybara.
@@ -11,7 +11,7 @@ It is perfect for scraping or doing any browser related tasks.
11
11
  ## Install
12
12
 
13
13
  ```sh
14
- gem install phantom-menace
14
+ gem install phantom_menace
15
15
  ```
16
16
 
17
17
  ## Getting Started
@@ -43,3 +43,30 @@ When the server is running, run the example by doing.
43
43
  ```sh
44
44
  bundle exec ruby examples/simple.rb
45
45
  ```
46
+
47
+ ## Running The Tests
48
+
49
+ Unfortunately, we still don't have an automated test suite to run the
50
+ different services.
51
+
52
+ We have to run three things.
53
+
54
+ 1. The `phantom_menace` binary
55
+
56
+ ```sh
57
+ bundle exec ./bin/phantom_menace
58
+ ```
59
+
60
+ 2. The sinatra test server - This serves the files needed for the tests
61
+ instead of hitting third party sites. This ensures that we can run
62
+ the tests without internet.
63
+
64
+ ```sh
65
+ bundle exec ruby ./spec/test_server/server.rb
66
+ ```
67
+
68
+ 3. Finally we can run the specs
69
+
70
+ ```sh
71
+ bundle exec rake spec
72
+ ```
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ desc "Run all specs"
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ desc "Default: run specs."
9
+ task default: :spec
@@ -1,17 +1,6 @@
1
1
  USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) ' +
2
2
  'AppleWebKit/A.B (KHTML, like Gecko) Chrome/X.Y.Z.W Safari/A.B.'
3
3
 
4
- class Page
5
- constructor: ->
6
- @_loaded = false
7
- @_page = require('webpage').create()
8
-
9
- open: (url) ->
10
- @_page.open url
11
-
12
- isLoaded: ->
13
- @_loaded
14
-
15
4
  class Browser
16
5
  constructor: ->
17
6
  # This is the response container
@@ -26,36 +15,32 @@ class Browser
26
15
  click: (left, top) ->
27
16
  @page.sendEvent left, top
28
17
 
29
- find: (selector) ->
18
+ find: (data) ->
30
19
  console.log 'Finding it'
31
-
32
- ret = @page.evaluate ->
20
+ onEvaluate = (eArgs) ->
33
21
  elements = []
34
- jQuery('a').each (i, obj) ->
22
+ jQuery(eArgs.selector).each (i, obj) ->
35
23
  attrs = {}
36
24
  attrs[attr.name] = attr.value for attr in obj.attributes
37
-
38
25
  elements.push
39
26
  attrs: attrs
40
27
  text: jQuery(obj).text()
41
28
  pos: jQuery(obj).offset()
42
29
  elements
43
30
 
31
+ ret = @page.evaluate(onEvaluate, { selector: data.selector })
32
+
44
33
  @resp =
45
34
  success: true
46
35
  ret: ret
47
36
 
48
37
  @state = 'default'
49
38
 
50
-
51
- findAll: ->
52
- console.log 'Finding all'
53
-
54
39
  goforward: ->
55
40
  console.log 'Going forward a page'
56
41
 
57
- goto: (url) ->
58
- @page.open decodeURIComponent(url)
42
+ goto: (data) ->
43
+ @page.open decodeURIComponent(data.url)
59
44
 
60
45
  goback: ->
61
46
  this.goto @history.pop
@@ -66,8 +51,10 @@ class Browser
66
51
  reload: ->
67
52
  this.goto @history[@history.length - 1]
68
53
 
69
- render: ->
70
- @page.render()
54
+ render: (data) ->
55
+ @page.render(data.filename)
56
+ @resp = success: true
57
+ @state = 'default'
71
58
 
72
59
  content: ->
73
60
  @page.content
@@ -118,23 +105,21 @@ class Server
118
105
  @server.listen 8080, this._handleRequest
119
106
 
120
107
  _handleRequest: (req, res) =>
121
- params = req.post
108
+ params = JSON.parse(req.post.payload)
122
109
 
123
110
  if @browser[params.command]
124
111
  @browser.runCommand(params.command, params.data)
125
112
  this._runLoop(req, res)
126
113
  else
127
114
  res.statusCode = 200
128
- res.write JSON.stringify({
115
+ res.write JSON.stringify
129
116
  success: false
130
117
  message: "Command not found"
131
- })
132
118
  res.close()
133
119
 
134
120
  _runLoop: (req, res) =>
135
121
  setTimeout =>
136
122
  console.log 'THE STATE: ' + @browser.state
137
-
138
123
  if @browser.state is 'loading'
139
124
  this._runLoop(req, res)
140
125
  else if @browser.state is 'default'
@@ -3,28 +3,65 @@ require "uri"
3
3
  require "json"
4
4
 
5
5
  module PhantomMenace
6
+ # PhantomMenace::Browser
7
+ #
8
+ # Creates a Browser that you can interact with. Exposes methods like
9
+ # how you would find a real browser.
10
+ #
11
+ # == Example
12
+ #
13
+ # browser = PhantomMenace::Browser.new
14
+ # browser.goto "http://facebook.com"
15
+ #
16
+ # Look at the API for more methods.
6
17
  class Browser
18
+ # Navigates to the specified URL.
7
19
  def goto(url)
8
20
  options = {
9
21
  command: "goto",
10
- data: url
22
+ data: { url: url }
11
23
  }
12
24
  post(options)
13
25
  end
14
26
 
15
27
  def find_all_links
16
28
  options = {
17
- command: "find"
29
+ command: "find",
30
+ data: { selector: "a" }
18
31
  }
19
32
  post(options)["ret"].map do |node|
20
33
  PhantomMenace::Element.new(node)
21
34
  end
22
35
  end
23
36
 
37
+ # Uses jQuery's selector method. `$(sel)`
38
+ def find(sel)
39
+ options = {
40
+ command: "find",
41
+ data: { selector: sel }
42
+ }
43
+ post(options)["ret"].map do |node|
44
+ PhantomMenace::Element.new(node)
45
+ end
46
+ end
47
+
48
+ # Renders the loaded page in the specified path,
49
+ # if path is not given, defaults to the current
50
+ # directory.
51
+ def render(filename = nil)
52
+ filename ||= File.expand_path("../", __FILE__) + "/screenshot.png"
53
+ options = {
54
+ command: "render",
55
+ data: { filename: filename }
56
+ }
57
+ post(options)
58
+ end
59
+
24
60
  private
25
61
 
26
62
  def post(options)
27
- req = Net::HTTP.post_form(URI.parse(URL), options)
63
+ data = { payload: options.to_json }
64
+ req = Net::HTTP.post_form(URI.parse(URL), data)
28
65
  JSON.parse(req.body)
29
66
  end
30
67
  end
@@ -1,3 +1,3 @@
1
1
  module PhantomMenace
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -18,4 +18,6 @@ Gem::Specification.new do |gem|
18
18
  gem.add_development_dependency "rspec"
19
19
  gem.add_development_dependency "rake"
20
20
  gem.add_development_dependency "phantomjs.rb"
21
+ gem.add_development_dependency "ZenTest"
22
+ gem.add_development_dependency "sinatra"
21
23
  end
@@ -1,5 +1,7 @@
1
1
  require 'phantom_menace'
2
2
 
3
+ TEST_URL = "http://localhost:4567/index.html"
4
+
3
5
  describe PhantomMenace::Browser do
4
6
  before do
5
7
  @browser = PhantomMenace::Browser.new
@@ -7,16 +9,38 @@ describe PhantomMenace::Browser do
7
9
 
8
10
  describe "#goto" do
9
11
  it "responds with success if page opens successfully" do
10
- resp = @browser.goto "http://google.com"
12
+ resp = @browser.goto TEST_URL
11
13
  resp["success"].should == true
12
14
  end
13
15
  end
14
16
 
15
17
  describe "#find_all_links" do
16
18
  it "responds with the links in the page" do
17
- @browser.goto "http://google.com"
19
+ @browser.goto TEST_URL
18
20
  resp = @browser.find_all_links
19
- resp.length.should_not be(0)
21
+ resp.length.should_not == 0
22
+ end
23
+ end
24
+
25
+ describe "#find" do
26
+ it "responds with the element found" do
27
+ @browser.goto TEST_URL
28
+ resp = @browser.find('#first_div')
29
+ resp.length.should_not == 0
30
+ end
31
+
32
+ it "responds with a blank array if nothing found" do
33
+ @browser.goto TEST_URL
34
+ resp = @browser.find('.non-existing-class')
35
+ resp.should be_empty
36
+ end
37
+ end
38
+
39
+ describe "#render" do
40
+ it "saves the file in the path specified" do
41
+ @browser.goto TEST_URL
42
+ resp = @browser.render
43
+ resp["success"].should == true
20
44
  end
21
45
  end
22
46
  end
@@ -0,0 +1,10 @@
1
+ # Test Server
2
+
3
+ The test server is a sinatra based server that serves static files
4
+ needed by the tests.
5
+
6
+ ## Running
7
+
8
+ ```sh
9
+ bundle exec ruby server.rb
10
+ ```
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Hello World</title>
5
+ </head>
6
+ <body>
7
+ <h1>Hello World</h1>
8
+ <a href="/first_link_href.html">The First Text</a>
9
+ <div id="first_div">I am the first div</div>
10
+ </body>
11
+ </html>
@@ -0,0 +1 @@
1
+ require "sinatra"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phantom_menace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-08 00:00:00.000000000 Z
12
+ date: 2012-06-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -59,6 +59,38 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: ZenTest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sinatra
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
62
94
  description: Ruby Wrapper for Phantomjs with a Browser API
63
95
  email:
64
96
  - william.estoque@gmail.com
@@ -69,7 +101,10 @@ executables:
69
101
  extensions: []
70
102
  extra_rdoc_files: []
71
103
  files:
104
+ - .autotest
72
105
  - .gitignore
106
+ - .rspec
107
+ - CHANGELOG.md
73
108
  - Gemfile
74
109
  - LICENSE
75
110
  - README.md
@@ -84,6 +119,9 @@ files:
84
119
  - lib/phantom_menace/version.rb
85
120
  - phantom_menace.gemspec
86
121
  - spec/browser_spec.rb
122
+ - spec/test_server/README.md
123
+ - spec/test_server/public/index.html
124
+ - spec/test_server/server.rb
87
125
  homepage: ''
88
126
  licenses: []
89
127
  post_install_message:
@@ -96,18 +134,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
134
  - - ! '>='
97
135
  - !ruby/object:Gem::Version
98
136
  version: '0'
99
- segments:
100
- - 0
101
- hash: -1323133816147866598
102
137
  required_rubygems_version: !ruby/object:Gem::Requirement
103
138
  none: false
104
139
  requirements:
105
140
  - - ! '>='
106
141
  - !ruby/object:Gem::Version
107
142
  version: '0'
108
- segments:
109
- - 0
110
- hash: -1323133816147866598
111
143
  requirements: []
112
144
  rubyforge_project:
113
145
  rubygems_version: 1.8.24
@@ -116,3 +148,6 @@ specification_version: 3
116
148
  summary: Phantomjs based browser with a ruby wrapper
117
149
  test_files:
118
150
  - spec/browser_spec.rb
151
+ - spec/test_server/README.md
152
+ - spec/test_server/public/index.html
153
+ - spec/test_server/server.rb