Node#[] should prefer properties over attributes

This commit is contained in:
Thomas Walpole 2017-11-08 09:11:56 -08:00
parent d53cf7c214
commit 7ce97f2539
5 changed files with 101 additions and 30 deletions

View File

@ -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

View File

@ -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

66
spec/node_spec.rb Normal file
View File

@ -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)
<html>
<head>
<title>Hello HTML</title>
</head>
<body>
<form action="/" method="GET">
<input type="text" name="foo" value="bar"/>
<input type="checkbox" name="checkedbox" value="1" checked="checked"/>
<input type="checkbox" name="uncheckedbox" value="2"/>
<input type="checkbox" name="falsecheckedbox" value="3" checked="false"/>
<input type="text" name="styled" style="font-size: 150%;"/>
</form>
</body>
</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

View File

@ -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 {

View File

@ -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) {