Skip to content

Sketch: e2e rspec tests #549

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

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
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
45 changes: 45 additions & 0 deletions .github/workflows/e2e-rspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: e2e rspec tests

on:
pull_request:
paths: ['app/**']

jobs:
rspec:
name: E2E Rspec
runs-on: ubuntu-22.04
services:
postgres:
image: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports: ["5432:5432"]
env:
POSTGRES_DB: iv_cbv_payroll_test
POSTGRES_USER: cidbuser
POSTGRES_PASSWORD: postgres

steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/cleanup-gemfile

- id: setup
uses: ./.github/actions/setup-project
with:
rails_env: test

- name: Run e2e tests via rspec
working-directory: app
env:
RAILS_ENV: test
DATABASE_URL: ${{ steps.setup.outputs.database_url }}
RAILS_MASTER_KEY: 0f5db7adba61669d4cc45dfa6b2464d7
RUN_E2E_TESTS: 1
PINWHEEL_API_TOKEN_SANDBOX: a-valid-token-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
PINWHEEL_SANDBOX: true
SUPPORTED_PROVIDERS: pinwheel

run: bundle exec rspec ./spec/e2e
4 changes: 3 additions & 1 deletion app/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ gem "sprockets-rails"
gem "pg", "~> 1.1"

# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 6.4.3"
gem "puma", "~> 6.5.0"

# Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]
gem "jsbundling-rails"
Expand Down Expand Up @@ -91,6 +91,7 @@ group :development, :test do
gem "rubocop-rails-omakase"
gem "selenium-webdriver"
gem "timecop"
gem "vcr"
end

group :development do
Expand All @@ -112,6 +113,7 @@ group :test do
gem "webmock"
gem "factory_bot", "~> 6.4"
gem "rails-controller-testing"
gem "puffing-billy"
end

group :production do
Expand Down
32 changes: 30 additions & 2 deletions app/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ GEM
climate_control (1.2.0)
concurrent-ruby (1.1.10)
connection_pool (2.5.0)
cookiejar (0.3.4)
crack (1.0.0)
bigdecimal
rexml
Expand Down Expand Up @@ -180,6 +181,17 @@ GEM
dotenv (= 2.8.1)
railties (>= 3.2)
drb (2.2.1)
em-http-request (1.1.7)
addressable (>= 2.3.4)
cookiejar (!= 0.3.1)
em-socksify (>= 0.3)
eventmachine (>= 1.0.3)
http_parser.rb (>= 0.6.0)
em-socksify (0.3.3)
base64
eventmachine (>= 1.0.0.beta.4)
em-synchrony (1.0.6)
eventmachine (>= 1.0.0.beta.1)
erb_lint (0.9.0)
activesupport
better_html (>= 2.0.1)
Expand All @@ -188,6 +200,8 @@ GEM
rubocop (>= 1)
smart_properties
erubi (1.13.1)
eventmachine (1.2.7)
eventmachine_httpserver (0.2.1)
factory_bot (6.4.6)
activesupport (>= 5.0.0)
faraday (2.9.2)
Expand All @@ -204,6 +218,7 @@ GEM
highline (3.1.0)
reline
htmlentities (4.3.4)
http_parser.rb (0.6.0)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.14)
Expand Down Expand Up @@ -251,6 +266,7 @@ GEM
minitest (5.25.5)
mixpanel-ruby (2.3.0)
msgpack (1.7.2)
multi_json (1.15.0)
multi_xml (0.7.1)
bigdecimal (~> 3.1)
mutex_m (0.3.0)
Expand Down Expand Up @@ -321,7 +337,15 @@ GEM
date
stringio
public_suffix (6.0.1)
puma (6.4.3)
puffing-billy (4.0.0)
addressable (~> 2.5)
em-http-request (~> 1.1, >= 1.1.0)
em-synchrony
eventmachine (~> 1.2)
eventmachine_httpserver
http_parser.rb (~> 0.6.0)
multi_json
puma (6.5.0)
nio4r (~> 2.0)
racc (1.8.1)
rack (2.2.13)
Expand Down Expand Up @@ -483,6 +507,8 @@ GEM
concurrent-ruby (~> 1.0)
unicode-display_width (2.6.0)
uri (1.0.3)
vcr (6.3.1)
base64
version_gem (1.1.4)
view_component (3.13.0)
activesupport (>= 5.2.0, < 8.0)
Expand Down Expand Up @@ -555,7 +581,8 @@ DEPENDENCIES
pg (~> 1.1)
pg-aws_rds_iam (~> 0.5.0)
premailer-rails
puma (~> 6.4.3)
puffing-billy
puma (~> 6.5.0)
rack-mini-profiler
rails (~> 7.1.5, >= 7.1.5.1)
rails-controller-testing
Expand All @@ -574,6 +601,7 @@ DEPENDENCIES
timecop
turbo-rails
tzinfo-data
vcr
view_component
web-console
webmock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@

context "when the user is not authorized" do
it "redirects to root url with an alert" do
ma_config = ClientAgencyConfig::ClientAgency.new({ "authorized_emails" => nil, "pinwheel" => { "environment" => "sandbox" },
"id" => "ma", "agency_name" => "Department of Transitional Assistance",
"argyle" => { "environment" => "sandbox" } })
allow(Rails.application.config.client_agencies).to receive(:[]).with("ma").and_return(ma_config)
post :ma_dta
expect(response).to redirect_to(root_url)
expect(flash[:alert]).to be_present
Expand Down
153 changes: 70 additions & 83 deletions app/spec/e2e/cbv_flow_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
require "rails_helper"

RSpec.describe "e2e CBV flow test", type: :feature, js: true do
# flip this to "all" if you need to record a new interaction
# to run these tests with record: :all, make sure you have a .env.test.local with PINWHEEL_API_TOKEN_SANDBOX, then you can run this test via running
# to run these tests at all,
# explicitly via rubymine, or RUN_E2E_TESTS=1 bundle exec rspec spec/e2e/cbb_flow_spec.rb
RECORD_OPTION = :none

RSpec.describe "e2e CBV flow test", type: :feature, js: true, vcr: { record: RECORD_OPTION, name: "e2e_cbv_flow_english" } do
include E2eTestHelpers
include_context "with_ngrok_tunnel"

let(:cbv_flow_invitation) { create(:cbv_flow_invitation) }

before(:all, js: true) do
unless ENV.fetch("PINWHEEL_API_TOKEN_SANDBOX", "").length == 64
raise "You need to set a PINWHEEL_API_TOKEN_SANDBOX in .env.test.local in order for this test to succeed"
Expand All @@ -17,96 +22,78 @@
# TODO: Remove this when we stub out Pinwheel usage:
# (We will have to allow access to the capybara server URL.)
WebMock.allow_net_connect!

# Register Ngrok with Pinwheel
capybara_server_url = URI(page.server_url)
@ngrok.start_tunnel(capybara_server_url.port)
puts "Found ngrok tunnel at #{@ngrok.tunnel_url}!"
@subscription_id = PinwheelWebhookManager.new.create_subscription_if_necessary(
@ngrok.tunnel_url,
ENV["USER"]
)
VCR.use_cassette("e2e_cbv_flow_english", record: RECORD_OPTION) do
capybara_server_url = URI(page.server_url)
@ngrok.start_tunnel(capybara_server_url.port)
puts "Found ngrok tunnel at #{@ngrok.tunnel_url}!"
@subscription_id = PinwheelWebhookManager.new.create_subscription_if_necessary(
@ngrok.tunnel_url,
ENV["USER"]
)
end if RECORD_OPTION == :all
end

after(:all, js: true) do
if @subscription_id
puts "[PINWHEEL] Deleting webhook subscription id: #{@subscription_id}"
Aggregators::Sdk::PinwheelService.new("sandbox").delete_webhook_subscription(@subscription_id)
end

# TODO: Remove these when we stub out Pinwheel usage:
page.quit
WebMock.disable_net_connect!
end

shared_examples "proceeding through the flow normally" do
it "completes the flow" do
# /cbv/entry
visit URI(cbv_flow_invitation.to_url).request_uri
verify_page(page, title: I18n.t("cbv.entries.show.header"))
find("label", text: I18n.t("cbv.entries.show.checkbox.default", agency_full_name: I18n.t("shared.agency_full_name.sandbox"))).click
click_button I18n.t("cbv.entries.show.continue")

# /cbv/employer_search
verify_page(page, title: I18n.t("cbv.employer_searches.show.header"))
fill_in name: "query", with: "foo"
click_button I18n.t("cbv.employer_searches.show.search")
expect(page).to have_content("McKee Foods")
find("div.usa-card__container", text: "McKee Foods").click_button(I18n.t("cbv.employer_searches.show.select"))

# Pinwheel modal
pinwheel_modal = page.find("iframe.pinwheel-modal-show")
page.within_frame(pinwheel_modal) do
if I18n.locale == :en
fill_in "Username", with: "user_good", wait: 10
fill_in "Workday Password", with: "pass_good"
click_button "Continue"
elsif I18n.locale == :es
fill_in "Nombre de usuario", with: "user_good", wait: 10
fill_in "Contraseña de Workday", with: "pass_good"
click_button "Continuar"
else
raise "Unknown locale: #{I18n.locale}"
end
if @subscription_id && RECORD_OPTION == :all
VCR.use_cassette("e2e_cbv_flow_english", record: :all) do
puts "[PINWHEEL] Deleting webhook subscription id: #{@subscription_id}"
Aggregators::Sdk::PinwheelService.new("sandbox").delete_webhook_subscription(@subscription_id)
end

# /cbv/synchronizations
verify_page(page, title: I18n.t("cbv.synchronizations.show.header"), wait: 15)

# All the pinwheel webhooks occur here!

# /cbv/payment_details
verify_page(page, title: I18n.t("cbv.payment_details.show.header", employer_name: "Acme Corporation"), wait: 60)
fill_in "cbv_flow[additional_information]", with: "Some kind of additional information"
click_button I18n.t("cbv.payment_details.show.continue")

# /cbv/add_job
verify_page(page, title: I18n.t("cbv.add_jobs.show.header"))
find("label", text: I18n.t("cbv.add_jobs.show.no_radio")).click
click_button I18n.t("cbv.add_jobs.show.continue")

# /cbv/summary
verify_page(page, title: I18n.t("cbv.summaries.show.header"))
find(:css, "label[for=cbv_flow_consent_to_authorized_use]").click
click_button I18n.t("cbv.summaries.show.send_report", agency_acronym: "CBV")

# TODO: Test PDF rendering by writing it to a file
end
end

context "in english" do
it_behaves_like "proceeding through the flow normally"
end

context "in spanish" do
before do
cbv_flow_invitation.update(language: "es")
end

around do |ex|
I18n.with_locale("es", &ex)
it "completes the flow" do
# /cbv/entry
mock_cbv_flow_responses

visit URI(root_url).request_uri
visit URI(cbv_flow_invitation.to_url).request_uri
verify_page(page, title: I18n.t("cbv.entries.show.header"))
find("label", text: I18n.t("cbv.entries.show.checkbox.default", agency_full_name: I18n.t("shared.agency_full_name.sandbox"))).click
click_button I18n.t("cbv.entries.show.continue")

# /cbv/employer_search
verify_page(page, title: I18n.t("cbv.employer_searches.show.header"), wait: 10)
fill_in name: "query", with: "foo"
click_button I18n.t("cbv.employer_searches.show.search")
expect(page).to have_content("McKee Foods")
find("div.usa-card__container", text: "McKee Foods").click_button(I18n.t("cbv.employer_searches.show.select"))


# Pinwheel modal
pinwheel_modal = page.find("iframe.pinwheel-modal-show")
page.within_frame(pinwheel_modal) do
fill_in "Workday Organization ID", with: "company_good", wait: 10
click_button "Continue"
fill_in "Username", with: "user_good", wait: 10
fill_in "Password", with: "pass_good", wait: 10
simulate_next_step_and_webhooks
click_button "Continue"
end

it_behaves_like "proceeding through the flow normally"
# /cbv/synchronizations
verify_page(page, title: I18n.t("cbv.synchronizations.show.header"), wait: 15)

# All the pinwheel webhooks occur here!
# TODO bring back the rest of this flow via sliding more webhooks in

# /cbv/payment_details
# verify_page(page, title: I18n.t("cbv.payment_details.show.header", employer_name: "Acme Corporation"), wait: 60)
# fill_in "cbv_flow[additional_information]", with: "Some kind of additional information"
# click_button I18n.t("cbv.payment_details.show.continue")

# /cbv/add_job
# verify_page(page, title: I18n.t("cbv.add_jobs.show.header"))
# find("label", text: I18n.t("cbv.add_jobs.show.no_radio")).click
# click_button I18n.t("cbv.add_jobs.show.continue")
#
# # /cbv/summary
# verify_page(page, title: I18n.t("cbv.summaries.show.header"))
# click_on "Continue"
# find(:css, "label[for=cbv_flow_consent_to_authorized_use]").click
# click_on "Share my report with CBV"

# TODO: Test PDF rendering by writing it to a file
end
end
41 changes: 41 additions & 0 deletions app/spec/e2e/client_signup_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'rails_helper'

RSpec.describe 'Client Steps through signing up', type: :system do
before do
driven_by(:selenium_chrome_headless) # Change to :selenium_chrome if you want to see the browser
WebMock.disable_net_connect!(allow_localhost: true)
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:sandbox] = OmniAuth::AuthHash.new(
provider: 'google_oauth2',
uid: '123456',
info: {
email: '[email protected]',
name: 'Test User',
nickname: 'the mockiest perrson'
},
credentials: {
token: 'mock_token',
refresh_token: 'mock_refresh_token',
expires_at: Time.now + 1.hour
}
)
end


it 'tries to sign up a new client through the flow' do
visit "sandbox/sso"
click_on "Continue to CBV Test Agency log in page"
click_on "Create a new invitation"
fill_in "cbv_flow_invitation[cbv_applicant_attributes][first_name]", with: "Dean"
fill_in "Client's middle name", with: "Alan"
fill_in "cbv_flow_invitation[cbv_applicant_attributes][last_name]", with: "Venture"
fill_in "Case Number", with: "Some kinda case"
fill_in "Your WELID", with: "12345"
fill_in "Client's email address", with: "[email protected]"
click_on "Send Invitation"
expect(page).to have_content "In what language should we send the invitation?"
find(".usa-radio-group .usa-radio__label[for='language-en-0']").click
click_on "Send Invitation"
expect(page).to have_content "Successfully delivered invitation to [email protected]"
end
end
Loading