1
0
Fork 0
mirror of https://github.com/teamcapybara/capybara.git synced 2022-11-09 12:08:07 -05:00

Implement :cols option for :table selector and add documentation

This commit is contained in:
Thomas Walpole 2019-03-18 11:02:27 -07:00
parent 2f2b14997f
commit 5146c4aa1f
5 changed files with 51 additions and 5 deletions

View file

@ -4,7 +4,7 @@ Release date: unreleased
### Added
* `attach_file` now supports a block mode on JS capable drivers to more accurately test user behavior when file inputs are hidden (beta)
* :table selector now supports `with_rows` and `with_cols` filters
* :table selector now supports `with_rows`, 'rows', `with_cols`, and 'cols' filters
### Fixed

View file

@ -514,8 +514,16 @@ module Capybara
#
# page.has_table?('People')
#
# @param [String] locator The id or caption of a table
# @return [Boolean] Whether it exist
# @param [String] locator The id or caption of a table
# @option options [Array<Array<String>>] :rows
# Text which should be contained in the tables `<td>` elements organized by row (`<td>` visibility is not considered)
# @option options [Array<Array<String>>, Array<Hash<String,String>>] :with_rows
# Partial set of text which should be contained in the tables `<td>` elements organized by row (`<td>` visibility is not considered)
# @option options [Array<Array<String>>] :cols
# Text which should be contained in the tables `<td>` elements organized by column (`<td>` visibility is not considered)
# @option options [Array<Array<String>>, Array<Hash<String,String>>] :with_cols
# Partial set of text which should be contained in the tables `<td>` elements organized by column (`<td>` visibility is not considered)
# @return [Boolean] Whether it exists
#
def has_table?(locator = nil, **options, &optional_filter_block)
has_selector?(:table, locator, options, &optional_filter_block)

View file

@ -483,6 +483,26 @@ Capybara.add_selector(:table, locator_type: [String, Symbol]) do
xpath[col_conditions]
end
expression_filter(:cols, valid_values: [Array]) do |xpath, cols|
raise ArgumentError, ":cols must be an Array of Arrays" unless cols.all? { |col| col.is_a? Array }
rows = cols.transpose
xpath = xpath[XPath.descendant(:tbody).descendant(:tr).count.equals(rows.size) | (XPath.descendant(:tr).count.equals(rows.size) & ~XPath.descendant(:tbody))]
col_conditions = rows.map do |row|
row_conditions = row.map do |cell|
XPath.self(:td)[XPath.string.n.is(cell)]
end
row_conditions = row_conditions.reverse.reduce do |cond, cell|
cell[XPath.following_sibling[cond]]
end
row_xpath = XPath.descendant(:tr)[XPath.descendant(:td)[row_conditions]]
row_xpath[XPath.descendant(:td).count.equals(row.size)]
end.reduce(:&)
xpath[col_conditions]
end
expression_filter(:with_rows, valid_values: [Array]) do |xpath, rows|
rows_conditions = rows.map do |row|
if row.is_a? Hash
@ -507,7 +527,7 @@ Capybara.add_selector(:table, locator_type: [String, Symbol]) do
end
expression_filter(:rows, valid_values: [Array]) do |xpath, rows|
xpath = xpath[XPath.descendant(:tbody).descendant(:tr).count.equals(rows.size)]
xpath = xpath[XPath.descendant(:tbody).descendant(:tr).count.equals(rows.size) | (XPath.descendant(:tr).count.equals(rows.size) & ~XPath.descendant(:tbody))]
rows_conditions = rows.map do |row|
row_xpath = if row.is_a? Hash
row_conditions = row.map do |header, cell|

View file

@ -158,6 +158,13 @@ module Capybara
# * :caption (String) — Match text of associated caption
# * :class ((String, Array<String>, Regexp, XPath::Expression) — Matches the class(es) provided
# * :style (String, Regexp, Hash)
# * :with_rows (Array<Array<String>>, Array<Hash<String, String>>) - Partial match <td> data - visibility of <td> elements is not considered
# * :rows (Array<Array<String>>) — Match all <td>s - visibility of <td> elements is not considered
# * :with_cols (Array<Array<String>>, Array<Hash<String, String>>) - Partial match <td> data - visibility of <td> elements is not considered
# * :cols (Array<Array<String>>) — Match all <td>s - visibility of <td> elements is not considered
#
# * **:table_row** - Find table row
# * Locator: Array<String>, Hash<String,String> table row <td> contents - visibility of <td> elements is not considered
#
# * **:frame** - Find frame/iframe elements
# * Locator: Match id or name

View file

@ -43,7 +43,7 @@ Capybara::SpecHelper.spec '#has_table?' do
])
end
it 'should accept rows with array of cell values' do
it 'should accept all rows with array of cell values' do
expect(@session).to have_table('Horizontal Headers', rows:
[
%w[Thomas Walpole Oceanside],
@ -78,6 +78,17 @@ Capybara::SpecHelper.spec '#has_table?' do
])
end
it 'should match all cols with array of cell values' do
expect(@session).to have_table('Vertical Headers', cols:
[
%w[Thomas Walpole Oceanside],
%w[Danilo Wilkinson Johnsonville],
%w[Vern Konopelski Everette],
["Ratke", "Lawrence", "East Sorayashire"],
["Palmer", "Sawayn", "West Trinidad"]
])
end
it "should not match if the order of cell values doesn't match" do
expect(@session).not_to have_table('Vertical Headers', with_cols:
[