diff --git a/CHANGELOG.md b/CHANGELOG.md index 20fc80da..9e222793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ #### Features #### * Implement support for Capybara Window#size and Window#resize_to (Thomas Walpole) * Add access to properties of node's native element (Mike Souza) +* Node#[] now prefers element properties over attributes when the property exists and is + not an object. This is similar to the selenium driver behavior. (Thomas Walpole) #### Bug fixes #### diff --git a/lib/capybara/poltergeist/client/browser.coffee b/lib/capybara/poltergeist/client/browser.coffee index 07e6e588..40101d4f 100644 --- a/lib/capybara/poltergeist/client/browser.coffee +++ b/lib/capybara/poltergeist/client/browser.coffee @@ -138,7 +138,7 @@ class Poltergeist.Browser @current_command.sendResponse this.node(page_id, id).deleteText() property: (page_id, id, name) -> - this.sendResponse this.node(page_id, id).getProperty(name) + @current_command.sendResponse this.node(page_id, id).getProperty(name) attribute: (page_id, id, name) -> @current_command.sendResponse this.node(page_id, id).getAttribute(name) diff --git a/lib/capybara/poltergeist/client/compiled/browser.js b/lib/capybara/poltergeist/client/compiled/browser.js index e0499c69..9ec11905 100644 --- a/lib/capybara/poltergeist/client/compiled/browser.js +++ b/lib/capybara/poltergeist/client/compiled/browser.js @@ -180,6 +180,10 @@ Poltergeist.Browser = (function() { return this.current_command.sendResponse(this.node(page_id, id).deleteText()); }; + Browser.prototype.property = function(page_id, id, name) { + return this.current_command.sendResponse(this.node(page_id, id).getProperty(name)); + }; + Browser.prototype.attribute = function(page_id, id, name) { return this.current_command.sendResponse(this.node(page_id, id).getAttribute(name)); }; @@ -188,10 +192,6 @@ Poltergeist.Browser = (function() { return this.current_command.sendResponse(this.node(page_id, id).getAttributes()); }; - Browser.prototype.property = function(page_id, id, name) { - return this.sendResponse(this.node(page_id, id).getProperty(name)); - }; - Browser.prototype.parents = function(page_id, id) { return this.current_command.sendResponse(this.node(page_id, id).parentIds()); }; diff --git a/lib/capybara/poltergeist/node.rb b/lib/capybara/poltergeist/node.rb index d78c45ae..1d20f7b1 100644 --- a/lib/capybara/poltergeist/node.rb +++ b/lib/capybara/poltergeist/node.rb @@ -55,7 +55,18 @@ def property(name) end def [](name) - command :attribute, name + # Although the attribute matters, the property is consistent. Return that in + # preference to the attribute for links and images. + if (tag_name == 'img' and name == 'src') or (tag_name == 'a' and name == 'href' ) + #if attribute exists get the property + value = command(:attribute, name) && command(:property, name) + return value + end + + value = property(name) + value = command(:attribute, name) if value.nil? || value.is_a?(Hash) + + value end def attributes diff --git a/spec/integration/session_spec.rb b/spec/integration/session_spec.rb index ad176151..a5680dc0 100644 --- a/spec/integration/session_spec.rb +++ b/spec/integration/session_spec.rb @@ -257,6 +257,42 @@ end end + describe 'Node#checked?' do + before do + @session.visit '/poltergeist/attributes_properties' + end + + it 'is a boolean' do + expect(@session.find_field('checked').checked?).to be true + expect(@session.find_field('unchecked').checked?).to be false + end + end + + describe 'Node#[]' do + before do + @session.visit '/poltergeist/attributes_properties' + end + + it 'gets normalized href' do + expect(@session.find(:link, 'Loop')['href']).to eq("http://#{@session.server.host}:#{@session.server.port}/poltergeist/attributes_properties") + end + + it 'gets innerHTML' do + expect(@session.find(:css,'.some_other_class')['innerHTML']).to eq '

foobar

' + end + + it 'gets attribute' do + link = @session.find(:link, 'Loop') + expect(link['data-random']).to eq '42' + expect(link['onclick']).to eq "return false;" + end + + it 'gets boolean attributes as booleans' do + expect(@session.find_field('checked')['checked']).to be true + expect(@session.find_field('unchecked')['checked']).to be false + end + end + it 'has no trouble clicking elements when the size of a document changes' do @session.visit('/poltergeist/long_page') @session.find(:css, '#penultimate').click @@ -737,20 +773,20 @@ context 'supports accessing element properties' do before do - @session.visit '/poltergeist/property' + @session.visit '/poltergeist/attributes_properties' end it 'gets property innerHTML' do - expect(@session.find(:css,'.some_class').native.property('innerHTML')).to eq '

foobar

' + expect(@session.find(:css,'.some_other_class').native.property('innerHTML')).to eq '

foobar

' end it 'gets property outerHTML' do - expect(@session.find(:css,'.some_class').native.property('outerHTML')).to eq '

foobar

' + expect(@session.find(:css,'.some_other_class').native.property('outerHTML')).to eq '

foobar

' end end it 'allows access to element attributes' do - @session.visit '/poltergeist/attributes' + @session.visit '/poltergeist/attributes_properties' expect(@session.find(:css,'#my_link').native.attributes).to eq( 'href' => '#', 'id' => 'my_link', 'class' => 'some_class', 'data' => 'rah!' ) diff --git a/spec/support/views/attributes.erb b/spec/support/views/attributes.erb deleted file mode 100644 index 84a7da62..00000000 --- a/spec/support/views/attributes.erb +++ /dev/null @@ -1,6 +0,0 @@ - - - - Link me - - diff --git a/spec/support/views/attributes_properties.erb b/spec/support/views/attributes_properties.erb new file mode 100644 index 00000000..a990e152 --- /dev/null +++ b/spec/support/views/attributes_properties.erb @@ -0,0 +1,10 @@ + + + + Link me +

foobar

+ Loop + + + + diff --git a/spec/support/views/property.erb b/spec/support/views/property.erb deleted file mode 100644 index 920d7464..00000000 --- a/spec/support/views/property.erb +++ /dev/null @@ -1,6 +0,0 @@ - - - -

foobar

- -