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:
parent
60c7e764b0
commit
852b78ab0d
8 changed files with 177 additions and 0 deletions
|
@ -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
|
||||
|
|
20
README.md
20
README.md
|
@ -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 ##
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
29
spec/support/views/send_keys.erb
Normal file
29
spec/support/views/send_keys.erb
Normal 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>
|
Loading…
Add table
Reference in a new issue