Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[114] Add CI for A11y (axe-core-rspec) #141

Merged
merged 5 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ version: 2.1
orbs:
cloudfoundry: circleci/cloudfoundry@1.0
ruby: circleci/ruby@2.1.3
browser-tools: circleci/browser-tools@1.4.8
node: circleci/node@5.2.0
docker: circleci/docker@2.6.0

Expand Down Expand Up @@ -37,6 +38,17 @@ commands:
- run: yarn build
- run: yarn build:css

install_chrome:
description: 'Install latest Chrome and ChromeDriver'
steps:
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- run:
command: |
google-chrome --version
chromedriver --version
name: Check install

jobs:
checkout_code:
executor:
Expand Down Expand Up @@ -73,6 +85,8 @@ jobs:

- build_assets

- install_chrome

- run:
name: Run Tests
command: |
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require:
- rubocop-rails
- rubocop-rake
- rubocop-rspec
- rubocop-capybara

AllCops:
NewCops: enable
Expand Down
11 changes: 8 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ group :development, :test do
gem "rubocop-rake", require: false
gem "rubocop-rails", ">= 2.26.0", require: false
gem "rubocop-rspec", require: false
gem "rubocop-capybara", require: false

gem "codeclimate-test-reporter"
end
Expand All @@ -87,11 +88,15 @@ group :development do
end

group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem "webmock"
gem "capybara"
gem "selenium-webdriver"
gem "rspec_junit_formatter"
gem 'simplecov', '~> 0.17.0', require: false
gem "rails-controller-testing"
end

# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
group :system_tests, :test do
gem "axe-core-rspec"
gem "capybara"
gem "selenium-webdriver"
end
26 changes: 26 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ GEM
activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
axe-core-api (4.9.1)
dumb_delegator
virtus
axe-core-rspec (4.9.1)
axe-core-api (= 4.9.1)
dumb_delegator
virtus
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
base64 (0.2.0)
bigdecimal (3.1.8)
bindex (0.8.1)
Expand All @@ -95,6 +106,8 @@ GEM
codeclimate-test-reporter (1.0.7)
simplecov
coderay (1.1.3)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
crack (1.0.0)
Expand All @@ -107,9 +120,12 @@ GEM
debug (1.9.2)
irb (~> 1.10)
reline (>= 0.3.8)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.5.1)
docile (1.4.1)
drb (2.2.1)
dumb_delegator (1.0.0)
erubi (1.13.0)
faraday (2.10.1)
faraday-net_http (>= 2.0, < 3.2)
Expand All @@ -122,6 +138,7 @@ GEM
hashdiff (1.1.1)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
io-console (0.7.2)
irb (1.14.0)
rdoc (>= 4.0.0)
Expand Down Expand Up @@ -278,6 +295,8 @@ GEM
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.32.1)
parser (>= 3.3.1.0)
rubocop-capybara (2.21.0)
rubocop (~> 1.41)
rubocop-performance (1.21.1)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
Expand Down Expand Up @@ -315,6 +334,7 @@ GEM
stringio (3.1.1)
strscan (3.1.0)
thor (1.3.2)
thread_safe (0.3.6)
timeout (0.4.1)
turbo-rails (2.0.6)
actionpack (>= 6.0.0)
Expand All @@ -325,6 +345,10 @@ GEM
unicode-display_width (2.5.0)
uri (0.13.0)
useragent (0.16.10)
virtus (2.0.0)
axiom-types (~> 0.1)
coercible (~> 1.0)
descendants_tracker (~> 0.0, >= 0.0.3)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand Down Expand Up @@ -353,6 +377,7 @@ PLATFORMS

DEPENDENCIES
annotate
axe-core-rspec
bootsnap
capybara
codeclimate-test-reporter
Expand All @@ -372,6 +397,7 @@ DEPENDENCIES
rspec-rails
rspec_junit_formatter
rubocop (>= 1.65.1)
rubocop-capybara
rubocop-performance
rubocop-rails (>= 2.26.0)
rubocop-rake
Expand Down
7 changes: 6 additions & 1 deletion app/assets/stylesheets/application.sass.scss
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
// Entry point for your Sass build
// Entry point for your Sass build

/* Backdrop is only displayed when dialog is opened with dialog.showModal() */
dialog::backdrop {
background: rgba(0, 0, 0, 0.5);
}
21 changes: 3 additions & 18 deletions app/javascript/session_timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,18 @@ document.addEventListener("DOMContentLoaded", function () {
const warningTimeoutMs =
(sessionTimeoutMinutes - warningTimeoutMinutes) * 60 * 1000;
// Debug overrides
// const sessionTimeoutMs = 10000;
// const sessionTimeoutMs = 20000;
// const warningTimeoutMs = 5000;

const renewalModal = document.getElementById("renew-modal");
const renewalModalOpenButton = document.getElementById(
"renew-modal-open-button"
);
const renewalModalCloseButton = document.getElementById(
"renew-modal-close-button"
);
const countdownDiv = document.querySelector("#renew-modal .countdown");
countdownDiv.textContent = formatMilliseconds(warningTimeoutMs);

const activityRenewalInterval = 1000;
var doRenewSession = false;
var ignoreNextActivity = false;

const showTimeoutWarning = () => {
ignoreNextActivity = true;
renewalModalOpenButton.click();
ignoreNextActivity = false;
renewalModal.showModal();
};

const updateCountdown = () => {
Expand All @@ -54,13 +45,7 @@ document.addEventListener("DOMContentLoaded", function () {

const handleUserActivity = (event) => {
// Don't count the modal showing and hiding as user activity
if (ignoreNextActivity) {
return;
}

ignoreNextActivity = true;
renewalModalCloseButton.click();
ignoreNextActivity = false;
renewalModal.close();

doRenewSession = true;
};
Expand Down
18 changes: 10 additions & 8 deletions app/views/dashboard/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<div class="usa-card__container custom-card col-md-6 rules-of-behavior">
<div class="usa-card__body">
<% if logged_in? %>
Logged In Dashboard Index
<% else %>
Logged Out Dashboard Index
<% end %>
<main role="main">
<div class="usa-card__container custom-card col-md-6 rules-of-behavior">
<h1 class="usa-card__body">
<% if logged_in? %>
Comment on lines +1 to +3
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new lines fix some existing a11y issues

Logged In Dashboard Index
<% else %>
Logged Out Dashboard Index
<% end %>
</h1>
</div>
</div>
</main>
6 changes: 3 additions & 3 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html lang="en">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a11y fix

<head>
<title>RailsNew</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
Expand All @@ -9,8 +9,6 @@
<%= stylesheet_link_tag "styles" %>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag 'application' %>
<%= javascript_include_tag 'uswds', async: true %>
<%= javascript_include_tag 'uswds-init', async: true %>

<% if logged_in? %>
<script>
Expand All @@ -34,5 +32,7 @@

<%= render "layouts/footer" %>
<%= render "modals/renew_session" %>
<%= javascript_include_tag 'uswds', async: true %>
<%= javascript_include_tag 'uswds-init', async: true %>
Comment on lines +35 to +36
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix the load order bug that caused race condition on js eval

</body>
</html>
20 changes: 8 additions & 12 deletions app/views/modals/_renew_session.html.erb
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
<a href="#renew-modal" style="display:none;" id="renew-modal-open-button" class="usa-button" aria-controls="renew-modal" data-open-modal></a>

<div
class="usa-modal"
id="renew-modal"
aria-labelledby="modal-1-heading"
aria-describedby="modal-1-description"
>
<dialog
id="renew-modal"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switching to standard <dialog> component allows us to bypass the hidden button clicks that were blocking keyboard tab navigation a11y

class="border-width-0 radius-lg"
aria-labelledby="renew-modal-heading"
aria-describedby="renew-modal-description">
<div class="usa-modal__content">
<div class="usa-modal__main">
<h2 class="usa-modal__heading" id="modal-1-heading">
<h2 class="usa-modal__heading" id="renew-modal-heading">
Session expire
</h2>
<div class="usa-prose">
<p id="modal-1-description">
<p id="renew-modal-description">
Your session will expire in <span class="countdown"></span><br>
Please click below if you would like to continue.
</p>
Expand All @@ -21,6 +18,5 @@
<button class="usa-button modal-btn" id="extend-session-button" data-close-modal type="button">Renew Session</button>
</div>
</div>
<a href="#renew-modal" style="display:none;" id="renew-modal-close-button" class="usa-button" data-close-modal></a>
</div>
</div>
</dialog>
2 changes: 2 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
require 'capybara/rspec'
require 'axe-rspec'

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
Expand Down
17 changes: 17 additions & 0 deletions spec/support/system_spec_configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :rack_test
WebMock.allow_net_connect!
end

config.before(:each, :js, type: :system) do
driven_by :selenium_chrome_headless

# Uncomment the next line to run system tests locally in a visible (non-headless) browser
# driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
end

config.after(:each, type: :system) do
WebMock.disable_net_connect!(allow_localhost: true)
end
end
17 changes: 17 additions & 0 deletions spec/system/logins_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require 'rails_helper'

describe "A11y", :js do
it "web root page is accessible" do
visit "/"

expect(page).to(be_axe_clean)
end

it "dashboard index page is accessible" do
visit dashboard_path

expect(page).to(be_axe_clean)
end
end
Loading