Permalink
Browse files

Convert HTML table, dl, ol and ul to tables to use with Table#diff. T…

…ested in cucumber_rails.
  • Loading branch information...
1 parent d4b6107 commit da3c6261c0cbdbf6349bff25628d106f6e82c4c1 @aslakhellesoy aslakhellesoy committed Aug 7, 2009
View
9 History.txt
@@ -1,9 +1,18 @@
== (In Git)
+This release improves Webrat support for table-like HTML markup. This means that you can easily get the
+2-dimensional data from HTML table, dl, ol and ul elements. This is particularly useful for comparing
+data in your HTML with a Cucumber table using Cucumber::Ast::Table#diff!
+
=== New Features
+* The object returned by element_at (Webrat::Element) has a #to_table that works for table, dl, ol and ul. (Aslak Hellesøy)
* An explanation of why failures are ok is printed when --wip is used. (Aslak Hellesøy)
* Added cucumber alias for cucumber:ok in Rails Rake tasks. (Aslak Hellesøy)
+=== Changed features
+* element_at('table').to_table should be used instead of table_at('table').to_a. The old way is deprecated but still works. (Aslak Hellesøy)
+* element_at (and the depracated table_at) no longer takes a DOM id, only CSS selectors. Change "my_id" to "#my_id". (Aslak Hellesøy)
+
== 0.3.94 2009-08-06
Kanban take II.
View
87 lib/cucumber/webrat/element_locator.rb
@@ -0,0 +1,87 @@
+module Webrat
+ class Element
+ # Returns an Array of Array of String where each String is the
+ # a "cell" in the table-like structure represented by this Element.
+ #
+ # Supported elements are table, dl, ol and ul. The return value depends
+ # on the type of the element:
+ #
+ # * table : Each tr is a row. The innerHTML of each tr or th becomes cells. The number
+ # of columns is determined by the number of cells in the first row.
+ # * dl : Each dt creates a row with 2 cells. The innerHTML of the dt itself and the next dd become cells.
+ # * ul or ol : Each ul creates a row with one cell, the innerHTML of the ul.
+ #
+ def to_table
+ case element.name
+ when 'table'
+ table_from_table
+ when 'dl'
+ table_from_dl
+ when /ul|ol/
+ table_from_list
+ else
+ raise "#to_table not supported for #{element.name} elements"
+ end
+ end
+
+ def table_from_table #:nodoc:
+ col_count = nil
+ Webrat::XML.css_search(element, 'tr').map do |row|
+ cols = Webrat::XML.css_search(row, 'th,td')
+ col_count ||= cols.length
+ cols[0...col_count].map do |col|
+ col.inner_html
+ end
+ end
+ end
+
+ def table_from_dl #:nodoc:
+ Webrat::XML.css_search(@element, 'dt').map do |dt|
+ next_node = dt.next_sibling
+ while next_node.name != 'dd'
+ next_node = next_node.next_sibling
+ end
+ [dt.inner_html, next_node.inner_html]
+ end
+ end
+
+ def table_from_list #:nodoc:
+ Webrat::XML.css_search(@element, 'li').map do |li|
+ [li.inner_html]
+ end
+ end
+
+ alias to_a to_table # Backwards compatibility with Cucumber
+ end
+
+ module Locators
+ class ElementLocator < Locator
+ def locate
+ Element.load(@session, table_element)
+ end
+
+ def table_element
+ Webrat::XML.css_search(@dom, @value)[0]
+ end
+
+ def error_message
+ "Could not find anything matching '#{@value}'"
+ end
+ end
+
+ # Returns a Webrat DOM element located by +css_selector+.
+ def element_at(css_selector)
+ ElementLocator.new(@session, dom, css_selector).locate!
+ end
+
+ alias table_at element_at # Backwards compatibility with Cucumber
+ end
+
+ module Methods
+ delegate_to_session :element_at, :table_at
+ end
+
+ class Session
+ def_delegators :current_scope, :element_at, :table_at
+ end
+end
View
67 lib/cucumber/webrat/table_locator.rb
@@ -1,66 +1 @@
-module Webrat
- class Table < Element
- def self.xpath_search
- ".//table"
- end
-
- # Converts this Table element into an Array of Array of String where each cell
- # represents the inner_html of the <td> and <th> elements. The number of columns is
- # determined by the number of cells in the first row.
- def to_a
- col_count = nil
- Webrat::XML.css_search(@element, 'tr').map do |row|
- cols = Webrat::XML.css_search(row, 'th,td')
- col_count ||= cols.length
- cols[0...col_count].map do |col|
- col.inner_html
- end
- end
- end
- end
-
- module Locators
- class TableLocator < Locator
- def locate
- Table.load(@session, table_element)
- end
-
- def table_element
- table_elements.detect do |table_element|
- matches_id?(table_element) ||
- matches_css_selector?(table_element)
- end
- end
-
- def matches_id?(table_element)
- Webrat::XML.attribute(table_element, "id") == @value.to_s
- end
-
- def matches_css_selector?(table_element)
- Webrat::XML.css_at(@dom, @value)
- end
-
- def table_elements
- Webrat::XML.xpath_search(@dom, *Table.xpath_search)
- end
-
- def error_message
- "Could not find table matching '#{@value}'"
- end
- end
-
- # Returns a Table element located by +id_or_selector+, which can
- # be a DOM id or a CSS selector.
- def table_at(id_or_selector)
- TableLocator.new(@session, dom, id_or_selector).locate!
- end
- end
-
- module Methods
- delegate_to_session :table_at
- end
-
- class Session
- def_delegators :current_scope, :table_at
- end
-end
+require 'cucumber/webrat/element_locator'
View
2 rails_generators/cucumber/templates/env.rb
@@ -15,7 +15,7 @@
Cucumber::Rails.bypass_rescue
require 'webrat'
-require 'cucumber/webrat/table_locator' # Lets you do table.diff!(table_at('#my_table').to_a)
+require 'cucumber/webrat/element_locator' # Lets you do table.diff!(element_at('#my_table_or_dl_or_ul_or_ol').to_table)
Webrat.configure do |config|
config.mode = :rails
View
2 rails_generators/cucumber/templates/spork_env.rb
@@ -7,7 +7,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
require 'webrat'
- require 'cucumber/webrat/table_locator' # Lets you do table.diff!(table_at('#my_table').to_a)
+ require 'cucumber/webrat/element_locator' # Lets you do table.diff!(element_at('#my_table_or_dl_or_ul_or_ol').to_table)
Webrat.configure do |config|
config.mode = :rails
View
4 rails_generators/cucumber/templates/webrat_steps.rb
@@ -167,3 +167,7 @@
assert_equal path_to(page_name), URI.parse(current_url).path
<% end -%>
end
+
+Then /^show me the page$/ do
+ save_and_open_page
+end

0 comments on commit da3c626

Please sign in to comment.