poltergeist 1.3.0 → 1.4.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.
@@ -5,7 +5,6 @@ var Poltergeist, _ref,
5
5
  Poltergeist = (function() {
6
6
  function Poltergeist(port, width, height) {
7
7
  var that;
8
-
9
8
  this.browser = new Poltergeist.Browser(this, width, height);
10
9
  this.connection = new Poltergeist.Connection(this, port);
11
10
  that = this;
@@ -17,7 +16,6 @@ Poltergeist = (function() {
17
16
 
18
17
  Poltergeist.prototype.runCommand = function(command) {
19
18
  var error;
20
-
21
19
  this.running = true;
22
20
  try {
23
21
  return this.browser.runCommand(command.name, command.args);
@@ -19,7 +19,6 @@ Poltergeist.Node = (function() {
19
19
  _fn = function(name) {
20
20
  return Node.prototype[name] = function() {
21
21
  var args;
22
-
23
22
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
24
23
  return this.page.nodeCall(this.id, name, args);
25
24
  };
@@ -31,7 +30,6 @@ Poltergeist.Node = (function() {
31
30
 
32
31
  Node.prototype.mouseEventPosition = function() {
33
32
  var middle, pos, viewport;
34
-
35
33
  viewport = this.page.viewportSize();
36
34
  pos = this.position();
37
35
  middle = function(start, end, size) {
@@ -45,7 +43,6 @@ Poltergeist.Node = (function() {
45
43
 
46
44
  Node.prototype.mouseEvent = function(name) {
47
45
  var pos, test;
48
-
49
46
  this.scrollIntoView();
50
47
  pos = this.mouseEventPosition();
51
48
  test = this.mouseEventTest(pos.x, pos.y);
@@ -59,7 +56,6 @@ Poltergeist.Node = (function() {
59
56
 
60
57
  Node.prototype.dragTo = function(other) {
61
58
  var otherPosition, position;
62
-
63
59
  this.scrollIntoView();
64
60
  position = this.mouseEventPosition();
65
61
  otherPosition = other.mouseEventPosition();
@@ -6,7 +6,7 @@ Poltergeist.WebPage = (function() {
6
6
 
7
7
  WebPage.CALLBACKS = ['onAlert', 'onConsoleMessage', 'onLoadFinished', 'onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived', 'onError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated'];
8
8
 
9
- WebPage.DELEGATES = ['open', 'sendEvent', 'uploadFile', 'release', 'render'];
9
+ WebPage.DELEGATES = ['open', 'sendEvent', 'uploadFile', 'release', 'render', 'renderBase64'];
10
10
 
11
11
  WebPage.COMMANDS = ['currentUrl', 'find', 'nodeCall', 'documentSize', 'beforeUpload', 'afterUpload'];
12
12
 
@@ -14,14 +14,13 @@ Poltergeist.WebPage = (function() {
14
14
 
15
15
  function WebPage(_native) {
16
16
  var callback, _i, _len, _ref;
17
-
18
17
  this["native"] = _native;
19
18
  this["native"] || (this["native"] = require('webpage').create());
20
- this._source = "";
19
+ this._source = null;
21
20
  this._errors = [];
22
21
  this._networkTraffic = {};
22
+ this._temp_headers = {};
23
23
  this.frames = [];
24
- this.sub_pages = {};
25
24
  _ref = WebPage.CALLBACKS;
26
25
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
27
26
  callback = _ref[_i];
@@ -33,7 +32,6 @@ Poltergeist.WebPage = (function() {
33
32
  _fn = function(command) {
34
33
  return WebPage.prototype[command] = function() {
35
34
  var args;
36
-
37
35
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
38
36
  return this.runCommand(command, args);
39
37
  };
@@ -57,6 +55,7 @@ Poltergeist.WebPage = (function() {
57
55
  WebPage.prototype.onInitializedNative = function() {
58
56
  this._source = null;
59
57
  this.injectAgent();
58
+ this.removeTempHeaders();
60
59
  return this.setScrollPosition({
61
60
  left: 0,
62
61
  top: 0
@@ -65,7 +64,6 @@ Poltergeist.WebPage = (function() {
65
64
 
66
65
  WebPage.prototype.injectAgent = function() {
67
66
  var extension, _k, _len2, _ref2, _results;
68
-
69
67
  if (this["native"].evaluate(function() {
70
68
  return typeof __poltergeist;
71
69
  }) === "undefined") {
@@ -106,7 +104,6 @@ Poltergeist.WebPage = (function() {
106
104
 
107
105
  WebPage.prototype.onErrorNative = function(message, stack) {
108
106
  var stackString;
109
-
110
107
  stackString = message;
111
108
  stack.forEach(function(frame) {
112
109
  stackString += "\n";
@@ -135,7 +132,6 @@ Poltergeist.WebPage = (function() {
135
132
 
136
133
  WebPage.prototype.onResourceReceivedNative = function(response) {
137
134
  var _ref2;
138
-
139
135
  if ((_ref2 = this._networkTraffic[response.id]) != null) {
140
136
  _ref2.responseParts.push(response);
141
137
  }
@@ -179,7 +175,6 @@ Poltergeist.WebPage = (function() {
179
175
 
180
176
  WebPage.prototype.responseHeaders = function() {
181
177
  var headers;
182
-
183
178
  headers = {};
184
179
  this._responseHeaders.forEach(function(item) {
185
180
  return headers[item.name] = item.value;
@@ -219,14 +214,45 @@ Poltergeist.WebPage = (function() {
219
214
  return this["native"].clipRect = rect;
220
215
  };
221
216
 
217
+ WebPage.prototype.elementBounds = function(selector) {
218
+ return this["native"].evaluate(function(selector) {
219
+ return document.querySelector(selector).getBoundingClientRect();
220
+ }, selector);
221
+ };
222
+
222
223
  WebPage.prototype.setUserAgent = function(userAgent) {
223
224
  return this["native"].settings.userAgent = userAgent;
224
225
  };
225
226
 
227
+ WebPage.prototype.getCustomHeaders = function() {
228
+ return this["native"].customHeaders;
229
+ };
230
+
226
231
  WebPage.prototype.setCustomHeaders = function(headers) {
227
232
  return this["native"].customHeaders = headers;
228
233
  };
229
234
 
235
+ WebPage.prototype.addTempHeader = function(header) {
236
+ var name, value, _results;
237
+ _results = [];
238
+ for (name in header) {
239
+ value = header[name];
240
+ _results.push(this._temp_headers[name] = value);
241
+ }
242
+ return _results;
243
+ };
244
+
245
+ WebPage.prototype.removeTempHeaders = function() {
246
+ var allHeaders, name, value, _ref2;
247
+ allHeaders = this.getCustomHeaders();
248
+ _ref2 = this._temp_headers;
249
+ for (name in _ref2) {
250
+ value = _ref2[name];
251
+ delete allHeaders[name];
252
+ }
253
+ return this.setCustomHeaders(allHeaders);
254
+ };
255
+
230
256
  WebPage.prototype.pushFrame = function(name) {
231
257
  if (this["native"].switchToFrame(name)) {
232
258
  this.frames.push(name);
@@ -236,6 +262,10 @@ Poltergeist.WebPage = (function() {
236
262
  }
237
263
  };
238
264
 
265
+ WebPage.prototype.pages = function() {
266
+ return this["native"].pagesWindowName;
267
+ };
268
+
239
269
  WebPage.prototype.popFrame = function() {
240
270
  this.frames.pop();
241
271
  return this["native"].switchToParentFrame();
@@ -243,20 +273,14 @@ Poltergeist.WebPage = (function() {
243
273
 
244
274
  WebPage.prototype.getPage = function(name) {
245
275
  var page;
246
-
247
- if (this.sub_pages[name]) {
248
- return this.sub_pages[name];
249
- } else {
250
- page = this["native"].getPage(name);
251
- if (page) {
252
- return this.sub_pages[name] = new Poltergeist.WebPage(page);
253
- }
276
+ page = this["native"].getPage(name);
277
+ if (page) {
278
+ return new Poltergeist.WebPage(page);
254
279
  }
255
280
  };
256
281
 
257
282
  WebPage.prototype.dimensions = function() {
258
283
  var scroll, viewport;
259
-
260
284
  scroll = this.scrollPosition();
261
285
  viewport = this.viewportSize();
262
286
  return {
@@ -271,7 +295,6 @@ Poltergeist.WebPage = (function() {
271
295
 
272
296
  WebPage.prototype.validatedDimensions = function() {
273
297
  var dimensions, document;
274
-
275
298
  dimensions = this.dimensions();
276
299
  document = dimensions.document;
277
300
  if (dimensions.right > document.width) {
@@ -300,7 +323,6 @@ Poltergeist.WebPage = (function() {
300
323
 
301
324
  WebPage.prototype.evaluate = function() {
302
325
  var args, fn;
303
-
304
326
  fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
305
327
  this.injectAgent();
306
328
  return JSON.parse(this["native"].evaluate("function() { return PoltergeistAgent.stringify(" + (this.stringifyCall(fn, args)) + ") }"));
@@ -308,7 +330,6 @@ Poltergeist.WebPage = (function() {
308
330
 
309
331
  WebPage.prototype.execute = function() {
310
332
  var args, fn;
311
-
312
333
  fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
313
334
  return this["native"].evaluate("function() { " + (this.stringifyCall(fn, args)) + " }");
314
335
  };
@@ -323,11 +344,9 @@ Poltergeist.WebPage = (function() {
323
344
 
324
345
  WebPage.prototype.bindCallback = function(name) {
325
346
  var that;
326
-
327
347
  that = this;
328
348
  return this["native"][name] = function() {
329
349
  var result;
330
-
331
350
  if (that[name + 'Native'] != null) {
332
351
  result = that[name + 'Native'].apply(that, arguments);
333
352
  }
@@ -339,7 +358,6 @@ Poltergeist.WebPage = (function() {
339
358
 
340
359
  WebPage.prototype.runCommand = function(name, args) {
341
360
  var result;
342
-
343
361
  result = this.evaluate(function(name, args) {
344
362
  return __poltergeist.externalCall(name, args);
345
363
  }, name, args);
@@ -3,7 +3,7 @@ class Poltergeist.WebPage
3
3
  'onLoadStarted', 'onResourceRequested', 'onResourceReceived',
4
4
  'onError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated']
5
5
 
6
- @DELEGATES = ['open', 'sendEvent', 'uploadFile', 'release', 'render']
6
+ @DELEGATES = ['open', 'sendEvent', 'uploadFile', 'release', 'render', 'renderBase64']
7
7
 
8
8
  @COMMANDS = ['currentUrl', 'find', 'nodeCall', 'documentSize', 'beforeUpload', 'afterUpload']
9
9
 
@@ -12,11 +12,11 @@ class Poltergeist.WebPage
12
12
  constructor: (@native) ->
13
13
  @native or= require('webpage').create()
14
14
 
15
- @_source = ""
15
+ @_source = null
16
16
  @_errors = []
17
17
  @_networkTraffic = {}
18
+ @_temp_headers = {}
18
19
  @frames = []
19
- @sub_pages = {}
20
20
 
21
21
  for callback in WebPage.CALLBACKS
22
22
  this.bindCallback(callback)
@@ -34,6 +34,7 @@ class Poltergeist.WebPage
34
34
  onInitializedNative: ->
35
35
  @_source = null
36
36
  @injectAgent()
37
+ this.removeTempHeaders()
37
38
  this.setScrollPosition(left: 0, top: 0)
38
39
 
39
40
  injectAgent: ->
@@ -143,12 +144,31 @@ class Poltergeist.WebPage
143
144
  setClipRect: (rect) ->
144
145
  @native.clipRect = rect
145
146
 
147
+ elementBounds: (selector) ->
148
+ @native.evaluate(
149
+ (selector) -> document.querySelector(selector).getBoundingClientRect(),
150
+ selector
151
+ )
152
+
146
153
  setUserAgent: (userAgent) ->
147
154
  @native.settings.userAgent = userAgent
148
155
 
156
+ getCustomHeaders: ->
157
+ @native.customHeaders
158
+
149
159
  setCustomHeaders: (headers) ->
150
160
  @native.customHeaders = headers
151
161
 
162
+ addTempHeader: (header) ->
163
+ for name, value of header
164
+ @_temp_headers[name] = value
165
+
166
+ removeTempHeaders: ->
167
+ allHeaders = this.getCustomHeaders()
168
+ for name, value of @_temp_headers
169
+ delete allHeaders[name]
170
+ this.setCustomHeaders(allHeaders)
171
+
152
172
  pushFrame: (name) ->
153
173
  if @native.switchToFrame(name)
154
174
  @frames.push(name)
@@ -156,16 +176,16 @@ class Poltergeist.WebPage
156
176
  else
157
177
  false
158
178
 
179
+ pages: ->
180
+ @native.pagesWindowName
181
+
159
182
  popFrame: ->
160
183
  @frames.pop()
161
184
  @native.switchToParentFrame()
162
185
 
163
186
  getPage: (name) ->
164
- if @sub_pages[name]
165
- @sub_pages[name]
166
- else
167
- page = @native.getPage(name)
168
- @sub_pages[name] = new Poltergeist.WebPage(page) if page
187
+ page = @native.getPage(name)
188
+ new Poltergeist.WebPage(page) if page
169
189
 
170
190
  dimensions: ->
171
191
  scroll = this.scrollPosition()
@@ -143,6 +143,10 @@ module Capybara::Poltergeist
143
143
  browser.within_window(name, &block)
144
144
  end
145
145
 
146
+ def window_handles
147
+ browser.window_handles
148
+ end
149
+
146
150
  def reset!
147
151
  browser.reset
148
152
  @started = false
@@ -153,19 +157,40 @@ module Capybara::Poltergeist
153
157
  end
154
158
  alias_method :render, :save_screenshot
155
159
 
160
+ def render_base64(format = :png, options = {})
161
+ browser.render_base64(format, options)
162
+ end
163
+
156
164
  def resize(width, height)
157
165
  browser.resize(width, height)
158
166
  end
159
167
  alias_method :resize_window, :resize
160
168
 
169
+ def scroll_to(left, top)
170
+ browser.scroll_to(left, top)
171
+ end
172
+
161
173
  def network_traffic
162
174
  browser.network_traffic
163
175
  end
164
176
 
177
+ def headers
178
+ browser.get_headers
179
+ end
180
+
165
181
  def headers=(headers)
166
182
  browser.set_headers(headers)
167
183
  end
168
184
 
185
+ def add_headers(headers)
186
+ browser.add_headers(headers)
187
+ end
188
+
189
+ def add_header(name, value, options = {})
190
+ permanent = options.fetch(:permanent, true)
191
+ browser.add_header({ name => value }, permanent)
192
+ end
193
+
169
194
  def response_headers
170
195
  browser.response_headers
171
196
  end
@@ -177,11 +202,12 @@ module Capybara::Poltergeist
177
202
  def set_cookie(name, value, options = {})
178
203
  options[:name] ||= name
179
204
  options[:value] ||= value
180
-
181
- if @started
182
- options[:domain] = URI.parse(browser.current_url).host
183
- else
184
- options[:domain] = Capybara.app_host || "127.0.0.1"
205
+ options[:domain] ||= begin
206
+ if @started
207
+ URI.parse(browser.current_url).host
208
+ else
209
+ Capybara.app_host || "127.0.0.1"
210
+ end
185
211
  end
186
212
 
187
213
  browser.set_cookie(options)
@@ -20,7 +20,7 @@ module Capybara
20
20
  end
21
21
 
22
22
  def to_s
23
- stack
23
+ [message, stack].join("\n")
24
24
  end
25
25
  end
26
26
 
@@ -140,28 +140,28 @@ module Capybara
140
140
  end
141
141
 
142
142
  class PhantomJSTooOld < Error
143
- attr_reader :version
144
-
145
- def initialize(version)
146
- @version = version
147
- end
148
-
149
- def message
150
- "PhantomJS version #{version} is too old. You must use at least version #{Client::PHANTOMJS_VERSION}"
143
+ def self.===(other)
144
+ if Cliver::Dependency::VersionMismatch === other
145
+ warn "{name} exception has been deprecated in favor of using the " +
146
+ "cliver gem for command-line dependency detection. Please " +
147
+ "handle Cliver::Dependency::VersionMismatch instead."
148
+ true
149
+ else
150
+ super
151
+ end
151
152
  end
152
153
  end
153
154
 
154
155
  class PhantomJSFailed < Error
155
- attr_reader :status
156
-
157
- def initialize(status)
158
- @status = status
159
- end
160
-
161
- def message
162
- "PhantomJS returned non-zero exit status #{status.exitstatus}. Make sure phantomjs runs successfully " \
163
- "on your system. You can test this by just running the `phantomjs` command which should give you " \
164
- "a Javascript REPL."
156
+ def self.===(other)
157
+ if Cliver::Dependency::NotMet === other
158
+ warn "{name} exception has been deprecated in favor of using the " +
159
+ "cliver gem for command-line dependency detection. Please " +
160
+ "handle Cliver::Dependency::NotMet instead."
161
+ true
162
+ else
163
+ super
164
+ end
165
165
  end
166
166
  end
167
167
  end
@@ -0,0 +1,25 @@
1
+ module Capybara::Poltergeist
2
+ module JSON
3
+ def self.load(message)
4
+ if dumpy_multi_json?
5
+ MultiJson.load(message)
6
+ else
7
+ MultiJson.decode(message)
8
+ end
9
+ end
10
+
11
+ def self.dump(message)
12
+ if dumpy_multi_json?
13
+ MultiJson.dump(message)
14
+ else
15
+ MultiJson.encode(message)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def self.dumpy_multi_json?
22
+ MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
23
+ end
24
+ end
25
+ end