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.
- checksums.yaml +7 -0
- data/README.md +68 -263
- data/lib/capybara/poltergeist.rb +1 -0
- data/lib/capybara/poltergeist/browser.rb +36 -3
- data/lib/capybara/poltergeist/client.rb +32 -31
- data/lib/capybara/poltergeist/client/agent.coffee +7 -6
- data/lib/capybara/poltergeist/client/browser.coffee +47 -13
- data/lib/capybara/poltergeist/client/compiled/agent.js +6 -24
- data/lib/capybara/poltergeist/client/compiled/browser.js +76 -39
- data/lib/capybara/poltergeist/client/compiled/main.js +0 -2
- data/lib/capybara/poltergeist/client/compiled/node.js +0 -4
- data/lib/capybara/poltergeist/client/compiled/web_page.js +42 -24
- data/lib/capybara/poltergeist/client/web_page.coffee +28 -8
- data/lib/capybara/poltergeist/driver.rb +31 -5
- data/lib/capybara/poltergeist/errors.rb +19 -19
- data/lib/capybara/poltergeist/json.rb +25 -0
- data/lib/capybara/poltergeist/node.rb +1 -1
- data/lib/capybara/poltergeist/version.rb +1 -1
- data/lib/capybara/poltergeist/web_socket_server.rb +13 -76
- metadata +47 -63
@@ -1,10 +1,11 @@
|
|
1
1
|
require "timeout"
|
2
2
|
require "capybara/poltergeist/utility"
|
3
|
+
require 'cliver'
|
3
4
|
|
4
5
|
module Capybara::Poltergeist
|
5
6
|
class Client
|
6
7
|
PHANTOMJS_SCRIPT = File.expand_path('../client/compiled/main.js', __FILE__)
|
7
|
-
PHANTOMJS_VERSION = '1.8.1'
|
8
|
+
PHANTOMJS_VERSION = ['~> 1.8','>= 1.8.1']
|
8
9
|
PHANTOMJS_NAME = 'phantomjs'
|
9
10
|
|
10
11
|
KILL_TIMEOUT = 2 # seconds
|
@@ -15,11 +16,26 @@ module Capybara::Poltergeist
|
|
15
16
|
client
|
16
17
|
end
|
17
18
|
|
19
|
+
# Returns a proc, that when called will attempt to kill the given process.
|
20
|
+
# This is because implementing ObjectSpace.define_finalizer is tricky.
|
21
|
+
# Hat-Tip to @mperham for describing in detail:
|
22
|
+
# http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
|
23
|
+
def self.process_killer(pid)
|
24
|
+
proc do
|
25
|
+
begin
|
26
|
+
Process.kill('KILL', pid)
|
27
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
18
32
|
attr_reader :pid, :server, :path, :window_size, :phantomjs_options
|
19
33
|
|
20
34
|
def initialize(server, options = {})
|
21
35
|
@server = server
|
22
|
-
@path = options[:path]
|
36
|
+
@path = Cliver::detect!((options[:path] || PHANTOMJS_NAME),
|
37
|
+
*PHANTOMJS_VERSION)
|
38
|
+
|
23
39
|
@window_size = options[:window_size] || [1024, 768]
|
24
40
|
@phantomjs_options = options[:phantomjs_options] || []
|
25
41
|
@phantomjs_logger = options[:phantomjs_logger] || $stdout
|
@@ -29,16 +45,19 @@ module Capybara::Poltergeist
|
|
29
45
|
end
|
30
46
|
|
31
47
|
def start
|
32
|
-
|
33
|
-
read, write = IO.pipe
|
48
|
+
@read_io, @write_io = IO.pipe
|
34
49
|
@out_thread = Thread.new {
|
35
|
-
while
|
50
|
+
while !@read_io.eof? && data = @read_io.readpartial(1024)
|
36
51
|
@phantomjs_logger.write(data)
|
37
52
|
end
|
38
53
|
}
|
39
54
|
|
40
|
-
|
41
|
-
|
55
|
+
process_options = {}
|
56
|
+
process_options[:pgroup] = true unless Capybara::Poltergeist.windows?
|
57
|
+
|
58
|
+
redirect_stdout do
|
59
|
+
@pid = Process.spawn(*command.map(&:to_s), process_options)
|
60
|
+
ObjectSpace.define_finalizer(self, self.class.process_killer(@pid) )
|
42
61
|
end
|
43
62
|
end
|
44
63
|
|
@@ -59,7 +78,9 @@ module Capybara::Poltergeist
|
|
59
78
|
rescue Errno::ESRCH, Errno::ECHILD
|
60
79
|
# Zed's dead, baby
|
61
80
|
end
|
62
|
-
|
81
|
+
ObjectSpace.undefine_finalizer(self)
|
82
|
+
@write_io.close
|
83
|
+
@read_io.close
|
63
84
|
@out_thread.kill
|
64
85
|
@pid = nil
|
65
86
|
end
|
@@ -81,33 +102,13 @@ module Capybara::Poltergeist
|
|
81
102
|
|
82
103
|
private
|
83
104
|
|
84
|
-
def check_phantomjs_version
|
85
|
-
return if @phantomjs_version_checked
|
86
|
-
|
87
|
-
version = `#{path} --version` rescue nil
|
88
|
-
|
89
|
-
if version.nil? || $? != 0
|
90
|
-
raise PhantomJSFailed.new($?)
|
91
|
-
else
|
92
|
-
major, minor, build = version.chomp.split('.').map(&:to_i)
|
93
|
-
min_major, min_minor, min_build = PHANTOMJS_VERSION.split('.').map(&:to_i)
|
94
|
-
if major < min_major ||
|
95
|
-
major == min_major && minor < min_minor ||
|
96
|
-
major == min_major && minor == min_minor && build < min_build
|
97
|
-
raise PhantomJSTooOld.new(version)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
@phantomjs_version_checked = true
|
102
|
-
end
|
103
|
-
|
104
105
|
# This abomination is because JRuby doesn't support the :out option of
|
105
106
|
# Process.spawn
|
106
|
-
def redirect_stdout
|
107
|
+
def redirect_stdout
|
107
108
|
prev = STDOUT.dup
|
108
109
|
prev.autoclose = false
|
109
|
-
$stdout =
|
110
|
-
STDOUT.reopen(
|
110
|
+
$stdout = @write_io
|
111
|
+
STDOUT.reopen(@write_io)
|
111
112
|
yield
|
112
113
|
ensure
|
113
114
|
STDOUT.reopen(prev)
|
@@ -25,7 +25,7 @@ class PoltergeistAgent
|
|
25
25
|
throw error
|
26
26
|
|
27
27
|
currentUrl: ->
|
28
|
-
window.location.
|
28
|
+
encodeURI(window.location.href)
|
29
29
|
|
30
30
|
find: (method, selector, within = document) ->
|
31
31
|
try
|
@@ -214,11 +214,12 @@ class PoltergeistAgent.Node
|
|
214
214
|
offset = { top: 0, left: 0 }
|
215
215
|
|
216
216
|
while win.frameElement
|
217
|
-
rect
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
offset.
|
217
|
+
rect = win.frameElement.getClientRects()[0]
|
218
|
+
style = win.getComputedStyle(win.frameElement)
|
219
|
+
win = win.parent
|
220
|
+
|
221
|
+
offset.top += rect.top + parseInt(style.getPropertyValue("padding-top"), 10)
|
222
|
+
offset.left += rect.left + parseInt(style.getPropertyValue("padding-left"), 10)
|
222
223
|
|
223
224
|
offset
|
224
225
|
|
@@ -82,7 +82,10 @@ class Poltergeist.Browser
|
|
82
82
|
visit: (url) ->
|
83
83
|
this.setState 'loading'
|
84
84
|
|
85
|
-
|
85
|
+
# Prevent firing `page.onInitialized` event twice. Calling currentUrl
|
86
|
+
# method before page is actually opened fires this event for the first time.
|
87
|
+
# The second time will be in the right place after `page.open`
|
88
|
+
prev_url = if @page.source() is null then 'about:blank' else @page.currentUrl()
|
86
89
|
|
87
90
|
@page.open(url)
|
88
91
|
|
@@ -171,6 +174,9 @@ class Poltergeist.Browser
|
|
171
174
|
else
|
172
175
|
@owner.sendError(new Poltergeist.FrameNotFound(name))
|
173
176
|
|
177
|
+
pages: ->
|
178
|
+
this.sendResponse(@page.pages())
|
179
|
+
|
174
180
|
pop_frame: ->
|
175
181
|
this.sendResponse(@page.popFrame())
|
176
182
|
|
@@ -240,21 +246,36 @@ class Poltergeist.Browser
|
|
240
246
|
this.resetPage()
|
241
247
|
this.sendResponse(true)
|
242
248
|
|
243
|
-
|
249
|
+
scroll_to: (left, top) ->
|
250
|
+
@page.setScrollPosition(left: left, top: top)
|
251
|
+
this.sendResponse(true)
|
252
|
+
|
253
|
+
render_base64: (format, full, selector = null)->
|
254
|
+
this.set_clip_rect(full, selector)
|
255
|
+
encoded_image = @page.renderBase64(format)
|
256
|
+
this.sendResponse(encoded_image)
|
257
|
+
|
258
|
+
render: (path, full, selector = null) ->
|
259
|
+
dimensions = this.set_clip_rect(full, selector)
|
260
|
+
@page.setScrollPosition(left: 0, top: 0)
|
261
|
+
@page.render(path)
|
262
|
+
@page.setScrollPosition(left: dimensions.left, top: dimensions.top)
|
263
|
+
this.sendResponse(true)
|
264
|
+
|
265
|
+
set_clip_rect: (full, selector) ->
|
244
266
|
dimensions = @page.validatedDimensions()
|
245
|
-
document
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
@page.setScrollPosition(left: 0, top: 0)
|
250
|
-
@page.setClipRect(left: 0, top: 0, width: document.width, height: document.height)
|
251
|
-
@page.render(path)
|
252
|
-
@page.setScrollPosition(left: dimensions.left, top: dimensions.top)
|
267
|
+
[document, viewport] = [dimensions.document, dimensions.viewport]
|
268
|
+
|
269
|
+
rect = if full
|
270
|
+
left: 0, top: 0, width: document.width, height: document.height
|
253
271
|
else
|
254
|
-
|
255
|
-
|
272
|
+
if selector?
|
273
|
+
@page.elementBounds(selector)
|
274
|
+
else
|
275
|
+
left: 0, top: 0, width: viewport.width, height: viewport.height
|
256
276
|
|
257
|
-
|
277
|
+
@page.setClipRect(rect)
|
278
|
+
dimensions
|
258
279
|
|
259
280
|
resize: (width, height) ->
|
260
281
|
@page.setViewportSize(width: width, height: height)
|
@@ -263,12 +284,25 @@ class Poltergeist.Browser
|
|
263
284
|
network_traffic: ->
|
264
285
|
this.sendResponse(@page.networkTraffic())
|
265
286
|
|
287
|
+
get_headers: ->
|
288
|
+
this.sendResponse(@page.getCustomHeaders())
|
289
|
+
|
266
290
|
set_headers: (headers) ->
|
267
291
|
# Workaround for https://code.google.com/p/phantomjs/issues/detail?id=745
|
268
292
|
@page.setUserAgent(headers['User-Agent']) if headers['User-Agent']
|
269
293
|
@page.setCustomHeaders(headers)
|
270
294
|
this.sendResponse(true)
|
271
295
|
|
296
|
+
add_headers: (headers) ->
|
297
|
+
allHeaders = @page.getCustomHeaders()
|
298
|
+
for name, value of headers
|
299
|
+
allHeaders[name] = value
|
300
|
+
this.set_headers(allHeaders)
|
301
|
+
|
302
|
+
add_header: (header, permanent) ->
|
303
|
+
@page.addTempHeader(header) unless permanent
|
304
|
+
this.add_headers(header)
|
305
|
+
|
272
306
|
response_headers: ->
|
273
307
|
this.sendResponse(@page.responseHeaders())
|
274
308
|
|
@@ -8,7 +8,6 @@ PoltergeistAgent = (function() {
|
|
8
8
|
|
9
9
|
PoltergeistAgent.prototype.externalCall = function(name, args) {
|
10
10
|
var error;
|
11
|
-
|
12
11
|
try {
|
13
12
|
return {
|
14
13
|
value: this[name].apply(this, args)
|
@@ -26,7 +25,6 @@ PoltergeistAgent = (function() {
|
|
26
25
|
|
27
26
|
PoltergeistAgent.stringify = function(object) {
|
28
27
|
var error;
|
29
|
-
|
30
28
|
try {
|
31
29
|
return JSON.stringify(object, function(key, value) {
|
32
30
|
if (Array.isArray(this[key])) {
|
@@ -46,12 +44,11 @@ PoltergeistAgent = (function() {
|
|
46
44
|
};
|
47
45
|
|
48
46
|
PoltergeistAgent.prototype.currentUrl = function() {
|
49
|
-
return window.location.
|
47
|
+
return encodeURI(window.location.href);
|
50
48
|
};
|
51
49
|
|
52
50
|
PoltergeistAgent.prototype.find = function(method, selector, within) {
|
53
51
|
var el, error, i, results, xpath, _i, _len, _results;
|
54
|
-
|
55
52
|
if (within == null) {
|
56
53
|
within = document;
|
57
54
|
}
|
@@ -60,7 +57,6 @@ PoltergeistAgent = (function() {
|
|
60
57
|
xpath = document.evaluate(selector, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
61
58
|
results = (function() {
|
62
59
|
var _i, _ref, _results;
|
63
|
-
|
64
60
|
_results = [];
|
65
61
|
for (i = _i = 0, _ref = xpath.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
66
62
|
_results.push(xpath.snapshotItem(i));
|
@@ -100,13 +96,11 @@ PoltergeistAgent = (function() {
|
|
100
96
|
|
101
97
|
PoltergeistAgent.prototype.get = function(id) {
|
102
98
|
var _base;
|
103
|
-
|
104
99
|
return (_base = this.nodes)[id] || (_base[id] = new PoltergeistAgent.Node(this, this.elements[id]));
|
105
100
|
};
|
106
101
|
|
107
102
|
PoltergeistAgent.prototype.nodeCall = function(id, name, args) {
|
108
103
|
var node;
|
109
|
-
|
110
104
|
node = this.get(id);
|
111
105
|
if (node.isObsolete()) {
|
112
106
|
throw new PoltergeistAgent.ObsoleteNode;
|
@@ -170,7 +164,6 @@ PoltergeistAgent.Node = (function() {
|
|
170
164
|
Node.prototype.isObsolete = function() {
|
171
165
|
var obsolete,
|
172
166
|
_this = this;
|
173
|
-
|
174
167
|
obsolete = function(element) {
|
175
168
|
if (element.parentNode != null) {
|
176
169
|
if (element.parentNode === document) {
|
@@ -187,7 +180,6 @@ PoltergeistAgent.Node = (function() {
|
|
187
180
|
|
188
181
|
Node.prototype.changed = function() {
|
189
182
|
var event;
|
190
|
-
|
191
183
|
event = document.createEvent('HTMLEvents');
|
192
184
|
event.initEvent('change', true, false);
|
193
185
|
return this.element.dispatchEvent(event);
|
@@ -195,7 +187,6 @@ PoltergeistAgent.Node = (function() {
|
|
195
187
|
|
196
188
|
Node.prototype.input = function() {
|
197
189
|
var event;
|
198
|
-
|
199
190
|
event = document.createEvent('HTMLEvents');
|
200
191
|
event.initEvent('input', true, false);
|
201
192
|
return this.element.dispatchEvent(event);
|
@@ -203,7 +194,6 @@ PoltergeistAgent.Node = (function() {
|
|
203
194
|
|
204
195
|
Node.prototype.keyupdowned = function(eventName, keyCode) {
|
205
196
|
var event;
|
206
|
-
|
207
197
|
event = document.createEvent('UIEvents');
|
208
198
|
event.initEvent(eventName, true, true);
|
209
199
|
event.keyCode = keyCode;
|
@@ -214,7 +204,6 @@ PoltergeistAgent.Node = (function() {
|
|
214
204
|
|
215
205
|
Node.prototype.keypressed = function(altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
|
216
206
|
var event;
|
217
|
-
|
218
207
|
event = document.createEvent('UIEvents');
|
219
208
|
event.initEvent('keypress', true, true);
|
220
209
|
event.window = this.agent.window;
|
@@ -258,7 +247,6 @@ PoltergeistAgent.Node = (function() {
|
|
258
247
|
|
259
248
|
Node.prototype.value = function() {
|
260
249
|
var option, _i, _len, _ref, _results;
|
261
|
-
|
262
250
|
if (this.element.tagName === 'SELECT' && this.element.multiple) {
|
263
251
|
_ref = this.element.children;
|
264
252
|
_results = [];
|
@@ -276,7 +264,6 @@ PoltergeistAgent.Node = (function() {
|
|
276
264
|
|
277
265
|
Node.prototype.set = function(value) {
|
278
266
|
var char, keyCode, _i, _len;
|
279
|
-
|
280
267
|
if (this.element.readOnly) {
|
281
268
|
return;
|
282
269
|
}
|
@@ -342,25 +329,24 @@ PoltergeistAgent.Node = (function() {
|
|
342
329
|
};
|
343
330
|
|
344
331
|
Node.prototype.frameOffset = function() {
|
345
|
-
var offset, rect, win;
|
346
|
-
|
332
|
+
var offset, rect, style, win;
|
347
333
|
win = window;
|
348
334
|
offset = {
|
349
335
|
top: 0,
|
350
336
|
left: 0
|
351
337
|
};
|
352
338
|
while (win.frameElement) {
|
353
|
-
rect =
|
339
|
+
rect = win.frameElement.getClientRects()[0];
|
340
|
+
style = win.getComputedStyle(win.frameElement);
|
354
341
|
win = win.parent;
|
355
|
-
offset.top += rect.top;
|
356
|
-
offset.left += rect.left;
|
342
|
+
offset.top += rect.top + parseInt(style.getPropertyValue("padding-top"), 10);
|
343
|
+
offset.left += rect.left + parseInt(style.getPropertyValue("padding-left"), 10);
|
357
344
|
}
|
358
345
|
return offset;
|
359
346
|
};
|
360
347
|
|
361
348
|
Node.prototype.position = function() {
|
362
349
|
var frameOffset, pos, rect;
|
363
|
-
|
364
350
|
rect = this.element.getClientRects()[0];
|
365
351
|
if (!rect) {
|
366
352
|
throw new PoltergeistAgent.ObsoleteNode;
|
@@ -379,7 +365,6 @@ PoltergeistAgent.Node = (function() {
|
|
379
365
|
|
380
366
|
Node.prototype.trigger = function(name) {
|
381
367
|
var event;
|
382
|
-
|
383
368
|
if (Node.EVENTS.MOUSE.indexOf(name) !== -1) {
|
384
369
|
event = document.createEvent('MouseEvent');
|
385
370
|
event.initMouseEvent(name, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
@@ -394,7 +379,6 @@ PoltergeistAgent.Node = (function() {
|
|
394
379
|
|
395
380
|
Node.prototype.mouseEventTest = function(x, y) {
|
396
381
|
var el, frameOffset, origEl;
|
397
|
-
|
398
382
|
frameOffset = this.frameOffset();
|
399
383
|
x -= frameOffset.left;
|
400
384
|
y -= frameOffset.top;
|
@@ -416,7 +400,6 @@ PoltergeistAgent.Node = (function() {
|
|
416
400
|
|
417
401
|
Node.prototype.getSelector = function(el) {
|
418
402
|
var className, selector, _i, _len, _ref;
|
419
|
-
|
420
403
|
selector = el.tagName !== 'HTML' ? this.getSelector(el.parentNode) + ' ' : '';
|
421
404
|
selector += el.tagName.toLowerCase();
|
422
405
|
if (el.id) {
|
@@ -432,7 +415,6 @@ PoltergeistAgent.Node = (function() {
|
|
432
415
|
|
433
416
|
Node.prototype.characterToKeyCode = function(character) {
|
434
417
|
var code, specialKeys;
|
435
|
-
|
436
418
|
code = character.toUpperCase().charCodeAt(0);
|
437
419
|
specialKeys = {
|
438
420
|
96: 192,
|
@@ -13,7 +13,6 @@ Poltergeist.Browser = (function() {
|
|
13
13
|
|
14
14
|
Browser.prototype.resetPage = function() {
|
15
15
|
var _this = this;
|
16
|
-
|
17
16
|
if (this.page != null) {
|
18
17
|
this.page.release();
|
19
18
|
phantom.clearCookies();
|
@@ -50,7 +49,6 @@ Poltergeist.Browser = (function() {
|
|
50
49
|
};
|
51
50
|
return this.page.onPageCreated = function(sub_page) {
|
52
51
|
var name;
|
53
|
-
|
54
52
|
if (_this.state === 'awaiting_sub_page') {
|
55
53
|
name = _this.page_name;
|
56
54
|
_this.page_name = null;
|
@@ -83,7 +81,6 @@ Poltergeist.Browser = (function() {
|
|
83
81
|
|
84
82
|
Browser.prototype.sendResponse = function(response) {
|
85
83
|
var errors;
|
86
|
-
|
87
84
|
errors = this.page.errors();
|
88
85
|
this.page.clearErrors();
|
89
86
|
if (errors.length > 0 && this.js_errors) {
|
@@ -108,9 +105,8 @@ Poltergeist.Browser = (function() {
|
|
108
105
|
|
109
106
|
Browser.prototype.visit = function(url) {
|
110
107
|
var prev_url;
|
111
|
-
|
112
108
|
this.setState('loading');
|
113
|
-
prev_url = this.page.currentUrl();
|
109
|
+
prev_url = this.page.source() === null ? 'about:blank' : this.page.currentUrl();
|
114
110
|
this.page.open(url);
|
115
111
|
if (/#/.test(url) && prev_url.split('#')[0] === url.split('#')[0]) {
|
116
112
|
this.setState('default');
|
@@ -172,7 +168,6 @@ Poltergeist.Browser = (function() {
|
|
172
168
|
|
173
169
|
Browser.prototype.select_file = function(page_id, id, value) {
|
174
170
|
var node;
|
175
|
-
|
176
171
|
node = this.node(page_id, id);
|
177
172
|
this.page.beforeUpload(node.id);
|
178
173
|
this.page.uploadFile('[_poltergeist_selected]', value);
|
@@ -207,7 +202,6 @@ Poltergeist.Browser = (function() {
|
|
207
202
|
|
208
203
|
Browser.prototype.push_frame = function(name, timeout) {
|
209
204
|
var _this = this;
|
210
|
-
|
211
205
|
if (timeout == null) {
|
212
206
|
timeout = new Date().getTime() + 2000;
|
213
207
|
}
|
@@ -228,6 +222,10 @@ Poltergeist.Browser = (function() {
|
|
228
222
|
}
|
229
223
|
};
|
230
224
|
|
225
|
+
Browser.prototype.pages = function() {
|
226
|
+
return this.sendResponse(this.page.pages());
|
227
|
+
};
|
228
|
+
|
231
229
|
Browser.prototype.pop_frame = function() {
|
232
230
|
return this.sendResponse(this.page.popFrame());
|
233
231
|
};
|
@@ -235,7 +233,6 @@ Poltergeist.Browser = (function() {
|
|
235
233
|
Browser.prototype.push_window = function(name) {
|
236
234
|
var sub_page,
|
237
235
|
_this = this;
|
238
|
-
|
239
236
|
sub_page = this.page.getPage(name);
|
240
237
|
if (sub_page) {
|
241
238
|
if (sub_page.currentUrl() === 'about:blank') {
|
@@ -257,7 +254,6 @@ Poltergeist.Browser = (function() {
|
|
257
254
|
|
258
255
|
Browser.prototype.pop_window = function() {
|
259
256
|
var prev_page;
|
260
|
-
|
261
257
|
prev_page = this.page_stack.pop();
|
262
258
|
if (prev_page) {
|
263
259
|
this.page = prev_page;
|
@@ -268,7 +264,6 @@ Poltergeist.Browser = (function() {
|
|
268
264
|
Browser.prototype.mouse_event = function(page_id, id, name) {
|
269
265
|
var node,
|
270
266
|
_this = this;
|
271
|
-
|
272
267
|
node = this.node(page_id, id);
|
273
268
|
this.setState('mouse_event');
|
274
269
|
this.last_mouse_event = node.mouseEvent(name);
|
@@ -321,40 +316,61 @@ Poltergeist.Browser = (function() {
|
|
321
316
|
return this.sendResponse(true);
|
322
317
|
};
|
323
318
|
|
324
|
-
Browser.prototype.
|
325
|
-
|
319
|
+
Browser.prototype.scroll_to = function(left, top) {
|
320
|
+
this.page.setScrollPosition({
|
321
|
+
left: left,
|
322
|
+
top: top
|
323
|
+
});
|
324
|
+
return this.sendResponse(true);
|
325
|
+
};
|
326
326
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
this.page.setScrollPosition({
|
332
|
-
left: 0,
|
333
|
-
top: 0
|
334
|
-
});
|
335
|
-
this.page.setClipRect({
|
336
|
-
left: 0,
|
337
|
-
top: 0,
|
338
|
-
width: document.width,
|
339
|
-
height: document.height
|
340
|
-
});
|
341
|
-
this.page.render(path);
|
342
|
-
this.page.setScrollPosition({
|
343
|
-
left: dimensions.left,
|
344
|
-
top: dimensions.top
|
345
|
-
});
|
346
|
-
} else {
|
347
|
-
this.page.setClipRect({
|
348
|
-
left: 0,
|
349
|
-
top: 0,
|
350
|
-
width: viewport.width,
|
351
|
-
height: viewport.height
|
352
|
-
});
|
353
|
-
this.page.render(path);
|
327
|
+
Browser.prototype.render_base64 = function(format, full, selector) {
|
328
|
+
var encoded_image;
|
329
|
+
if (selector == null) {
|
330
|
+
selector = null;
|
354
331
|
}
|
332
|
+
this.set_clip_rect(full, selector);
|
333
|
+
encoded_image = this.page.renderBase64(format);
|
334
|
+
return this.sendResponse(encoded_image);
|
335
|
+
};
|
336
|
+
|
337
|
+
Browser.prototype.render = function(path, full, selector) {
|
338
|
+
var dimensions;
|
339
|
+
if (selector == null) {
|
340
|
+
selector = null;
|
341
|
+
}
|
342
|
+
dimensions = this.set_clip_rect(full, selector);
|
343
|
+
this.page.setScrollPosition({
|
344
|
+
left: 0,
|
345
|
+
top: 0
|
346
|
+
});
|
347
|
+
this.page.render(path);
|
348
|
+
this.page.setScrollPosition({
|
349
|
+
left: dimensions.left,
|
350
|
+
top: dimensions.top
|
351
|
+
});
|
355
352
|
return this.sendResponse(true);
|
356
353
|
};
|
357
354
|
|
355
|
+
Browser.prototype.set_clip_rect = function(full, selector) {
|
356
|
+
var dimensions, document, rect, viewport, _ref;
|
357
|
+
dimensions = this.page.validatedDimensions();
|
358
|
+
_ref = [dimensions.document, dimensions.viewport], document = _ref[0], viewport = _ref[1];
|
359
|
+
rect = full ? {
|
360
|
+
left: 0,
|
361
|
+
top: 0,
|
362
|
+
width: document.width,
|
363
|
+
height: document.height
|
364
|
+
} : selector != null ? this.page.elementBounds(selector) : {
|
365
|
+
left: 0,
|
366
|
+
top: 0,
|
367
|
+
width: viewport.width,
|
368
|
+
height: viewport.height
|
369
|
+
};
|
370
|
+
this.page.setClipRect(rect);
|
371
|
+
return dimensions;
|
372
|
+
};
|
373
|
+
|
358
374
|
Browser.prototype.resize = function(width, height) {
|
359
375
|
this.page.setViewportSize({
|
360
376
|
width: width,
|
@@ -367,6 +383,10 @@ Poltergeist.Browser = (function() {
|
|
367
383
|
return this.sendResponse(this.page.networkTraffic());
|
368
384
|
};
|
369
385
|
|
386
|
+
Browser.prototype.get_headers = function() {
|
387
|
+
return this.sendResponse(this.page.getCustomHeaders());
|
388
|
+
};
|
389
|
+
|
370
390
|
Browser.prototype.set_headers = function(headers) {
|
371
391
|
if (headers['User-Agent']) {
|
372
392
|
this.page.setUserAgent(headers['User-Agent']);
|
@@ -375,6 +395,23 @@ Poltergeist.Browser = (function() {
|
|
375
395
|
return this.sendResponse(true);
|
376
396
|
};
|
377
397
|
|
398
|
+
Browser.prototype.add_headers = function(headers) {
|
399
|
+
var allHeaders, name, value;
|
400
|
+
allHeaders = this.page.getCustomHeaders();
|
401
|
+
for (name in headers) {
|
402
|
+
value = headers[name];
|
403
|
+
allHeaders[name] = value;
|
404
|
+
}
|
405
|
+
return this.set_headers(allHeaders);
|
406
|
+
};
|
407
|
+
|
408
|
+
Browser.prototype.add_header = function(header, permanent) {
|
409
|
+
if (!permanent) {
|
410
|
+
this.page.addTempHeader(header);
|
411
|
+
}
|
412
|
+
return this.add_headers(header);
|
413
|
+
};
|
414
|
+
|
378
415
|
Browser.prototype.response_headers = function() {
|
379
416
|
return this.sendResponse(this.page.responseHeaders());
|
380
417
|
};
|