poltergeist 1.13.0 → 1.14.0
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.
- checksums.yaml +4 -4
- data/README.md +12 -4
- data/lib/capybara/poltergeist/browser.rb +4 -4
- data/lib/capybara/poltergeist/client/agent.coffee +21 -1
- data/lib/capybara/poltergeist/client/browser.coffee +10 -6
- data/lib/capybara/poltergeist/client/compiled/agent.js +42 -2
- data/lib/capybara/poltergeist/client/compiled/browser.js +14 -6
- data/lib/capybara/poltergeist/client/compiled/web_page.js +108 -42
- data/lib/capybara/poltergeist/client/web_page.coffee +77 -48
- data/lib/capybara/poltergeist/driver.rb +19 -7
- data/lib/capybara/poltergeist/node.rb +1 -1
- data/lib/capybara/poltergeist/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc319cb98595a9cedd482bffd3756720c4ed24b4
|
4
|
+
data.tar.gz: a79f76c1344f910aac1aa9f38a0cb6fd40dfa075
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0c6a5e24513e4c34e755c2a4cee6191580648d98bea2ba26877b8d4267dafb75a6aedd0d61d49b767b02dd825cdbcbbd1a59d05a85fc35a3230aaf92eccadaa
|
7
|
+
data.tar.gz: c634a8ee97d076785499dd803553174d1ed5932cede4f80bdc23dc11a364cec694d024a8e51bf10cf0155948ddc9a38515d5f43fbc7d3c1590ace315a88d3169
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ provided by [PhantomJS](http://phantomjs.org/).
|
|
9
9
|
**If you're viewing this at https://github.com/teampoltergeist/poltergeist,
|
10
10
|
you're reading the documentation for the master branch.
|
11
11
|
[View documentation for the latest release
|
12
|
-
(1.
|
12
|
+
(1.13.0).](https://github.com/teampoltergeist/poltergeist/tree/v1.13.0)**
|
13
13
|
|
14
14
|
## Getting help ##
|
15
15
|
|
@@ -88,7 +88,8 @@ was 1.0.2, so you should use that if you still need Ruby 1.8 support.
|
|
88
88
|
There are no special steps to take. You don't need Xvfb or any running X
|
89
89
|
server at all.
|
90
90
|
|
91
|
-
[Travis CI](https://travis-ci.org/)
|
91
|
+
[Travis CI](https://travis-ci.org/), [CircleCI](https://circleci.com/)
|
92
|
+
and [Codeship](https://codeship.com/) has PhantomJS pre-installed.
|
92
93
|
|
93
94
|
Depending on your tests, one thing that you may need is some fonts. If
|
94
95
|
you're getting errors on a CI that don't occur during development then
|
@@ -192,8 +193,9 @@ visit(login_path)
|
|
192
193
|
page.driver.headers # => { "User-Agent" => "Poltergeist" }
|
193
194
|
```
|
194
195
|
|
195
|
-
This way your temporary headers will be sent only for the initial request,
|
196
|
-
subsequent request will only contain your permanent headers.
|
196
|
+
This way your temporary headers will be sent only for the initial request, and related 30x redirects. All
|
197
|
+
subsequent request will only contain your permanent headers. If the temporary
|
198
|
+
headers should not be sent on related 30x redirects, specify `permanent: :no_redirect`.
|
197
199
|
|
198
200
|
### Inspecting network traffic ###
|
199
201
|
|
@@ -201,6 +203,12 @@ You can inspect the network traffic (i.e. what resources have been
|
|
201
203
|
loaded) on the current page by calling `page.driver.network_traffic`.
|
202
204
|
This returns an array of request objects. A request object has a
|
203
205
|
`response_parts` method containing data about the response chunks.
|
206
|
+
|
207
|
+
You can inspect requests that were blocked by a whitelist or blacklist
|
208
|
+
by calling `page.driver.network_traffic(:blocked)`. This returns an array of
|
209
|
+
request objects. The `response_parts` portion of these requests will always
|
210
|
+
be empty.
|
211
|
+
|
204
212
|
Please note that network traffic is not cleared when you visit new page.
|
205
213
|
You can manually clear the network traffic by calling `page.driver.clear_network_traffic`
|
206
214
|
or `page.driver.reset`
|
@@ -260,8 +260,8 @@ module Capybara::Poltergeist
|
|
260
260
|
command 'path', page_id, id
|
261
261
|
end
|
262
262
|
|
263
|
-
def network_traffic
|
264
|
-
command('network_traffic').
|
263
|
+
def network_traffic(type = nil)
|
264
|
+
command('network_traffic', type).map do |event|
|
265
265
|
NetworkTraffic::Request.new(
|
266
266
|
event['request'],
|
267
267
|
event['responseParts'].map { |response| NetworkTraffic::Response.new(response) },
|
@@ -297,8 +297,8 @@ module Capybara::Poltergeist
|
|
297
297
|
command 'add_headers', headers
|
298
298
|
end
|
299
299
|
|
300
|
-
def add_header(header,
|
301
|
-
command 'add_header', header,
|
300
|
+
def add_header(header, options={})
|
301
|
+
command 'add_header', header, options
|
302
302
|
end
|
303
303
|
|
304
304
|
def response_headers
|
@@ -57,6 +57,26 @@ class PoltergeistAgent
|
|
57
57
|
clearLocalStorage: ->
|
58
58
|
localStorage?.clear()
|
59
59
|
|
60
|
+
wrapResults: (result, page_id)->
|
61
|
+
@_visitedObjects ||= [];
|
62
|
+
switch
|
63
|
+
when result in @_visitedObjects
|
64
|
+
'(cyclic structure)'
|
65
|
+
when Array.isArray(result) || (result instanceof NodeList)
|
66
|
+
@wrapResults(res, page_id) for res in result
|
67
|
+
when result && result.nodeType == 1 && result['tagName']
|
68
|
+
{'ELEMENT': { id: @register(result), page_id: page_id } };
|
69
|
+
when not result?
|
70
|
+
undefined
|
71
|
+
when typeof result == 'object'
|
72
|
+
@_visitedObjects.push(result);
|
73
|
+
obj = {}
|
74
|
+
obj[key] = @wrapResults(val, page_id) for own key, val of result
|
75
|
+
@_visitedObjects.pop();
|
76
|
+
obj
|
77
|
+
else
|
78
|
+
result
|
79
|
+
|
60
80
|
class PoltergeistAgent.ObsoleteNode
|
61
81
|
toString: -> "PoltergeistAgent.ObsoleteNode"
|
62
82
|
|
@@ -89,7 +109,7 @@ class PoltergeistAgent.Node
|
|
89
109
|
|
90
110
|
isObsolete: ->
|
91
111
|
obsolete = (element) =>
|
92
|
-
if (parent = element
|
112
|
+
if (parent = element?.parentNode)?
|
93
113
|
if parent == document
|
94
114
|
return false
|
95
115
|
else
|
@@ -75,8 +75,10 @@ class Poltergeist.Browser
|
|
75
75
|
return
|
76
76
|
|
77
77
|
add_extension: (extension) ->
|
78
|
-
@currentPage.injectExtension extension
|
79
|
-
|
78
|
+
if @currentPage.injectExtension extension
|
79
|
+
@current_command.sendResponse 'success'
|
80
|
+
else
|
81
|
+
@current_command.sendError(new Poltergeist.BrowserError("Unable to load extension: #{extension}"))
|
80
82
|
|
81
83
|
node: (page_id, id) ->
|
82
84
|
if @currentPage.id == page_id
|
@@ -417,8 +419,8 @@ class Poltergeist.Browser
|
|
417
419
|
@currentPage.setViewportSize(width: width, height: height)
|
418
420
|
@current_command.sendResponse(true)
|
419
421
|
|
420
|
-
network_traffic: ->
|
421
|
-
@current_command.sendResponse(@currentPage.networkTraffic())
|
422
|
+
network_traffic: (type) ->
|
423
|
+
@current_command.sendResponse(@currentPage.networkTraffic(type))
|
422
424
|
|
423
425
|
clear_network_traffic: ->
|
424
426
|
@currentPage.clearNetworkTraffic()
|
@@ -443,8 +445,10 @@ class Poltergeist.Browser
|
|
443
445
|
allHeaders[name] = value
|
444
446
|
this.set_headers(allHeaders)
|
445
447
|
|
446
|
-
add_header: (header, permanent) ->
|
447
|
-
|
448
|
+
add_header: (header, { permanent = true }) ->
|
449
|
+
unless permanent == true
|
450
|
+
@currentPage.addTempHeader(header)
|
451
|
+
@currentPage.addTempHeaderToRemoveOnRedirect(header) if permanent == "no_redirect"
|
448
452
|
this.add_headers(header)
|
449
453
|
|
450
454
|
response_headers: ->
|
@@ -1,4 +1,6 @@
|
|
1
|
-
var PoltergeistAgent
|
1
|
+
var PoltergeistAgent,
|
2
|
+
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
3
|
+
hasProp = {}.hasOwnProperty;
|
2
4
|
|
3
5
|
PoltergeistAgent = (function() {
|
4
6
|
function PoltergeistAgent() {
|
@@ -100,6 +102,44 @@ PoltergeistAgent = (function() {
|
|
100
102
|
return typeof localStorage !== "undefined" && localStorage !== null ? localStorage.clear() : void 0;
|
101
103
|
};
|
102
104
|
|
105
|
+
PoltergeistAgent.prototype.wrapResults = function(result, page_id) {
|
106
|
+
var j, key, len, obj, res, results1, val;
|
107
|
+
this._visitedObjects || (this._visitedObjects = []);
|
108
|
+
switch (false) {
|
109
|
+
case indexOf.call(this._visitedObjects, result) < 0:
|
110
|
+
return '(cyclic structure)';
|
111
|
+
case !(Array.isArray(result) || (result instanceof NodeList)):
|
112
|
+
results1 = [];
|
113
|
+
for (j = 0, len = result.length; j < len; j++) {
|
114
|
+
res = result[j];
|
115
|
+
results1.push(this.wrapResults(res, page_id));
|
116
|
+
}
|
117
|
+
return results1;
|
118
|
+
break;
|
119
|
+
case !(result && result.nodeType === 1 && result['tagName']):
|
120
|
+
return {
|
121
|
+
'ELEMENT': {
|
122
|
+
id: this.register(result),
|
123
|
+
page_id: page_id
|
124
|
+
}
|
125
|
+
};
|
126
|
+
case !(result == null):
|
127
|
+
return void 0;
|
128
|
+
case typeof result !== 'object':
|
129
|
+
this._visitedObjects.push(result);
|
130
|
+
obj = {};
|
131
|
+
for (key in result) {
|
132
|
+
if (!hasProp.call(result, key)) continue;
|
133
|
+
val = result[key];
|
134
|
+
obj[key] = this.wrapResults(val, page_id);
|
135
|
+
}
|
136
|
+
this._visitedObjects.pop();
|
137
|
+
return obj;
|
138
|
+
default:
|
139
|
+
return result;
|
140
|
+
}
|
141
|
+
};
|
142
|
+
|
103
143
|
return PoltergeistAgent;
|
104
144
|
|
105
145
|
})();
|
@@ -162,7 +202,7 @@ PoltergeistAgent.Node = (function() {
|
|
162
202
|
obsolete = (function(_this) {
|
163
203
|
return function(element) {
|
164
204
|
var parent;
|
165
|
-
if ((parent = element.parentNode) != null) {
|
205
|
+
if ((parent = element != null ? element.parentNode : void 0) != null) {
|
166
206
|
if (parent === document) {
|
167
207
|
return false;
|
168
208
|
} else {
|
@@ -100,8 +100,11 @@ Poltergeist.Browser = (function() {
|
|
100
100
|
};
|
101
101
|
|
102
102
|
Browser.prototype.add_extension = function(extension) {
|
103
|
-
this.currentPage.injectExtension(extension)
|
104
|
-
|
103
|
+
if (this.currentPage.injectExtension(extension)) {
|
104
|
+
return this.current_command.sendResponse('success');
|
105
|
+
} else {
|
106
|
+
return this.current_command.sendError(new Poltergeist.BrowserError("Unable to load extension: " + extension));
|
107
|
+
}
|
105
108
|
};
|
106
109
|
|
107
110
|
Browser.prototype.node = function(page_id, id) {
|
@@ -588,8 +591,8 @@ Poltergeist.Browser = (function() {
|
|
588
591
|
return this.current_command.sendResponse(true);
|
589
592
|
};
|
590
593
|
|
591
|
-
Browser.prototype.network_traffic = function() {
|
592
|
-
return this.current_command.sendResponse(this.currentPage.networkTraffic());
|
594
|
+
Browser.prototype.network_traffic = function(type) {
|
595
|
+
return this.current_command.sendResponse(this.currentPage.networkTraffic(type));
|
593
596
|
};
|
594
597
|
|
595
598
|
Browser.prototype.clear_network_traffic = function() {
|
@@ -624,9 +627,14 @@ Poltergeist.Browser = (function() {
|
|
624
627
|
return this.set_headers(allHeaders);
|
625
628
|
};
|
626
629
|
|
627
|
-
Browser.prototype.add_header = function(header,
|
628
|
-
|
630
|
+
Browser.prototype.add_header = function(header, arg1) {
|
631
|
+
var permanent, ref;
|
632
|
+
permanent = (ref = arg1.permanent) != null ? ref : true;
|
633
|
+
if (permanent !== true) {
|
629
634
|
this.currentPage.addTempHeader(header);
|
635
|
+
if (permanent === "no_redirect") {
|
636
|
+
this.currentPage.addTempHeaderToRemoveOnRedirect(header);
|
637
|
+
}
|
630
638
|
}
|
631
639
|
return this.add_headers(header);
|
632
640
|
};
|
@@ -29,6 +29,7 @@ Poltergeist.WebPage = (function() {
|
|
29
29
|
this._blockedUrls = [];
|
30
30
|
this._requestedResources = {};
|
31
31
|
this._responseHeaders = [];
|
32
|
+
this._tempHeadersToRemoveOnRedirect = {};
|
32
33
|
ref = WebPage.CALLBACKS;
|
33
34
|
for (i = 0, len = ref.length; i < len; i++) {
|
34
35
|
callback = ref[i];
|
@@ -68,6 +69,7 @@ Poltergeist.WebPage = (function() {
|
|
68
69
|
this.source = null;
|
69
70
|
this.injectAgent();
|
70
71
|
this.removeTempHeaders();
|
72
|
+
this.removeTempHeadersForRedirect();
|
71
73
|
return this.setScrollPosition({
|
72
74
|
left: 0,
|
73
75
|
top: 0
|
@@ -118,22 +120,14 @@ Poltergeist.WebPage = (function() {
|
|
118
120
|
};
|
119
121
|
|
120
122
|
WebPage.prototype.onResourceRequestedNative = function(request, net) {
|
121
|
-
var
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
abort = false;
|
130
|
-
if (useWhitelist && !whitelisted) {
|
131
|
-
abort = true;
|
132
|
-
}
|
133
|
-
if (blacklisted) {
|
134
|
-
abort = true;
|
135
|
-
}
|
136
|
-
if (abort) {
|
123
|
+
var ref2;
|
124
|
+
this._networkTraffic[request.id] = {
|
125
|
+
request: request,
|
126
|
+
responseParts: [],
|
127
|
+
error: null
|
128
|
+
};
|
129
|
+
if (this._blockRequest(request.url)) {
|
130
|
+
this._networkTraffic[request.id].blocked = true;
|
137
131
|
if (ref2 = request.url, indexOf.call(this._blockedUrls, ref2) < 0) {
|
138
132
|
this._blockedUrls.push(request.url);
|
139
133
|
}
|
@@ -141,14 +135,10 @@ Poltergeist.WebPage = (function() {
|
|
141
135
|
} else {
|
142
136
|
this.lastRequestId = request.id;
|
143
137
|
if (this.normalizeURL(request.url) === this.redirectURL) {
|
138
|
+
this.removeTempHeadersForRedirect();
|
144
139
|
this.redirectURL = null;
|
145
140
|
this.requestId = request.id;
|
146
141
|
}
|
147
|
-
this._networkTraffic[request.id] = {
|
148
|
-
request: request,
|
149
|
-
responseParts: [],
|
150
|
-
error: null
|
151
|
-
};
|
152
142
|
this._requestedResources[request.id] = request.url;
|
153
143
|
}
|
154
144
|
return true;
|
@@ -164,6 +154,7 @@ Poltergeist.WebPage = (function() {
|
|
164
154
|
}
|
165
155
|
if (this.requestId === response.id) {
|
166
156
|
if (response.redirectURL) {
|
157
|
+
this.removeTempHeadersForRedirect();
|
167
158
|
this.redirectURL = this.normalizeURL(response.redirectURL);
|
168
159
|
} else {
|
169
160
|
this.statusCode = response.status;
|
@@ -294,8 +285,43 @@ Poltergeist.WebPage = (function() {
|
|
294
285
|
return true;
|
295
286
|
};
|
296
287
|
|
297
|
-
WebPage.prototype.networkTraffic = function() {
|
298
|
-
|
288
|
+
WebPage.prototype.networkTraffic = function(type) {
|
289
|
+
var id, ref2, ref3, ref4, request, results, results1, results2;
|
290
|
+
switch (type) {
|
291
|
+
case 'all':
|
292
|
+
ref2 = this._networkTraffic;
|
293
|
+
results = [];
|
294
|
+
for (id in ref2) {
|
295
|
+
if (!hasProp.call(ref2, id)) continue;
|
296
|
+
request = ref2[id];
|
297
|
+
results.push(request);
|
298
|
+
}
|
299
|
+
return results;
|
300
|
+
break;
|
301
|
+
case 'blocked':
|
302
|
+
ref3 = this._networkTraffic;
|
303
|
+
results1 = [];
|
304
|
+
for (id in ref3) {
|
305
|
+
if (!hasProp.call(ref3, id)) continue;
|
306
|
+
request = ref3[id];
|
307
|
+
if (request.blocked) {
|
308
|
+
results1.push(request);
|
309
|
+
}
|
310
|
+
}
|
311
|
+
return results1;
|
312
|
+
break;
|
313
|
+
default:
|
314
|
+
ref4 = this._networkTraffic;
|
315
|
+
results2 = [];
|
316
|
+
for (id in ref4) {
|
317
|
+
if (!hasProp.call(ref4, id)) continue;
|
318
|
+
request = ref4[id];
|
319
|
+
if (!request.blocked) {
|
320
|
+
results2.push(request);
|
321
|
+
}
|
322
|
+
}
|
323
|
+
return results2;
|
324
|
+
}
|
299
325
|
};
|
300
326
|
|
301
327
|
WebPage.prototype.clearNetworkTraffic = function() {
|
@@ -422,6 +448,26 @@ Poltergeist.WebPage = (function() {
|
|
422
448
|
return this._tempHeaders;
|
423
449
|
};
|
424
450
|
|
451
|
+
WebPage.prototype.addTempHeaderToRemoveOnRedirect = function(header) {
|
452
|
+
var name, value;
|
453
|
+
for (name in header) {
|
454
|
+
value = header[name];
|
455
|
+
this._tempHeadersToRemoveOnRedirect[name] = value;
|
456
|
+
}
|
457
|
+
return this._tempHeadersToRemoveOnRedirect;
|
458
|
+
};
|
459
|
+
|
460
|
+
WebPage.prototype.removeTempHeadersForRedirect = function() {
|
461
|
+
var allHeaders, name, ref2, value;
|
462
|
+
allHeaders = this.getCustomHeaders();
|
463
|
+
ref2 = this._tempHeadersToRemoveOnRedirect;
|
464
|
+
for (name in ref2) {
|
465
|
+
value = ref2[name];
|
466
|
+
delete allHeaders[name];
|
467
|
+
}
|
468
|
+
return this.setCustomHeaders(allHeaders);
|
469
|
+
};
|
470
|
+
|
425
471
|
WebPage.prototype.removeTempHeaders = function() {
|
426
472
|
var allHeaders, name, ref2, value;
|
427
473
|
allHeaders = this.getCustomHeaders();
|
@@ -513,10 +559,11 @@ Poltergeist.WebPage = (function() {
|
|
513
559
|
};
|
514
560
|
|
515
561
|
WebPage.prototype.evaluate = function() {
|
516
|
-
var args, fn, ref2;
|
562
|
+
var args, fn, ref2, result;
|
517
563
|
fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
518
564
|
this.injectAgent();
|
519
|
-
|
565
|
+
result = (ref2 = this["native"]()).evaluate.apply(ref2, ["function() { var page_id = arguments[0]; var args = []; for(var i=1; i < arguments.length; i++){ if ((typeof(arguments[i]) == 'object') && (typeof(arguments[i]['ELEMENT']) == 'object')){ args.push(window.__poltergeist.get(arguments[i]['ELEMENT']['id']).element); } else { args.push(arguments[i]) } } var _result = " + (this.stringifyCall(fn, "args")) + "; return window.__poltergeist.wrapResults(_result, page_id); }", this.id].concat(slice.call(args)));
|
566
|
+
return result;
|
520
567
|
};
|
521
568
|
|
522
569
|
WebPage.prototype.execute = function() {
|
@@ -525,8 +572,11 @@ Poltergeist.WebPage = (function() {
|
|
525
572
|
return (ref2 = this["native"]()).evaluate.apply(ref2, ["function() { for(var i=0; i < arguments.length; i++){ if ((typeof(arguments[i]) == 'object') && (typeof(arguments[i]['ELEMENT']) == 'object')){ arguments[i] = window.__poltergeist.get(arguments[i]['ELEMENT']['id']).element; } } " + (this.stringifyCall(fn)) + " }"].concat(slice.call(args)));
|
526
573
|
};
|
527
574
|
|
528
|
-
WebPage.prototype.stringifyCall = function(fn) {
|
529
|
-
|
575
|
+
WebPage.prototype.stringifyCall = function(fn, args_name) {
|
576
|
+
if (args_name == null) {
|
577
|
+
args_name = "arguments";
|
578
|
+
}
|
579
|
+
return "(" + (fn.toString()) + ").apply(this, " + args_name + ")";
|
530
580
|
};
|
531
581
|
|
532
582
|
WebPage.prototype.bindCallback = function(name) {
|
@@ -549,22 +599,20 @@ Poltergeist.WebPage = (function() {
|
|
549
599
|
result = this.evaluate(function(name, args) {
|
550
600
|
return __poltergeist.externalCall(name, args);
|
551
601
|
}, name, args);
|
552
|
-
if (result
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
throw new Poltergeist.BrowserError(result.error.message, result.error.stack);
|
564
|
-
}
|
565
|
-
} else {
|
566
|
-
return result.value;
|
602
|
+
if ((result != null ? result.error : void 0) != null) {
|
603
|
+
switch (result.error.message) {
|
604
|
+
case 'PoltergeistAgent.ObsoleteNode':
|
605
|
+
throw new Poltergeist.ObsoleteNode;
|
606
|
+
break;
|
607
|
+
case 'PoltergeistAgent.InvalidSelector':
|
608
|
+
method = args[0], selector = args[1];
|
609
|
+
throw new Poltergeist.InvalidSelector(method, selector);
|
610
|
+
break;
|
611
|
+
default:
|
612
|
+
throw new Poltergeist.BrowserError(result.error.message, result.error.stack);
|
567
613
|
}
|
614
|
+
} else {
|
615
|
+
return result != null ? result.value : void 0;
|
568
616
|
}
|
569
617
|
};
|
570
618
|
|
@@ -593,6 +641,24 @@ Poltergeist.WebPage = (function() {
|
|
593
641
|
}
|
594
642
|
};
|
595
643
|
|
644
|
+
WebPage.prototype._blockRequest = function(url) {
|
645
|
+
var blacklisted, useWhitelist, whitelisted;
|
646
|
+
useWhitelist = this.urlWhitelist.length > 0;
|
647
|
+
whitelisted = this.urlWhitelist.some(function(whitelisted_regex) {
|
648
|
+
return whitelisted_regex.test(url);
|
649
|
+
});
|
650
|
+
blacklisted = this.urlBlacklist.some(function(blacklisted_regex) {
|
651
|
+
return blacklisted_regex.test(url);
|
652
|
+
});
|
653
|
+
if (useWhitelist && !whitelisted) {
|
654
|
+
return true;
|
655
|
+
}
|
656
|
+
if (blacklisted) {
|
657
|
+
return true;
|
658
|
+
}
|
659
|
+
return false;
|
660
|
+
};
|
661
|
+
|
596
662
|
WebPage.prototype._overrideNativeEvaluate = function() {
|
597
663
|
return this._native.evaluate = function (func, args) {
|
598
664
|
function quoteString(str) {
|
@@ -28,6 +28,7 @@ class Poltergeist.WebPage
|
|
28
28
|
@_blockedUrls = []
|
29
29
|
@_requestedResources = {}
|
30
30
|
@_responseHeaders = []
|
31
|
+
@_tempHeadersToRemoveOnRedirect = {}
|
31
32
|
|
32
33
|
for callback in WebPage.CALLBACKS
|
33
34
|
this.bindCallback(callback)
|
@@ -49,8 +50,9 @@ class Poltergeist.WebPage
|
|
49
50
|
@id += 1
|
50
51
|
@source = null
|
51
52
|
@injectAgent()
|
52
|
-
|
53
|
-
|
53
|
+
@removeTempHeaders()
|
54
|
+
@removeTempHeadersForRedirect()
|
55
|
+
@setScrollPosition(left: 0, top: 0)
|
54
56
|
|
55
57
|
onClosingNative: ->
|
56
58
|
@handle = null
|
@@ -84,38 +86,25 @@ class Poltergeist.WebPage
|
|
84
86
|
return true
|
85
87
|
|
86
88
|
onResourceRequestedNative: (request, net) ->
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
abort = false
|
96
|
-
|
97
|
-
if useWhitelist && !whitelisted
|
98
|
-
abort = true
|
99
|
-
|
100
|
-
if blacklisted
|
101
|
-
abort = true
|
102
|
-
|
103
|
-
if abort
|
89
|
+
@_networkTraffic[request.id] = {
|
90
|
+
request: request,
|
91
|
+
responseParts: []
|
92
|
+
error: null
|
93
|
+
}
|
94
|
+
|
95
|
+
if @_blockRequest(request.url)
|
96
|
+
@_networkTraffic[request.id].blocked = true
|
104
97
|
@_blockedUrls.push request.url unless request.url in @_blockedUrls
|
98
|
+
|
105
99
|
net.abort()
|
106
100
|
else
|
107
101
|
@lastRequestId = request.id
|
108
102
|
|
109
103
|
if @normalizeURL(request.url) == @redirectURL
|
104
|
+
@removeTempHeadersForRedirect()
|
110
105
|
@redirectURL = null
|
111
106
|
@requestId = request.id
|
112
107
|
|
113
|
-
@_networkTraffic[request.id] = {
|
114
|
-
request: request,
|
115
|
-
responseParts: []
|
116
|
-
error: null
|
117
|
-
}
|
118
|
-
|
119
108
|
@_requestedResources[request.id] = request.url
|
120
109
|
return true
|
121
110
|
|
@@ -127,6 +116,7 @@ class Poltergeist.WebPage
|
|
127
116
|
|
128
117
|
if @requestId == response.id
|
129
118
|
if response.redirectURL
|
119
|
+
@removeTempHeadersForRedirect()
|
130
120
|
@redirectURL = @normalizeURL(response.redirectURL)
|
131
121
|
else
|
132
122
|
@statusCode = response.status
|
@@ -197,8 +187,14 @@ class Poltergeist.WebPage
|
|
197
187
|
this.native().settings.password = password
|
198
188
|
return true
|
199
189
|
|
200
|
-
networkTraffic: ->
|
201
|
-
|
190
|
+
networkTraffic: (type) ->
|
191
|
+
switch type
|
192
|
+
when 'all'
|
193
|
+
request for own id, request of @_networkTraffic
|
194
|
+
when 'blocked'
|
195
|
+
request for own id, request of @_networkTraffic when request.blocked
|
196
|
+
else
|
197
|
+
request for own id, request of @_networkTraffic when not request.blocked
|
202
198
|
|
203
199
|
clearNetworkTraffic: ->
|
204
200
|
@_networkTraffic = {}
|
@@ -286,11 +282,22 @@ class Poltergeist.WebPage
|
|
286
282
|
@_tempHeaders[name] = value
|
287
283
|
@_tempHeaders
|
288
284
|
|
285
|
+
addTempHeaderToRemoveOnRedirect: (header) ->
|
286
|
+
for name, value of header
|
287
|
+
@_tempHeadersToRemoveOnRedirect[name] = value
|
288
|
+
@_tempHeadersToRemoveOnRedirect
|
289
|
+
|
290
|
+
removeTempHeadersForRedirect: ->
|
291
|
+
allHeaders = @getCustomHeaders()
|
292
|
+
for name, value of @_tempHeadersToRemoveOnRedirect
|
293
|
+
delete allHeaders[name]
|
294
|
+
@setCustomHeaders(allHeaders)
|
295
|
+
|
289
296
|
removeTempHeaders: ->
|
290
|
-
allHeaders =
|
297
|
+
allHeaders = @getCustomHeaders()
|
291
298
|
for name, value of @_tempHeaders
|
292
299
|
delete allHeaders[name]
|
293
|
-
|
300
|
+
@setCustomHeaders(allHeaders)
|
294
301
|
|
295
302
|
pushFrame: (name) ->
|
296
303
|
return true if this.native().switchToFrame(name)
|
@@ -346,14 +353,20 @@ class Poltergeist.WebPage
|
|
346
353
|
|
347
354
|
evaluate: (fn, args...) ->
|
348
355
|
this.injectAgent()
|
349
|
-
this.native().evaluate("function() {
|
350
|
-
|
356
|
+
result = this.native().evaluate("function() {
|
357
|
+
var page_id = arguments[0];
|
358
|
+
var args = [];
|
359
|
+
|
360
|
+
for(var i=1; i < arguments.length; i++){
|
351
361
|
if ((typeof(arguments[i]) == 'object') && (typeof(arguments[i]['ELEMENT']) == 'object')){
|
352
|
-
|
362
|
+
args.push(window.__poltergeist.get(arguments[i]['ELEMENT']['id']).element);
|
363
|
+
} else {
|
364
|
+
args.push(arguments[i])
|
353
365
|
}
|
354
366
|
}
|
355
|
-
var _result = #{this.stringifyCall(fn)};
|
356
|
-
return (_result
|
367
|
+
var _result = #{this.stringifyCall(fn, "args")};
|
368
|
+
return window.__poltergeist.wrapResults(_result, page_id); }", @id, args...)
|
369
|
+
result
|
357
370
|
|
358
371
|
execute: (fn, args...) ->
|
359
372
|
this.native().evaluate("function() {
|
@@ -364,8 +377,8 @@ class Poltergeist.WebPage
|
|
364
377
|
}
|
365
378
|
#{this.stringifyCall(fn)} }", args...)
|
366
379
|
|
367
|
-
stringifyCall: (fn) ->
|
368
|
-
"(#{fn.toString()}).apply(this,
|
380
|
+
stringifyCall: (fn, args_name = "arguments") ->
|
381
|
+
"(#{fn.toString()}).apply(this, #{args_name})"
|
369
382
|
|
370
383
|
bindCallback: (name) ->
|
371
384
|
@native()[name] = =>
|
@@ -382,18 +395,17 @@ class Poltergeist.WebPage
|
|
382
395
|
name, args
|
383
396
|
)
|
384
397
|
|
385
|
-
if result
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
result.value
|
398
|
+
if result?.error?
|
399
|
+
switch result.error.message
|
400
|
+
when 'PoltergeistAgent.ObsoleteNode'
|
401
|
+
throw new Poltergeist.ObsoleteNode
|
402
|
+
when 'PoltergeistAgent.InvalidSelector'
|
403
|
+
[method, selector] = args
|
404
|
+
throw new Poltergeist.InvalidSelector(method, selector)
|
405
|
+
else
|
406
|
+
throw new Poltergeist.BrowserError(result.error.message, result.error.stack)
|
407
|
+
else
|
408
|
+
result?.value
|
397
409
|
|
398
410
|
canGoBack: ->
|
399
411
|
this.native().canGoBack
|
@@ -413,6 +425,23 @@ class Poltergeist.WebPage
|
|
413
425
|
else
|
414
426
|
throw new Poltergeist.UnsupportedFeature("clearMemoryCache is supported since PhantomJS 2.0.0")
|
415
427
|
|
428
|
+
_blockRequest: (url) ->
|
429
|
+
useWhitelist = @urlWhitelist.length > 0
|
430
|
+
|
431
|
+
whitelisted = @urlWhitelist.some (whitelisted_regex) ->
|
432
|
+
whitelisted_regex.test url
|
433
|
+
|
434
|
+
blacklisted = @urlBlacklist.some (blacklisted_regex) ->
|
435
|
+
blacklisted_regex.test url
|
436
|
+
|
437
|
+
if useWhitelist && !whitelisted
|
438
|
+
return true
|
439
|
+
|
440
|
+
if blacklisted
|
441
|
+
return true
|
442
|
+
|
443
|
+
false
|
444
|
+
|
416
445
|
_overrideNativeEvaluate: ->
|
417
446
|
# PhantomJS 1.9.x WebPage#evaluate depends on the browser context JSON, this replaces it
|
418
447
|
# with the evaluate from 2.1.1 which uses the PhantomJS JSON
|
@@ -135,7 +135,8 @@ module Capybara::Poltergeist
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def evaluate_script(script, *args)
|
138
|
-
browser.evaluate(script, *args.map { |arg| arg.is_a?(Capybara::Poltergeist::Node) ? arg.native : arg})
|
138
|
+
result = browser.evaluate(script, *args.map { |arg| arg.is_a?(Capybara::Poltergeist::Node) ? arg.native : arg})
|
139
|
+
unwrap_script_result(result)
|
139
140
|
end
|
140
141
|
|
141
142
|
def execute_script(script, *args)
|
@@ -228,8 +229,8 @@ module Capybara::Poltergeist
|
|
228
229
|
browser.scroll_to(left, top)
|
229
230
|
end
|
230
231
|
|
231
|
-
def network_traffic
|
232
|
-
browser.network_traffic
|
232
|
+
def network_traffic(type = nil)
|
233
|
+
browser.network_traffic(type)
|
233
234
|
end
|
234
235
|
|
235
236
|
def clear_network_traffic
|
@@ -253,8 +254,7 @@ module Capybara::Poltergeist
|
|
253
254
|
end
|
254
255
|
|
255
256
|
def add_header(name, value, options = {})
|
256
|
-
permanent
|
257
|
-
browser.add_header({ name => value }, permanent)
|
257
|
+
browser.add_header({ name => value }, { permanent: true }.merge(options))
|
258
258
|
end
|
259
259
|
|
260
260
|
def response_headers
|
@@ -340,8 +340,8 @@ module Capybara::Poltergeist
|
|
340
340
|
rescue EOFError, IO::WaitReadable # Ignore problems reading from STDIN.
|
341
341
|
end unless signal
|
342
342
|
|
343
|
-
|
344
|
-
|
343
|
+
ensure
|
344
|
+
trap('SIGCONT', old_trap) # Restore the previous signal handler, if there was one.
|
345
345
|
STDERR.puts 'Continuing'
|
346
346
|
end
|
347
347
|
|
@@ -410,5 +410,17 @@ module Capybara::Poltergeist
|
|
410
410
|
end
|
411
411
|
modal_text
|
412
412
|
end
|
413
|
+
|
414
|
+
def unwrap_script_result(arg)
|
415
|
+
case arg
|
416
|
+
when Array
|
417
|
+
arg.map { |e| unwrap_script_result(e) }
|
418
|
+
when Hash
|
419
|
+
return Capybara::Poltergeist::Node.new(self, arg['ELEMENT']['page_id'], arg['ELEMENT']['id']) if arg['ELEMENT']
|
420
|
+
arg.each { |k, v| arg[k] = unwrap_script_result(v) }
|
421
|
+
else
|
422
|
+
arg
|
423
|
+
end
|
424
|
+
end
|
413
425
|
end
|
414
426
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poltergeist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Leighton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|