Update tests for new content layout of index tables
Use unreleased and custom :table_row selector features.
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user