mirror of
https://github.com/teampoltergeist/poltergeist.git
synced 2022-11-09 12:05:00 -05:00
Don't alter focus with send_keys if we're already in the target element.
If the click event is fired on the target element, then the caret position that was previously set by, e.g., send_keys(:Left) is lost. This addresses that by first checking if the target element already contains the current selection, meaning we have focus within the target element and don't need to first give it focus. Fixes #493.
This commit is contained in:
parent
05531dfd62
commit
b67c643b74
7 changed files with 44 additions and 5 deletions
|
@ -235,6 +235,16 @@ class PoltergeistAgent.Node
|
|||
isDisabled: ->
|
||||
@element.disabled || @element.tagName == 'OPTION' && @element.parentNode.disabled
|
||||
|
||||
containsSelection: ->
|
||||
selectedNode = document.getSelection().focusNode
|
||||
|
||||
return false if !selectedNode
|
||||
|
||||
if selectedNode.nodeType == 3
|
||||
selectedNode = selectedNode.parentNode
|
||||
|
||||
@element.contains(selectedNode)
|
||||
|
||||
frameOffset: ->
|
||||
win = window
|
||||
offset = { top: 0, left: 0 }
|
||||
|
|
|
@ -262,9 +262,13 @@ class Poltergeist.Browser
|
|||
this.sendResponse(true)
|
||||
|
||||
send_keys: (page_id, id, keys) ->
|
||||
target = this.node(page_id, id)
|
||||
|
||||
# Programmatically generated focus doesn't work for `sendKeys`.
|
||||
# That's why we need something more realistic like user behavior.
|
||||
this.node(page_id, id).mouseEvent('click')
|
||||
if !target.containsSelection()
|
||||
target.mouseEvent('click')
|
||||
|
||||
for sequence in keys
|
||||
key = if sequence.key? then @page.native.event.key[sequence.key] else sequence
|
||||
@page.sendEvent('keypress', key)
|
||||
|
|
|
@ -365,6 +365,18 @@ PoltergeistAgent.Node = (function() {
|
|||
return this.element.disabled || this.element.tagName === 'OPTION' && this.element.parentNode.disabled;
|
||||
};
|
||||
|
||||
Node.prototype.containsSelection = function() {
|
||||
var selectedNode;
|
||||
selectedNode = document.getSelection().focusNode;
|
||||
if (!selectedNode) {
|
||||
return false;
|
||||
}
|
||||
if (selectedNode.nodeType === 3) {
|
||||
selectedNode = selectedNode.parentNode;
|
||||
}
|
||||
return this.element.contains(selectedNode);
|
||||
};
|
||||
|
||||
Node.prototype.frameOffset = function() {
|
||||
var offset, rect, style, win;
|
||||
win = window;
|
||||
|
|
|
@ -351,8 +351,11 @@ Poltergeist.Browser = (function() {
|
|||
};
|
||||
|
||||
Browser.prototype.send_keys = function(page_id, id, keys) {
|
||||
var key, sequence, _i, _len;
|
||||
this.node(page_id, id).mouseEvent('click');
|
||||
var key, sequence, target, _i, _len;
|
||||
target = this.node(page_id, id);
|
||||
if (!target.containsSelection()) {
|
||||
target.mouseEvent('click');
|
||||
}
|
||||
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
||||
sequence = keys[_i];
|
||||
key = sequence.key != null ? this.page["native"].event.key[sequence.key] : sequence;
|
||||
|
|
|
@ -3,7 +3,7 @@ var __slice = [].slice;
|
|||
Poltergeist.Node = (function() {
|
||||
var name, _fn, _i, _len, _ref;
|
||||
|
||||
Node.DELEGATES = ['allText', 'visibleText', 'getAttribute', 'value', 'set', 'setAttribute', 'isObsolete', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'getAttributes', 'isVisible', 'position', 'trigger', 'parentId', 'parentIds', 'mouseEventTest', 'scrollIntoView', 'isDOMEqual', 'isDisabled', 'deleteText'];
|
||||
Node.DELEGATES = ['allText', 'visibleText', 'getAttribute', 'value', 'set', 'setAttribute', 'isObsolete', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'getAttributes', 'isVisible', 'position', 'trigger', 'parentId', 'parentIds', 'mouseEventTest', 'scrollIntoView', 'isDOMEqual', 'isDisabled', 'deleteText', 'containsSelection'];
|
||||
|
||||
function Node(page, id) {
|
||||
this.page = page;
|
||||
|
|
|
@ -4,7 +4,7 @@ class Poltergeist.Node
|
|||
@DELEGATES = ['allText', 'visibleText', 'getAttribute', 'value', 'set', 'setAttribute', 'isObsolete',
|
||||
'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'getAttributes',
|
||||
'isVisible', 'position', 'trigger', 'parentId', 'parentIds', 'mouseEventTest',
|
||||
'scrollIntoView', 'isDOMEqual', 'isDisabled', 'deleteText']
|
||||
'scrollIntoView', 'isDOMEqual', 'isDisabled', 'deleteText', 'containsSelection']
|
||||
|
||||
constructor: (@page, @id) ->
|
||||
|
||||
|
|
|
@ -779,6 +779,16 @@ module Capybara::Poltergeist
|
|||
expect(input.text).to eq('Input')
|
||||
end
|
||||
|
||||
it 'persists focus across calls' do
|
||||
input = @session.find(:css, '#empty_div')
|
||||
|
||||
input.native.send_keys('helo')
|
||||
input.native.send_keys(:Left)
|
||||
input.native.send_keys('l')
|
||||
|
||||
expect(input.text).to eq('hello')
|
||||
end
|
||||
|
||||
it 'sends keys to filled contenteditable div' do
|
||||
input = @session.find(:css, '#filled_div')
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue