poltergeist 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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