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 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