1
0
Fork 0
mirror of https://github.com/teampoltergeist/poltergeist.git synced 2022-11-09 12:05:00 -05:00

#202 Add send_keys basic implementation

This commit is contained in:
Dmitry Vorotilin 2013-12-01 21:41:41 +04:00
parent 60c7e764b0
commit 852b78ab0d
8 changed files with 177 additions and 0 deletions

View file

@ -4,6 +4,7 @@
* Added ability to clear network traffic (Vick Vu)
* Added ability to set paper_size via a driver setter (Philippe Lehoux)
* Can support Basic HTTP authentication
* Added basic implementation of `send_keys`
#### Bug fixes ####
* Use `Capybara::Helpers.normalize_whitespace` in filter_text to strip unicode

View file

@ -104,6 +104,7 @@ and the following optional features:
* `page.driver.render_base64(format, options)`
* `page.driver.scroll_to(left, top)`
* `page.driver.basic_authorize(user, password)`
* `element.native.send_keys(*keys)`
* cookie handling
* drag-and-drop
@ -241,6 +242,25 @@ page.within_window fb_popup do
end
```
### Sending keys ###
There's an ability to send arbitrary keys to the element:
``` ruby
element = find('input#id')
element.native.send_key('String')
```
or even more complicated:
``` ruby
element.native.send_keys('H', 'elo', :Left, 'l') # => 'Hello'
element.native.send_key(:Enter) # triggers Enter key
```
Since it's implemented natively in PhantomJS this will exactly imitate user
behavior.
See more about [sendEvent](http://phantomjs.org/api/webpage/method/send-event.html) and
[PhantomJS keys](https://github.com/ariya/phantomjs/commit/cab2635e66d74b7e665c44400b8b20a8f225153a)
## Customization ##

View file

@ -179,6 +179,10 @@ module Capybara::Poltergeist
command 'resize', width, height
end
def send_keys(page_id, id, keys)
command 'send_keys', page_id, id, normalize_keys(keys)
end
def network_traffic
command('network_traffic').values.map do |event|
NetworkTraffic::Request.new(
@ -285,5 +289,20 @@ module Capybara::Poltergeist
options.delete(:selector)
end
end
def normalize_keys(keys)
keys.map do |key|
case key
when Array
# String itself with modifiers like :alt, :shift, etc
raise Error, 'PhantomJS behaviour for key modifiers is currently ' \
'broken, we will add this in later versions'
when Symbol
{ key: key } # Return a known sequence for PhantomJS
when String
key # Plain string, nothing to do
end
end
end
end
end

View file

@ -250,6 +250,15 @@ class Poltergeist.Browser
@page.setScrollPosition(left: left, top: top)
this.sendResponse(true)
send_keys: (page_id, id, keys) ->
# 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')
for sequence in keys
key = if sequence.key? then @page.native.event.key[sequence.key] else sequence
@page.sendEvent('keypress', key)
this.sendResponse(true)
render_base64: (format, full, selector = null)->
this.set_clip_rect(full, selector)
encoded_image = @page.renderBase64(format)

View file

@ -324,6 +324,17 @@ Poltergeist.Browser = (function() {
return this.sendResponse(true);
};
Browser.prototype.send_keys = function(page_id, id, keys) {
var key, sequence, _i, _len;
this.node(page_id, id).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;
this.page.sendEvent('keypress', key);
}
return this.sendResponse(true);
};
Browser.prototype.render_base64 = function(format, full, selector) {
var encoded_image;
if (selector == null) {

View file

@ -125,6 +125,11 @@ module Capybara::Poltergeist
command :equals, other.id
end
def send_keys(*keys)
command :send_keys, keys
end
alias_method :send_key, :send_keys
private
def filter_text(text)

View file

@ -674,5 +674,88 @@ module Capybara::Poltergeist
expect(@session).to have_content('Authorized POST request')
end
end
context 'has ability to send keys' do
before { @session.visit('/poltergeist/send_keys') }
it 'sends keys to empty input' do
input = @session.find(:css, '#empty_input')
input.native.send_keys('Input')
expect(input.value).to eq('Input')
end
it 'sends keys to filled input' do
input = @session.find(:css, '#filled_input')
input.native.send_keys(' appended')
expect(input.value).to eq('Text appended')
end
it 'sends keys to empty textarea' do
input = @session.find(:css, '#empty_textarea')
input.native.send_keys('Input')
expect(input.value).to eq('Input')
end
it 'sends keys to filled textarea' do
input = @session.find(:css, '#filled_textarea')
input.native.send_keys(' appended')
expect(input.value).to eq('Description appended')
end
it 'sends keys to empty contenteditable div' do
input = @session.find(:css, '#empty_div')
input.native.send_keys('Input')
expect(input.text).to eq('Input')
end
it 'sends keys to filled contenteditable div' do
input = @session.find(:css, '#filled_div')
input.native.send_keys(' appended')
expect(input.text).to eq('Content appended')
end
it 'sends sequences' do
input = @session.find(:css, '#empty_input')
input.native.send_keys(:Shift, 'S', :Alt, 't', 'r', 'i', 'g', :Left, 'n')
expect(input.value).to eq('String')
end
it 'submits the form with sequence' do
input = @session.find(:css, '#without_submit_button input')
input.native.send_keys(:Enter)
expect(input.value).to eq('Submitted')
end
it 'raises error on modifier' do
input = @session.find(:css, '#empty_input')
expect { input.native.send_keys([:Shift, 's'], 'tring') }
.to raise_error(Capybara::Poltergeist::Error)
end
it 'has an alias' do
input = @session.find(:css, '#empty_input')
input.native.send_key('S')
expect(input.value).to eq('S')
end
end
end
end

View file

@ -0,0 +1,29 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
</head>
<body>
<input id="empty_input" type="text">
<input id="filled_input" type="text" value="Text">
<textarea id="empty_textarea"></textarea>
<textarea id="filled_textarea">Description</textarea>
<div id="empty_div" contenteditable="true"></div>
<div id="filled_div" contenteditable="true">Content</div>
<form id="without_submit_button">
<input type="text">
</form>
<script>
function processForm(e) {
if (e.preventDefault) e.preventDefault();
document.querySelector("#without_submit_button input").value = "Submitted";
return false;
}
var form = document.getElementById("without_submit_button");
form.addEventListener("submit", processForm);
</script>
</body>
</html>