Update tests for new content layout of index tables

Use unreleased and custom :table_row selector features.
This commit is contained in:
2026-10-27 06:15:14 +01:00
parent 9c51887024
commit 31db40fae8
4 changed files with 54 additions and 27 deletions
+3 -1
View File
@@ -40,7 +40,9 @@ end
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem "capybara"
# TODO: move back from git after this PR is included:
# https://github.com/teamcapybara/capybara/pull/2862
gem "capybara", git: "https://github.com/teamcapybara/capybara", branch: "table_row-optional-header-and-integer-locator"
gem "selenium-webdriver"
end
+16 -10
View File
@@ -6,6 +6,21 @@ GIT
i18n (1.15.2)
concurrent-ruby (~> 1.0)
GIT
remote: https://github.com/teamcapybara/capybara
revision: 3e9a2bff144fc5dc980e7f5c9dce31a13e3cad31
branch: table_row-optional-header-and-integer-locator
specs:
capybara (3.40.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.11)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
GEM
remote: https://rubygems.org/
specs:
@@ -92,15 +107,6 @@ GEM
builder (3.3.0)
byebug (13.0.0)
reline (>= 0.6.0)
capybara (3.40.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.11)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
concurrent-ruby (1.3.8)
connection_pool (3.0.2)
crass (1.0.7)
@@ -318,7 +324,7 @@ PLATFORMS
DEPENDENCIES
byebug
capybara
capybara!
devise (~> 5.0.4)
i18n!
importmap-rails
+12 -2
View File
@@ -73,6 +73,11 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
rows_conditions = rows.map { |row| match_row(row) }.reduce(:&)
xpath[match_row_count(rows.size)][rows_conditions]
end
# Override to count only data rows, to make it consistent with #match_row.
def match_row_count(size)
XPath.descendant(:tr).where(XPath.descendant(:td)).count.equals(size)
end
end
# This regex has to be only strict enough to properly reconstruct number. It
@@ -87,6 +92,7 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
# Based on Capybara :table and :table_row selectors.
Capybara.add_selector(:table_cell, locator_type: [String, Symbol]) do
xpath do |locator|
# TODO: make sure to only include visible column headers
column = XPath.string.n.is(locator.to_s)
header_xp = XPath.ancestor(:table)[1].descendant(:tr)[1].descendant(:th)[column]
position_xp = XPath.position.equals(header_xp.preceding_sibling.count.plus(1))
@@ -97,13 +103,15 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
value ? xpath.where(XPath.descendant(:input, :select, :textarea)) : xpath
end
node_filter(:with) do |node, expected|
node_filter(:value) do |node, expected|
value =
case expected
when Float
node.text.match(NUMBER) { |m| "#{m['base'] || '1'}e#{m['exp']&.lstrip}".to_f }
when Integer
node.to_i
else
node.text
node.text.presence || nil
end
(expected == value).tap do |result|
add_error("Expected value to be #{expected.inspect}" \
@@ -114,6 +122,8 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
Capybara.modify_selector(:table_row) do
# Beware: filters of #boolean? type are called within different context.
# TODO: add in separate FilterSet and import using #filter_set?
# TODO: replace node_filter with expression_filter `:focus-within`?
node_filter(:with_focus, :boolean) do |node, value|
node.has_selector?(':focus') == value
end
+23 -14
View File
@@ -10,6 +10,7 @@ require "application_system_test_case"
# * user with single unit,
# * user with no units.
# Users need to be active and confirmed. Units w/ and w/o description.
# TODO: use :table_row instead of css locators (tbody etc.), optionally without locator
class UnitsTest < ApplicationSystemTestCase
def sign_in(...)
@@ -35,7 +36,7 @@ class UnitsTest < ApplicationSystemTestCase
sign_in
if @user.units.empty?
assert_selector :table, rows: [[t('units.no_items')]]
assert_selector :table, caption: t('units.index.no_items'), rows: []
else
column = column(:symbol)
assert_selector :table, rows_with: @user.units.map { |u| {column => u.symbol} }
@@ -56,6 +57,8 @@ class UnitsTest < ApplicationSystemTestCase
attributes = [:symbol, :description]
attributes << :multiplier if action == :new_subunit
# TODO: verify form location and focus
# action == :new_subunit ? first(:table_row) : :table_row, after: {column(:symbol) => ...}
within :table_row, {}, with_focus: true do
attributes.map! do |name|
field = find(:table_cell, column(name)).find(:fillable_field)
@@ -90,13 +93,16 @@ class UnitsTest < ApplicationSystemTestCase
multiplier = attributes.delete(:multiplier).to_f if action == :new_subunit
within :table_row, attributes.transform_keys { |k| column(k) } do
assert_selector :table_cell, column(:multiplier), with: multiplier if multiplier
assert_selector :table_cell, column(:multiplier), value: multiplier
end
end
assert_no_selector :link, disabled: true,
exact_text: Regexp.union(link_labels.values)
# TODO: 50/50 open new form and check if alert is no longer visible? #91
refresh
# TODO: change to assert_selector :table, rows: ...
assert_equal new_symbols, list_symbols
end
@@ -132,23 +138,24 @@ class UnitsTest < ApplicationSystemTestCase
sign_in(user: users.select { |u| u.confirmed? && u.units.many? }.sample)
link = all(:link_or_button, exact_text: t('units.unit.destroy')).sample
symbol = link.ancestor('tr').first(:link).text
index = link.ancestor('tbody').all('tr').index { |e| e.first(:link).text == symbol }
unit = @user.units.find_by(symbol: symbol)
symbol = link.ancestor(:table_row).find(:table_cell, column(:symbol)).text
index = all(:table_cell, column(:symbol)).map(&:text).index(symbol)
unit = @user.units.find_sole_by(symbol: symbol)
link.click
assert_selector '.flash.notice'
if unit.base_id?
find_link(unit.base.symbol).ancestor('tr').click_on(t('units.unit.new_subunit'))
fill_in 'unit[multiplier]', with: unit.multiplier
find(:table_cell, column(:multiplier), fillable: true)
.fill_in with: unit.multiplier
else
click_on t('units.index.new_unit')
end
fill_in 'unit[symbol]', with: unit.symbol
find(:table_cell, column(:symbol), fillable: true).fill_in with: unit.symbol
click_on t('helpers.submit.create')
within "tbody > tr:nth-child(#{index+1})" do
assert_selector :link, exact_text: symbol
within :table_row, index+1 do
assert_selector :table_cell, column(:symbol), exact_text: symbol
end
end
@@ -186,9 +193,11 @@ class UnitsTest < ApplicationSystemTestCase
click_on t(:cancel)
assert_no_selector '.flash.alert'
# TODO: change to assert_selector :table, rows: ...
assert_equal symbols, list_symbols
refresh
assert_no_selector '.flash.alert'
# TODO: change to assert_selector :table, rows: ...
assert_equal symbols, list_symbols
end
@@ -235,11 +244,11 @@ class UnitsTest < ApplicationSystemTestCase
end
# NOTE: extend with any add/edit link
test "new form closes on escape key" do
test "new and edit forms close on escape key" do
sign_in
click_on t('units.index.new_unit')
first('tbody > tr').all(:field).sample.send_keys :escape
within 'tbody' do
first(:table_row).all(:field).sample.send_keys :escape
within :table do
assert_no_selector :fillable_field
end
end
@@ -272,8 +281,8 @@ class UnitsTest < ApplicationSystemTestCase
end
end
assert_selector :table, rows: [[t('units.no_items')]]
assert_selector :table, caption: t('units.index.no_items'), rows: []
refresh
assert_selector :table, rows: [[t('units.no_items')]]
assert_selector :table, caption: t('units.index.no_items'), rows: []
end
end