Add Element method for getting specific CSS styles

This commit is contained in:
Thomas Walpole 2018-06-19 13:34:54 -07:00
parent 5c8ca3866d
commit faa45e1354
8 changed files with 77 additions and 3 deletions

View File

@ -26,6 +26,10 @@ module Capybara
raise NotImplementedError
end
def style(styles)
raise NotImplementedError
end
# @param value String or Array. Array is only allowed if node has 'multiple' attribute
# @param options [Hash{}] Driver specific options for how to set a value on a node
def set(value, **options)

View File

@ -71,6 +71,27 @@ module Capybara
synchronize { base[attribute] }
end
##
#
# Retrieve the given CSS styles
#
# element.style('color') # => Computed value of CSS 'color' style
#
def style(*styles)
styles = styles.flatten.map(&:to_s)
raise ArgumentError, "You must specify at least one CSS style" if styles.empty?
result = begin
synchronize { base.style(styles) }
rescue NotImplementedError => e
begin
evaluate_script(STYLE_SCRIPT, *styles)
rescue Capybara::NotSupportedByDriverError
raise e
end
end
styles.length == 1 ? result[styles[0]] : result
end
##
#
# @return [String] The value of the form element
@ -419,6 +440,20 @@ module Capybara
%(Obsolete #<Capybara::Node::Element>)
end
private
STYLE_SCRIPT = <<~JS
(function(){
var s = window.getComputedStyle(this);
var result = {};
for (var i = arguments.length; i--; ) {
var property_name = arguments[i];
result[property_name] = s.getPropertyValue(property_name);
}
return result;
}).apply(this, arguments)
JS
end
end
end

View File

@ -24,6 +24,10 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
string_node[name]
end
def style(styles)
raise NotImplementedError, "The rack_test driver does not process CSS"
end
def value
string_node.value
end

View File

@ -28,6 +28,13 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
end
end
def style(styles)
styles.inject({}) do |memo, style|
memo[style] = native.css_value(style)
memo
end
end
##
#
# Set the value of the form element to the given value.

View File

@ -51,6 +51,17 @@ Capybara::SpecHelper.spec "node" do
end
end
describe "#style", requires: [:css] do
it "should return the computed style value" do
expect(@session.find(:css, '#first').style('display')).to eq 'block'
expect(@session.find(:css, '#second').style(:display)).to eq 'inline'
end
it "should return multiple style values" do
expect(@session.find(:css, '#first').style('display', :'line-height')).to eq({ 'display' => 'block', 'line-height' => '25px' })
end
end
describe "#value" do
it "should allow retrieval of the value" do
expect(@session.find('//textarea[@id="normal"]').value).to eq('banana')

View File

@ -1,4 +1,8 @@
<style>
p { display: block; }
</style>
<div id="referrer"><%= referrer %></div>
<h1>This is a test</h1>
@ -13,7 +17,7 @@
<span class="number">42</span>
<span>Other span</span>
<p class="para" id="first" data-random="abc\def">
<p class="para" id="first" data-random="abc\def" style="line-height: 25px;">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
et dolore magna aliqua. Ut enim ad minim veniam,
@ -22,7 +26,7 @@
<a href="/with_simple_html" aria-label="Go to simple"><img id="first_image" width="20" height="20" alt="awesome image" /></a>
</p>
<p class="para" id="second">
<p class="para" id="second" style="display: inline;">
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat <a href="/redirect" id="red">Redirect</a> pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia

View File

@ -8,7 +8,7 @@ class TestClass
end
Capybara::SpecHelper.run_specs TestClass.new, "DSL", capybara_skip: %i[
js modals screenshot frames windows send_keys server hover about_scheme psc download
js modals screenshot frames windows send_keys server hover about_scheme psc download css
]
RSpec.describe Capybara::DSL do

View File

@ -17,6 +17,7 @@ skipped_tests = %i[
hover
about_scheme
download
css
]
Capybara::SpecHelper.run_specs TestSessions::RackTest, "RackTest", capybara_skip: skipped_tests
@ -126,6 +127,14 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
expect(normal.text).to eq 'banana'
end
end
describe '#style' do
it "should raise an error" do
@session.visit('/with_html')
el = @session.find(:css, '#first')
expect { el.style('display') }.to raise_error NotImplementedError, /not process CSS/
end
end
end
end