poltergeist 1.17.0 → 1.18.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 +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
|