Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Capybara 2.1 beta1 compatibility #501

Closed
wants to merge 4 commits into from

2 participants

@mhoran
Collaborator

This PR addresses the additional changes mentioned in jnicklas/capybara#984.

a5c51b2 should also fix #303 and #384.

@jferris
Admin

This looks good.

@mhoran mhoran closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 28, 2013
  1. @mhoran
Commits on Mar 29, 2013
  1. @mhoran
  2. @mhoran
  3. @mhoran

    Enabled options in disabled selects are disabled

    mhoran authored
    This is the behavior of Selenium and has been standardized in Capybara.
This page is out of date. Refresh to see the latest.
View
1  .travis.yml
@@ -6,7 +6,6 @@ rvm:
matrix:
allow_failures:
- rvm: rbx-19mode
- - gemfile: gemfiles/2.1.gemfile
exclude:
- rvm: 1.9.3
gemfile: gemfiles/2.0.gemfile
View
2  Appraisals
@@ -3,5 +3,5 @@ appraise "2.0" do
end
appraise "2.1" do
- gem "capybara", github: "jnicklas/capybara", submodules: true
+ gem "capybara", "~> 2.1.0.beta1"
end
View
2  gemfiles/2.0.gemfile
@@ -1,6 +1,6 @@
# This file was generated by Appraisal
-source "http://rubygems.org"
+source "https://rubygems.org"
gem "capybara", "~> 2.0.2"
View
2  gemfiles/2.0.gemfile.lock
@@ -6,7 +6,7 @@ PATH
json
GEM
- remote: http://rubygems.org/
+ remote: https://rubygems.org/
specs:
appraisal (0.4.1)
bundler
View
4 gemfiles/2.1.gemfile
@@ -1,7 +1,7 @@
# This file was generated by Appraisal
-source "http://rubygems.org"
+source "https://rubygems.org"
-gem "capybara", :github=>"jnicklas/capybara", :submodules=>true
+gem "capybara", "~> 2.1.0.beta1"
gemspec :path=>"../"
View
28 gemfiles/2.1.gemfile.lock
@@ -1,17 +1,3 @@
-GIT
- remote: git://github.com/jnicklas/capybara.git
- revision: 458bb23a5cc17199aa0989fb0a0b6fb2617be74e
- submodules: true
- specs:
- capybara (2.0.2)
- mime-types (>= 1.16)
- nokogiri (>= 1.3.3)
- rack (>= 1.0.0)
- rack-test (>= 0.5.4)
- xpath (~> 1.0.0)
- xpath (1.0.0)
- nokogiri (~> 1.3)
-
PATH
remote: /home/mhoran/capybara-webkit
specs:
@@ -20,11 +6,17 @@ PATH
json
GEM
- remote: http://rubygems.org/
+ remote: https://rubygems.org/
specs:
appraisal (0.4.1)
bundler
rake
+ capybara (2.1.0.beta1)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ xpath (>= 2.0.0.beta1)
childprocess (0.3.8)
ffi (~> 1.0, >= 1.0.11)
diff-lcs (1.1.3)
@@ -34,7 +26,7 @@ GEM
mini_magick (3.5.0)
subexec (~> 0.2.1)
multi_json (1.6.1)
- nokogiri (1.5.6)
+ nokogiri (1.5.7)
rack (1.5.2)
rack-protection (1.3.2)
rack
@@ -62,13 +54,15 @@ GEM
subexec (0.2.2)
tilt (1.3.3)
websocket (1.0.7)
+ xpath (2.0.0.beta1)
+ nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
appraisal (~> 0.4.0)
- capybara!
+ capybara (~> 2.1.0.beta1)
capybara-webkit!
mini_magick
rake
View
6 lib/capybara/webkit/node.rb
@@ -92,7 +92,11 @@ def checked?
end
def disabled?
- self['disabled']
+ if %w(option optgroup).include? tag_name
+ self['disabled'] || find_xpath("parent::*")[0].disabled?
+ else
+ self['disabled']
+ end
end
def path
View
24 spec/driver_spec.rb
@@ -773,12 +773,16 @@ def visit(url, driver=driver)
<input type="text" name="foo" value="bar"/>
<input type="text" name="maxlength_foo" value="bar" maxlength="10"/>
<input type="text" id="disabled_input" disabled="disabled"/>
+ <input type="text" id="readonly_input" readonly="readonly" value="readonly"/>
<input type="checkbox" name="checkedbox" value="1" checked="checked"/>
<input type="checkbox" name="uncheckedbox" value="2"/>
<select name="animal">
<option id="select-option-monkey">Monkey</option>
<option id="select-option-capybara" selected="selected">Capybara</option>
</select>
+ <select name="disabled" disabled="disabled">
+ <option id="select-option-disabled">Disabled</option>
+ </select>
<select name="toppings" multiple="multiple">
<optgroup label="Mediocre Toppings">
<option selected="selected" id="topping-apple">Apple</option>
@@ -981,6 +985,16 @@ def visit(url, driver=driver)
it "knows a not disabled input is not disabled" do
enabled_input['disabled'].should_not be_true
end
+
+ it "does not modify a readonly input" do
+ readonly_input = driver.find_css("#readonly_input").first
+ readonly_input.set('enabled')
+ readonly_input.value.should == 'readonly'
+ end
+
+ it "should see enabled options in disabled select as disabled" do
+ driver.find_css("#select-option-disabled").first.should be_disabled
+ end
end
context "dom events" do
@@ -1083,8 +1097,8 @@ def visit(url, driver=driver)
let(:keyevents) do
(%w{focus} +
- newtext.length.times.collect { %w{keydown keypress keyup input} } +
- %w{change}).flatten
+ newtext.length.times.collect { %w{keydown keypress input keyup} }
+ ).flatten
end
%w(email number password search tel text url).each do | field_type |
@@ -1812,7 +1826,7 @@ def which_for(character)
it "returns a 0 charCode for the event" do
charCode_for("a").should == "0"
charCode_for("A").should == "0"
- charCode_for("\r").should == "0"
+ charCode_for("\b").should == "0"
charCode_for(",").should == "0"
charCode_for("<").should == "0"
charCode_for("0").should == "0"
@@ -1821,7 +1835,7 @@ def which_for(character)
it "returns the keyCode for the event" do
keyCode_for("a").should == "65"
keyCode_for("A").should == "65"
- keyCode_for("\r").should == "13"
+ keyCode_for("\b").should == "8"
keyCode_for(",").should == "188"
keyCode_for("<").should == "188"
keyCode_for("0").should == "48"
@@ -1830,7 +1844,7 @@ def which_for(character)
it "returns the which for the event" do
which_for("a").should == "65"
which_for("A").should == "65"
- which_for("\r").should == "13"
+ which_for("\b").should == "8"
which_for(",").should == "188"
which_for("<").should == "188"
which_for("0").should == "48"
View
4 spec/selenium_compatibility_spec.rb
@@ -9,6 +9,7 @@
<form onsubmit="return false">
<label for="one">One</label><input type="text" name="one" id="one" />
<label for="two">Two</label><input type="text" name="two" id="two" />
+ <label for="three">Three</label><input type="text" name="three" id="three" readonly="readonly" />
<input type="submit" value="Submit" id="submit" />
</form>
<script type="text/javascript">
@@ -18,7 +19,7 @@
};
var elements = document.getElementsByTagName("input");
var events = ["mousedown", "mouseup", "click", "keyup", "keydown",
- "keypress", "focus", "blur"];
+ "keypress", "focus", "blur", "input", "change"];
for (var i = 0; i < elements.length; i++) {
for (var j = 0; j < events.length; j++) {
elements[i].addEventListener(events[j], recordEvent);
@@ -33,6 +34,7 @@
fill_in "One", :with => "some value"
fill_in "One", :with => "a new value"
fill_in "Two", :with => "other value"
+ fill_in "Three", :with => "readonly value"
click_button "Submit"
end
end
View
31 src/JavascriptInvocation.cpp
@@ -108,3 +108,34 @@ void JavascriptInvocation::hover(int absoluteX, int absoluteY) {
void JavascriptInvocation::hover(const QPoint &mousePos) {
mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
}
+
+int JavascriptInvocation::keyCodeFor(const QChar &key) {
+ switch(key.unicode()) {
+ case 0x18:
+ return Qt::Key_Cancel;
+ case 0x08:
+ return Qt::Key_Backspace;
+ case 0x09:
+ return Qt::Key_Tab;
+ case 0x0A:
+ return Qt::Key_Return;
+ case 0x1B:
+ return Qt::Key_Escape;
+ case 0x7F:
+ return Qt::Key_Delete;
+ default:
+ int keyCode = key.toUpper().toLatin1();
+ if (keyCode >= Qt::Key_Space || keyCode <= Qt::Key_AsciiTilde)
+ return keyCode;
+ else
+ return Qt::Key_unknown;
+ }
+}
+
+void JavascriptInvocation::keypress(QChar key) {
+ int keyCode = keyCodeFor(key);
+ QKeyEvent event(QKeyEvent::KeyPress, keyCode, Qt::NoModifier, key);
+ QApplication::sendEvent(m_page, &event);
+ event = QKeyEvent(QKeyEvent::KeyRelease, keyCode, Qt::NoModifier, key);
+ QApplication::sendEvent(m_page, &event);
+}
View
2  src/JavascriptInvocation.h
@@ -23,6 +23,7 @@ class JavascriptInvocation : public QObject {
Q_INVOKABLE bool clickTest(QWebElement element, int absoluteX, int absoluteY);
Q_INVOKABLE QVariantMap clickPosition(QWebElement element, int left, int top, int width, int height);
Q_INVOKABLE void hover(int absoluteX, int absoluteY);
+ Q_INVOKABLE void keypress(QChar);
QVariant getError();
void setError(QVariant error);
InvocationResult invoke(QWebFrame *);
@@ -34,5 +35,6 @@ class JavascriptInvocation : public QObject {
QVariant m_error;
void mouseEvent(QEvent::Type type, const QPoint & position, Qt::MouseButton button);
void hover(const QPoint &);
+ int keyCodeFor(const QChar &);
};
View
78 src/capybara.js
@@ -196,29 +196,6 @@ Capybara = {
this.nodes[index].dispatchEvent(eventObject);
},
- keypress: function(index, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
- var eventObject = document.createEvent("Events");
- eventObject.initEvent('keypress', true, true);
- eventObject.window = window;
- eventObject.altKey = altKey;
- eventObject.ctrlKey = ctrlKey;
- eventObject.shiftKey = shiftKey;
- eventObject.metaKey = metaKey;
- eventObject.keyCode = keyCode;
- eventObject.charCode = charCode;
- eventObject.which = keyCode;
- this.nodes[index].dispatchEvent(eventObject);
- },
-
- keyupdown: function(index, eventName, keyCode) {
- var eventObject = document.createEvent("HTMLEvents");
- eventObject.initEvent(eventName, true, true);
- eventObject.keyCode = keyCode;
- eventObject.which = keyCode;
- eventObject.charCode = 0;
- this.nodes[index].dispatchEvent(eventObject);
- },
-
visible: function (index) {
var element = this.nodes[index];
while (element) {
@@ -248,49 +225,6 @@ Capybara = {
return true;
},
- characterToKeyCode: function(character) {
- var code = character.toUpperCase().charCodeAt(0);
- var 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 //?
- };
- if (specialKeys[code]) {
- code = specialKeys[code];
- }
- return code;
- },
-
set: function (index, value) {
var length, maxLength, node, strindex, textTypes, type;
@@ -308,16 +242,12 @@ Capybara = {
length = value.length;
}
- node.value = "";
+ if (!node.readOnly)
+ node.value = "";
+
for (strindex = 0; strindex < length; strindex++) {
- node.value += value[strindex];
- var keyCode = this.characterToKeyCode(value[strindex]);
- this.keyupdown(index, "keydown", keyCode);
- this.keypress(index, false, false, false, false, value.charCodeAt(strindex), value.charCodeAt(strindex));
- this.keyupdown(index, "keyup", keyCode);
- this.trigger(index, "input");
+ CapybaraInvocation.keypress(value[strindex]);
}
- this.trigger(index, "change");
} else if (type === "checkbox" || type === "radio") {
if (node.checked != (value === "true")) {
Something went wrong with that request. Please try again.