mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Merge pull request #21480 from opf/dependabot/bundler/dev/capybara_accessible_selectors-v0.16.0
Bump capybara_accessible_selectors from v0.15.0 to v0.16.0
This commit is contained in:
@@ -295,7 +295,7 @@ group :test do
|
||||
gem "rails-controller-testing", "~> 1.0.2"
|
||||
|
||||
gem "capybara", "~> 3.40.0"
|
||||
gem "capybara_accessible_selectors", git: "https://github.com/citizensadvice/capybara_accessible_selectors", tag: "v0.15.0"
|
||||
gem "capybara_accessible_selectors", git: "https://github.com/citizensadvice/capybara_accessible_selectors", tag: "v0.16.0"
|
||||
gem "capybara-screenshot", "~> 1.0.17"
|
||||
gem "cuprite", "~> 0.17.0"
|
||||
gem "rspec-wait"
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
GIT
|
||||
remote: https://github.com/citizensadvice/capybara_accessible_selectors
|
||||
revision: 5b9ce7840d04270e99f4f0cb03989e05437326a6
|
||||
tag: v0.15.0
|
||||
revision: 568699fc71b6648e7186a4ac77bba072447c131e
|
||||
tag: v0.16.0
|
||||
specs:
|
||||
capybara_accessible_selectors (0.15.0)
|
||||
capybara (~> 3.36)
|
||||
|
||||
@@ -42,7 +42,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<% if sortable_column?(name) %>
|
||||
<%= helpers.sort_header_tag(name, **options) %>
|
||||
<% else %>
|
||||
<th>
|
||||
<th aria-label="<%= options[:caption] %>">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span>
|
||||
|
||||
@@ -338,7 +338,7 @@ module SortHelper
|
||||
|
||||
# Extracts the given `options` and provides them to a block.
|
||||
# See #sort_header_tag and #sort_header_with_action_menu for usage examples.
|
||||
def with_sort_header_options(column, allowed_params: nil, with_title: false, **options)
|
||||
def with_sort_header_options(column, allowed_params: nil, with_title: false, **options) # rubocop:disable Metrics/AbcSize
|
||||
caption = get_caption(column, options)
|
||||
|
||||
default_order = options.delete(:default_order) || "asc"
|
||||
@@ -349,6 +349,12 @@ module SortHelper
|
||||
options[:title] = sort_header_title(column, caption, options) if with_title
|
||||
options[:icon_only_header] = column == :favorited
|
||||
|
||||
# Give the header cell an explicit accessible name equal to the plain caption.
|
||||
# Without it, the column header's accessible name is derived from its contents,
|
||||
# which can include the action menu trigger text and is uppercased by the
|
||||
# `text-transform` styling, neither of which should be part of the name.
|
||||
options[:"aria-label"] = caption if caption.present?
|
||||
|
||||
within_sort_header_tag_hierarchy(options, sort_class(column)) do
|
||||
yield(column, caption, default_order, allowed_params:, param:, lang:, title: options[:title],
|
||||
sortable: options.fetch(:sortable, false), data:)
|
||||
|
||||
@@ -45,7 +45,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<tr>
|
||||
<th><div class="generic-table--empty-header"></div></th>
|
||||
<% @roles.each do |role| %>
|
||||
<th>
|
||||
<th aria-label="<%= role.name %>">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<%= content_tag(role.builtin? ? "em" : "span", h(role.name)) %>
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
}
|
||||
@for (column of columns; track column.href) {
|
||||
<th
|
||||
[attr.aria-label]="column.name"
|
||||
[ngClass]="{'-max': column.id === 'subject', '-min-200': ['estimatedTime', 'remainingTime'].includes(column.id) }"
|
||||
class="wp-table--table-header">
|
||||
<sortHeader [headerColumn]="column"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -145,7 +145,7 @@ RSpec.describe SortHelper do
|
||||
|
||||
it "renders a th with a sort link" do
|
||||
expect(output).to be_html_eql(<<-HTML)
|
||||
<th title="Sort by "Id"">
|
||||
<th title="Sort by "Id"" aria-label="Id">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span>
|
||||
@@ -165,7 +165,7 @@ RSpec.describe SortHelper do
|
||||
|
||||
it "adds the sort class" do
|
||||
expect(output).to be_html_eql(<<-HTML)
|
||||
<th title="Ascending sorted by "Id"">
|
||||
<th title="Ascending sorted by "Id"" aria-label="Id">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span class="sort asc">
|
||||
@@ -187,7 +187,7 @@ RSpec.describe SortHelper do
|
||||
|
||||
it "adds the sort class" do
|
||||
expect(output).to be_html_eql(<<-HTML)
|
||||
<th title="Descending sorted by "Id"">
|
||||
<th title="Descending sorted by "Id"" aria-label="Id">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span class="sort desc">
|
||||
@@ -219,7 +219,7 @@ RSpec.describe SortHelper do
|
||||
context "when not given allowed parameters" do
|
||||
it "copies default ones to the link" do
|
||||
expect(output).to be_html_eql(<<-HTML)
|
||||
<th title="Sort by "Id"">
|
||||
<th title="Sort by "Id"" aria-label="Id">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span>
|
||||
@@ -240,7 +240,7 @@ RSpec.describe SortHelper do
|
||||
|
||||
it "copies them to the link" do
|
||||
expect(output).to be_html_eql(<<-HTML)
|
||||
<th title="Sort by "Id"">
|
||||
<th title="Sort by "Id"" aria-label="Id">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span>
|
||||
@@ -262,7 +262,7 @@ RSpec.describe SortHelper do
|
||||
|
||||
it "includes the passed data param in the link" do
|
||||
expect(output).to be_html_eql(<<~HTML)
|
||||
<th title="Sort by "Id"">
|
||||
<th title="Sort by "Id"" aria-label="Id">
|
||||
<div class="generic-table--sort-header-outer">
|
||||
<div class="generic-table--sort-header">
|
||||
<span>
|
||||
|
||||
@@ -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