poltergeist 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eac1d67cd0c1e7872a042e4d0dfa10740b132858
4
- data.tar.gz: e52276ce486bb4bda8e17416da7492cdae0af9aa
3
+ metadata.gz: dc319cb98595a9cedd482bffd3756720c4ed24b4
4
+ data.tar.gz: a79f76c1344f910aac1aa9f38a0cb6fd40dfa075
5
5
  SHA512:
6
- metadata.gz: aa4a1e4fa49103bb1989d16a46c1135ebffaec9df3fb0a86f1fdf5841389fffd9c6ebaa59ffc8f57abf150a981ce419d38c5c9516d1b0281e73e96f3c78cc517
7
- data.tar.gz: a7088f6835bf5ef8eb42e724e99dc3271e37deb56c47cce57d68bdd54493ed0e4ed795717dc10d91a56196c55df59fed3c8bdf2c437c9d387d58cc5e7f0d4cbf
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.10.0).](https://github.com/teampoltergeist/poltergeist/tree/v1.10.0)**
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/) and [Codeship](https://codeship.com/) has PhantomJS pre-installed.
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, all
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').values.map do |event|
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, permanent)
301
- command 'add_header', header, permanent
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.parentNode)?
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
- @current_command.sendResponse 'success'
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
- @currentPage.addTempHeader(header) unless permanent
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
- return this.current_command.sendResponse('success');
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, permanent) {
628
- if (!permanent) {
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 abort, blacklisted, ref2, useWhitelist, whitelisted;
122
- useWhitelist = this.urlWhitelist.length > 0;
123
- whitelisted = this.urlWhitelist.some(function(whitelisted_regex) {
124
- return whitelisted_regex.test(request.url);
125
- });
126
- blacklisted = this.urlBlacklist.some(function(blacklisted_regex) {
127
- return blacklisted_regex.test(request.url);
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
- return this._networkTraffic;
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
- 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; } } var _result = " + (this.stringifyCall(fn)) + "; return (_result == null) ? undefined : _result; }"].concat(slice.call(args)));
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
- return "(" + (fn.toString()) + ").apply(this, arguments)";
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 !== null) {
553
- if (result.error != null) {
554
- switch (result.error.message) {
555
- case 'PoltergeistAgent.ObsoleteNode':
556
- throw new Poltergeist.ObsoleteNode;
557
- break;
558
- case 'PoltergeistAgent.InvalidSelector':
559
- method = args[0], selector = args[1];
560
- throw new Poltergeist.InvalidSelector(method, selector);
561
- break;
562
- default:
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
- this.removeTempHeaders()
53
- this.setScrollPosition(left: 0, top: 0)
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
- useWhitelist = @urlWhitelist.length > 0
88
-
89
- whitelisted = @urlWhitelist.some (whitelisted_regex) ->
90
- whitelisted_regex.test request.url
91
-
92
- blacklisted = @urlBlacklist.some (blacklisted_regex) ->
93
- blacklisted_regex.test request.url
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
- @_networkTraffic
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 = this.getCustomHeaders()
297
+ allHeaders = @getCustomHeaders()
291
298
  for name, value of @_tempHeaders
292
299
  delete allHeaders[name]
293
- this.setCustomHeaders(allHeaders)
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
- for(var i=0; i < arguments.length; i++){
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
- arguments[i] = window.__poltergeist.get(arguments[i]['ELEMENT']['id']).element;
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 == null) ? undefined : _result; }", args...)
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, arguments)"
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 != null
386
- if result.error?
387
- switch result.error.message
388
- when 'PoltergeistAgent.ObsoleteNode'
389
- throw new Poltergeist.ObsoleteNode
390
- when 'PoltergeistAgent.InvalidSelector'
391
- [method, selector] = args
392
- throw new Poltergeist.InvalidSelector(method, selector)
393
- else
394
- throw new Poltergeist.BrowserError(result.error.message, result.error.stack)
395
- else
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 = options.fetch(:permanent, true)
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
- trap('SIGCONT', old_trap) # Restore the previuos signal handler, if there was one.
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
@@ -156,7 +156,7 @@ module Capybara::Poltergeist
156
156
  end
157
157
 
158
158
  def ==(other)
159
- command :equals, other.id
159
+ (page_id == other.page_id) && command(:equals, other.id)
160
160
  end
161
161
 
162
162
  def send_keys(*keys)
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Poltergeist
3
- VERSION = "1.13.0"
3
+ VERSION = "1.14.0"
4
4
  end
5
5
  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.13.0
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-01-22 00:00:00.000000000 Z
11
+ date: 2017-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara