mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Adapt specs to capybara_accessible_selectors 0.16
Refactors the custom `:list`/`:list_item` selectors onto CAS's
`add_role_selector` and drops the now-native `Capybara::Node::Simple#role`
hack. `:list_item` resolves the listitem role, so specs matching
non-listitem `<li>` are updated (`have_row` for the custom field table,
presentation dividers via CSS).
CAS 0.16 also resolves role selectors by computed role and accessible
name, which our CSS-styled tables and Primer menus do not expose through
plain markup. Affected feature specs switch to robust locators:
Capybara's `:table_row`, the FullCalendar `data-date`, and the action
menu's real accessible name ("Edit status").
The `:columnheader` `colindex` filter lost its off-by-one offset and now
uses the true 1-based `th` position. Also fixes Webhooks `RowComponent`
spec capitalization.
This commit is contained in:
@@ -259,8 +259,8 @@ RSpec.describe Backlogs::SprintComponent, type: :component do
|
||||
rendered_component
|
||||
|
||||
expect(menu_items).to eq(["Edit sprint", "Add work package", "Sprint board", "Burndown chart"])
|
||||
expect(page).to have_list_item position: 2, role: "presentation"
|
||||
expect(page).to have_list_item position: 4, role: "presentation"
|
||||
# The three item groups are separated by presentation-only dividers.
|
||||
expect(page).to have_css("li[role='presentation']", count: 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -67,6 +67,7 @@ RSpec.describe "OAuth Access Grant Nudge upon adding a storage to a project",
|
||||
|
||||
it "adds a storage, nudges the project admin to grant OAuth access" do
|
||||
visit external_file_storages_project_settings_project_storages_path(project_id: project)
|
||||
expect(page).to have_heading "Files"
|
||||
|
||||
click_on("Storage")
|
||||
|
||||
@@ -76,8 +77,7 @@ RSpec.describe "OAuth Access Grant Nudge upon adding a storage to a project",
|
||||
expect(page).to have_checked_field("New folder with automatically managed permissions")
|
||||
click_on("Add")
|
||||
|
||||
expect(page).to have_heading "Files"
|
||||
expect(page).to have_text(storage.name)
|
||||
expect(page).to have_selector(:table_row, [storage.name])
|
||||
|
||||
within_test_selector("oauth-access-grant-nudge-modal") do
|
||||
expect(page).to be_axe_clean
|
||||
|
||||
@@ -69,7 +69,9 @@ module Components
|
||||
|
||||
def drag_wp_to_date(work_package, date)
|
||||
wp_card = card(work_package)
|
||||
day_header = page.find(:columnheader, exact_text: date.strftime("%02d %A"))
|
||||
# The FullCalendar timeline day headers are not exposed as columnheaders
|
||||
# (their table has a presentation role), so target the labelled slot by date.
|
||||
day_header = page.find(".fc-timeline-slot-label[data-date='#{date.iso8601}']")
|
||||
drag_n_drop_element(from: wp_card, to: day_header, offset_y: day_header.native.size.height)
|
||||
end
|
||||
|
||||
|
||||
@@ -95,8 +95,8 @@ RSpec.describe Webhooks::Outgoing::Webhooks::RowComponent, type: :component do
|
||||
it "renders events list grouped by Resource", :aggregate_failures do
|
||||
expect(rendered_component).to have_list do |list|
|
||||
expect(list).to have_list_item count: 2
|
||||
expect(list).to have_list_item "Projects (created)"
|
||||
expect(list).to have_list_item "Work package comments (comment)"
|
||||
expect(list).to have_list_item "Projects (Created)"
|
||||
expect(list).to have_list_item "Work package comments (Comment)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -112,9 +112,8 @@ RSpec.describe OpPrimer::ListComponent, type: :component do
|
||||
end
|
||||
|
||||
it "renders list items" do
|
||||
expect(rendered_component).to have_list_item count: 3
|
||||
expect(rendered_component).to have_list_item count: 2
|
||||
expect(rendered_component).to have_list_item position: 1, text: "List item 1"
|
||||
expect(rendered_component).to have_list_item position: 2, role: "presentation"
|
||||
expect(rendered_component).to have_list_item position: 3, text: "List item 2"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -144,7 +144,7 @@ RSpec.describe "work package custom fields of type hierarchy", :js do
|
||||
|
||||
# Finally, we delete the custom field ... I'm done with this ...
|
||||
custom_field_index_page.visit!
|
||||
expect(page).to have_list_item(hierarchy_name)
|
||||
expect(page).to have_row(hierarchy_name)
|
||||
within("tr", text: hierarchy_name) { accept_prompt { click_on "Delete" } }
|
||||
expect(page).to have_no_text(hierarchy_name)
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ RSpec.describe "Projects", "editing settings", :js do
|
||||
within_section "Status" do
|
||||
click_on "Edit status"
|
||||
|
||||
within :menu, "Not set" do
|
||||
within :menu, "Edit status" do
|
||||
find(:menuitem, "Not started").click
|
||||
end
|
||||
end
|
||||
@@ -179,7 +179,7 @@ RSpec.describe "Projects", "editing settings", :js do
|
||||
expect(button).to have_text "Not started"
|
||||
button.click
|
||||
|
||||
expect(find(:menu, "Not started")).to have_selector :menuitem, "Not started", aria: { current: true }
|
||||
expect(find(:menu, "Edit status")).to have_selector :menuitem, "Not started", aria: { current: true }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -187,7 +187,7 @@ RSpec.describe "Projects", "editing settings", :js do
|
||||
within_section "Status" do
|
||||
click_on "Edit status"
|
||||
|
||||
within :menu, "Not set" do
|
||||
within :menu, "Edit status" do
|
||||
find(:menuitem, "Finished").click
|
||||
end
|
||||
end
|
||||
@@ -197,7 +197,7 @@ RSpec.describe "Projects", "editing settings", :js do
|
||||
within_section "Status" do
|
||||
click_on "Edit status"
|
||||
|
||||
within :menu, "Finished" do
|
||||
within :menu, "Edit status" do
|
||||
find(:menuitem, "Not set").click
|
||||
end
|
||||
end
|
||||
@@ -209,7 +209,7 @@ RSpec.describe "Projects", "editing settings", :js do
|
||||
expect(button).to have_text "Not set"
|
||||
button.click
|
||||
|
||||
expect(find(:menu, "Not set")).to have_selector :menuitem, "Not set", aria: { current: true }
|
||||
expect(find(:menu, "Edit status")).to have_selector :menuitem, "Not set", aria: { current: true }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ RSpec.describe "Work Package table configuration modal columns spec", :js do
|
||||
expect(page).to have_selector :columnheader, text: /.+/, count: 3
|
||||
expect(page).to have_selector :columnheader, "ID"
|
||||
expect(page).to have_selector :columnheader, "Subject"
|
||||
expect(page).to have_selector :columnheader, "Project", colindex: 2
|
||||
expect(page).to have_selector :columnheader, "Project", colindex: 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,49 +28,20 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
# Workaround to support role filters in component specs. This should be fixed upstream.
|
||||
Capybara::Node::Simple.class_eval do
|
||||
def role
|
||||
self[:role]
|
||||
end
|
||||
CapybaraAccessibleSelectors.add_role_selector(:list, within: true) do
|
||||
filter_set(:capybara_accessible_selectors, %i[aria described_by])
|
||||
end
|
||||
|
||||
Capybara.add_selector(:list) do
|
||||
xpath do |*|
|
||||
XPath.descendant[[
|
||||
XPath.self(:ul),
|
||||
XPath.self(:ol)
|
||||
].reduce(:|)]
|
||||
end
|
||||
|
||||
locator_filter skip_if: nil do |node, locator, exact:, **|
|
||||
method = exact ? :eql? : :include?
|
||||
if node[:"aria-labelledby"]
|
||||
CapybaraAccessibleSelectors::Helpers.element_labelledby(node).public_send(method, locator)
|
||||
elsif node[:"aria-label"]
|
||||
node[:"aria-label"].public_send(method, locator.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
filter_set(:capybara_accessible_selectors, %i[aria role described_by])
|
||||
end
|
||||
|
||||
Capybara.add_selector(:list_item) do
|
||||
label "list item"
|
||||
|
||||
xpath do |*|
|
||||
XPath.descendant[XPath.self(:li)]
|
||||
end
|
||||
|
||||
expression_filter(:position) do |xpath, position|
|
||||
position ? "#{xpath}[#{position}]" : xpath
|
||||
CapybaraAccessibleSelectors.add_role_selector(:list_item, role: :listitem, within: true, content_fallback: true) do
|
||||
expression_filter(:position, skip_if: nil) do |xpath, position|
|
||||
xpath[position]
|
||||
end
|
||||
|
||||
describe_expression_filters do |position: nil, **|
|
||||
position ? " at position #{position}" : ""
|
||||
end
|
||||
|
||||
filter_set(:capybara_accessible_selectors, %i[aria role described_by])
|
||||
filter_set(:capybara_accessible_selectors, %i[aria described_by])
|
||||
end
|
||||
|
||||
module Capybara
|
||||
|
||||
Reference in New Issue
Block a user