poltergeist 1.17.0 → 1.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/lib/capybara/poltergeist/browser.rb +18 -6
- data/lib/capybara/poltergeist/client/agent.coffee +18 -9
- data/lib/capybara/poltergeist/client/browser.coffee +42 -27
- data/lib/capybara/poltergeist/client/compiled/agent.js +19 -7
- data/lib/capybara/poltergeist/client/compiled/browser.js +64 -29
- data/lib/capybara/poltergeist/client/compiled/node.js +39 -12
- data/lib/capybara/poltergeist/client/compiled/web_page.js +64 -7
- data/lib/capybara/poltergeist/client/node.coffee +27 -8
- data/lib/capybara/poltergeist/client/web_page.coffee +39 -7
- data/lib/capybara/poltergeist/driver.rb +19 -2
- data/lib/capybara/poltergeist/node.rb +28 -10
- data/lib/capybara/poltergeist/version.rb +1 -1
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7f5bf350711720abecb06c20bab6cea6489844fc3cd60b89a19d89c64723b02
|
4
|
+
data.tar.gz: 10b8c208d718baecf0515a7e3add9d185f522e04ad62773c41dd562de8a8817f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18313bbc53ca8455008626bb7d521ad1cdd3f66daefad18b859a2a4a2132e38b4f306f46bc8e4a5c8bb80bd2232b3e7693653d3d7be12d86c7470ec01319d63c
|
7
|
+
data.tar.gz: bc7d1dd21d97d69b2902e77a4cf175be3fbec635650d5879e240fe29ec90511e96200cced21dbc225d82babd8154aaa47b60653cc75b813a1692893c13bbca31
|
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.
|
12
|
+
(1.18.0).](https://github.com/teampoltergeist/poltergeist/tree/v1.18.0)**
|
13
13
|
|
14
14
|
## Getting help ##
|
15
15
|
|
@@ -207,6 +207,10 @@ This way your temporary headers will be sent only for the initial request, and r
|
|
207
207
|
subsequent request will only contain your permanent headers. If the temporary
|
208
208
|
headers should not be sent on related 30x redirects, specify `permanent: :no_redirect`.
|
209
209
|
|
210
|
+
Headers set with any of these methods will be set within all windows in the
|
211
|
+
session, with the exception of temporary headers, which are only set within the
|
212
|
+
current window.
|
213
|
+
|
210
214
|
### Inspecting network traffic ###
|
211
215
|
|
212
216
|
You can inspect the network traffic (i.e. what resources have been
|
@@ -294,6 +298,7 @@ end
|
|
294
298
|
* `:host` (String) - The name or IP of the PhantomJS host. Default is '127.0.0.1'.
|
295
299
|
* `:url_blacklist` (Array) - Default session url blacklist - expressed as an array of strings to match against requested URLs.
|
296
300
|
* `:url_whitelist` (Array) - Default session url whitelist - expressed as an array of strings to match against requested URLs.
|
301
|
+
* `:page_settings` (Hash) - PhantomJS web page settings (http://phantomjs.org/api/webpage/property/settings.html).
|
297
302
|
|
298
303
|
### URL Blacklisting & Whitelisting ###
|
299
304
|
Poltergeist supports URL blacklisting, which allows you
|
@@ -43,6 +43,10 @@ module Capybara::Poltergeist
|
|
43
43
|
command 'current_url'
|
44
44
|
end
|
45
45
|
|
46
|
+
def frame_url
|
47
|
+
command 'frame_url'
|
48
|
+
end
|
49
|
+
|
46
50
|
def status_code
|
47
51
|
command 'status_code'
|
48
52
|
end
|
@@ -59,6 +63,10 @@ module Capybara::Poltergeist
|
|
59
63
|
command 'title'
|
60
64
|
end
|
61
65
|
|
66
|
+
def frame_title
|
67
|
+
command 'frame_title'
|
68
|
+
end
|
69
|
+
|
62
70
|
def parents(page_id, id)
|
63
71
|
command 'parents', page_id, id
|
64
72
|
end
|
@@ -196,16 +204,16 @@ module Capybara::Poltergeist
|
|
196
204
|
switch_to_window(original)
|
197
205
|
end
|
198
206
|
|
199
|
-
def click(page_id, id)
|
200
|
-
command 'click', page_id, id
|
207
|
+
def click(page_id, id, keys=[], offset={})
|
208
|
+
command 'click', page_id, id, keys, offset
|
201
209
|
end
|
202
210
|
|
203
|
-
def right_click(page_id, id)
|
204
|
-
command 'right_click', page_id, id
|
211
|
+
def right_click(page_id, id, keys=[], offset={})
|
212
|
+
command 'right_click', page_id, id, keys, offset
|
205
213
|
end
|
206
214
|
|
207
|
-
def double_click(page_id, id)
|
208
|
-
command 'double_click', page_id, id
|
215
|
+
def double_click(page_id, id, keys=[], offset={})
|
216
|
+
command 'double_click', page_id, id, keys, offset
|
209
217
|
end
|
210
218
|
|
211
219
|
def hover(page_id, id)
|
@@ -346,6 +354,10 @@ module Capybara::Poltergeist
|
|
346
354
|
command 'set_js_errors', !!val
|
347
355
|
end
|
348
356
|
|
357
|
+
def page_settings=(settings)
|
358
|
+
command 'set_page_settings', settings
|
359
|
+
end
|
360
|
+
|
349
361
|
def extensions=(names)
|
350
362
|
@extensions = names
|
351
363
|
Array(names).each do |name|
|
@@ -13,8 +13,8 @@ class PoltergeistAgent
|
|
13
13
|
# Somehow PhantomJS returns all characters(brackets, etc) properly encoded
|
14
14
|
# except whitespace character in pathname part of the location. This hack
|
15
15
|
# is intended to fix this up.
|
16
|
-
|
17
|
-
window.location.href
|
16
|
+
frameUrl: ->
|
17
|
+
window.location.href
|
18
18
|
|
19
19
|
find: (method, selector, within = document) ->
|
20
20
|
try
|
@@ -55,7 +55,9 @@ class PoltergeistAgent
|
|
55
55
|
this.get(id).removeAttribute('_poltergeist_selected')
|
56
56
|
|
57
57
|
clearLocalStorage: ->
|
58
|
-
|
58
|
+
try
|
59
|
+
localStorage?.clear()
|
60
|
+
catch error
|
59
61
|
|
60
62
|
wrapResults: (result, page_id)->
|
61
63
|
@_visitedObjects ||= [];
|
@@ -250,12 +252,12 @@ class PoltergeistAgent.Node
|
|
250
252
|
else if value == false && !@element.parentNode.multiple
|
251
253
|
false
|
252
254
|
else
|
253
|
-
this.trigger('focus', @element.parentNode)
|
255
|
+
this.trigger('focus', {}, @element.parentNode)
|
254
256
|
|
255
257
|
@element.selected = value
|
256
258
|
this.changed()
|
257
259
|
|
258
|
-
this.trigger('blur', @element.parentNode)
|
260
|
+
this.trigger('blur', {}, @element.parentNode)
|
259
261
|
true
|
260
262
|
|
261
263
|
tagName: ->
|
@@ -326,7 +328,7 @@ class PoltergeistAgent.Node
|
|
326
328
|
offset
|
327
329
|
|
328
330
|
position: ->
|
329
|
-
# Elements inside an SVG return
|
331
|
+
# Elements inside an SVG return undefined for getClientRects???
|
330
332
|
rect = @element.getClientRects()[0] || @element.getBoundingClientRect()
|
331
333
|
throw new PoltergeistAgent.ObsoleteNode unless rect
|
332
334
|
frameOffset = this.frameOffset()
|
@@ -342,12 +344,18 @@ class PoltergeistAgent.Node
|
|
342
344
|
|
343
345
|
pos
|
344
346
|
|
345
|
-
trigger: (name, element = @element) ->
|
347
|
+
trigger: (name, options = {}, element = @element) ->
|
346
348
|
if Node.EVENTS.MOUSE.indexOf(name) != -1
|
347
349
|
event = document.createEvent('MouseEvent')
|
348
350
|
event.initMouseEvent(
|
349
|
-
name, true, true, window, 0,
|
350
|
-
|
351
|
+
name, true, true, window, 0,
|
352
|
+
options['screenX'] || 0, options['screenY'] || 0,
|
353
|
+
options['clientX'] || 0, options['clientY'] || 0,
|
354
|
+
options['ctrlKey'] || false,
|
355
|
+
options['altKey'] || false,
|
356
|
+
options['shiftKey'] || false,
|
357
|
+
options['metaKey'] || false,
|
358
|
+
options['button'] || 0, null
|
351
359
|
)
|
352
360
|
else if Node.EVENTS.FOCUS.indexOf(name) != -1
|
353
361
|
event = this.obtainEvent(name)
|
@@ -437,3 +445,4 @@ document.addEventListener(
|
|
437
445
|
'DOMContentLoaded',
|
438
446
|
-> console.log('__DOMContentLoaded')
|
439
447
|
)
|
448
|
+
console.log('__DOMContentLoaded') if document.readyState == 'complete'
|
@@ -6,6 +6,7 @@ class Poltergeist.Browser
|
|
6
6
|
@js_errors = true
|
7
7
|
@_debug = false
|
8
8
|
@_counter = 0
|
9
|
+
@_page_settings = null
|
9
10
|
|
10
11
|
@processed_modal_messages = []
|
11
12
|
@confirm_processes = []
|
@@ -18,11 +19,11 @@ class Poltergeist.Browser
|
|
18
19
|
|
19
20
|
if @page?
|
20
21
|
unless @page.closed
|
21
|
-
@page.clearLocalStorage() if @page.
|
22
|
+
@page.clearLocalStorage() if @page.frameUrl() != 'about:blank'
|
22
23
|
@page.close()
|
23
24
|
phantom.clearCookies()
|
24
25
|
|
25
|
-
@page = @currentPage = new Poltergeist.WebPage
|
26
|
+
@page = @currentPage = new Poltergeist.WebPage(null, @_page_settings)
|
26
27
|
@page.setViewportSize(width: @width, height: @height)
|
27
28
|
@page.handle = "#{@_counter++}"
|
28
29
|
@pages.push(@page)
|
@@ -54,11 +55,13 @@ class Poltergeist.Browser
|
|
54
55
|
return response
|
55
56
|
|
56
57
|
page.onPageCreated = (newPage) =>
|
57
|
-
_page = new Poltergeist.WebPage(newPage)
|
58
|
+
_page = new Poltergeist.WebPage(newPage, @_page_settings)
|
58
59
|
_page.handle = "#{@_counter++}"
|
59
60
|
_page.urlBlacklist = page.urlBlacklist
|
60
61
|
_page.urlWhitelist = page.urlWhitelist
|
61
62
|
_page.setViewportSize(page.viewportSize())
|
63
|
+
_page.setUserAgent(page.getUserAgent())
|
64
|
+
_page.setCustomHeaders(page.getPermanentCustomHeaders())
|
62
65
|
@setupPageHandlers(_page)
|
63
66
|
@pages.push(_page)
|
64
67
|
|
@@ -98,11 +101,10 @@ class Poltergeist.Browser
|
|
98
101
|
@confirm_processes = []
|
99
102
|
@prompt_responses = []
|
100
103
|
|
101
|
-
|
102
104
|
# Prevent firing `page.onInitialized` event twice. Calling currentUrl
|
103
105
|
# method before page is actually opened fires this event for the first time.
|
104
106
|
# The second time will be in the right place after `page.open`
|
105
|
-
prevUrl = if @currentPage.source
|
107
|
+
prevUrl = if @currentPage.source? then @currentPage.currentUrl() else 'about:blank'
|
106
108
|
|
107
109
|
@currentPage.open(url)
|
108
110
|
|
@@ -130,6 +132,9 @@ class Poltergeist.Browser
|
|
130
132
|
current_url: ->
|
131
133
|
@current_command.sendResponse @currentPage.currentUrl()
|
132
134
|
|
135
|
+
frame_url: ->
|
136
|
+
@current_command.sendResponse @currentPage.frameUrl()
|
137
|
+
|
133
138
|
status_code: ->
|
134
139
|
@current_command.sendResponse @currentPage.statusCode
|
135
140
|
|
@@ -142,6 +147,9 @@ class Poltergeist.Browser
|
|
142
147
|
title: ->
|
143
148
|
@current_command.sendResponse @currentPage.title()
|
144
149
|
|
150
|
+
frame_title: ->
|
151
|
+
@current_command.sendResponse @currentPage.frameTitle()
|
152
|
+
|
145
153
|
find: (method, selector) ->
|
146
154
|
@current_command.sendResponse(page_id: @currentPage.id, ids: @currentPage.find(method, selector))
|
147
155
|
|
@@ -231,8 +239,8 @@ class Poltergeist.Browser
|
|
231
239
|
@currentPage.execute("function() { #{script} }", args...)
|
232
240
|
@current_command.sendResponse(true)
|
233
241
|
|
234
|
-
|
235
|
-
@currentPage.
|
242
|
+
frameUrlFor: (frame_name) ->
|
243
|
+
@currentPage.frameUrlFor(frame_name)
|
236
244
|
|
237
245
|
pushFrame: (command, name, timeout) ->
|
238
246
|
if Array.isArray(name)
|
@@ -242,11 +250,12 @@ class Poltergeist.Browser
|
|
242
250
|
frame.setAttribute('name', "_random_name_#{new Date().getTime()}")
|
243
251
|
name = frame.getAttribute('name')
|
244
252
|
|
245
|
-
frame_url = @
|
253
|
+
frame_url = @frameUrlFor(name)
|
246
254
|
if frame_url in @currentPage.blockedUrls()
|
247
255
|
command.sendResponse(true)
|
248
256
|
else if @currentPage.pushFrame(name)
|
249
|
-
if frame_url && (frame_url != 'about:blank') && (@currentPage.currentUrl() == 'about:blank')
|
257
|
+
# if frame_url && (frame_url != 'about:blank') && (@currentPage.currentUrl() == 'about:blank')
|
258
|
+
if frame_url && (frame_url != 'about:blank') && (@currentPage.frameUrl() == 'about:blank')
|
250
259
|
@currentPage.state = 'awaiting_frame_load'
|
251
260
|
@currentPage.waitState 'default', ->
|
252
261
|
command.sendResponse(true)
|
@@ -302,14 +311,14 @@ class Poltergeist.Browser
|
|
302
311
|
else
|
303
312
|
@current_command.sendResponse(false)
|
304
313
|
|
305
|
-
mouse_event: (page_id, id, name) ->
|
314
|
+
mouse_event: (page_id, id, name, keys=[], offset={}) ->
|
306
315
|
# Get the node before changing state, in case there is an exception
|
307
316
|
node = this.node(page_id, id)
|
308
317
|
# If the event triggers onNavigationRequested, we will transition to the 'loading'
|
309
318
|
# state and wait for onLoadFinished before sending a response.
|
310
319
|
@currentPage.state = 'mouse_event'
|
311
320
|
|
312
|
-
last_mouse_event = node.mouseEvent(name)
|
321
|
+
last_mouse_event = node.mouseEvent(name, keys, offset)
|
313
322
|
event_page = @currentPage
|
314
323
|
command = @current_command
|
315
324
|
|
@@ -323,14 +332,14 @@ class Poltergeist.Browser
|
|
323
332
|
command.sendResponse(position: last_mouse_event)
|
324
333
|
, 5
|
325
334
|
|
326
|
-
click: (page_id, id) ->
|
327
|
-
this.mouse_event page_id, id, 'click'
|
335
|
+
click: (page_id, id, keys, offset) ->
|
336
|
+
this.mouse_event page_id, id, 'click', keys, offset
|
328
337
|
|
329
|
-
right_click: (page_id, id) ->
|
330
|
-
this.mouse_event page_id, id, 'rightclick'
|
338
|
+
right_click: (page_id, id, keys, offset) ->
|
339
|
+
this.mouse_event page_id, id, 'rightclick', keys, offset
|
331
340
|
|
332
|
-
double_click: (page_id, id) ->
|
333
|
-
this.mouse_event page_id, id, 'doubleclick'
|
341
|
+
double_click: (page_id, id, keys, offset) ->
|
342
|
+
this.mouse_event page_id, id, 'doubleclick', keys, offset
|
334
343
|
|
335
344
|
hover: (page_id, id) ->
|
336
345
|
this.mouse_event page_id, id, 'mousemove'
|
@@ -458,22 +467,23 @@ class Poltergeist.Browser
|
|
458
467
|
@current_command.sendResponse(@currentPage.getCustomHeaders())
|
459
468
|
|
460
469
|
set_headers: (headers) ->
|
461
|
-
|
462
|
-
|
463
|
-
|
470
|
+
this.add_headers(headers, false, false)
|
471
|
+
|
472
|
+
add_headers: (headers, local = false, keepExisting = true) ->
|
473
|
+
pages = if local then [@currentPage] else @pages
|
474
|
+
pages.forEach (page) =>
|
475
|
+
allHeaders = if keepExisting then page.getCustomHeaders() else {}
|
476
|
+
for name, value of headers
|
477
|
+
allHeaders[name] = value
|
478
|
+
page.setUserAgent(allHeaders['User-Agent']) if allHeaders['User-Agent']
|
479
|
+
page.setCustomHeaders(allHeaders)
|
464
480
|
@current_command.sendResponse(true)
|
465
481
|
|
466
|
-
add_headers: (headers) ->
|
467
|
-
allHeaders = @currentPage.getCustomHeaders()
|
468
|
-
for name, value of headers
|
469
|
-
allHeaders[name] = value
|
470
|
-
this.set_headers(allHeaders)
|
471
|
-
|
472
482
|
add_header: (header, { permanent = true }) ->
|
473
483
|
unless permanent == true
|
474
484
|
@currentPage.addTempHeader(header)
|
475
485
|
@currentPage.addTempHeaderToRemoveOnRedirect(header) if permanent == "no_redirect"
|
476
|
-
this.add_headers(header)
|
486
|
+
this.add_headers(header, permanent != true)
|
477
487
|
|
478
488
|
response_headers: ->
|
479
489
|
@current_command.sendResponse(@currentPage.responseHeaders())
|
@@ -511,6 +521,11 @@ class Poltergeist.Browser
|
|
511
521
|
@_debug = value
|
512
522
|
@current_command.sendResponse(true)
|
513
523
|
|
524
|
+
set_page_settings: (settings)->
|
525
|
+
@_page_settings = settings
|
526
|
+
@page.setSettings(@_page_settings)
|
527
|
+
@current_command.sendResponse(true)
|
528
|
+
|
514
529
|
exit: ->
|
515
530
|
phantom.exit()
|
516
531
|
|
@@ -25,8 +25,8 @@ PoltergeistAgent = (function() {
|
|
25
25
|
}
|
26
26
|
};
|
27
27
|
|
28
|
-
PoltergeistAgent.prototype.
|
29
|
-
return window.location.href
|
28
|
+
PoltergeistAgent.prototype.frameUrl = function() {
|
29
|
+
return window.location.href;
|
30
30
|
};
|
31
31
|
|
32
32
|
PoltergeistAgent.prototype.find = function(method, selector, within) {
|
@@ -99,7 +99,12 @@ PoltergeistAgent = (function() {
|
|
99
99
|
};
|
100
100
|
|
101
101
|
PoltergeistAgent.prototype.clearLocalStorage = function() {
|
102
|
-
|
102
|
+
var error;
|
103
|
+
try {
|
104
|
+
return typeof localStorage !== "undefined" && localStorage !== null ? localStorage.clear() : void 0;
|
105
|
+
} catch (error1) {
|
106
|
+
error = error1;
|
107
|
+
}
|
103
108
|
};
|
104
109
|
|
105
110
|
PoltergeistAgent.prototype.wrapResults = function(result, page_id) {
|
@@ -388,10 +393,10 @@ PoltergeistAgent.Node = (function() {
|
|
388
393
|
} else if (value === false && !this.element.parentNode.multiple) {
|
389
394
|
return false;
|
390
395
|
} else {
|
391
|
-
this.trigger('focus', this.element.parentNode);
|
396
|
+
this.trigger('focus', {}, this.element.parentNode);
|
392
397
|
this.element.selected = value;
|
393
398
|
this.changed();
|
394
|
-
this.trigger('blur', this.element.parentNode);
|
399
|
+
this.trigger('blur', {}, this.element.parentNode);
|
395
400
|
return true;
|
396
401
|
}
|
397
402
|
};
|
@@ -497,14 +502,17 @@ PoltergeistAgent.Node = (function() {
|
|
497
502
|
return pos;
|
498
503
|
};
|
499
504
|
|
500
|
-
Node.prototype.trigger = function(name, element) {
|
505
|
+
Node.prototype.trigger = function(name, options, element) {
|
501
506
|
var event;
|
507
|
+
if (options == null) {
|
508
|
+
options = {};
|
509
|
+
}
|
502
510
|
if (element == null) {
|
503
511
|
element = this.element;
|
504
512
|
}
|
505
513
|
if (Node.EVENTS.MOUSE.indexOf(name) !== -1) {
|
506
514
|
event = document.createEvent('MouseEvent');
|
507
|
-
event.initMouseEvent(name, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
515
|
+
event.initMouseEvent(name, true, true, window, 0, options['screenX'] || 0, options['screenY'] || 0, options['clientX'] || 0, options['clientY'] || 0, options['ctrlKey'] || false, options['altKey'] || false, options['shiftKey'] || false, options['metaKey'] || false, options['button'] || 0, null);
|
508
516
|
} else if (Node.EVENTS.FOCUS.indexOf(name) !== -1) {
|
509
517
|
event = this.obtainEvent(name);
|
510
518
|
} else if (Node.EVENTS.FORM.indexOf(name) !== -1) {
|
@@ -614,3 +622,7 @@ window.__poltergeist = new PoltergeistAgent;
|
|
614
622
|
document.addEventListener('DOMContentLoaded', function() {
|
615
623
|
return console.log('__DOMContentLoaded');
|
616
624
|
});
|
625
|
+
|
626
|
+
if (document.readyState === 'complete') {
|
627
|
+
console.log('__DOMContentLoaded');
|
628
|
+
}
|
@@ -9,6 +9,7 @@ Poltergeist.Browser = (function() {
|
|
9
9
|
this.js_errors = true;
|
10
10
|
this._debug = false;
|
11
11
|
this._counter = 0;
|
12
|
+
this._page_settings = null;
|
12
13
|
this.processed_modal_messages = [];
|
13
14
|
this.confirm_processes = [];
|
14
15
|
this.prompt_responses = [];
|
@@ -20,14 +21,14 @@ Poltergeist.Browser = (function() {
|
|
20
21
|
ref = [0, []], this._counter = ref[0], this.pages = ref[1];
|
21
22
|
if (this.page != null) {
|
22
23
|
if (!this.page.closed) {
|
23
|
-
if (this.page.
|
24
|
+
if (this.page.frameUrl() !== 'about:blank') {
|
24
25
|
this.page.clearLocalStorage();
|
25
26
|
}
|
26
27
|
this.page.close();
|
27
28
|
}
|
28
29
|
phantom.clearCookies();
|
29
30
|
}
|
30
|
-
this.page = this.currentPage = new Poltergeist.WebPage;
|
31
|
+
this.page = this.currentPage = new Poltergeist.WebPage(null, this._page_settings);
|
31
32
|
this.page.setViewportSize({
|
32
33
|
width: this.width,
|
33
34
|
height: this.height
|
@@ -71,11 +72,13 @@ Poltergeist.Browser = (function() {
|
|
71
72
|
page.onPageCreated = (function(_this) {
|
72
73
|
return function(newPage) {
|
73
74
|
var _page;
|
74
|
-
_page = new Poltergeist.WebPage(newPage);
|
75
|
+
_page = new Poltergeist.WebPage(newPage, _this._page_settings);
|
75
76
|
_page.handle = "" + (_this._counter++);
|
76
77
|
_page.urlBlacklist = page.urlBlacklist;
|
77
78
|
_page.urlWhitelist = page.urlWhitelist;
|
78
79
|
_page.setViewportSize(page.viewportSize());
|
80
|
+
_page.setUserAgent(page.getUserAgent());
|
81
|
+
_page.setCustomHeaders(page.getPermanentCustomHeaders());
|
79
82
|
_this.setupPageHandlers(_page);
|
80
83
|
return _this.pages.push(_page);
|
81
84
|
};
|
@@ -129,7 +132,7 @@ Poltergeist.Browser = (function() {
|
|
129
132
|
this.processed_modal_messages = [];
|
130
133
|
this.confirm_processes = [];
|
131
134
|
this.prompt_responses = [];
|
132
|
-
prevUrl = this.currentPage.source
|
135
|
+
prevUrl = this.currentPage.source != null ? this.currentPage.currentUrl() : 'about:blank';
|
133
136
|
this.currentPage.open(url);
|
134
137
|
if (/#/.test(url) && prevUrl.split('#')[0] === url.split('#')[0]) {
|
135
138
|
this.currentPage.state = 'default';
|
@@ -160,6 +163,10 @@ Poltergeist.Browser = (function() {
|
|
160
163
|
return this.current_command.sendResponse(this.currentPage.currentUrl());
|
161
164
|
};
|
162
165
|
|
166
|
+
Browser.prototype.frame_url = function() {
|
167
|
+
return this.current_command.sendResponse(this.currentPage.frameUrl());
|
168
|
+
};
|
169
|
+
|
163
170
|
Browser.prototype.status_code = function() {
|
164
171
|
return this.current_command.sendResponse(this.currentPage.statusCode);
|
165
172
|
};
|
@@ -176,6 +183,10 @@ Poltergeist.Browser = (function() {
|
|
176
183
|
return this.current_command.sendResponse(this.currentPage.title());
|
177
184
|
};
|
178
185
|
|
186
|
+
Browser.prototype.frame_title = function() {
|
187
|
+
return this.current_command.sendResponse(this.currentPage.frameTitle());
|
188
|
+
};
|
189
|
+
|
179
190
|
Browser.prototype.find = function(method, selector) {
|
180
191
|
return this.current_command.sendResponse({
|
181
192
|
page_id: this.currentPage.id,
|
@@ -311,8 +322,8 @@ Poltergeist.Browser = (function() {
|
|
311
322
|
return this.current_command.sendResponse(true);
|
312
323
|
};
|
313
324
|
|
314
|
-
Browser.prototype.
|
315
|
-
return this.currentPage.
|
325
|
+
Browser.prototype.frameUrlFor = function(frame_name) {
|
326
|
+
return this.currentPage.frameUrlFor(frame_name);
|
316
327
|
};
|
317
328
|
|
318
329
|
Browser.prototype.pushFrame = function(command, name, timeout) {
|
@@ -325,11 +336,11 @@ Poltergeist.Browser = (function() {
|
|
325
336
|
name = frame.getAttribute('name');
|
326
337
|
}
|
327
338
|
}
|
328
|
-
frame_url = this.
|
339
|
+
frame_url = this.frameUrlFor(name);
|
329
340
|
if (indexOf.call(this.currentPage.blockedUrls(), frame_url) >= 0) {
|
330
341
|
return command.sendResponse(true);
|
331
342
|
} else if (this.currentPage.pushFrame(name)) {
|
332
|
-
if (frame_url && (frame_url !== 'about:blank') && (this.currentPage.
|
343
|
+
if (frame_url && (frame_url !== 'about:blank') && (this.currentPage.frameUrl() === 'about:blank')) {
|
333
344
|
this.currentPage.state = 'awaiting_frame_load';
|
334
345
|
return this.currentPage.waitState('default', function() {
|
335
346
|
return command.sendResponse(true);
|
@@ -421,11 +432,17 @@ Poltergeist.Browser = (function() {
|
|
421
432
|
}
|
422
433
|
};
|
423
434
|
|
424
|
-
Browser.prototype.mouse_event = function(page_id, id, name) {
|
435
|
+
Browser.prototype.mouse_event = function(page_id, id, name, keys, offset) {
|
425
436
|
var command, event_page, last_mouse_event, node;
|
437
|
+
if (keys == null) {
|
438
|
+
keys = [];
|
439
|
+
}
|
440
|
+
if (offset == null) {
|
441
|
+
offset = {};
|
442
|
+
}
|
426
443
|
node = this.node(page_id, id);
|
427
444
|
this.currentPage.state = 'mouse_event';
|
428
|
-
last_mouse_event = node.mouseEvent(name);
|
445
|
+
last_mouse_event = node.mouseEvent(name, keys, offset);
|
429
446
|
event_page = this.currentPage;
|
430
447
|
command = this.current_command;
|
431
448
|
return setTimeout(function() {
|
@@ -444,16 +461,16 @@ Poltergeist.Browser = (function() {
|
|
444
461
|
}, 5);
|
445
462
|
};
|
446
463
|
|
447
|
-
Browser.prototype.click = function(page_id, id) {
|
448
|
-
return this.mouse_event(page_id, id, 'click');
|
464
|
+
Browser.prototype.click = function(page_id, id, keys, offset) {
|
465
|
+
return this.mouse_event(page_id, id, 'click', keys, offset);
|
449
466
|
};
|
450
467
|
|
451
|
-
Browser.prototype.right_click = function(page_id, id) {
|
452
|
-
return this.mouse_event(page_id, id, 'rightclick');
|
468
|
+
Browser.prototype.right_click = function(page_id, id, keys, offset) {
|
469
|
+
return this.mouse_event(page_id, id, 'rightclick', keys, offset);
|
453
470
|
};
|
454
471
|
|
455
|
-
Browser.prototype.double_click = function(page_id, id) {
|
456
|
-
return this.mouse_event(page_id, id, 'doubleclick');
|
472
|
+
Browser.prototype.double_click = function(page_id, id, keys, offset) {
|
473
|
+
return this.mouse_event(page_id, id, 'doubleclick', keys, offset);
|
457
474
|
};
|
458
475
|
|
459
476
|
Browser.prototype.hover = function(page_id, id) {
|
@@ -643,21 +660,33 @@ Poltergeist.Browser = (function() {
|
|
643
660
|
};
|
644
661
|
|
645
662
|
Browser.prototype.set_headers = function(headers) {
|
646
|
-
|
647
|
-
this.currentPage.setUserAgent(headers['User-Agent']);
|
648
|
-
}
|
649
|
-
this.currentPage.setCustomHeaders(headers);
|
650
|
-
return this.current_command.sendResponse(true);
|
663
|
+
return this.add_headers(headers, false, false);
|
651
664
|
};
|
652
665
|
|
653
|
-
Browser.prototype.add_headers = function(headers) {
|
654
|
-
var
|
655
|
-
|
656
|
-
|
657
|
-
value = headers[name];
|
658
|
-
allHeaders[name] = value;
|
666
|
+
Browser.prototype.add_headers = function(headers, local, keepExisting) {
|
667
|
+
var pages;
|
668
|
+
if (local == null) {
|
669
|
+
local = false;
|
659
670
|
}
|
660
|
-
|
671
|
+
if (keepExisting == null) {
|
672
|
+
keepExisting = true;
|
673
|
+
}
|
674
|
+
pages = local ? [this.currentPage] : this.pages;
|
675
|
+
pages.forEach((function(_this) {
|
676
|
+
return function(page) {
|
677
|
+
var allHeaders, name, value;
|
678
|
+
allHeaders = keepExisting ? page.getCustomHeaders() : {};
|
679
|
+
for (name in headers) {
|
680
|
+
value = headers[name];
|
681
|
+
allHeaders[name] = value;
|
682
|
+
}
|
683
|
+
if (allHeaders['User-Agent']) {
|
684
|
+
page.setUserAgent(allHeaders['User-Agent']);
|
685
|
+
}
|
686
|
+
return page.setCustomHeaders(allHeaders);
|
687
|
+
};
|
688
|
+
})(this));
|
689
|
+
return this.current_command.sendResponse(true);
|
661
690
|
};
|
662
691
|
|
663
692
|
Browser.prototype.add_header = function(header, arg1) {
|
@@ -669,7 +698,7 @@ Poltergeist.Browser = (function() {
|
|
669
698
|
this.currentPage.addTempHeaderToRemoveOnRedirect(header);
|
670
699
|
}
|
671
700
|
}
|
672
|
-
return this.add_headers(header);
|
701
|
+
return this.add_headers(header, permanent !== true);
|
673
702
|
};
|
674
703
|
|
675
704
|
Browser.prototype.response_headers = function() {
|
@@ -715,6 +744,12 @@ Poltergeist.Browser = (function() {
|
|
715
744
|
return this.current_command.sendResponse(true);
|
716
745
|
};
|
717
746
|
|
747
|
+
Browser.prototype.set_page_settings = function(settings) {
|
748
|
+
this._page_settings = settings;
|
749
|
+
this.page.setSettings(this._page_settings);
|
750
|
+
return this.current_command.sendResponse(true);
|
751
|
+
};
|
752
|
+
|
718
753
|
Browser.prototype.exit = function() {
|
719
754
|
return phantom.exit();
|
720
755
|
};
|
@@ -27,8 +27,11 @@ Poltergeist.Node = (function() {
|
|
27
27
|
fn(name);
|
28
28
|
}
|
29
29
|
|
30
|
-
Node.prototype.mouseEventPosition = function() {
|
31
|
-
var area_offset, image, middle, pos,
|
30
|
+
Node.prototype.mouseEventPosition = function(offset) {
|
31
|
+
var area_offset, image, middle, pos, viewport;
|
32
|
+
if (offset == null) {
|
33
|
+
offset = {};
|
34
|
+
}
|
32
35
|
viewport = this.page.viewportSize();
|
33
36
|
if (image = this._getAreaImage()) {
|
34
37
|
pos = image.position();
|
@@ -44,27 +47,51 @@ Poltergeist.Node = (function() {
|
|
44
47
|
middle = function(start, end, size) {
|
45
48
|
return start + ((Math.min(end, size) - start) / 2);
|
46
49
|
};
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
if ((offset['x'] != null) && (offset['y'] != null)) {
|
51
|
+
return {
|
52
|
+
x: pos.left + offset['x'],
|
53
|
+
y: pos.top + offset['y']
|
54
|
+
};
|
55
|
+
} else {
|
56
|
+
return {
|
57
|
+
x: middle(pos.left, pos.right, viewport.width),
|
58
|
+
y: middle(pos.top, pos.bottom, viewport.height)
|
59
|
+
};
|
60
|
+
}
|
51
61
|
};
|
52
62
|
|
53
|
-
Node.prototype.mouseEvent = function(name) {
|
54
|
-
var area_image, pos, test;
|
63
|
+
Node.prototype.mouseEvent = function(name, keys, offset) {
|
64
|
+
var area_image, modifier_keys, modifiers_code, pos, scroll_pos, test;
|
55
65
|
if (area_image = this._getAreaImage()) {
|
56
66
|
area_image.scrollIntoView();
|
57
67
|
} else {
|
58
68
|
this.scrollIntoView();
|
59
69
|
}
|
60
|
-
pos = this.mouseEventPosition();
|
70
|
+
pos = this.mouseEventPosition(offset);
|
61
71
|
test = this.mouseEventTest(pos.x, pos.y);
|
62
72
|
if (test.status === 'success') {
|
73
|
+
modifier_keys = (keys || []).join(',').replace('control', 'ctrl');
|
74
|
+
modifiers_code = this.page.keyModifierCode(modifier_keys);
|
63
75
|
if (name === 'rightclick') {
|
64
|
-
this.page.mouseEvent('click', pos.x, pos.y, 'right');
|
65
|
-
|
76
|
+
this.page.mouseEvent('click', pos.x, pos.y, 'right', modifiers_code);
|
77
|
+
if (phantom.version.major === 2 && phantom.version.minor >= 1) {
|
78
|
+
this.page.sendEvent('contextmenu', pos.x, pos.y, 'right', modifiers_code);
|
79
|
+
} else {
|
80
|
+
scroll_pos = this.page.scrollPosition();
|
81
|
+
this.trigger('contextmenu', {
|
82
|
+
screenX: pos.x,
|
83
|
+
screenY: pos.y,
|
84
|
+
clientX: pos.x + scroll_pos['left'],
|
85
|
+
clientY: pos.y + scroll_pos['top'],
|
86
|
+
ctrlKey: modifier_keys.indexOf('ctrl') !== -1,
|
87
|
+
altKey: modifier_keys.indexOf('alt') !== -1,
|
88
|
+
metaKey: modifier_keys.indexOf('meta') !== -1,
|
89
|
+
shiftKey: modifier_keys.indexOf('shift') !== -1,
|
90
|
+
button: 2
|
91
|
+
});
|
92
|
+
}
|
66
93
|
} else {
|
67
|
-
this.page.mouseEvent(name, pos.x, pos.y);
|
94
|
+
this.page.mouseEvent(name, pos.x, pos.y, 'left', modifiers_code);
|
68
95
|
}
|
69
96
|
return pos;
|
70
97
|
} else {
|
@@ -6,15 +6,15 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
|
6
6
|
Poltergeist.WebPage = (function() {
|
7
7
|
var command, delegate, fn1, fn2, i, j, len, len1, ref, ref1;
|
8
8
|
|
9
|
-
WebPage.CALLBACKS = ['onConsoleMessage', 'onError', 'onLoadFinished', 'onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived', 'onResourceError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated', 'onClosing', 'onCallback'];
|
9
|
+
WebPage.CALLBACKS = ['onConsoleMessage', 'onError', 'onLoadFinished', 'onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived', 'onResourceError', 'onResourceTimeout', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated', 'onClosing', 'onCallback'];
|
10
10
|
|
11
|
-
WebPage.DELEGATES = ['open', 'sendEvent', 'uploadFile', 'render', 'close', 'renderBase64', 'goBack', 'goForward', 'reload'];
|
11
|
+
WebPage.DELEGATES = ['url', 'open', 'sendEvent', 'uploadFile', 'render', 'close', 'renderBase64', 'goBack', 'goForward', 'reload'];
|
12
12
|
|
13
|
-
WebPage.COMMANDS = ['
|
13
|
+
WebPage.COMMANDS = ['find', 'nodeCall', 'documentSize', 'beforeUpload', 'afterUpload', 'clearLocalStorage'];
|
14
14
|
|
15
15
|
WebPage.EXTENSIONS = [];
|
16
16
|
|
17
|
-
function WebPage(_native) {
|
17
|
+
function WebPage(_native, settings) {
|
18
18
|
var callback, i, len, ref;
|
19
19
|
this._native = _native;
|
20
20
|
this._checkForAsyncResult = bind(this._checkForAsyncResult, this);
|
@@ -34,6 +34,7 @@ Poltergeist.WebPage = (function() {
|
|
34
34
|
this._tempHeadersToRemoveOnRedirect = {};
|
35
35
|
this._asyncResults = {};
|
36
36
|
this._asyncEvaluationId = 0;
|
37
|
+
this.setSettings(settings);
|
37
38
|
ref = WebPage.CALLBACKS;
|
38
39
|
for (i = 0, len = ref.length; i < len; i++) {
|
39
40
|
callback = ref[i];
|
@@ -68,6 +69,19 @@ Poltergeist.WebPage = (function() {
|
|
68
69
|
fn2(delegate);
|
69
70
|
}
|
70
71
|
|
72
|
+
WebPage.prototype.setSettings = function(settings) {
|
73
|
+
var results, setting, value;
|
74
|
+
if (settings == null) {
|
75
|
+
settings = {};
|
76
|
+
}
|
77
|
+
results = [];
|
78
|
+
for (setting in settings) {
|
79
|
+
value = settings[setting];
|
80
|
+
results.push(this._native.settings[setting] = value);
|
81
|
+
}
|
82
|
+
return results;
|
83
|
+
};
|
84
|
+
|
71
85
|
WebPage.prototype.onInitializedNative = function() {
|
72
86
|
this.id += 1;
|
73
87
|
this.source = null;
|
@@ -182,6 +196,10 @@ Poltergeist.WebPage = (function() {
|
|
182
196
|
return true;
|
183
197
|
};
|
184
198
|
|
199
|
+
WebPage.prototype.onResourceTimeoutNative = function(request) {
|
200
|
+
return console.log("Resource request timed out for " + request.url);
|
201
|
+
};
|
202
|
+
|
185
203
|
WebPage.prototype.injectAgent = function() {
|
186
204
|
var extension, k, len2, ref2;
|
187
205
|
if (this["native"]().evaluate(function() {
|
@@ -366,10 +384,26 @@ Poltergeist.WebPage = (function() {
|
|
366
384
|
};
|
367
385
|
|
368
386
|
WebPage.prototype.title = function() {
|
387
|
+
return this["native"]().title;
|
388
|
+
};
|
389
|
+
|
390
|
+
WebPage.prototype.frameTitle = function() {
|
369
391
|
return this["native"]().frameTitle;
|
370
392
|
};
|
371
393
|
|
372
|
-
WebPage.prototype.
|
394
|
+
WebPage.prototype.currentUrl = function() {
|
395
|
+
return this["native"]().url;
|
396
|
+
};
|
397
|
+
|
398
|
+
WebPage.prototype.frameUrl = function() {
|
399
|
+
if (phantom.version.major > 2 || (phantom.version.major === 2 && phantom.version.minor >= 1)) {
|
400
|
+
return this["native"]().frameUrl;
|
401
|
+
} else {
|
402
|
+
return this.runCommand('frameUrl');
|
403
|
+
}
|
404
|
+
};
|
405
|
+
|
406
|
+
WebPage.prototype.frameUrlFor = function(frameNameOrId) {
|
373
407
|
var query;
|
374
408
|
query = function(frameNameOrId) {
|
375
409
|
var ref2;
|
@@ -438,6 +472,10 @@ Poltergeist.WebPage = (function() {
|
|
438
472
|
}, selector);
|
439
473
|
};
|
440
474
|
|
475
|
+
WebPage.prototype.getUserAgent = function() {
|
476
|
+
return this["native"]().settings.userAgent;
|
477
|
+
};
|
478
|
+
|
441
479
|
WebPage.prototype.setUserAgent = function(userAgent) {
|
442
480
|
return this["native"]().settings.userAgent = userAgent;
|
443
481
|
};
|
@@ -446,6 +484,22 @@ Poltergeist.WebPage = (function() {
|
|
446
484
|
return this["native"]().customHeaders;
|
447
485
|
};
|
448
486
|
|
487
|
+
WebPage.prototype.getPermanentCustomHeaders = function() {
|
488
|
+
var allHeaders, name, ref2, ref3, value;
|
489
|
+
allHeaders = this.getCustomHeaders();
|
490
|
+
ref2 = this._tempHeaders;
|
491
|
+
for (name in ref2) {
|
492
|
+
value = ref2[name];
|
493
|
+
delete allHeaders[name];
|
494
|
+
}
|
495
|
+
ref3 = this._tempHeadersToRemoveOnRedirect;
|
496
|
+
for (name in ref3) {
|
497
|
+
value = ref3[name];
|
498
|
+
delete allHeaders[name];
|
499
|
+
}
|
500
|
+
return allHeaders;
|
501
|
+
};
|
502
|
+
|
449
503
|
WebPage.prototype.setCustomHeaders = function(headers) {
|
450
504
|
return this["native"]().customHeaders = headers;
|
451
505
|
};
|
@@ -561,12 +615,15 @@ Poltergeist.WebPage = (function() {
|
|
561
615
|
return new Poltergeist.Node(this, id);
|
562
616
|
};
|
563
617
|
|
564
|
-
WebPage.prototype.mouseEvent = function(name, x, y, button) {
|
618
|
+
WebPage.prototype.mouseEvent = function(name, x, y, button, modifiers) {
|
565
619
|
if (button == null) {
|
566
620
|
button = 'left';
|
567
621
|
}
|
622
|
+
if (modifiers == null) {
|
623
|
+
modifiers = 0;
|
624
|
+
}
|
568
625
|
this.sendEvent('mousemove', x, y);
|
569
|
-
return this.sendEvent(name, x, y, button);
|
626
|
+
return this.sendEvent(name, x, y, button, modifiers);
|
570
627
|
};
|
571
628
|
|
572
629
|
WebPage.prototype.evaluate = function() {
|
@@ -17,7 +17,7 @@ class Poltergeist.Node
|
|
17
17
|
this.prototype[name] = (args...) ->
|
18
18
|
@page.nodeCall(@id, name, args)
|
19
19
|
|
20
|
-
mouseEventPosition: ->
|
20
|
+
mouseEventPosition: (offset = {})->
|
21
21
|
viewport = @page.viewportSize()
|
22
22
|
|
23
23
|
if image = @_getAreaImage()
|
@@ -34,25 +34,44 @@ class Poltergeist.Node
|
|
34
34
|
middle = (start, end, size) ->
|
35
35
|
start + ((Math.min(end, size) - start) / 2)
|
36
36
|
|
37
|
-
|
37
|
+
if offset['x']? && offset['y']?
|
38
|
+
x: pos.left + offset['x'],
|
39
|
+
y: pos.top + offset['y']
|
40
|
+
else
|
38
41
|
x: middle(pos.left, pos.right, viewport.width),
|
39
42
|
y: middle(pos.top, pos.bottom, viewport.height)
|
40
|
-
}
|
41
43
|
|
42
44
|
|
43
|
-
mouseEvent: (name) ->
|
45
|
+
mouseEvent: (name, keys, offset) ->
|
44
46
|
if area_image = @_getAreaImage()
|
45
47
|
area_image.scrollIntoView()
|
46
48
|
else
|
47
49
|
@scrollIntoView()
|
48
|
-
pos = this.mouseEventPosition()
|
50
|
+
pos = this.mouseEventPosition(offset)
|
49
51
|
test = this.mouseEventTest(pos.x, pos.y)
|
50
52
|
if test.status == 'success'
|
53
|
+
modifier_keys = (keys || []).join(',').replace('control', 'ctrl')
|
54
|
+
modifiers_code = @page.keyModifierCode(modifier_keys)
|
51
55
|
if name == 'rightclick'
|
52
|
-
@page.mouseEvent('click', pos.x, pos.y, 'right')
|
53
|
-
|
56
|
+
@page.mouseEvent('click', pos.x, pos.y, 'right', modifiers_code)
|
57
|
+
if phantom.version.major == 2 && phantom.version.minor >= 1
|
58
|
+
@page.sendEvent('contextmenu', pos.x, pos.y, 'right', modifiers_code)
|
59
|
+
else
|
60
|
+
scroll_pos = @page.scrollPosition()
|
61
|
+
@trigger('contextmenu',
|
62
|
+
screenX: pos.x
|
63
|
+
screenY: pos.y
|
64
|
+
clientX: pos.x + scroll_pos['left']
|
65
|
+
clientY: pos.y + scroll_pos['top']
|
66
|
+
ctrlKey: modifier_keys.indexOf('ctrl') != -1
|
67
|
+
altKey: modifier_keys.indexOf('alt') != -1
|
68
|
+
metaKey: modifier_keys.indexOf('meta') != -1
|
69
|
+
shiftKey: modifier_keys.indexOf('shift') != -1
|
70
|
+
button: 2
|
71
|
+
)
|
54
72
|
else
|
55
|
-
@page.mouseEvent(name, pos.x, pos.y)
|
73
|
+
@page.mouseEvent(name, pos.x, pos.y, 'left', modifiers_code)
|
74
|
+
|
56
75
|
pos
|
57
76
|
else
|
58
77
|
throw new Poltergeist.MouseEventFailed(name, test.selector, pos)
|
@@ -1,19 +1,20 @@
|
|
1
1
|
class Poltergeist.WebPage
|
2
2
|
@CALLBACKS = ['onConsoleMessage','onError',
|
3
3
|
'onLoadFinished', 'onInitialized', 'onLoadStarted',
|
4
|
-
'onResourceRequested', 'onResourceReceived', 'onResourceError',
|
4
|
+
'onResourceRequested', 'onResourceReceived', 'onResourceError', 'onResourceTimeout',
|
5
5
|
'onNavigationRequested', 'onUrlChanged', 'onPageCreated',
|
6
6
|
'onClosing', 'onCallback']
|
7
7
|
|
8
|
-
@DELEGATES = ['open', 'sendEvent', 'uploadFile', 'render', 'close',
|
8
|
+
@DELEGATES = ['url', 'open', 'sendEvent', 'uploadFile', 'render', 'close',
|
9
9
|
'renderBase64', 'goBack', 'goForward', 'reload']
|
10
10
|
|
11
|
-
@COMMANDS = ['currentUrl', 'find', 'nodeCall', 'documentSize',
|
11
|
+
# @COMMANDS = ['currentUrl', 'find', 'nodeCall', 'documentSize',
|
12
|
+
@COMMANDS = ['find', 'nodeCall', 'documentSize',
|
12
13
|
'beforeUpload', 'afterUpload', 'clearLocalStorage']
|
13
14
|
|
14
15
|
@EXTENSIONS = []
|
15
16
|
|
16
|
-
constructor: (@_native) ->
|
17
|
+
constructor: (@_native, settings) ->
|
17
18
|
@_native or= require('webpage').create()
|
18
19
|
|
19
20
|
@id = 0
|
@@ -32,6 +33,8 @@ class Poltergeist.WebPage
|
|
32
33
|
@_asyncResults = {}
|
33
34
|
@_asyncEvaluationId = 0
|
34
35
|
|
36
|
+
@setSettings(settings)
|
37
|
+
|
35
38
|
for callback in WebPage.CALLBACKS
|
36
39
|
this.bindCallback(callback)
|
37
40
|
|
@@ -48,6 +51,9 @@ class Poltergeist.WebPage
|
|
48
51
|
this.prototype[delegate] =
|
49
52
|
-> @_native[delegate].apply(@_native, arguments)
|
50
53
|
|
54
|
+
setSettings: (settings = {})->
|
55
|
+
@_native.settings[setting] = value for setting, value of settings
|
56
|
+
|
51
57
|
onInitializedNative: ->
|
52
58
|
@id += 1
|
53
59
|
@source = null
|
@@ -134,6 +140,9 @@ class Poltergeist.WebPage
|
|
134
140
|
delete @_requestedResources[errorResponse.id]
|
135
141
|
return true
|
136
142
|
|
143
|
+
onResourceTimeoutNative: (request) ->
|
144
|
+
console.log "Resource request timed out for #{request.url}"
|
145
|
+
|
137
146
|
injectAgent: ->
|
138
147
|
if this.native().evaluate(-> typeof __poltergeist) == "undefined"
|
139
148
|
this.native().injectJs "#{phantom.libraryPath}/agent.js"
|
@@ -221,9 +230,21 @@ class Poltergeist.WebPage
|
|
221
230
|
this.native().frameContent
|
222
231
|
|
223
232
|
title: ->
|
233
|
+
this.native().title
|
234
|
+
|
235
|
+
frameTitle: ->
|
224
236
|
this.native().frameTitle
|
225
237
|
|
226
|
-
|
238
|
+
currentUrl: ->
|
239
|
+
@native().url
|
240
|
+
|
241
|
+
frameUrl: ->
|
242
|
+
if phantom.version.major > 2 || (phantom.version.major == 2 && phantom.version.minor >= 1)
|
243
|
+
@native().frameUrl
|
244
|
+
else
|
245
|
+
@runCommand('frameUrl')
|
246
|
+
|
247
|
+
frameUrlFor: (frameNameOrId) ->
|
227
248
|
query = (frameNameOrId) ->
|
228
249
|
document.querySelector("iframe[name='#{frameNameOrId}'], iframe[id='#{frameNameOrId}']")?.src
|
229
250
|
this.evaluate(query, frameNameOrId)
|
@@ -275,12 +296,23 @@ class Poltergeist.WebPage
|
|
275
296
|
, selector
|
276
297
|
)
|
277
298
|
|
299
|
+
getUserAgent: ->
|
300
|
+
this.native().settings.userAgent
|
301
|
+
|
278
302
|
setUserAgent: (userAgent) ->
|
279
303
|
this.native().settings.userAgent = userAgent
|
280
304
|
|
281
305
|
getCustomHeaders: ->
|
282
306
|
this.native().customHeaders
|
283
307
|
|
308
|
+
getPermanentCustomHeaders: ->
|
309
|
+
allHeaders = @getCustomHeaders()
|
310
|
+
for name, value of @_tempHeaders
|
311
|
+
delete allHeaders[name]
|
312
|
+
for name, value of @_tempHeadersToRemoveOnRedirect
|
313
|
+
delete allHeaders[name]
|
314
|
+
allHeaders
|
315
|
+
|
284
316
|
setCustomHeaders: (headers) ->
|
285
317
|
this.native().customHeaders = headers
|
286
318
|
|
@@ -354,9 +386,9 @@ class Poltergeist.WebPage
|
|
354
386
|
|
355
387
|
# Before each mouse event we make sure that the mouse is moved to where the
|
356
388
|
# event will take place. This deals with e.g. :hover changes.
|
357
|
-
mouseEvent: (name, x, y, button = 'left') ->
|
389
|
+
mouseEvent: (name, x, y, button = 'left', modifiers = 0) ->
|
358
390
|
this.sendEvent('mousemove', x, y)
|
359
|
-
this.sendEvent(name, x, y, button)
|
391
|
+
this.sendEvent(name, x, y, button, modifiers)
|
360
392
|
|
361
393
|
evaluate: (fn, args...) ->
|
362
394
|
this.injectAgent()
|
@@ -30,6 +30,7 @@ module Capybara::Poltergeist
|
|
30
30
|
browser.debug = true if options[:debug]
|
31
31
|
browser.url_blacklist = options[:url_blacklist] if options.key?(:url_blacklist)
|
32
32
|
browser.url_whitelist = options[:url_whitelist] if options.key?(:url_whitelist)
|
33
|
+
browser.page_settings = options[:page_settings] if options.key?(:page_settings)
|
33
34
|
browser
|
34
35
|
end
|
35
36
|
end
|
@@ -100,7 +101,15 @@ module Capybara::Poltergeist
|
|
100
101
|
end
|
101
102
|
|
102
103
|
def current_url
|
103
|
-
|
104
|
+
if Capybara::VERSION.to_f < 3.0
|
105
|
+
frame_url
|
106
|
+
else
|
107
|
+
browser.current_url.gsub(' ', '%20') # PhantomJS < 2.1 doesn't escape spaces
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def frame_url
|
112
|
+
browser.frame_url.gsub(' ', '%20') # PhantomJS < 2.1 doesn't escape spaces
|
104
113
|
end
|
105
114
|
|
106
115
|
def status_code
|
@@ -117,7 +126,15 @@ module Capybara::Poltergeist
|
|
117
126
|
end
|
118
127
|
|
119
128
|
def title
|
120
|
-
|
129
|
+
if Capybara::VERSION.to_f < 3.0
|
130
|
+
frame_title
|
131
|
+
else
|
132
|
+
browser.title
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def frame_title
|
137
|
+
browser.frame_title
|
121
138
|
end
|
122
139
|
|
123
140
|
def find(method, selector)
|
@@ -49,7 +49,15 @@ module Capybara::Poltergeist
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def visible_text
|
52
|
-
|
52
|
+
if Capybara::VERSION.to_f < 3.0
|
53
|
+
filter_text command(:visible_text)
|
54
|
+
else
|
55
|
+
command(:visible_text).to_s
|
56
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
|
57
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
|
58
|
+
.gsub(/\n+/, "\n")
|
59
|
+
.tr("\u00a0", ' ')
|
60
|
+
end
|
53
61
|
end
|
54
62
|
|
55
63
|
def property(name)
|
@@ -79,7 +87,9 @@ module Capybara::Poltergeist
|
|
79
87
|
command :value
|
80
88
|
end
|
81
89
|
|
82
|
-
def set(value)
|
90
|
+
def set(value, options = {})
|
91
|
+
warn "Options passed to Node#set but Poltergeist doesn't currently support any - ignoring" unless options.empty?
|
92
|
+
|
83
93
|
if tag_name == 'input'
|
84
94
|
case self[:type]
|
85
95
|
when 'radio'
|
@@ -129,16 +139,16 @@ module Capybara::Poltergeist
|
|
129
139
|
command :disabled?
|
130
140
|
end
|
131
141
|
|
132
|
-
def click
|
133
|
-
command :click
|
142
|
+
def click(keys=[], offset={})
|
143
|
+
command :click, keys, offset
|
134
144
|
end
|
135
145
|
|
136
|
-
def right_click
|
137
|
-
command :right_click
|
146
|
+
def right_click(keys=[], offset={})
|
147
|
+
command :right_click, keys, offset
|
138
148
|
end
|
139
149
|
|
140
|
-
def double_click
|
141
|
-
command :double_click
|
150
|
+
def double_click(keys=[], offset={})
|
151
|
+
command :double_click, keys, offset
|
142
152
|
end
|
143
153
|
|
144
154
|
def hover
|
@@ -182,8 +192,16 @@ module Capybara::Poltergeist
|
|
182
192
|
|
183
193
|
private
|
184
194
|
|
185
|
-
def filter_text(text)
|
186
|
-
Capybara::
|
195
|
+
def filter_text(text, visible = true)
|
196
|
+
if Capybara::VERSION.to_f < 3
|
197
|
+
Capybara::Helpers.normalize_whitespace(text.to_s)
|
198
|
+
else
|
199
|
+
text.gsub(/[\u200b\u200e\u200f]/, '')
|
200
|
+
.gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
|
201
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
|
202
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
|
203
|
+
.tr("\u00a0", ' ')
|
204
|
+
end
|
187
205
|
end
|
188
206
|
end
|
189
207
|
end
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poltergeist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.18.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:
|
11
|
+
date: 2018-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2.1'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '4'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '2.1'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '4'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: websocket-driver
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -273,7 +279,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
273
279
|
version: '0'
|
274
280
|
requirements: []
|
275
281
|
rubyforge_project:
|
276
|
-
rubygems_version: 2.7.
|
282
|
+
rubygems_version: 2.7.6
|
277
283
|
signing_key:
|
278
284
|
specification_version: 4
|
279
285
|
summary: PhantomJS driver for Capybara
|