poltergeist 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +22 -1
- data/lib/capybara/poltergeist/browser.rb +6 -1
- data/lib/capybara/poltergeist/client.rb +8 -2
- data/lib/capybara/poltergeist/client/agent.coffee +15 -6
- data/lib/capybara/poltergeist/client/browser.coffee +10 -1
- data/lib/capybara/poltergeist/client/compiled/agent.js +40 -20
- data/lib/capybara/poltergeist/client/compiled/browser.js +14 -1
- data/lib/capybara/poltergeist/client/compiled/main.js +18 -1
- data/lib/capybara/poltergeist/client/compiled/web_page.js +9 -4
- data/lib/capybara/poltergeist/client/main.coffee +6 -1
- data/lib/capybara/poltergeist/client/web_page.coffee +7 -4
- data/lib/capybara/poltergeist/driver.rb +4 -0
- data/lib/capybara/poltergeist/errors.rb +11 -0
- data/lib/capybara/poltergeist/version.rb +1 -1
- metadata +9 -9
data/README.md
CHANGED
@@ -9,7 +9,7 @@ provided by [PhantomJS](http://www.phantomjs.org/).
|
|
9
9
|
**If you're viewing this at https://github.com/jonleighton/poltergeist,
|
10
10
|
you're reading the documentation for the master branch.
|
11
11
|
[View documentation for the latest release
|
12
|
-
(1.
|
12
|
+
(1.3.0).](https://github.com/jonleighton/poltergeist/tree/v1.3.0)**
|
13
13
|
|
14
14
|
## Getting help ##
|
15
15
|
|
@@ -324,6 +324,20 @@ Include as much information as possible. For example:
|
|
324
324
|
|
325
325
|
## Changes ##
|
326
326
|
|
327
|
+
### 1.3.0 ###
|
328
|
+
|
329
|
+
#### Features ####
|
330
|
+
|
331
|
+
* Add support for PhantomJS 1.7's `cookiesEnabled` API
|
332
|
+
(Micah Frost)
|
333
|
+
|
334
|
+
#### Bug fixes ####
|
335
|
+
|
336
|
+
* Fix logging of mouse event co-ordinates
|
337
|
+
* Invalid selectors throw a useful error message
|
338
|
+
* Tie us to the 0.4 version of faye-websocket since the 0.5 version
|
339
|
+
contains breaking changes.
|
340
|
+
|
327
341
|
### 1.2.0 ###
|
328
342
|
|
329
343
|
#### Features ####
|
@@ -341,6 +355,13 @@ Include as much information as possible. For example:
|
|
341
355
|
* Run phantomjs in a new process group so ^C doesn't trigger a
|
342
356
|
DeadClient error [Issue #252]
|
343
357
|
|
358
|
+
### 1.1.1 ###
|
359
|
+
|
360
|
+
#### Features ####
|
361
|
+
|
362
|
+
* Changed Capybara dependency to `~> 2.0.1` because Poltergeist 1.1 is
|
363
|
+
not compatible with Capybara 2.1.
|
364
|
+
|
344
365
|
### 1.1.0 ###
|
345
366
|
|
346
367
|
#### Features ####
|
@@ -6,7 +6,8 @@ module Capybara::Poltergeist
|
|
6
6
|
class Browser
|
7
7
|
ERROR_MAPPINGS = {
|
8
8
|
"Poltergeist.JavascriptError" => JavascriptError,
|
9
|
-
"Poltergeist.FrameNotFound" => FrameNotFound
|
9
|
+
"Poltergeist.FrameNotFound" => FrameNotFound,
|
10
|
+
"Poltergeist.InvalidSelector" => InvalidSelector
|
10
11
|
}
|
11
12
|
|
12
13
|
attr_reader :server, :client, :logger
|
@@ -197,6 +198,10 @@ module Capybara::Poltergeist
|
|
197
198
|
command 'remove_cookie', name
|
198
199
|
end
|
199
200
|
|
201
|
+
def cookies_enabled=(flag)
|
202
|
+
command 'cookies_enabled', !!flag
|
203
|
+
end
|
204
|
+
|
200
205
|
def js_errors=(val)
|
201
206
|
command 'set_js_errors', !!val
|
202
207
|
end
|
@@ -88,8 +88,14 @@ module Capybara::Poltergeist
|
|
88
88
|
|
89
89
|
if version.nil? || $? != 0
|
90
90
|
raise PhantomJSFailed.new($?)
|
91
|
-
|
92
|
-
|
91
|
+
else
|
92
|
+
major, minor, build = version.chomp.split('.').map(&:to_i)
|
93
|
+
min_major, min_minor, min_build = PHANTOMJS_VERSION.split('.').map(&:to_i)
|
94
|
+
if major < min_major ||
|
95
|
+
major == min_major && minor < min_minor ||
|
96
|
+
major == min_major && minor == min_minor && build < min_build
|
97
|
+
raise PhantomJSTooOld.new(version)
|
98
|
+
end
|
93
99
|
end
|
94
100
|
|
95
101
|
@phantomjs_version_checked = true
|
@@ -28,13 +28,19 @@ class PoltergeistAgent
|
|
28
28
|
window.location.toString()
|
29
29
|
|
30
30
|
find: (method, selector, within = document) ->
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
try
|
32
|
+
if method == "xpath"
|
33
|
+
xpath = document.evaluate(selector, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
|
34
|
+
results = (xpath.snapshotItem(i) for i in [0...xpath.snapshotLength])
|
35
|
+
else
|
36
|
+
results = within.querySelectorAll(selector)
|
36
37
|
|
37
|
-
|
38
|
+
this.register(el) for el in results
|
39
|
+
catch error
|
40
|
+
if error.code == DOMException.SYNTAX_ERR
|
41
|
+
throw new PoltergeistAgent.InvalidSelector
|
42
|
+
else
|
43
|
+
throw error
|
38
44
|
|
39
45
|
register: (element) ->
|
40
46
|
@elements.push(element)
|
@@ -61,6 +67,9 @@ class PoltergeistAgent
|
|
61
67
|
class PoltergeistAgent.ObsoleteNode
|
62
68
|
toString: -> "PoltergeistAgent.ObsoleteNode"
|
63
69
|
|
70
|
+
class PoltergeistAgent.InvalidSelector
|
71
|
+
toString: -> "PoltergeistAgent.InvalidSelector"
|
72
|
+
|
64
73
|
class PoltergeistAgent.Node
|
65
74
|
@EVENTS = {
|
66
75
|
FOCUS: ['blur', 'focus', 'focusin', 'focusout'],
|
@@ -26,7 +26,7 @@ class Poltergeist.Browser
|
|
26
26
|
|
27
27
|
@page.onLoadFinished = (status) =>
|
28
28
|
if @state == 'loading'
|
29
|
-
this.sendResponse(status: status,
|
29
|
+
this.sendResponse(status: status, position: @last_mouse_event)
|
30
30
|
this.setState 'default'
|
31
31
|
else if @state == 'awaiting_frame_load'
|
32
32
|
this.sendResponse(true)
|
@@ -47,11 +47,16 @@ class Poltergeist.Browser
|
|
47
47
|
# window.
|
48
48
|
setTimeout((=> this.push_window(name)), 0)
|
49
49
|
|
50
|
+
runCommand: (name, args) ->
|
51
|
+
this.setState "default"
|
52
|
+
this[name].apply(this, args)
|
53
|
+
|
50
54
|
debug: (message) ->
|
51
55
|
if @_debug
|
52
56
|
console.log "poltergeist [#{new Date().getTime()}] #{message}"
|
53
57
|
|
54
58
|
setState: (state) ->
|
59
|
+
return if @state == state
|
55
60
|
this.debug "state #{@state} -> #{state}"
|
56
61
|
@state = state
|
57
62
|
|
@@ -280,6 +285,10 @@ class Poltergeist.Browser
|
|
280
285
|
@page.deleteCookie(name)
|
281
286
|
this.sendResponse(true)
|
282
287
|
|
288
|
+
cookies_enabled: (flag) ->
|
289
|
+
phantom.cookiesEnabled = flag
|
290
|
+
this.sendResponse(true)
|
291
|
+
|
283
292
|
set_js_errors: (value) ->
|
284
293
|
@js_errors = value
|
285
294
|
this.sendResponse(true)
|
@@ -50,31 +50,40 @@ PoltergeistAgent = (function() {
|
|
50
50
|
};
|
51
51
|
|
52
52
|
PoltergeistAgent.prototype.find = function(method, selector, within) {
|
53
|
-
var el, i, results, xpath, _i, _len, _results;
|
53
|
+
var el, error, i, results, xpath, _i, _len, _results;
|
54
54
|
|
55
55
|
if (within == null) {
|
56
56
|
within = document;
|
57
57
|
}
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
58
|
+
try {
|
59
|
+
if (method === "xpath") {
|
60
|
+
xpath = document.evaluate(selector, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
61
|
+
results = (function() {
|
62
|
+
var _i, _ref, _results;
|
63
|
+
|
64
|
+
_results = [];
|
65
|
+
for (i = _i = 0, _ref = xpath.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
66
|
+
_results.push(xpath.snapshotItem(i));
|
67
|
+
}
|
68
|
+
return _results;
|
69
|
+
})();
|
70
|
+
} else {
|
71
|
+
results = within.querySelectorAll(selector);
|
72
|
+
}
|
73
|
+
_results = [];
|
74
|
+
for (_i = 0, _len = results.length; _i < _len; _i++) {
|
75
|
+
el = results[_i];
|
76
|
+
_results.push(this.register(el));
|
77
|
+
}
|
78
|
+
return _results;
|
79
|
+
} catch (_error) {
|
80
|
+
error = _error;
|
81
|
+
if (error.code === DOMException.SYNTAX_ERR) {
|
82
|
+
throw new PoltergeistAgent.InvalidSelector;
|
83
|
+
} else {
|
84
|
+
throw error;
|
85
|
+
}
|
76
86
|
}
|
77
|
-
return _results;
|
78
87
|
};
|
79
88
|
|
80
89
|
PoltergeistAgent.prototype.register = function(element) {
|
@@ -128,6 +137,17 @@ PoltergeistAgent.ObsoleteNode = (function() {
|
|
128
137
|
|
129
138
|
})();
|
130
139
|
|
140
|
+
PoltergeistAgent.InvalidSelector = (function() {
|
141
|
+
function InvalidSelector() {}
|
142
|
+
|
143
|
+
InvalidSelector.prototype.toString = function() {
|
144
|
+
return "PoltergeistAgent.InvalidSelector";
|
145
|
+
};
|
146
|
+
|
147
|
+
return InvalidSelector;
|
148
|
+
|
149
|
+
})();
|
150
|
+
|
131
151
|
PoltergeistAgent.Node = (function() {
|
132
152
|
Node.EVENTS = {
|
133
153
|
FOCUS: ['blur', 'focus', 'focusin', 'focusout'],
|
@@ -37,7 +37,7 @@ Poltergeist.Browser = (function() {
|
|
37
37
|
if (_this.state === 'loading') {
|
38
38
|
_this.sendResponse({
|
39
39
|
status: status,
|
40
|
-
|
40
|
+
position: _this.last_mouse_event
|
41
41
|
});
|
42
42
|
return _this.setState('default');
|
43
43
|
} else if (_this.state === 'awaiting_frame_load') {
|
@@ -62,6 +62,11 @@ Poltergeist.Browser = (function() {
|
|
62
62
|
};
|
63
63
|
};
|
64
64
|
|
65
|
+
Browser.prototype.runCommand = function(name, args) {
|
66
|
+
this.setState("default");
|
67
|
+
return this[name].apply(this, args);
|
68
|
+
};
|
69
|
+
|
65
70
|
Browser.prototype.debug = function(message) {
|
66
71
|
if (this._debug) {
|
67
72
|
return console.log("poltergeist [" + (new Date().getTime()) + "] " + message);
|
@@ -69,6 +74,9 @@ Poltergeist.Browser = (function() {
|
|
69
74
|
};
|
70
75
|
|
71
76
|
Browser.prototype.setState = function(state) {
|
77
|
+
if (this.state === state) {
|
78
|
+
return;
|
79
|
+
}
|
72
80
|
this.debug("state " + this.state + " -> " + state);
|
73
81
|
return this.state = state;
|
74
82
|
};
|
@@ -385,6 +393,11 @@ Poltergeist.Browser = (function() {
|
|
385
393
|
return this.sendResponse(true);
|
386
394
|
};
|
387
395
|
|
396
|
+
Browser.prototype.cookies_enabled = function(flag) {
|
397
|
+
phantom.cookiesEnabled = flag;
|
398
|
+
return this.sendResponse(true);
|
399
|
+
};
|
400
|
+
|
388
401
|
Browser.prototype.set_js_errors = function(value) {
|
389
402
|
this.js_errors = value;
|
390
403
|
return this.sendResponse(true);
|
@@ -20,7 +20,7 @@ Poltergeist = (function() {
|
|
20
20
|
|
21
21
|
this.running = true;
|
22
22
|
try {
|
23
|
-
return this.browser
|
23
|
+
return this.browser.runCommand(command.name, command.args);
|
24
24
|
} catch (_error) {
|
25
25
|
error = _error;
|
26
26
|
if (error instanceof Poltergeist.Error) {
|
@@ -88,6 +88,23 @@ Poltergeist.ObsoleteNode = (function(_super) {
|
|
88
88
|
|
89
89
|
})(Poltergeist.Error);
|
90
90
|
|
91
|
+
Poltergeist.InvalidSelector = (function(_super) {
|
92
|
+
__extends(InvalidSelector, _super);
|
93
|
+
|
94
|
+
function InvalidSelector(selector) {
|
95
|
+
this.selector = selector;
|
96
|
+
}
|
97
|
+
|
98
|
+
InvalidSelector.prototype.name = "Poltergeist.InvalidSelector";
|
99
|
+
|
100
|
+
InvalidSelector.prototype.args = function() {
|
101
|
+
return [this.selector];
|
102
|
+
};
|
103
|
+
|
104
|
+
return InvalidSelector;
|
105
|
+
|
106
|
+
})(Poltergeist.Error);
|
107
|
+
|
91
108
|
Poltergeist.FrameNotFound = (function(_super) {
|
92
109
|
__extends(FrameNotFound, _super);
|
93
110
|
|
@@ -344,10 +344,15 @@ Poltergeist.WebPage = (function() {
|
|
344
344
|
return __poltergeist.externalCall(name, args);
|
345
345
|
}, name, args);
|
346
346
|
if (result.error != null) {
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
347
|
+
switch (result.error.message) {
|
348
|
+
case 'PoltergeistAgent.ObsoleteNode':
|
349
|
+
throw new Poltergeist.ObsoleteNode;
|
350
|
+
break;
|
351
|
+
case 'PoltergeistAgent.InvalidSelector':
|
352
|
+
throw new Poltergeist.InvalidSelector(args[1]);
|
353
|
+
break;
|
354
|
+
default:
|
355
|
+
throw new Poltergeist.BrowserError(result.error.message, result.error.stack);
|
351
356
|
}
|
352
357
|
} else {
|
353
358
|
return result.value;
|
@@ -13,7 +13,7 @@ class Poltergeist
|
|
13
13
|
@running = true
|
14
14
|
|
15
15
|
try
|
16
|
-
@browser
|
16
|
+
@browser.runCommand(command.name, command.args)
|
17
17
|
catch error
|
18
18
|
if error instanceof Poltergeist.Error
|
19
19
|
this.sendError(error)
|
@@ -50,6 +50,11 @@ class Poltergeist.ObsoleteNode extends Poltergeist.Error
|
|
50
50
|
args: -> []
|
51
51
|
toString: -> this.name
|
52
52
|
|
53
|
+
class Poltergeist.InvalidSelector extends Poltergeist.Error
|
54
|
+
constructor: (@selector) ->
|
55
|
+
name: "Poltergeist.InvalidSelector"
|
56
|
+
args: -> [@selector]
|
57
|
+
|
53
58
|
class Poltergeist.FrameNotFound extends Poltergeist.Error
|
54
59
|
constructor: (@frameName) ->
|
55
60
|
name: "Poltergeist.FrameNotFound"
|
@@ -238,9 +238,12 @@ class Poltergeist.WebPage
|
|
238
238
|
)
|
239
239
|
|
240
240
|
if result.error?
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
241
|
+
switch result.error.message
|
242
|
+
when 'PoltergeistAgent.ObsoleteNode'
|
243
|
+
throw new Poltergeist.ObsoleteNode
|
244
|
+
when 'PoltergeistAgent.InvalidSelector'
|
245
|
+
throw new Poltergeist.InvalidSelector(args[1])
|
246
|
+
else
|
247
|
+
throw new Poltergeist.BrowserError(result.error.message, result.error.stack)
|
245
248
|
else
|
246
249
|
result.value
|
@@ -64,6 +64,17 @@ module Capybara
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
class InvalidSelector < ClientError
|
68
|
+
def selector
|
69
|
+
response['args'].first
|
70
|
+
end
|
71
|
+
|
72
|
+
def message
|
73
|
+
"The browser raised a syntax error while trying to evaluate " \
|
74
|
+
"the selector #{selector.inspect}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
67
78
|
class NodeError < ClientError
|
68
79
|
attr_reader :node
|
69
80
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poltergeist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
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: 2013-
|
12
|
+
date: 2013-05-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: capybara
|
@@ -48,23 +48,23 @@ dependencies:
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- - ~>
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0.4'
|
54
51
|
- - ! '>='
|
55
52
|
- !ruby/object:Gem::Version
|
56
53
|
version: 0.4.4
|
54
|
+
- - <
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.5.0
|
57
57
|
type: :runtime
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
none: false
|
61
61
|
requirements:
|
62
|
-
- - ~>
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '0.4'
|
65
62
|
- - ! '>='
|
66
63
|
- !ruby/object:Gem::Version
|
67
64
|
version: 0.4.4
|
65
|
+
- - <
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.5.0
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
69
|
name: rspec
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -233,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
233
233
|
version: '0'
|
234
234
|
segments:
|
235
235
|
- 0
|
236
|
-
hash:
|
236
|
+
hash: 4058260924079530296
|
237
237
|
requirements: []
|
238
238
|
rubyforge_project:
|
239
239
|
rubygems_version: 1.8.24
|