lib/capybara/poltergeist/client/agent.coffee in poltergeist-0.6.0 vs lib/capybara/poltergeist/client/agent.coffee in poltergeist-0.7.0
- old
+ new
@@ -5,13 +5,23 @@
@elements = []
@nodes = {}
@windows = []
this.pushWindow(window)
- externalCall: (name, arguments) ->
- { value: this[name].apply(this, arguments) }
+ externalCall: (name, args) ->
+ try
+ { value: this[name].apply(this, args) }
+ catch error
+ { error: { message: error.toString(), stack: error.stack } }
+ @stringify: (object) ->
+ JSON.stringify object, (key, value) ->
+ if Array.isArray(this[key])
+ return this[key]
+ else
+ return value
+
pushWindow: (new_window) ->
@windows.push(new_window)
@window = new_window
@document = @window.document
@@ -53,14 +63,14 @@
width: @document.documentElement.scrollWidth
get: (id) ->
@nodes[id] or= new PoltergeistAgent.Node(this, @elements[id])
- nodeCall: (id, name, arguments) ->
+ nodeCall: (id, name, args) ->
node = this.get(id)
throw new PoltergeistAgent.ObsoleteNode if node.isObsolete()
- node[name].apply(node, arguments)
+ node[name].apply(node, args)
class PoltergeistAgent.ObsoleteNode
toString: -> "PoltergeistAgent.ObsoleteNode"
class PoltergeistAgent.Node
@@ -89,13 +99,39 @@
true
obsolete @element
changed: ->
event = document.createEvent('HTMLEvents')
- event.initEvent("change", true, false)
+ event.initEvent('change', true, false)
@element.dispatchEvent(event)
+ input: ->
+ event = document.createEvent('HTMLEvents')
+ event.initEvent('input', true, false)
+ @element.dispatchEvent(event)
+
+ keyupdowned: (eventName, keyCode) ->
+ event = document.createEvent('UIEvents')
+ event.initEvent(eventName, true, true)
+ event.keyCode = keyCode
+ event.which = keyCode
+ event.charCode = 0
+ @element.dispatchEvent(event)
+
+ keypressed: (altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) ->
+ event = document.createEvent('UIEvents')
+ event.initEvent('keypress', true, true)
+ event.window = @agent.window
+ event.altKey = altKey
+ event.ctrlKey = ctrlKey
+ event.shiftKey = shiftKey
+ event.metaKey = metaKey
+ event.keyCode = keyCode
+ event.charCode = charCode
+ event.which = keyCode
+ @element.dispatchEvent(event)
+
insideBody: ->
@element == @agent.document.body ||
@agent.document.evaluate('ancestor::body', @element, null, XPathResult.BOOLEAN_TYPE, null).booleanValue
text: ->
@@ -118,22 +154,37 @@
if name == 'checked' || name == 'selected'
@element[name]
else
@element.getAttribute(name)
+ scrollIntoView: ->
+ @element.scrollIntoViewIfNeeded()
+
value: ->
if @element.tagName == 'SELECT' && @element.multiple
option.value for option in @element.children when option.selected
else
@element.value
set: (value) ->
if (@element.maxLength >= 0)
value = value.substr(0, @element.maxLength)
- @element.value = value
+ @element.value = ''
+ this.trigger('focus')
+
+ for char in value
+ @element.value += char
+
+ keyCode = this.characterToKeyCode(char)
+ this.keyupdowned('keydown', keyCode)
+ this.keypressed(false, false, false, false, char.charCodeAt(0), char.charCodeAt(0))
+ this.keyupdowned('keyup', keyCode)
+
this.changed()
+ this.input()
+ this.trigger('blur')
isMultiple: ->
@element.multiple
setAttribute: (name, value) ->
@@ -206,9 +257,51 @@
selector += el.tagName.toLowerCase()
selector += "##{el.id}" if el.id
for className in el.classList
selector += ".#{className}"
selector
+
+ characterToKeyCode: (character) ->
+ code = character.toUpperCase().charCodeAt(0)
+ specialKeys =
+ 96: 192 #`
+ 45: 189 #-
+ 61: 187 #=
+ 91: 219 #[
+ 93: 221 #]
+ 92: 220 #\
+ 59: 186 #;
+ 39: 222 #'
+ 44: 188 #,
+ 46: 190 #.
+ 47: 191 #/
+ 127: 46 #delete
+ 126: 192 #~
+ 33: 49 #!
+ 64: 50 #@
+ 35: 51 ##
+ 36: 52 #$
+ 37: 53 #%
+ 94: 54 #^
+ 38: 55 #&
+ 42: 56 #*
+ 40: 57 #(
+ 41: 48 #)
+ 95: 189 #_
+ 43: 187 #+
+ 123: 219 #{
+ 125: 221 #}
+ 124: 220 #|
+ 58: 186 #:
+ 34: 222 #"
+ 60: 188 #<
+ 62: 190 #>
+ 63: 191 #?
+
+ specialKeys[code] || code
+
+ isDOMEqual: (other_id) ->
+ @element == @agent.get(other_id).element
window.__poltergeist = new PoltergeistAgent
document.addEventListener(
'DOMContentLoaded',