diff --git a/lib/capybara/webkit/node.rb b/lib/capybara/webkit/node.rb index 2f7ccac..211f921 100644 --- a/lib/capybara/webkit/node.rb +++ b/lib/capybara/webkit/node.rb @@ -15,16 +15,18 @@ module Capybara::Webkit end def [](name) - value = invoke("attribute", name) - if name == 'checked' || name == 'disabled' || name == 'multiple' - value == 'true' + name = name.to_s + tn = tag_name + if (tn == "img" && name == "src") || (tn == "a" && name == "href") + # Although the attribute matters, the property is consistent. Return that in + # preference to the attribute for links and images. + # if attribute exists get the property + val = invoke(:attribute, name) && invoke(:property, name) else - if invoke("hasAttribute", name) == 'true' - value - else - nil - end + val = invoke(:property, name) + val = invoke(:attribute, name) if val.nil? || val.is_a?(Hash) end + val end def value @@ -91,15 +93,15 @@ module Capybara::Webkit end def visible? - invoke("visible") == "true" + invoke("visible") == true end def selected? - invoke("selected") == "true" + invoke("selected") == true end def checked? - self['checked'] + !!self["checked"] end def disabled? @@ -139,7 +141,8 @@ module Capybara::Webkit end def invoke(name, *args) - @browser.command "Node", name, allow_unattached_nodes?, native, *args + result = @browser.command "Node", name, allow_unattached_nodes?, native, *args + JSON.parse(result, quirks_mode: true) end def allow_unattached_nodes? @@ -153,7 +156,8 @@ module Capybara::Webkit def attached? warn "[DEPRECATION] The Capybara::Webkit::Node#attached? " \ "method is deprecated without replacement." - @browser.command("Node", "isAttached", native) == "true" + result = @browser.command("Node", "isAttached", native) + JSON.parse(result, quirks_mode: true) end def multiple_select? @@ -161,7 +165,7 @@ module Capybara::Webkit end def ==(other) - invoke("equals", other.native) == "true" + invoke("equals", other.native) end private diff --git a/spec/driver_spec.rb b/spec/driver_spec.rb index 707fa91..dff9399 100644 --- a/spec/driver_spec.rb +++ b/spec/driver_spec.rb @@ -1439,7 +1439,7 @@ describe Capybara::Webkit::Driver do end it "does not modify the selected attribute of a new selection" do - expect(monkey_option['selected']).to be_nil + expect(driver.evaluate_script("arguments[0].getAttribute('selected')", monkey_option)).to be_nil end it "returns the old value when a reset button is clicked" do diff --git a/spec/node_spec.rb b/spec/node_spec.rb new file mode 100644 index 0000000..88cfe78 --- /dev/null +++ b/spec/node_spec.rb @@ -0,0 +1,66 @@ +# -*- encoding: UTF-8 -*- + +require "spec_helper" +require "capybara/webkit/driver" +require "base64" +require "self_signed_ssl_cert" + +describe Capybara::Webkit::Node do + include AppRunner + + def visit(path, driver = self.driver) + driver.visit(url(path)) + end + + def url(path) + "#{AppRunner.app_host}#{path}" + end + + context "html app" do + let(:driver) do + driver_for_html(<<-HTML) + + + Hello HTML + + +
+ + + + + +
+ + + HTML + end + + before { visit("/") } + + context "Node#[]" do + it "gets boolean properties" do + box1 = driver.find_css('input[name="checkedbox"]').first + box2 = driver.find_css('input[name="uncheckedbox"]').first + box3 = driver.find_css('input[name="falsecheckedbox"]').first + expect(box1["checked"]).to eq true + expect(box2["checked"]).to eq false + expect(box3["checked"]).to eq true + box1.set(false) + expect(box1["checked"]).to eq false + end + + it "prefers property over attribute" do + input = driver.find_css('input[name="foo"]').first + expect(input["value"]).to eq "bar" + input.set("new value") + expect(input["value"]).to eq "new value" + end + + it "returns attribute when property is an object" do + input = driver.find_css('input[name="styled"]').first + expect(input["style"]).to eq "font-size: 150%;" + end + end + end +end diff --git a/src/Node.cpp b/src/Node.cpp index baed90a..4feea23 100644 --- a/src/Node.cpp +++ b/src/Node.cpp @@ -1,6 +1,7 @@ #include "Node.h" #include "WebPage.h" #include "WebPageManager.h" +#include "JsonSerializer.h" #include "InvocationResult.h" Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : JavascriptCommand(manager, arguments, parent) { @@ -14,7 +15,14 @@ void Node::start() { if (functionName == "focus_frame") { page()->setCurrentFrameParent(page()->currentFrame()->parentFrame()); } - finish(&result); + + if (result.hasError()) { + finish(&result); + } else { + JsonSerializer serializer; + InvocationResult jsonResult = InvocationResult(serializer.serialize(result.result())); + finish(&jsonResult); + } } QString Node::toString() const { diff --git a/src/capybara.js b/src/capybara.js index 2954cfd..3365d05 100644 --- a/src/capybara.js +++ b/src/capybara.js @@ -85,22 +85,15 @@ Capybara = { attribute: function (index, name) { var node = this.getNode(index); - switch(name) { - case 'checked': - return node.checked; - break; - - case 'disabled': - return node.disabled; - break; - - case 'multiple': - return node.multiple; - break; - - default: + if (node.hasAttribute(name)) { return node.getAttribute(name); } + return void 0; + }, + + property: function (index, name) { + var node = this.getNode(index); + return node[name]; }, hasAttribute: function(index, name) {