Fix for missing select events

This is a fix for an issue where select tags don't bubble the correct
events when clicked. More discussion here:
https://github.com/thoughtbot/capybara-webkit/issues/763
This commit is contained in:
Robert Fletcher 2015-05-22 13:41:01 -04:00 committed by Joe Ferris
parent f524847616
commit 4334dbbf6d
2 changed files with 30 additions and 8 deletions

View File

@ -7,19 +7,23 @@ describe Capybara::Webkit, 'compatibility with selenium' do
run_application_for_html(<<-HTML) run_application_for_html(<<-HTML)
<html><body> <html><body>
<form onsubmit="return false"> <form onsubmit="return false">
<label for="one">One</label><input type="text" name="one" id="one" /> <label for="one">One</label><input type="text" name="one" id="one" class="watch" />
<label for="two">Two</label><input type="text" name="two" id="two" /> <label for="two">Two</label><input type="text" name="two" id="two" class="watch" />
<label for="three">Three</label><input type="text" name="three" id="three" readonly="readonly" /> <label for="three">Three</label><input type="text" name="three" id="three" readonly="readonly" class="watch" />
<label for="textarea">Textarea</label> <label for="textarea">Textarea</label>
<textarea name="textarea" id="textarea"></textarea> <textarea name="textarea" id="textarea"></textarea>
<input type="submit" value="Submit" id="submit" /> <select name="select" id="five" class="watch">
<option>Nothing here</option>
<option>some option</option>
</select>
<input type="submit" value="Submit" id="submit" class="watch" />
</form> </form>
<script type="text/javascript"> <script type="text/javascript">
window.log = []; window.log = [];
var recordEvent = function (event) { var recordEvent = function (event) {
log.push(event.target.id + '.' + event.type); log.push(event.target.id + '.' + event.type);
}; };
var elements = document.getElementsByTagName("input"); var elements = document.getElementsByClassName("watch");
var events = ["mousedown", "mouseup", "click", "keyup", "keydown", var events = ["mousedown", "mouseup", "click", "keyup", "keydown",
"keypress", "focus", "blur", "input", "change"]; "keypress", "focus", "blur", "input", "change"];
for (var i = 0; i < elements.length; i++) { for (var i = 0; i < elements.length; i++) {
@ -38,6 +42,7 @@ describe Capybara::Webkit, 'compatibility with selenium' do
fill_in "Two", :with => "other value" fill_in "Two", :with => "other value"
fill_in "Three", :with => "readonly value" fill_in "Three", :with => "readonly value"
fill_in "Textarea", :with => "last value" fill_in "Textarea", :with => "last value"
select "some option", :from => "five"
click_button "Submit" click_button "Submit"
end end
end end

View File

@ -228,9 +228,13 @@ Capybara = {
}, },
trigger: function (index, eventName) { trigger: function (index, eventName) {
this.triggerOnNode(this.getNode(index), eventName);
},
triggerOnNode: function(node, eventName) {
var eventObject = document.createEvent("HTMLEvents"); var eventObject = document.createEvent("HTMLEvents");
eventObject.initEvent(eventName, true, true); eventObject.initEvent(eventName, true, true);
this.getNode(index).dispatchEvent(eventObject); node.dispatchEvent(eventObject);
}, },
visible: function (index) { visible: function (index) {
@ -323,8 +327,21 @@ Capybara = {
}, },
selectOption: function(index) { selectOption: function(index) {
this.getNode(index).selected = true; var optionNode = this.getNode(index);
this.trigger(index, "change"); var selectNode = optionNode.parentNode;
// click on select list
this.triggerOnNode(selectNode, 'mousedown');
selectNode.focus();
this.triggerOnNode(selectNode, 'mouseup');
this.triggerOnNode(selectNode, 'click');
// select option from list
this.triggerOnNode(optionNode, 'mousedown');
optionNode.selected = true;
this.triggerOnNode(selectNode, 'change');
this.triggerOnNode(optionNode, 'mouseup');
this.triggerOnNode(optionNode, 'click');
}, },
unselectOption: function(index) { unselectOption: function(index) {