Node#[] should prefer properties over attributes
This commit is contained in:
parent
d53cf7c214
commit
7ce97f2539
|
@ -15,16 +15,18 @@ module Capybara::Webkit
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](name)
|
def [](name)
|
||||||
value = invoke("attribute", name)
|
name = name.to_s
|
||||||
if name == 'checked' || name == 'disabled' || name == 'multiple'
|
tn = tag_name
|
||||||
value == 'true'
|
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
|
else
|
||||||
if invoke("hasAttribute", name) == 'true'
|
val = invoke(:property, name)
|
||||||
value
|
val = invoke(:attribute, name) if val.nil? || val.is_a?(Hash)
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
val
|
||||||
end
|
end
|
||||||
|
|
||||||
def value
|
def value
|
||||||
|
@ -91,15 +93,15 @@ module Capybara::Webkit
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible?
|
def visible?
|
||||||
invoke("visible") == "true"
|
invoke("visible") == true
|
||||||
end
|
end
|
||||||
|
|
||||||
def selected?
|
def selected?
|
||||||
invoke("selected") == "true"
|
invoke("selected") == true
|
||||||
end
|
end
|
||||||
|
|
||||||
def checked?
|
def checked?
|
||||||
self['checked']
|
!!self["checked"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def disabled?
|
def disabled?
|
||||||
|
@ -139,7 +141,8 @@ module Capybara::Webkit
|
||||||
end
|
end
|
||||||
|
|
||||||
def invoke(name, *args)
|
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
|
end
|
||||||
|
|
||||||
def allow_unattached_nodes?
|
def allow_unattached_nodes?
|
||||||
|
@ -153,7 +156,8 @@ module Capybara::Webkit
|
||||||
def attached?
|
def attached?
|
||||||
warn "[DEPRECATION] The Capybara::Webkit::Node#attached? " \
|
warn "[DEPRECATION] The Capybara::Webkit::Node#attached? " \
|
||||||
"method is deprecated without replacement."
|
"method is deprecated without replacement."
|
||||||
@browser.command("Node", "isAttached", native) == "true"
|
result = @browser.command("Node", "isAttached", native)
|
||||||
|
JSON.parse(result, quirks_mode: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def multiple_select?
|
def multiple_select?
|
||||||
|
@ -161,7 +165,7 @@ module Capybara::Webkit
|
||||||
end
|
end
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
invoke("equals", other.native) == "true"
|
invoke("equals", other.native)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -1439,7 +1439,7 @@ describe Capybara::Webkit::Driver do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not modify the selected attribute of a new selection" do
|
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
|
end
|
||||||
|
|
||||||
it "returns the old value when a reset button is clicked" do
|
it "returns the old value when a reset button is clicked" do
|
||||||
|
|
|
@ -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
|
10
src/Node.cpp
10
src/Node.cpp
|
@ -1,6 +1,7 @@
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
#include "WebPage.h"
|
#include "WebPage.h"
|
||||||
#include "WebPageManager.h"
|
#include "WebPageManager.h"
|
||||||
|
#include "JsonSerializer.h"
|
||||||
#include "InvocationResult.h"
|
#include "InvocationResult.h"
|
||||||
|
|
||||||
Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : JavascriptCommand(manager, arguments, parent) {
|
Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : JavascriptCommand(manager, arguments, parent) {
|
||||||
|
@ -14,7 +15,14 @@ void Node::start() {
|
||||||
if (functionName == "focus_frame") {
|
if (functionName == "focus_frame") {
|
||||||
page()->setCurrentFrameParent(page()->currentFrame()->parentFrame());
|
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 {
|
QString Node::toString() const {
|
||||||
|
|
|
@ -85,22 +85,15 @@ Capybara = {
|
||||||
|
|
||||||
attribute: function (index, name) {
|
attribute: function (index, name) {
|
||||||
var node = this.getNode(index);
|
var node = this.getNode(index);
|
||||||
switch(name) {
|
if (node.hasAttribute(name)) {
|
||||||
case 'checked':
|
|
||||||
return node.checked;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'disabled':
|
|
||||||
return node.disabled;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'multiple':
|
|
||||||
return node.multiple;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return node.getAttribute(name);
|
return node.getAttribute(name);
|
||||||
}
|
}
|
||||||
|
return void 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
property: function (index, name) {
|
||||||
|
var node = this.getNode(index);
|
||||||
|
return node[name];
|
||||||
},
|
},
|
||||||
|
|
||||||
hasAttribute: function(index, name) {
|
hasAttribute: function(index, name) {
|
||||||
|
|
Loading…
Reference in New Issue