diff --git a/Gemfile b/Gemfile index 5af461422..585300664 100644 --- a/Gemfile +++ b/Gemfile @@ -69,6 +69,7 @@ group :development, :test do end group :test do + gem 'axe-matchers' gem 'capybara-selenium' gem 'climate_control' gem 'codeclimate-test-reporter', require: nil diff --git a/Gemfile.lock b/Gemfile.lock index 9b55ba96f..820a0ae73 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -116,6 +116,13 @@ GEM aws-sigv4 (~> 1.1) aws-sigv4 (1.1.1) aws-eventstream (~> 1.0, >= 1.0.2) + axe-matchers (2.6.0) + dumb_delegator (~> 0.8) + virtus (~> 1.0) + axiom-types (0.1.1) + descendants_tracker (~> 0.0.4) + ice_nine (~> 0.11.0) + thread_safe (~> 0.3, >= 0.3.1) bcrypt (3.1.13) better_errors (2.5.1) coderay (>= 1.0.0) @@ -166,6 +173,8 @@ GEM codeclimate-test-reporter (1.0.8) simplecov (<= 0.13) coderay (1.1.2) + coercible (1.0.0) + descendants_tracker (~> 0.0.1) colorize (0.8.1) concurrent-ruby (1.1.6) crack (0.4.3) @@ -173,6 +182,8 @@ GEM crass (1.0.6) database_cleaner (1.7.0) debug_inspector (0.0.3) + descendants_tracker (0.0.4) + thread_safe (~> 0.3, >= 0.3.1) devise (4.7.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -187,11 +198,13 @@ GEM dotenv-rails (2.7.5) dotenv (= 2.7.5) railties (>= 3.2, < 6.1) + dumb_delegator (0.8.1) easy_translate (0.5.1) thread thread_safe enum_help (0.0.17) activesupport (>= 3.0.0) + equalizer (0.0.11) erubi (1.9.0) execjs (2.7.0) factory_bot (4.11.1) @@ -227,6 +240,7 @@ GEM parser (>= 2.2.3.0) rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) + ice_nine (0.11.2) jmespath (1.4.0) jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) @@ -465,6 +479,11 @@ GEM useragent (0.16.10) uuid (2.3.8) macaddr (~> 1.0) + virtus (1.0.5) + axiom-types (~> 0.1) + coercible (~> 1.0) + descendants_tracker (~> 0.0, >= 0.0.3) + equalizer (~> 0.0, >= 0.0.9) warden (1.2.8) rack (>= 2.0.6) web-console (3.7.0) @@ -499,6 +518,7 @@ DEPENDENCIES acts_as_paranoid autoprefixer-rails (~> 9.6) aws-sdk-s3 + axe-matchers better_errors binding_of_caller bullet diff --git a/app/assets/stylesheets/application.css.scss.erb b/app/assets/stylesheets/application.css.scss.erb index e57cec4cd..8df3eb80d 100644 --- a/app/assets/stylesheets/application.css.scss.erb +++ b/app/assets/stylesheets/application.css.scss.erb @@ -28,10 +28,20 @@ $image-path: 'img'; padding: 9px 20px; } +.lg-card { + h2 { + margin-top: 0; + } +} + .usa-label { color: map-get($site-palette, 'site-dark-grey'); } +.usa-alertx { + margin-bottom: 1em; +} + .usa-navbar .usa-logo { a { display: flex; diff --git a/app/helpers/service_provider_helper.rb b/app/helpers/service_provider_helper.rb index 670cc0176..fd4747f94 100644 --- a/app/helpers/service_provider_helper.rb +++ b/app/helpers/service_provider_helper.rb @@ -78,6 +78,11 @@ def yamlized_sp(service_provider) yamlable_json.to_yaml.delete('\"') end + def sp_active_img_alt(service_provider_is_active) + return 'Active service provider' if service_provider_is_active + 'Inactive service provider' + end + private def config_hash(service_provider) diff --git a/app/views/emails/index.html.erb b/app/views/emails/index.html.erb index 4228ecd55..0c7b40e13 100644 --- a/app/views/emails/index.html.erb +++ b/app/views/emails/index.html.erb @@ -1,4 +1,4 @@ -
Emails
+

Emails

diff --git a/app/views/env/index.html.erb b/app/views/env/index.html.erb index cb313683d..d7fe44322 100644 --- a/app/views/env/index.html.erb +++ b/app/views/env/index.html.erb @@ -1,4 +1,4 @@ -
Environments status
+

Environments status

<% @deploy_statuses.each do |environment| %>

diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index 4928da8d3..5c3a2add5 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -1,8 +1,8 @@ -
<% unless user_signed_in? %> -

+

<%= t 'home.body_intro' %> -

+

+

<%= t 'home.body_dev_docs_html', href_dev_docs: link_to(t('home.dev_docs_link'), 'https://developers.login.gov') %> @@ -11,5 +11,5 @@ <%= t 'home.body_partners_html', href_partners: link_to(t('home.partners_link'), 'https://login.gov/partners') %>

-<% end %>
+<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index c521e896a..77c77ddf5 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -36,9 +36,9 @@ Skip to main content -
+
-
+
<%= image_tag 'img/us_flag_small.png', class: 'usa-banner__header-flag', alt: 'U.S. flag' %> @@ -52,7 +52,7 @@ Here’s how you know
-
+
-
+ -
- +
diff --git a/app/views/service_providers/all.html.erb b/app/views/service_providers/all.html.erb index e11abcdc1..c08844843 100644 --- a/app/views/service_providers/all.html.erb +++ b/app/views/service_providers/all.html.erb @@ -1,9 +1,8 @@ -
Apps
+

Apps

<%= button_to t('forms.buttons.trigger_idp_refresh'), api_service_providers_path, method: :post, :class => "usa-button" %> -
diff --git a/app/views/service_providers/edit.html.erb b/app/views/service_providers/edit.html.erb index 019093924..40e9effba 100644 --- a/app/views/service_providers/edit.html.erb +++ b/app/views/service_providers/edit.html.erb @@ -1,5 +1,5 @@ -
Editing "<%= service_provider.friendly_name %>"
+

Editing "<%= service_provider.friendly_name %>"

<%= simple_form_for(service_provider, html: { autocomplete: 'off', role: 'form', class: 'service-provider-form usa-form usa-form--large' }) do |form| %> <% selected_team = @service_provider.group_id %> diff --git a/app/views/service_providers/index.html.erb b/app/views/service_providers/index.html.erb index 919a8778e..86c77d1aa 100644 --- a/app/views/service_providers/index.html.erb +++ b/app/views/service_providers/index.html.erb @@ -1,4 +1,4 @@ -
My apps
+

My apps

<%= button_to t('headings.service_providers.new_app'), new_service_provider_path, method: :get, :class => "usa-button" %> diff --git a/app/views/service_providers/new.html.erb b/app/views/service_providers/new.html.erb index 236a8fd05..886684a09 100644 --- a/app/views/service_providers/new.html.erb +++ b/app/views/service_providers/new.html.erb @@ -1,7 +1,5 @@ -
New test app
- - +

New test app

<%= simple_form_for(@service_provider, html: { autocomplete: 'off', role: 'form', class: 'service-provider-form usa-form usa-form--large' }) do |form| %> <%= render 'form', form: form %> diff --git a/app/views/service_providers/show.html.erb b/app/views/service_providers/show.html.erb index 7d67b2460..04973bf1b 100644 --- a/app/views/service_providers/show.html.erb +++ b/app/views/service_providers/show.html.erb @@ -1,37 +1,37 @@ <%= link_to 'Back to apps', '/service_providers', :class => 'usa-link' %> -
Details for "<%= service_provider.friendly_name %>"
+

Details for "<%= service_provider.friendly_name %>"

-

+

<%= service_provider.friendly_name %>

-

+

<%= service_provider.description %>

-

+

<%= service_provider&.agency&.name %>

-

+

<%= service_provider.team %>

-

+

<%= service_provider.identity_protocol %>

-

+

<%= service_provider.ial_friendly %>

-

+

<%= service_provider.issuer %>

<% if current_user.admin? %> -

+

<%= service_provider.production_issuer %>

<% end %> <%# Temp hack to allow feature in dev but not int for testing %> <% if Figaro.env.logo_upload_enabled == 'true' %> -

+

<% if service_provider.logo_file.attached? %>

<%= image_tag url_for(service_provider.logo_file), height: "120px" %> @@ -42,61 +42,66 @@

<% end %> <% else %> -

+

+ <% if service_provider.logo %>

<%= service_provider.logo %>

+ <% end %> <% end %> <% if service_provider.identity_protocol == 'saml' %> -

+

<%= service_provider.acs_url %>

-

+

<%= service_provider.assertion_consumer_logout_service_url %>

-

+

<%= service_provider.sp_initiated_login_url %>

-

+

<%= service_provider.block_encryption %>

<% end %> -

+

<%= service_provider.saml_client_cert %>
<% unless service_provider.saml_client_cert.blank? %>

Expires: <%= render partial: 'certificate_expiration', locals: { app: service_provider } %>

<% end %> -

+

<%= service_provider.return_to_sp_url %>

-

+

<%= service_provider.failure_to_proof_url %>

-

+

<%= service_provider.push_notification_url %>

<% if service_provider.identity_protocol == 'openid_connect' %> -

+

<% end %> <% if service_provider.identity_protocol == 'saml' %> -

+

<% end %>

<%= (service_provider.redirect_uris || []).sort.join('
').html_safe %>

-

+

<%= (service_provider.attribute_bundle || []).sort.join(', ') %>

-

-

<%= image_tag service_provider.active? ? 'img/alerts/success.svg' : 'img/alerts/error.svg', height: '27', width: '27', :class =>'margin-bottom-neg-105' %>

+

+

<%= image_tag service_provider.active? ? 'img/alerts/success.svg' : 'img/alerts/error.svg', + height: '27', width: '27', + :class => 'margin-bottom-neg-105', + :alt => sp_active_img_alt(service_provider.active?) %>

<% if current_user.admin? %> -

+

<%= render 'service_provider_yaml' %>

<%end %> diff --git a/app/views/teams/_no_teams.html.erb b/app/views/teams/_no_teams.html.erb index f05e9ac85..73839c2de 100644 --- a/app/views/teams/_no_teams.html.erb +++ b/app/views/teams/_no_teams.html.erb @@ -2,7 +2,7 @@
-

Create your first team

+

Create your first team

Get started with the sandbox environment. Make a team for your integration project.

diff --git a/app/views/teams/_teams_list.html.erb b/app/views/teams/_teams_list.html.erb index b4cadace7..5df6253e7 100644 --- a/app/views/teams/_teams_list.html.erb +++ b/app/views/teams/_teams_list.html.erb @@ -2,9 +2,9 @@
-

+

<%= link_to team.name, team_path(team), class: 'text-primary text-no-underline' %> -

+

Agency: <%= team&.agency&.name %>

diff --git a/app/views/teams/all.html.erb b/app/views/teams/all.html.erb index e1fbfd417..e62d880c2 100644 --- a/app/views/teams/all.html.erb +++ b/app/views/teams/all.html.erb @@ -1,4 +1,4 @@ -
All teams
+

All teams

<% if @teams.count > 0 %> @@ -15,7 +15,7 @@
-

Create your first team

+

Create your first team

Get started with the sandbox environment. Make a team for your integration project.

diff --git a/app/views/teams/edit.html.erb b/app/views/teams/edit.html.erb index 3fac7c71c..49c521bd3 100644 --- a/app/views/teams/edit.html.erb +++ b/app/views/teams/edit.html.erb @@ -1,4 +1,4 @@ -
Edit team
+

Edit team

<%= simple_form_for(@team, html: { autocomplete: 'off', role: 'form', class: 'usa-form usa-form--large' }) do |form| %> @@ -6,7 +6,7 @@ <%= render 'form', form: form, agency_required: false, extra_message: t('headings.teams.temporary_warning_team_user') %>
-

+

    <% @team.users.each do |u| %>
  • <%= u.email %>
  • diff --git a/app/views/teams/index.html.erb b/app/views/teams/index.html.erb index b3a11a18f..1f778d4a3 100644 --- a/app/views/teams/index.html.erb +++ b/app/views/teams/index.html.erb @@ -1,4 +1,4 @@ -
    My teams
    +

    My teams

    <% if @teams.count > 0 %> diff --git a/app/views/teams/new.html.erb b/app/views/teams/new.html.erb index 96e1e6133..3a7a115a1 100644 --- a/app/views/teams/new.html.erb +++ b/app/views/teams/new.html.erb @@ -1,4 +1,4 @@ -
    New team
    +

    New team

    <%= simple_form_for(@team, html: { autocomplete: 'off', role: 'form', class: 'usa-form usa-form--large' }, diff --git a/app/views/teams/show.html.erb b/app/views/teams/show.html.erb index 569be9b8f..5806b6fce 100644 --- a/app/views/teams/show.html.erb +++ b/app/views/teams/show.html.erb @@ -3,15 +3,15 @@
  • <%= link_to "Back to Teams", teams_path, :class => 'usa-link' %>
-
Team details for "<%= @team.name %>"
+

Team details for "<%= @team.name %>"

-

+

<%= @team&.agency&.name %>

-

+

<%= @team.description %>

-

+

    <% @team.users.each do |u| %>
  • <%= u.email %>
  • @@ -23,7 +23,7 @@ class: 'margin-y-1 display-block', ) %> -

    +

      <% @team.service_providers.each do |a| %>
    • <%= link_to a.friendly_name, service_provider_path(a) %>
    • diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 4230ca830..ff7d8493e 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -1,5 +1,5 @@ -
      Edit user "<%= @user.email %>"
      +

      Edit user "<%= @user.email %>"

      <%= simple_form_for(@user, html: { autocomplete: 'off', role: 'form' }) do |form| %> <%= form.error_notification %> diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index ad76fa175..ebe37b994 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -1,5 +1,5 @@ -
      Users
      +

      Users

      <%= button_to t('headings.users.new_user'), new_user_path, diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 481a78ec7..ed6d39f1f 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,4 +1,4 @@ -
      New user
      +

      New user

      <%= simple_form_for(@user, html: { autocomplete: 'off', role: 'form' }, diff --git a/app/views/users/none.html.erb b/app/views/users/none.html.erb index e5c7549aa..d929b53e0 100644 --- a/app/views/users/none.html.erb +++ b/app/views/users/none.html.erb @@ -1,4 +1,4 @@ -
      No account exists
      +

      No account exists

      We were unable to find an account matching your email address in the <%= Rails.application.config.app_name %>.

      diff --git a/spec/features/accessibility/emails_spec.rb b/spec/features/accessibility/emails_spec.rb new file mode 100644 index 000000000..3ff02f6f5 --- /dev/null +++ b/spec/features/accessibility/emails_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +feature 'Email pages', :js do + let(:admin) { create(:admin) } + + before do + login_as(admin) + end + + scenario 'index page is accessible' do + visit emails_path + expect(page).to be_accessible + end +end diff --git a/spec/features/accessibility/env_spec.rb b/spec/features/accessibility/env_spec.rb new file mode 100644 index 000000000..44e21295d --- /dev/null +++ b/spec/features/accessibility/env_spec.rb @@ -0,0 +1,17 @@ +require 'rails_helper' + +feature 'Environments page', :js do + include DeployStatusCheckerHelper + + before do + stub_deploy_status + end + + scenario 'is accessible' do + user = create(:user) + + login_as(user) + visit env_path + expect(page).to be_accessible + end +end diff --git a/spec/features/accessibility/home_spec.rb b/spec/features/accessibility/home_spec.rb new file mode 100644 index 000000000..42c675c8c --- /dev/null +++ b/spec/features/accessibility/home_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +feature 'Home page', :js do + scenario 'is accessible' do + user = create(:user) + + login_as(user) + visit root_path + + expect(page).to be_accessible + end +end diff --git a/spec/features/accessibility/service_providers_spec.rb b/spec/features/accessibility/service_providers_spec.rb new file mode 100644 index 000000000..b6972779e --- /dev/null +++ b/spec/features/accessibility/service_providers_spec.rb @@ -0,0 +1,52 @@ +require 'rails_helper' + +feature 'Service provider pages', :js do + before do + allow(Figaro.env).to receive(:logo_upload_enabled).and_return('false') + ENV['logo_upload_enabled'] = 'false' + end + + context 'for admins' do + scenario 'all service providers page is accessible' do + admin = create(:admin) + login_as(admin) + + visit service_providers_all_path + expect(page).to be_accessible + end + end + + context 'for users' do + let(:user) { create(:user, :with_teams) } + + before do + login_as(user) + end + + scenario 'index page is accessible' do + visit service_providers_path + expect(page).to be_accessible + end + + scenario 'new service provider page is accessible' do + visit new_service_provider_path + expect(page).to be_accessible + end + + scenario 'service provider details page is accessible' do + app = create(:service_provider, :with_users_team, user: user, logo: 'generic.svg') + login_as(user) + + visit service_provider_path(app) + expect(page).to be_accessible + end + + scenario 'service provider details edit page is accessible' do + app = create(:service_provider, :with_users_team, user: user) + login_as(user) + + visit edit_service_provider_path(app) + expect(page).to be_accessible + end + end +end diff --git a/spec/features/accessibility/teams_spec.rb b/spec/features/accessibility/teams_spec.rb new file mode 100644 index 000000000..551027e53 --- /dev/null +++ b/spec/features/accessibility/teams_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +feature 'Team pages', :js do + let(:admin) { create(:admin) } + + before do + login_as(admin) + end + + scenario 'index page is accessible' do + visit teams_path + expect(page).to be_accessible + end + + scenario 'All teams page is accessible' do + visit teams_all_path + expect(page).to be_accessible + end + + scenario 'New team page is accessible' do + visit new_team_path + expect(page).to be_accessible + end + + scenario 'Edit team page is accessible' do + user = create(:user) + team = create(:team, users: [user]) + visit edit_team_path(team) + expect(page).to be_accessible + end + + scenario 'New team user page is accessible' do + create(:agency, name: 'GSA') + + visit new_team_path + + fill_in 'Description', with: 'department name' + fill_in 'Name', with: 'team name' + select('GSA', from: 'Agency') + + click_on 'Create' + expect(page).to be_accessible + end +end diff --git a/spec/features/accessibility/users_spec.rb b/spec/features/accessibility/users_spec.rb new file mode 100644 index 000000000..512621d09 --- /dev/null +++ b/spec/features/accessibility/users_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +feature 'User pages', :js do + before do + admin = create(:admin) + login_as(admin) + end + + scenario 'all users page is accessible' do + visit users_path + expect(page).to be_accessible + end + + scenario 'new user page is accessible' do + visit new_user_path + expect(page).to be_accessible + end + + scenario 'edit user page is accessible' do + user = create(:user) + visit edit_user_path(user) + expect(page).to be_accessible + end +end diff --git a/spec/helpers/service_provider_helper_spec.rb b/spec/helpers/service_provider_helper_spec.rb index 298aebb7f..c422e5f2e 100644 --- a/spec/helpers/service_provider_helper_spec.rb +++ b/spec/helpers/service_provider_helper_spec.rb @@ -91,4 +91,14 @@ end end end + + describe '#sp_active_img_alt' do + it 'returns alt tag indicatng active service provider' do + expect(sp_active_img_alt(true)).to eq('Active service provider') + end + + it 'returns alt tag indicatng inactive service provider' do + expect(sp_active_img_alt(false)).to eq('Inactive service provider') + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a11b1f115..a4b89c3b1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,6 +9,8 @@ require 'webmock/rspec' +require 'axe/rspec' + # http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| config.color = true diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 02b01014c..1fccd8feb 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -14,7 +14,7 @@ end Capybara.javascript_driver = :headless_chrome -Capybara.asset_host = 'http://localhost:3000' +Capybara.asset_host = 'http://localhost:3001' Capybara.default_max_wait_time = 5 Capybara.server = :puma, { Silent: true }