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.
- data/.autotest +7 -0
- data/.rspec +0 -0
- data/CHANGELOG.md +9 -0
- data/README.md +29 -2
- data/Rakefile +7 -0
- data/bin/phantom_menace.coffee +13 -28
- data/lib/phantom_menace/browser.rb +40 -3
- data/lib/phantom_menace/version.rb +1 -1
- data/phantom_menace.gemspec +2 -0
- data/spec/browser_spec.rb +27 -3
- data/spec/test_server/README.md +10 -0
- data/spec/test_server/public/index.html +11 -0
- data/spec/test_server/server.rb +1 -0
- metadata +43 -8
data/.autotest
ADDED
data/.rspec
ADDED
File without changes
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
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
|
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
data/bin/phantom_menace.coffee
CHANGED
@@ -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: (
|
18
|
+
find: (data) ->
|
30
19
|
console.log 'Finding it'
|
31
|
-
|
32
|
-
ret = @page.evaluate ->
|
20
|
+
onEvaluate = (eArgs) ->
|
33
21
|
elements = []
|
34
|
-
jQuery(
|
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: (
|
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
|
-
|
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
|
data/phantom_menace.gemspec
CHANGED
data/spec/browser_spec.rb
CHANGED
@@ -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
|
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
|
19
|
+
@browser.goto TEST_URL
|
18
20
|
resp = @browser.find_all_links
|
19
|
-
resp.length.should_not
|
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 @@
|
|
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.
|
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-
|
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
|