Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 6 commits
  • 13 files changed
  • 0 comments
  • 2 contributors
1  .travis.yml
@@ -6,7 +6,6 @@ rvm:
6 6 matrix:
7 7 allow_failures:
8 8 - rvm: rbx-19mode
9   - - gemfile: gemfiles/2.1.gemfile
10 9 exclude:
11 10 - rvm: 1.9.3
12 11 gemfile: gemfiles/2.0.gemfile
2  Appraisals
@@ -3,5 +3,5 @@ appraise "2.0" do
3 3 end
4 4
5 5 appraise "2.1" do
6   - gem "capybara", github: "jnicklas/capybara", submodules: true
  6 + gem "capybara", "~> 2.1.0.beta1"
7 7 end
3  README.md
Source Rendered
... ... @@ -1,7 +1,8 @@
1 1 capybara-webkit
2 2 ===============
3 3
4   -[![Build Status](https://secure.travis-ci.org/thoughtbot/capybara-webkit.png?branch=master)](https://travis-ci.org/thoughtbot/capybara-webkit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/thoughtbot/capybara-webkit)
  4 +[![Build Status](https://secure.travis-ci.org/thoughtbot/capybara-webkit.png?branch=master)](https://travis-ci.org/thoughtbot/capybara-webkit)
  5 +[![Code Climate](https://codeclimate.com/github/thoughtbot/capybara-webkit.png)](https://codeclimate.com/github/thoughtbot/capybara-webkit)
5 6
6 7 A [capybara](https://github.com/jnicklas/capybara) driver that uses [WebKit](http://webkit.org) via [QtWebKit](http://doc.qt.nokia.com/4.7/qtwebkit.html).
7 8
2  gemfiles/2.0.gemfile
... ... @@ -1,6 +1,6 @@
1 1 # This file was generated by Appraisal
2 2
3   -source "http://rubygems.org"
  3 +source "https://rubygems.org"
4 4
5 5 gem "capybara", "~> 2.0.2"
6 6
2  gemfiles/2.0.gemfile.lock
@@ -6,7 +6,7 @@ PATH
6 6 json
7 7
8 8 GEM
9   - remote: http://rubygems.org/
  9 + remote: https://rubygems.org/
10 10 specs:
11 11 appraisal (0.4.1)
12 12 bundler
4 gemfiles/2.1.gemfile
... ... @@ -1,7 +1,7 @@
1 1 # This file was generated by Appraisal
2 2
3   -source "http://rubygems.org"
  3 +source "https://rubygems.org"
4 4
5   -gem "capybara", :github=>"jnicklas/capybara", :submodules=>true
  5 +gem "capybara", "~> 2.1.0.beta1"
6 6
7 7 gemspec :path=>"../"
28 gemfiles/2.1.gemfile.lock
... ... @@ -1,17 +1,3 @@
1   -GIT
2   - remote: git://github.com/jnicklas/capybara.git
3   - revision: 458bb23a5cc17199aa0989fb0a0b6fb2617be74e
4   - submodules: true
5   - specs:
6   - capybara (2.0.2)
7   - mime-types (>= 1.16)
8   - nokogiri (>= 1.3.3)
9   - rack (>= 1.0.0)
10   - rack-test (>= 0.5.4)
11   - xpath (~> 1.0.0)
12   - xpath (1.0.0)
13   - nokogiri (~> 1.3)
14   -
15 1 PATH
16 2 remote: /home/mhoran/capybara-webkit
17 3 specs:
@@ -20,11 +6,17 @@ PATH
20 6 json
21 7
22 8 GEM
23   - remote: http://rubygems.org/
  9 + remote: https://rubygems.org/
24 10 specs:
25 11 appraisal (0.4.1)
26 12 bundler
27 13 rake
  14 + capybara (2.1.0.beta1)
  15 + mime-types (>= 1.16)
  16 + nokogiri (>= 1.3.3)
  17 + rack (>= 1.0.0)
  18 + rack-test (>= 0.5.4)
  19 + xpath (>= 2.0.0.beta1)
28 20 childprocess (0.3.8)
29 21 ffi (~> 1.0, >= 1.0.11)
30 22 diff-lcs (1.1.3)
@@ -34,7 +26,7 @@ GEM
34 26 mini_magick (3.5.0)
35 27 subexec (~> 0.2.1)
36 28 multi_json (1.6.1)
37   - nokogiri (1.5.6)
  29 + nokogiri (1.5.7)
38 30 rack (1.5.2)
39 31 rack-protection (1.3.2)
40 32 rack
@@ -62,13 +54,15 @@ GEM
62 54 subexec (0.2.2)
63 55 tilt (1.3.3)
64 56 websocket (1.0.7)
  57 + xpath (2.0.0.beta1)
  58 + nokogiri (~> 1.3)
65 59
66 60 PLATFORMS
67 61 ruby
68 62
69 63 DEPENDENCIES
70 64 appraisal (~> 0.4.0)
71   - capybara!
  65 + capybara (~> 2.1.0.beta1)
72 66 capybara-webkit!
73 67 mini_magick
74 68 rake
6 lib/capybara/webkit/node.rb
@@ -92,7 +92,11 @@ def checked?
92 92 end
93 93
94 94 def disabled?
95   - self['disabled']
  95 + if %w(option optgroup).include? tag_name
  96 + self['disabled'] || find_xpath("parent::*")[0].disabled?
  97 + else
  98 + self['disabled']
  99 + end
96 100 end
97 101
98 102 def path
24 spec/driver_spec.rb
@@ -773,12 +773,16 @@ def visit(url, driver=driver)
773 773 <input type="text" name="foo" value="bar"/>
774 774 <input type="text" name="maxlength_foo" value="bar" maxlength="10"/>
775 775 <input type="text" id="disabled_input" disabled="disabled"/>
  776 + <input type="text" id="readonly_input" readonly="readonly" value="readonly"/>
776 777 <input type="checkbox" name="checkedbox" value="1" checked="checked"/>
777 778 <input type="checkbox" name="uncheckedbox" value="2"/>
778 779 <select name="animal">
779 780 <option id="select-option-monkey">Monkey</option>
780 781 <option id="select-option-capybara" selected="selected">Capybara</option>
781 782 </select>
  783 + <select name="disabled" disabled="disabled">
  784 + <option id="select-option-disabled">Disabled</option>
  785 + </select>
782 786 <select name="toppings" multiple="multiple">
783 787 <optgroup label="Mediocre Toppings">
784 788 <option selected="selected" id="topping-apple">Apple</option>
@@ -981,6 +985,16 @@ def visit(url, driver=driver)
981 985 it "knows a not disabled input is not disabled" do
982 986 enabled_input['disabled'].should_not be_true
983 987 end
  988 +
  989 + it "does not modify a readonly input" do
  990 + readonly_input = driver.find_css("#readonly_input").first
  991 + readonly_input.set('enabled')
  992 + readonly_input.value.should == 'readonly'
  993 + end
  994 +
  995 + it "should see enabled options in disabled select as disabled" do
  996 + driver.find_css("#select-option-disabled").first.should be_disabled
  997 + end
984 998 end
985 999
986 1000 context "dom events" do
@@ -1083,8 +1097,8 @@ def visit(url, driver=driver)
1083 1097
1084 1098 let(:keyevents) do
1085 1099 (%w{focus} +
1086   - newtext.length.times.collect { %w{keydown keypress keyup input} } +
1087   - %w{change}).flatten
  1100 + newtext.length.times.collect { %w{keydown keypress input keyup} }
  1101 + ).flatten
1088 1102 end
1089 1103
1090 1104 %w(email number password search tel text url).each do | field_type |
@@ -1812,7 +1826,7 @@ def which_for(character)
1812 1826 it "returns a 0 charCode for the event" do
1813 1827 charCode_for("a").should == "0"
1814 1828 charCode_for("A").should == "0"
1815   - charCode_for("\r").should == "0"
  1829 + charCode_for("\b").should == "0"
1816 1830 charCode_for(",").should == "0"
1817 1831 charCode_for("<").should == "0"
1818 1832 charCode_for("0").should == "0"
@@ -1821,7 +1835,7 @@ def which_for(character)
1821 1835 it "returns the keyCode for the event" do
1822 1836 keyCode_for("a").should == "65"
1823 1837 keyCode_for("A").should == "65"
1824   - keyCode_for("\r").should == "13"
  1838 + keyCode_for("\b").should == "8"
1825 1839 keyCode_for(",").should == "188"
1826 1840 keyCode_for("<").should == "188"
1827 1841 keyCode_for("0").should == "48"
@@ -1830,7 +1844,7 @@ def which_for(character)
1830 1844 it "returns the which for the event" do
1831 1845 which_for("a").should == "65"
1832 1846 which_for("A").should == "65"
1833   - which_for("\r").should == "13"
  1847 + which_for("\b").should == "8"
1834 1848 which_for(",").should == "188"
1835 1849 which_for("<").should == "188"
1836 1850 which_for("0").should == "48"
4 spec/selenium_compatibility_spec.rb
@@ -9,6 +9,7 @@
9 9 <form onsubmit="return false">
10 10 <label for="one">One</label><input type="text" name="one" id="one" />
11 11 <label for="two">Two</label><input type="text" name="two" id="two" />
  12 + <label for="three">Three</label><input type="text" name="three" id="three" readonly="readonly" />
12 13 <input type="submit" value="Submit" id="submit" />
13 14 </form>
14 15 <script type="text/javascript">
@@ -18,7 +19,7 @@
18 19 };
19 20 var elements = document.getElementsByTagName("input");
20 21 var events = ["mousedown", "mouseup", "click", "keyup", "keydown",
21   - "keypress", "focus", "blur"];
  22 + "keypress", "focus", "blur", "input", "change"];
22 23 for (var i = 0; i < elements.length; i++) {
23 24 for (var j = 0; j < events.length; j++) {
24 25 elements[i].addEventListener(events[j], recordEvent);
@@ -33,6 +34,7 @@
33 34 fill_in "One", :with => "some value"
34 35 fill_in "One", :with => "a new value"
35 36 fill_in "Two", :with => "other value"
  37 + fill_in "Three", :with => "readonly value"
36 38 click_button "Submit"
37 39 end
38 40 end
31 src/JavascriptInvocation.cpp
@@ -108,3 +108,34 @@ void JavascriptInvocation::hover(int absoluteX, int absoluteY) {
108 108 void JavascriptInvocation::hover(const QPoint &mousePos) {
109 109 mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
110 110 }
  111 +
  112 +int JavascriptInvocation::keyCodeFor(const QChar &key) {
  113 + switch(key.unicode()) {
  114 + case 0x18:
  115 + return Qt::Key_Cancel;
  116 + case 0x08:
  117 + return Qt::Key_Backspace;
  118 + case 0x09:
  119 + return Qt::Key_Tab;
  120 + case 0x0A:
  121 + return Qt::Key_Return;
  122 + case 0x1B:
  123 + return Qt::Key_Escape;
  124 + case 0x7F:
  125 + return Qt::Key_Delete;
  126 + default:
  127 + int keyCode = key.toUpper().toLatin1();
  128 + if (keyCode >= Qt::Key_Space || keyCode <= Qt::Key_AsciiTilde)
  129 + return keyCode;
  130 + else
  131 + return Qt::Key_unknown;
  132 + }
  133 +}
  134 +
  135 +void JavascriptInvocation::keypress(QChar key) {
  136 + int keyCode = keyCodeFor(key);
  137 + QKeyEvent event(QKeyEvent::KeyPress, keyCode, Qt::NoModifier, key);
  138 + QApplication::sendEvent(m_page, &event);
  139 + event = QKeyEvent(QKeyEvent::KeyRelease, keyCode, Qt::NoModifier, key);
  140 + QApplication::sendEvent(m_page, &event);
  141 +}
2  src/JavascriptInvocation.h
@@ -23,6 +23,7 @@ class JavascriptInvocation : public QObject {
23 23 Q_INVOKABLE bool clickTest(QWebElement element, int absoluteX, int absoluteY);
24 24 Q_INVOKABLE QVariantMap clickPosition(QWebElement element, int left, int top, int width, int height);
25 25 Q_INVOKABLE void hover(int absoluteX, int absoluteY);
  26 + Q_INVOKABLE void keypress(QChar);
26 27 QVariant getError();
27 28 void setError(QVariant error);
28 29 InvocationResult invoke(QWebFrame *);
@@ -34,5 +35,6 @@ class JavascriptInvocation : public QObject {
34 35 QVariant m_error;
35 36 void mouseEvent(QEvent::Type type, const QPoint & position, Qt::MouseButton button);
36 37 void hover(const QPoint &);
  38 + int keyCodeFor(const QChar &);
37 39 };
38 40
78 src/capybara.js
@@ -196,29 +196,6 @@ Capybara = {
196 196 this.nodes[index].dispatchEvent(eventObject);
197 197 },
198 198
199   - keypress: function(index, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
200   - var eventObject = document.createEvent("Events");
201   - eventObject.initEvent('keypress', true, true);
202   - eventObject.window = window;
203   - eventObject.altKey = altKey;
204   - eventObject.ctrlKey = ctrlKey;
205   - eventObject.shiftKey = shiftKey;
206   - eventObject.metaKey = metaKey;
207   - eventObject.keyCode = keyCode;
208   - eventObject.charCode = charCode;
209   - eventObject.which = keyCode;
210   - this.nodes[index].dispatchEvent(eventObject);
211   - },
212   -
213   - keyupdown: function(index, eventName, keyCode) {
214   - var eventObject = document.createEvent("HTMLEvents");
215   - eventObject.initEvent(eventName, true, true);
216   - eventObject.keyCode = keyCode;
217   - eventObject.which = keyCode;
218   - eventObject.charCode = 0;
219   - this.nodes[index].dispatchEvent(eventObject);
220   - },
221   -
222 199 visible: function (index) {
223 200 var element = this.nodes[index];
224 201 while (element) {
@@ -248,49 +225,6 @@ Capybara = {
248 225 return true;
249 226 },
250 227
251   - characterToKeyCode: function(character) {
252   - var code = character.toUpperCase().charCodeAt(0);
253   - var specialKeys = {
254   - 96: 192, //`
255   - 45: 189, //-
256   - 61: 187, //=
257   - 91: 219, //[
258   - 93: 221, //]
259   - 92: 220, //\
260   - 59: 186, //;
261   - 39: 222, //'
262   - 44: 188, //,
263   - 46: 190, //.
264   - 47: 191, ///
265   - 127: 46, //delete
266   - 126: 192, //~
267   - 33: 49, //!
268   - 64: 50, //@
269   - 35: 51, //#
270   - 36: 52, //$
271   - 37: 53, //%
272   - 94: 54, //^
273   - 38: 55, //&
274   - 42: 56, //*
275   - 40: 57, //(
276   - 41: 48, //)
277   - 95: 189, //_
278   - 43: 187, //+
279   - 123: 219, //{
280   - 125: 221, //}
281   - 124: 220, //|
282   - 58: 186, //:
283   - 34: 222, //"
284   - 60: 188, //<
285   - 62: 190, //>
286   - 63: 191 //?
287   - };
288   - if (specialKeys[code]) {
289   - code = specialKeys[code];
290   - }
291   - return code;
292   - },
293   -
294 228 set: function (index, value) {
295 229 var length, maxLength, node, strindex, textTypes, type;
296 230
@@ -308,16 +242,12 @@ Capybara = {
308 242 length = value.length;
309 243 }
310 244
311   - node.value = "";
  245 + if (!node.readOnly)
  246 + node.value = "";
  247 +
312 248 for (strindex = 0; strindex < length; strindex++) {
313   - node.value += value[strindex];
314   - var keyCode = this.characterToKeyCode(value[strindex]);
315   - this.keyupdown(index, "keydown", keyCode);
316   - this.keypress(index, false, false, false, false, value.charCodeAt(strindex), value.charCodeAt(strindex));
317   - this.keyupdown(index, "keyup", keyCode);
318   - this.trigger(index, "input");
  249 + CapybaraInvocation.keypress(value[strindex]);
319 250 }
320   - this.trigger(index, "change");
321 251
322 252 } else if (type === "checkbox" || type === "radio") {
323 253 if (node.checked != (value === "true")) {

No commit comments for this range

Something went wrong with that request. Please try again.