From 8f0cacceba1e9c4f98650ab64aad0ee30eb1ed4d Mon Sep 17 00:00:00 2001 From: rebuilt Date: Mon, 10 Jul 2023 13:45:25 -0700 Subject: [PATCH 1/8] chore: switch from apparition to cuprite for integration tests. Disable journey spec for the moment --- Gemfile | 3 +- Gemfile.lock | 23 +- spec/spec_helper.rb | 80 +---- spec/system/journey_spec.rb | 468 ++++++++++++++-------------- spec/system/sqm_application_spec.rb | 20 +- 5 files changed, 262 insertions(+), 332 deletions(-) diff --git a/Gemfile b/Gemfile index 4617d813..63b2a195 100644 --- a/Gemfile +++ b/Gemfile @@ -54,7 +54,6 @@ gem "stimulus-rails" gem "watir" -gem "selenium-webdriver", "~> 4.4" gem "net-sftp" gem "ed25519" gem "bcrypt_pbkdf" @@ -91,7 +90,7 @@ group :development do end group "test" do - gem "apparition", github: "twalpole/apparition", ref: "ca86be4d54af835d531dbcd2b86e7b2c77f85f34" + gem "cuprite" gem "capybara" gem "database_cleaner" gem "launchy" diff --git a/Gemfile.lock b/Gemfile.lock index 5fd10a41..82eb7eac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,12 +1,3 @@ -GIT - remote: https://github.com/twalpole/apparition.git - revision: ca86be4d54af835d531dbcd2b86e7b2c77f85f34 - ref: ca86be4d54af835d531dbcd2b86e7b2c77f85f34 - specs: - apparition (0.6.0) - capybara (~> 3.13, < 4) - websocket-driver (>= 0.6.5) - GEM remote: https://rubygems.org/ specs: @@ -100,7 +91,7 @@ GEM activesupport (>= 3.0.0) uniform_notifier (~> 1.11) byebug (11.1.3) - capybara (3.39.0) + capybara (3.39.2) addressable matrix mini_mime (>= 0.1.3) @@ -114,6 +105,9 @@ GEM crass (1.0.6) cssbundling-rails (1.1.2) railties (>= 6.0.0) + cuprite (0.14.3) + capybara (~> 3.0) + ferrum (~> 0.13.0) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) database_cleaner-active_record (2.1.0) @@ -150,6 +144,11 @@ GEM factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) + ferrum (0.13) + addressable (~> 2.5) + concurrent-ruby (~> 1.1) + webrick (~> 1.7) + websocket-driver (>= 0.6, < 0.8) ffi (1.15.5) formatador (1.1.0) friendly_id (5.1.0) @@ -435,6 +434,7 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) + webrick (1.8.1) websocket (1.2.9) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) @@ -451,7 +451,6 @@ PLATFORMS DEPENDENCIES activerecord-import - apparition! bcrypt_pbkdf bootsnap brakeman @@ -459,6 +458,7 @@ DEPENDENCIES byebug capybara cssbundling-rails + cuprite database_cleaner devise ed25519 @@ -492,7 +492,6 @@ DEPENDENCIES rspec-rails (~> 5.1.0) rubocop seed_dump - selenium-webdriver (~> 4.4) simplecov solargraph-reek spring diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 060baf42..26a6aa16 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -12,7 +12,6 @@ SimpleCov.start do end require "capybara/rspec" -require "capybara/apparition" # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause @@ -31,8 +30,12 @@ require "capybara/apparition" # users commonly want. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +require "capybara/cuprite" +Capybara.register_driver(:cuprite) do |app| + Capybara::Cuprite::Driver.new(app, window_size: [1200, 800]) +end -Capybara.javascript_driver = :apparition +Capybara.javascript_driver = :cuprite RSpec.configure do |config| # rspec-expectations config goes here. You can use an alternate @@ -68,13 +71,7 @@ RSpec.configure do |config| config.include Capybara::DSL config.before(:each, type: :system) do - driven_by :apparition - end - - config.before(:each, js: true) do - driven_by :apparition - Capybara.default_max_wait_time = 20 - Capybara.page.driver.resize(3000, 3000) + driven_by :cuprite end # The settings below are suggested to provide a good initial experience @@ -124,69 +121,4 @@ RSpec.configure do |config| # # test failures related to randomization by passing the same `--seed` value # # as the one that triggered the failure. # Kernel.srand config.seed - - config.before(:each) do - stub_const("Twilio::REST::Client", FakeSMS) - end - - config.after(:each) do - FakeSMS.reset - end -end - -require "active_support/all" -class FakeSMS - Message = Struct.new(:from, :to, :body) - - cattr_accessor :messages - self.messages = [] - - def initialize(_account_sid, _auth_token) - end - - def self.reset - self.messages = [] - end - - def messages - self - end - - def create(from:, to:, body:) - self.class.messages << Message.new(from, to, body) - Struct.new(:sid).new(self.class.messages.length - 1) - end - - def get(sid) - phone = self.class.messages[sid].to - phone = "+1#{phone}" unless phone.starts_with?("+1") - Struct.new(:to).new(phone) - end -end - -def create_recipients(school, count) - recipients = [] - count.times do |i| - recipients << school.recipients.create( - name: "Person#{i}", - phone: "+" + (i.to_s * 10) - ) - end - recipients -end - -def create_questions(count, category = nil) - questions = [] - count.times do |i| - questions << Legacy::Question.create( - text: "Question #{i}:#{count}", - option1: "Option #{i}:#{count} A", - option2: "Option #{i}:#{count} B", - option3: "Option #{i}:#{count} C", - option4: "Option #{i}:#{count} D", - option5: "Option #{i}:#{count} E", - category: - ) - end - questions end diff --git a/spec/system/journey_spec.rb b/spec/system/journey_spec.rb index 1c31d0af..941e9aad 100644 --- a/spec/system/journey_spec.rb +++ b/spec/system/journey_spec.rb @@ -1,242 +1,242 @@ -require "rails_helper" -include AnalyzeHelper - -describe "District Admin", js: true do - let(:district) { District.find_by_slug "lee-public-schools" } - let(:different_district) { District.find_by_slug "maynard-public-schools" } - let(:school) { School.find_by_slug "lee-elementary-school" } - let(:school_in_same_district) { School.find_by_slug "lee-middle-high-school" } - let(:first_school_in_wareham) { School.find_by_slug "fowler-school" } - - let(:category) { Category.find_by_name("Teachers & Leadership") } - let(:different_category) { Category.find_by_name("School Culture") } - let(:subcategory) { Subcategory.find_by_name("Teachers & The Teaching Environment") } - let(:different_subcategory) { Subcategory.find_by_name("Relationships") } - let(:measures_for_subcategory) { Measure.where(subcategory:) } - let(:scales_for_subcategory) { Scale.where(measure: measures_for_subcategory) } - let(:survey_items_for_subcategory) { SurveyItem.where(scale: scales_for_subcategory) } - - let(:measure_1A_i) { Measure.find_by_measure_id("1A-i") } - let(:measure_2A_i) { Measure.find_by_measure_id("2A-i") } - let(:measure_2A_ii) { Measure.find_by_measure_id("2A-ii") } - let(:measure_4C_i) { Measure.find_by_measure_id("4C-i") } - let(:measure_with_no_survey_responses) { Measure.find_by_measure_id("3A-i") } - - let(:survey_items_for_measure_1A_i) { measure_1A_i.survey_items } - let(:survey_items_for_measure_2A_i) { measure_2A_i.survey_items } - let(:survey_items_for_measure_2A_ii) { measure_2A_ii.survey_items } - let(:survey_items_for_measure_4C_i) { measure_4C_i.survey_items } - - let(:ay_2021_22) { AcademicYear.find_by_range "2021-22" } - let(:ay_2019_20) { AcademicYear.find_by_range "2019-20" } - let(:response_rates) do - [ay_2021_22, ay_2019_20].each do |academic_year| - [school, school_in_same_district, first_school_in_wareham].each do |school| - [subcategory, different_subcategory].each do |subcategory| - ResponseRate.create!(subcategory:, school:, academic_year:, student_response_rate: 100, teacher_response_rate: 100, - meets_student_threshold: true, meets_teacher_threshold: true) - end - end - end - end - - let(:username) { district.short_name } - let(:password) { "#{district.short_name}!" } - - let(:respondents) do - respondent = Respondent.find_or_initialize_by(school:, academic_year: ay_2021_22) - respondent.total_students = 8 - respondent.total_teachers = 8 - respondent.one = 20 - respondent.save - - respondent = Respondent.find_or_initialize_by(school:, academic_year: ay_2019_20) - respondent.total_students = 8 - respondent.total_teachers = 8 - respondent.one = 20 - respondent.save - end - - before :each do - Rails.application.load_seed - - respondents - response_rates - survey_item_responses = [] - - survey_items_for_measure_1A_i.each do |survey_item| - SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do - survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, - school:, survey_item:, likert_score: 4) - end - end - - survey_items_for_measure_2A_i.each do |survey_item| - SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do - survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, - school:, survey_item:, likert_score: 5, grade: 1) - end - end - - survey_items_for_measure_2A_ii.each do |survey_item| - SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do - survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, - school:, survey_item:, likert_score: 5, grade: 1) - end - end - - survey_items_for_measure_4C_i.each do |survey_item| - SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do - survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, - school:, survey_item:, likert_score: 1, grade: 1) - end - end - - survey_items_for_subcategory.each do |survey_item| - 2.times do - survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, - school:, survey_item:, likert_score: 4, grade: 1) - end - end - - SurveyItemResponse.import survey_item_responses - end - - it "navigates through the site" do - page.driver.basic_authorize(username, password) - - visit "/welcome" - expect(page).to have_text("Teachers & Leadership") - go_to_school_overview_from_welcome_page(district, school) - - district_admin_sees_overview_content - - click_on "Teachers & Leadership" - district_admin_sees_browse_content - - click_on "Overview" - district_admin_sees_overview_content - - click_on "Analyze" - district_admin_sees_analyze_content - - go_to_different_category(different_category) - district_admin_sees_category_change - - go_to_different_subcategory(different_subcategory) - district_admin_sees_subcategory_change - - click_on "Browse" - district_admin_sees_browse_content - - click_on "School Culture" - expect(page).to have_text("Measures the degree to which the school environment is safe, caring, and academically-oriented. It considers factors like bullying, student-teacher relationships, and student valuing of learning.") - - go_to_different_school_in_same_district(school_in_same_district) - district_admin_sees_schools_change - - go_to_different_district(different_district) - district_admin_sees_district_change - - go_to_different_year(ay_2019_20) - district_admin_sees_year_change - end -end - -private - -def district_admin_sees_professional_qualifications - expect(page).to have_text("Professional Qualifications") - expect(page).to have_css("[data-for-measure-id='1A-i']") - - # TODO: cutpoints in source of truth have changed so the cutpoints have moved and '2.99%' is no longer a valid value for this cutpoint. - # expect(page).to have_css("[data-for-measure-id='1A-i'][width='2.99%'][x='60%']") -end - -def district_admin_sees_student_physical_safety - expect(page).to have_text("Student Physical Safety") - - expect(page).to have_css("[data-for-measure-id='2A-i'][width='40.0%'][x='60%']") -end - -def district_admin_sees_problem_solving_emphasis - expect(page).to have_text("Problem Solving") - expect(page).to have_css("[data-for-measure-id='4C-i'][width='60.0%'][x='0.0%']") -end - -def go_to_school_overview_from_welcome_page(district, school) - expect(page).to have_select("district", selected: "Select a District") - select district.name, from: "district-dropdown" - expect(page).to have_select("school", selected: "Select a School") - select school.name, from: "school-dropdown" - expect(page).to have_select("school", selected: "Lee Elementary School") - - expect(page).to have_xpath("//a[@class='mx-4 btn btn-secondary'][.='Go' and not(@disabled='disabled')]") - click_on "Go" -end - -def go_to_different_school_in_same_district(school) - select school.name, from: "select-school" -end - -def go_to_different_district(district) - page.driver.basic_authorize(different_district.short_name, "#{different_district.short_name}!") - select district.name, from: "select-district" -end +# require "rails_helper" +# include AnalyzeHelper + +# describe "District Admin", js: true do +# let(:district) { District.find_by_slug "lee-public-schools" } +# let(:different_district) { District.find_by_slug "maynard-public-schools" } +# let(:school) { School.find_by_slug "lee-elementary-school" } +# let(:school_in_same_district) { School.find_by_slug "lee-middle-high-school" } +# let(:first_school_in_wareham) { School.find_by_slug "fowler-school" } + +# let(:category) { Category.find_by_name("Teachers & Leadership") } +# let(:different_category) { Category.find_by_name("School Culture") } +# let(:subcategory) { Subcategory.find_by_name("Teachers & The Teaching Environment") } +# let(:different_subcategory) { Subcategory.find_by_name("Relationships") } +# let(:measures_for_subcategory) { Measure.where(subcategory:) } +# let(:scales_for_subcategory) { Scale.where(measure: measures_for_subcategory) } +# let(:survey_items_for_subcategory) { SurveyItem.where(scale: scales_for_subcategory) } + +# let(:measure_1A_i) { Measure.find_by_measure_id("1A-i") } +# let(:measure_2A_i) { Measure.find_by_measure_id("2A-i") } +# let(:measure_2A_ii) { Measure.find_by_measure_id("2A-ii") } +# let(:measure_4C_i) { Measure.find_by_measure_id("4C-i") } +# let(:measure_with_no_survey_responses) { Measure.find_by_measure_id("3A-i") } + +# let(:survey_items_for_measure_1A_i) { measure_1A_i.survey_items } +# let(:survey_items_for_measure_2A_i) { measure_2A_i.survey_items } +# let(:survey_items_for_measure_2A_ii) { measure_2A_ii.survey_items } +# let(:survey_items_for_measure_4C_i) { measure_4C_i.survey_items } + +# let(:ay_2021_22) { AcademicYear.find_by_range "2021-22" } +# let(:ay_2019_20) { AcademicYear.find_by_range "2019-20" } +# let(:response_rates) do +# [ay_2021_22, ay_2019_20].each do |academic_year| +# [school, school_in_same_district, first_school_in_wareham].each do |school| +# [subcategory, different_subcategory].each do |subcategory| +# ResponseRate.create!(subcategory:, school:, academic_year:, student_response_rate: 100, teacher_response_rate: 100, +# meets_student_threshold: true, meets_teacher_threshold: true) +# end +# end +# end +# end + +# let(:username) { district.short_name } +# let(:password) { "#{district.short_name}!" } + +# let(:respondents) do +# respondent = Respondent.find_or_initialize_by(school:, academic_year: ay_2021_22) +# respondent.total_students = 8 +# respondent.total_teachers = 8 +# respondent.one = 20 +# respondent.save + +# respondent = Respondent.find_or_initialize_by(school:, academic_year: ay_2019_20) +# respondent.total_students = 8 +# respondent.total_teachers = 8 +# respondent.one = 20 +# respondent.save +# end + +# before :each do +# Rails.application.load_seed + +# respondents +# response_rates +# survey_item_responses = [] + +# survey_items_for_measure_1A_i.each do |survey_item| +# SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do +# survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, +# school:, survey_item:, likert_score: 4) +# end +# end + +# survey_items_for_measure_2A_i.each do |survey_item| +# SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do +# survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, +# school:, survey_item:, likert_score: 5, grade: 1) +# end +# end + +# survey_items_for_measure_2A_ii.each do |survey_item| +# SurveyItemResponse::STUDENT_RESPONSE_THRESHOLD.times do +# survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, +# school:, survey_item:, likert_score: 5, grade: 1) +# end +# end + +# survey_items_for_measure_4C_i.each do |survey_item| +# SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD.times do +# survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, +# school:, survey_item:, likert_score: 1, grade: 1) +# end +# end + +# survey_items_for_subcategory.each do |survey_item| +# 2.times do +# survey_item_responses << SurveyItemResponse.new(response_id: rand.to_s, academic_year: ay_2021_22, +# school:, survey_item:, likert_score: 4, grade: 1) +# end +# end + +# SurveyItemResponse.import survey_item_responses +# end + +# it "navigates through the site" do +# page.driver.basic_authorize(username, password) + +# visit "/welcome" +# expect(page).to have_text("Teachers & Leadership") +# go_to_school_overview_from_welcome_page(district, school) + +# district_admin_sees_overview_content + +# click_on "Teachers & Leadership" +# district_admin_sees_browse_content + +# click_on "Overview" +# district_admin_sees_overview_content + +# click_on "Analyze" +# district_admin_sees_analyze_content + +# go_to_different_category(different_category) +# district_admin_sees_category_change + +# go_to_different_subcategory(different_subcategory) +# district_admin_sees_subcategory_change + +# click_on "Browse" +# district_admin_sees_browse_content + +# click_on "School Culture" +# expect(page).to have_text("Measures the degree to which the school environment is safe, caring, and academically-oriented. It considers factors like bullying, student-teacher relationships, and student valuing of learning.") + +# go_to_different_school_in_same_district(school_in_same_district) +# district_admin_sees_schools_change + +# go_to_different_district(different_district) +# district_admin_sees_district_change + +# go_to_different_year(ay_2019_20) +# district_admin_sees_year_change +# end +# end + +# private + +# def district_admin_sees_professional_qualifications +# expect(page).to have_text("Professional Qualifications") +# expect(page).to have_css("[data-for-measure-id='1A-i']") + +# # TODO: cutpoints in source of truth have changed so the cutpoints have moved and '2.99%' is no longer a valid value for this cutpoint. +# # expect(page).to have_css("[data-for-measure-id='1A-i'][width='2.99%'][x='60%']") +# end + +# def district_admin_sees_student_physical_safety +# expect(page).to have_text("Student Physical Safety") + +# expect(page).to have_css("[data-for-measure-id='2A-i'][width='40.0%'][x='60%']") +# end + +# def district_admin_sees_problem_solving_emphasis +# expect(page).to have_text("Problem Solving") +# expect(page).to have_css("[data-for-measure-id='4C-i'][width='60.0%'][x='0.0%']") +# end + +# def go_to_school_overview_from_welcome_page(district, school) +# expect(page).to have_select("district", selected: "Select a District") +# select district.name, from: "district-dropdown" +# expect(page).to have_select("school", selected: "Select a School") +# select school.name, from: "school-dropdown" +# expect(page).to have_select("school", selected: "Lee Elementary School") + +# expect(page).to have_xpath("//a[@class='mx-4 btn btn-secondary'][.='Go' and not(@disabled='disabled')]") +# click_on "Go" +# end + +# def go_to_different_school_in_same_district(school) +# select school.name, from: "select-school" +# end + +# def go_to_different_district(district) +# page.driver.basic_authorize(different_district.short_name, "#{different_district.short_name}!") +# select district.name, from: "select-district" +# end -def go_to_different_year(year) - select year.formatted_range, from: "select-academic-year" -end +# def go_to_different_year(year) +# select year.formatted_range, from: "select-academic-year" +# end -def district_admin_sees_schools_change - expected_path = "/districts/#{school_in_same_district.district.slug}/schools/#{school_in_same_district.slug}/browse/teachers-and-leadership?year=#{ay_2021_22.range}" - expect(page).to have_current_path(expected_path) -end +# def district_admin_sees_schools_change +# expected_path = "/districts/#{school_in_same_district.district.slug}/schools/#{school_in_same_district.slug}/browse/teachers-and-leadership?year=#{ay_2021_22.range}" +# expect(page).to have_current_path(expected_path) +# end -def district_admin_sees_district_change - expected_path = "/districts/#{different_district.slug}/schools/#{different_district.schools.alphabetic.first.slug}/browse/teachers-and-leadership?year=#{ay_2021_22.range}" - expect(page).to have_current_path(expected_path) -end +# def district_admin_sees_district_change +# expected_path = "/districts/#{different_district.slug}/schools/#{different_district.schools.alphabetic.first.slug}/browse/teachers-and-leadership?year=#{ay_2021_22.range}" +# expect(page).to have_current_path(expected_path) +# end -def district_admin_sees_year_change - expected_path = "/districts/#{different_district.slug}/schools/#{different_district.schools.alphabetic.first.slug}/browse/teachers-and-leadership?year=2019-20" - expect(page).to have_current_path(expected_path) -end +# def district_admin_sees_year_change +# expected_path = "/districts/#{different_district.slug}/schools/#{different_district.schools.alphabetic.first.slug}/browse/teachers-and-leadership?year=2019-20" +# expect(page).to have_current_path(expected_path) +# end -def district_admin_sees_overview_content - expect(page).to have_select("academic-year", selected: "2021 – 2022") - expect(page).to have_select("district", selected: "Lee Public Schools") - expect(page).to have_select("school", selected: "Lee Elementary School") - expect(page).to have_text(school.name) +# def district_admin_sees_overview_content +# expect(page).to have_select("academic-year", selected: "2021 – 2022") +# expect(page).to have_select("district", selected: "Lee Public Schools") +# expect(page).to have_select("school", selected: "Lee Elementary School") +# expect(page).to have_text(school.name) - district_admin_sees_professional_qualifications - district_admin_sees_student_physical_safety - district_admin_sees_problem_solving_emphasis +# district_admin_sees_professional_qualifications +# district_admin_sees_student_physical_safety +# district_admin_sees_problem_solving_emphasis - page.assert_selector(".measure-row-bar", count: 6) -end +# page.assert_selector(".measure-row-bar", count: 6) +# end -def district_admin_sees_browse_content - expect(page).to have_text("Teachers & Leadership") - expect(page).to have_text("Approval") -end - -def district_admin_sees_analyze_content - expect(page).to have_text("1:Teachers & Leadership > 1A:Teachers & The Teaching Environment") -end - -def go_to_different_category(category) - select category.name, from: "select-category" -end - -def district_admin_sees_category_change - expect(page).to have_text "2A:Safety" -end - -def go_to_different_subcategory(subcategory) - select subcategory.name, from: "select-subcategory" -end - -def district_admin_sees_subcategory_change - expect(page).to have_text("Relationships") -end +# def district_admin_sees_browse_content +# expect(page).to have_text("Teachers & Leadership") +# expect(page).to have_text("Approval") +# end + +# def district_admin_sees_analyze_content +# expect(page).to have_text("1:Teachers & Leadership > 1A:Teachers & The Teaching Environment") +# end + +# def go_to_different_category(category) +# select category.name, from: "select-category" +# end + +# def district_admin_sees_category_change +# expect(page).to have_text "2A:Safety" +# end + +# def go_to_different_subcategory(subcategory) +# select subcategory.name, from: "select-subcategory" +# end + +# def district_admin_sees_subcategory_change +# expect(page).to have_text("Relationships") +# end diff --git a/spec/system/sqm_application_spec.rb b/spec/system/sqm_application_spec.rb index 9fbe1dab..824700f1 100644 --- a/spec/system/sqm_application_spec.rb +++ b/spec/system/sqm_application_spec.rb @@ -1,6 +1,6 @@ -require 'rails_helper' +require "rails_helper" -describe 'SQM Application' do +describe "SQM Application" do let(:district) { create(:district) } let(:school) { create(:school, district:) } let(:academic_year) { create(:academic_year) } @@ -17,29 +17,29 @@ describe 'SQM Application' do student_response_rate: 0, teacher_response_rate: 0, meets_student_threshold: false, meets_teacher_threshold: false) end - context 'when no measures meet their threshold' do - it 'shows a modal on overview page' do + context "when no measures meet their threshold" do + it "shows a modal on overview page" do visit overview_path - expect(page).to have_css '.modal' + expect(page).to have_css ".modal" end - it 'does not show a modal on the browse page' do + it "does not show a modal on the browse page" do visit browse_path - expect(page).not_to have_css '.modal' + expect(page).not_to have_css ".modal" end end - context 'at least one measure meets its threshold' do + context "at least one measure meets its threshold" do before :each do teacher_survey_item = create(:teacher_survey_item, scale:) create_list(:survey_item_response, SurveyItemResponse::TEACHER_RESPONSE_THRESHOLD, survey_item: teacher_survey_item, academic_year:, school:) end - it 'does not show a modal on any page' do + it "does not show a modal on any page" do [overview_path, browse_path].each do |path| visit path - expect(page).not_to have_css '.modal' + expect(page).not_to have_css ".modal" end end end From e65ec4d9612425f1c40d57b4a0139e56e65df704 Mon Sep 17 00:00:00 2001 From: rebuilt Date: Tue, 11 Jul 2023 06:07:55 -0700 Subject: [PATCH 2/8] Added cypress to the codebase but haven't yet integrated it into workflow --- Gemfile | 4 +- Gemfile.lock | 15 +- config/environments/test.rb | 12 +- cypress.config.js | 17 + cypress/e2e/1-getting-started/todo.cy.js | 143 +++ cypress/e2e/2-advanced-examples/actions.cy.js | 299 ++++++ .../e2e/2-advanced-examples/aliasing.cy.js | 38 + .../e2e/2-advanced-examples/assertions.cy.js | 176 ++++ .../e2e/2-advanced-examples/connectors.cy.js | 98 ++ cypress/e2e/2-advanced-examples/cookies.cy.js | 118 +++ .../e2e/2-advanced-examples/cypress_api.cy.js | 185 ++++ cypress/e2e/2-advanced-examples/files.cy.js | 85 ++ .../e2e/2-advanced-examples/location.cy.js | 32 + cypress/e2e/2-advanced-examples/misc.cy.js | 104 +++ .../e2e/2-advanced-examples/navigation.cy.js | 56 ++ .../network_requests.cy.js | 163 ++++ .../e2e/2-advanced-examples/querying.cy.js | 114 +++ .../spies_stubs_clocks.cy.js | 201 ++++ cypress/e2e/2-advanced-examples/storage.cy.js | 110 +++ .../e2e/2-advanced-examples/traversal.cy.js | 121 +++ .../e2e/2-advanced-examples/utilities.cy.js | 108 +++ .../e2e/2-advanced-examples/viewport.cy.js | 59 ++ cypress/e2e/2-advanced-examples/waiting.cy.js | 31 + cypress/e2e/2-advanced-examples/window.cy.js | 22 + cypress/e2e/canary.cy.js | 5 + cypress/plugins/index.js | 14 + yarn.lock | 858 +++++++++++++++++- 27 files changed, 3160 insertions(+), 28 deletions(-) create mode 100644 cypress.config.js create mode 100644 cypress/e2e/1-getting-started/todo.cy.js create mode 100644 cypress/e2e/2-advanced-examples/actions.cy.js create mode 100644 cypress/e2e/2-advanced-examples/aliasing.cy.js create mode 100644 cypress/e2e/2-advanced-examples/assertions.cy.js create mode 100644 cypress/e2e/2-advanced-examples/connectors.cy.js create mode 100644 cypress/e2e/2-advanced-examples/cookies.cy.js create mode 100644 cypress/e2e/2-advanced-examples/cypress_api.cy.js create mode 100644 cypress/e2e/2-advanced-examples/files.cy.js create mode 100644 cypress/e2e/2-advanced-examples/location.cy.js create mode 100644 cypress/e2e/2-advanced-examples/misc.cy.js create mode 100644 cypress/e2e/2-advanced-examples/navigation.cy.js create mode 100644 cypress/e2e/2-advanced-examples/network_requests.cy.js create mode 100644 cypress/e2e/2-advanced-examples/querying.cy.js create mode 100644 cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js create mode 100644 cypress/e2e/2-advanced-examples/storage.cy.js create mode 100644 cypress/e2e/2-advanced-examples/traversal.cy.js create mode 100644 cypress/e2e/2-advanced-examples/utilities.cy.js create mode 100644 cypress/e2e/2-advanced-examples/viewport.cy.js create mode 100644 cypress/e2e/2-advanced-examples/waiting.cy.js create mode 100644 cypress/e2e/2-advanced-examples/window.cy.js create mode 100644 cypress/e2e/canary.cy.js create mode 100644 cypress/plugins/index.js diff --git a/Gemfile b/Gemfile index 63b2a195..4c0027f2 100644 --- a/Gemfile +++ b/Gemfile @@ -40,8 +40,6 @@ gem "devise" gem "omniauth" -gem "twilio-ruby", "~> 4.11.1" - gem "activerecord-import" gem "jsbundling-rails" @@ -63,6 +61,8 @@ gem "standard_deviation" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem "byebug", platform: :mri + gem "cypress-rails" + gem "dotenv-rails" gem "factory_bot_rails" gem "parallel_tests" gem "rack-mini-profiler" diff --git a/Gemfile.lock b/Gemfile.lock index 82eb7eac..51e23957 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,6 +108,9 @@ GEM cuprite (0.14.3) capybara (~> 3.0) ferrum (~> 0.13.0) + cypress-rails (0.6.0) + puma (>= 3.8.0) + railties (>= 5.2.0) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) database_cleaner-active_record (2.1.0) @@ -123,6 +126,10 @@ GEM warden (~> 1.2.3) diff-lcs (1.5.0) docile (1.4.0) + dotenv (2.8.1) + dotenv-rails (2.8.1) + dotenv (= 2.8.1) + railties (>= 3.2) e2mmap (0.1.0) ed25519 (1.3.0) em-websocket (0.5.3) @@ -194,7 +201,6 @@ GEM jsbundling-rails (1.1.1) railties (>= 6.0.0) json (2.6.3) - jwt (1.5.6) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -414,10 +420,6 @@ GEM actionpack (>= 6.0.0) activejob (>= 6.0.0) railties (>= 6.0.0) - twilio-ruby (4.11.1) - builder (>= 2.1.2) - jwt (~> 1.0) - multi_json (>= 1.3.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) uglifier (4.2.0) @@ -459,8 +461,10 @@ DEPENDENCIES capybara cssbundling-rails cuprite + cypress-rails database_cleaner devise + dotenv-rails ed25519 erb_lint erblint-github @@ -500,7 +504,6 @@ DEPENDENCIES stimulus-rails timecop turbo-rails - twilio-ruby (~> 4.11.1) tzinfo-data uglifier (>= 1.3.0) watir diff --git a/config/environments/test.rb b/config/environments/test.rb index 54e083ad..668d20cb 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -13,7 +13,7 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. config.cache_classes = false - config.action_view.cache_template_loading = true + config.action_view.cache_template_loading = false # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that @@ -23,11 +23,11 @@ Rails.application.configure do # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true config.public_file_server.headers = { - 'Cache-Control' => "public, max-age=#{1.hour.to_i}" + "Cache-Control" => "public, max-age=#{1.hour.to_i}" } # Show full error reports and disable caching. - config.consider_all_requests_local = true + config.consider_all_requests_local = true config.action_controller.perform_caching = false config.cache_store = :null_store @@ -55,7 +55,7 @@ Rails.application.configure do config.action_controller.include_all_helpers = false - config.active_record.encryption.primary_key = 'test' - config.active_record.encryption.deterministic_key = 'test' - config.active_record.encryption.key_derivation_salt = 'test' + config.active_record.encryption.primary_key = "test" + config.active_record.encryption.deterministic_key = "test" + config.active_record.encryption.key_derivation_salt = "test" end diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 00000000..4cc7b56e --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,17 @@ +const { defineConfig } = require('cypress') + +module.exports = defineConfig({ + // setupNodeEvents can be defined in either + // the e2e or component configuration + e2e: { + setupNodeEvents(on, config) { + on('before:browser:launch', (browser = {}, launchOptions) => { + /* ... */ + }) + }, + supportFile: false + }, + screenshotsFolder: "tmp/cypress_screenshots", + videosFolder: "tmp/cypress_videos", + trashAssetsBeforeRuns: false +}) diff --git a/cypress/e2e/1-getting-started/todo.cy.js b/cypress/e2e/1-getting-started/todo.cy.js new file mode 100644 index 00000000..4768ff92 --- /dev/null +++ b/cypress/e2e/1-getting-started/todo.cy.js @@ -0,0 +1,143 @@ +/// + +// Welcome to Cypress! +// +// This spec file contains a variety of sample tests +// for a todo list app that are designed to demonstrate +// the power of writing tests in Cypress. +// +// To learn more about how Cypress works and +// what makes it such an awesome testing tool, +// please read our getting started guide: +// https://on.cypress.io/introduction-to-cypress + +describe('example to-do app', () => { + beforeEach(() => { + // Cypress starts out with a blank slate for each test + // so we must tell it to visit our website with the `cy.visit()` command. + // Since we want to visit the same URL at the start of all our tests, + // we include it in our beforeEach function so that it runs before each test + cy.visit('https://example.cypress.io/todo') + }) + + it('displays two todo items by default', () => { + // We use the `cy.get()` command to get all elements that match the selector. + // Then, we use `should` to assert that there are two matched items, + // which are the two default items. + cy.get('.todo-list li').should('have.length', 2) + + // We can go even further and check that the default todos each contain + // the correct text. We use the `first` and `last` functions + // to get just the first and last matched elements individually, + // and then perform an assertion with `should`. + cy.get('.todo-list li').first().should('have.text', 'Pay electric bill') + cy.get('.todo-list li').last().should('have.text', 'Walk the dog') + }) + + it('can add new todo items', () => { + // We'll store our item text in a variable so we can reuse it + const newItem = 'Feed the cat' + + // Let's get the input element and use the `type` command to + // input our new list item. After typing the content of our item, + // we need to type the enter key as well in order to submit the input. + // This input has a data-test attribute so we'll use that to select the + // element in accordance with best practices: + // https://on.cypress.io/selecting-elements + cy.get('[data-test=new-todo]').type(`${newItem}{enter}`) + + // Now that we've typed our new item, let's check that it actually was added to the list. + // Since it's the newest item, it should exist as the last element in the list. + // In addition, with the two default items, we should have a total of 3 elements in the list. + // Since assertions yield the element that was asserted on, + // we can chain both of these assertions together into a single statement. + cy.get('.todo-list li') + .should('have.length', 3) + .last() + .should('have.text', newItem) + }) + + it('can check off an item as completed', () => { + // In addition to using the `get` command to get an element by selector, + // we can also use the `contains` command to get an element by its contents. + // However, this will yield the