From 76e73784e0fd72d3618296859db68a57a476bd35 Mon Sep 17 00:00:00 2001 From: solebared Date: Fri, 31 May 2024 13:42:59 -0400 Subject: [PATCH 1/3] Uncomment specs to unearth flakes in CI Note: also removed all forced `wait:`s. --- spec/system/volunteers/index_spec.rb | 257 +++++++++++++-------------- 1 file changed, 128 insertions(+), 129 deletions(-) diff --git a/spec/system/volunteers/index_spec.rb b/spec/system/volunteers/index_spec.rb index 459e38ff53..6d2b2d8e58 100644 --- a/spec/system/volunteers/index_spec.rb +++ b/spec/system/volunteers/index_spec.rb @@ -180,175 +180,174 @@ # These tests are very flaky do to the use of datatables on this page. # If the page is switched over to Hotwire, should try to re-instate these tests. describe "Manage Volunteers button" do - # let!(:volunteers) { - # [ - # create(:volunteer, casa_org: organization), - # create(:volunteer, casa_org: organization), - # create(:volunteer, casa_org: organization) - # ] - # } - # - # before do - # sign_in admin - # end - - xit "does not display by default" do - # visit volunteers_path - # expect(page).not_to have_text "Manage Volunteer" + let!(:volunteers) { + [ + create(:volunteer, casa_org: organization), + create(:volunteer, casa_org: organization), + create(:volunteer, casa_org: organization) + ] + } + + before do + sign_in admin + end + + it "does not display by default" do + visit volunteers_path + expect(page).not_to have_text "Manage Volunteer" end context "when one or more volunteers selected" do - xit "is displayed" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}", wait: 3).click + it "is displayed" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click - # expect(page).to have_text "Manage Volunteer" + expect(page).to have_text "Manage Volunteer" end - xit "displays number of volunteers selected" do - # visit volunteers_path - # volunteers.each_with_index do |volunteer, index| - # find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}", wait: 3).click - # button = find("[data-select-all-target='buttonLabel']", wait: 3) - # expect(button).to have_text "(#{index + 1})" - # end + it "displays number of volunteers selected" do + visit volunteers_path + volunteers.each_with_index do |volunteer, index| + find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click + button = find("[data-select-all-target='buttonLabel']") + expect(button).to have_text "(#{index + 1})" + end end - xit "text matches pluralization of volunteers selected" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}", wait: 3).click - # expect(page).not_to have_text "Manage Volunteers" - # - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[1].id}").click - # expect(page).to have_text "Manage Volunteers" + it "text matches pluralization of volunteers selected" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click + expect(page).not_to have_text "Manage Volunteers" + + find("#supervisor_volunteer_volunteer_ids_#{volunteers[1].id}").click + expect(page).to have_text "Manage Volunteers" end - xit "is hidden when all volunteers unchecked" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}", wait: 3).click - # expect(page).to have_text "Manage Volunteer" - # - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click - # expect(page).not_to have_text "Manage Volunteer" + it "is hidden when all volunteers unchecked" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click + expect(page).to have_text "Manage Volunteer" + + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click + expect(page).not_to have_text "Manage Volunteer" end end end describe "Select All Checkbox" do - # let!(:volunteers) { - # [ - # create(:volunteer, casa_org: organization), - # create(:volunteer, casa_org: organization), - # create(:volunteer, casa_org: organization) - # ] - # } - - # before do - # sign_in admin - # end - - xit "selects all volunteers" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}") # Wait for data table to be loaded - # find("[data-select-all-target='checkboxAll']").click - # - # volunteers.each do |volunteer| - # expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be true - # end + let!(:volunteers) { + [ + create(:volunteer, casa_org: organization), + create(:volunteer, casa_org: organization), + create(:volunteer, casa_org: organization) + ] + } + + before do + sign_in admin + end + + it "selects all volunteers" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}") # Wait for data table to be loaded + find("[data-select-all-target='checkboxAll']").click + + volunteers.each do |volunteer| + expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be true + end end context "when all are checked" do - xit "deselects all volunteers" do - # visit volunteers_path - # volunteers.each do |volunteer| - # find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click - # end - # - # find("[data-select-all-target='checkboxAll']").click - # expect(find("[data-select-all-target='checkboxAll']").checked?).to be false - # - # volunteers.each do |volunteer| - # expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be false - # end + it "deselects all volunteers" do + visit volunteers_path + volunteers.each do |volunteer| + find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click + end + + find("[data-select-all-target='checkboxAll']").click + expect(find("[data-select-all-target='checkboxAll']").checked?).to be false + + volunteers.each do |volunteer| + expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be false + end end end context "when some are checked" do - xit "is semi-checked (indeterminate)" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click - # sleep(1) - # - # expect(find("[data-select-all-target='checkboxAll']").checked?).to be false - # expect(find("[data-select-all-target='checkboxAll']")[:indeterminate]).to eq("true") + it "is semi-checked (indeterminate)" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click + + expect(find("[data-select-all-target='checkboxAll']").checked?).to be false + expect(find("[data-select-all-target='checkboxAll']")[:indeterminate]).to eq("true") end - xit "selects all volunteers" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click - # find("[data-select-all-target='checkboxAll']").click - # - # volunteers.each do |volunteer| - # expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be true - # end + it "selects all volunteers" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click + find("[data-select-all-target='checkboxAll']").click + + volunteers.each do |volunteer| + expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be true + end end end end describe "Select Supervisor Modal Submit button" do - # let!(:volunteer) { create(:volunteer, casa_org: organization) } - # let!(:supervisor) { create(:supervisor, casa_org: organization) } - # - # before do - # sign_in admin - # end + let!(:volunteer) { create(:volunteer, casa_org: organization) } + let!(:supervisor) { create(:supervisor, casa_org: organization) } + + before do + sign_in admin + end - xit "is disabled by default" + pending "is disabled by default" context "when none is selected" do - xit "is enabled" do # TODO: Flaky. Fix this test - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}", wait: 3).click - # find("[data-select-all-target='button']", wait: 3).click - # select "None", from: "supervisor_volunteer_supervisor_id" - # - # button = find("[data-disable-form-target='submitButton']") - # - # expect(button.disabled?).to be false - # expect(button[:class].include?("deactive-btn")).to be false - # expect(button[:class].include?("dark-btn")).to be true - # expect(button[:class].include?("btn-hover")).to be true + it "is enabled" do # TODO: Flaky. Fix this test + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click + find("[data-select-all-target='button']").click + select "None", from: "supervisor_volunteer_supervisor_id" + + button = find("[data-disable-form-target='submitButton']") + + expect(button.disabled?).to be false + expect(button[:class].include?("deactive-btn")).to be false + expect(button[:class].include?("dark-btn")).to be true + expect(button[:class].include?("btn-hover")).to be true end end context "when a supervisor is selected" do - xit "is enabled" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}", wait: 3).click - # find("[data-select-all-target='button']", wait: 3).click - # - # select supervisor.display_name, from: "supervisor_volunteer_supervisor_id" - # button = find("[data-disable-form-target='submitButton']") - # expect(button.disabled?).to be false - # expect(button[:class].include?("deactive-btn")).to be false - # expect(button[:class].include?("dark-btn")).to be true - # expect(button[:class].include?("btn-hover")).to be true + it "is enabled" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click + find("[data-select-all-target='button']").click + + select supervisor.display_name, from: "supervisor_volunteer_supervisor_id" + button = find("[data-disable-form-target='submitButton']") + expect(button.disabled?).to be false + expect(button[:class].include?("deactive-btn")).to be false + expect(button[:class].include?("dark-btn")).to be true + expect(button[:class].include?("btn-hover")).to be true end end context "when Choose a supervisor is selected" do - xit "is disabled" do - # visit volunteers_path - # find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}", wait: 3).click - # find("[data-select-all-target='button']", wait: 3).click - # - # select supervisor.display_name, from: "supervisor_volunteer_supervisor_id" - # select "Choose a supervisor", from: "supervisor_volunteer_supervisor_id" - # button = find("[data-disable-form-target='submitButton']") - # expect(button.disabled?).to be true - # expect(button[:class].include?("deactive-btn")).to be true - # expect(button[:class].include?("dark-btn")).to be false - # expect(button[:class].include?("btn-hover")).to be false + it "is disabled" do + visit volunteers_path + find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click + find("[data-select-all-target='button']").click + + select supervisor.display_name, from: "supervisor_volunteer_supervisor_id" + select "Choose a supervisor", from: "supervisor_volunteer_supervisor_id" + button = find("[data-disable-form-target='submitButton']") + expect(button.disabled?).to be true + expect(button[:class].include?("deactive-btn")).to be true + expect(button[:class].include?("dark-btn")).to be false + expect(button[:class].include?("btn-hover")).to be false end end end From a2467d46113913532ea7b1402a151018e3efc57a Mon Sep 17 00:00:00 2001 From: solebared Date: Fri, 31 May 2024 14:22:29 -0400 Subject: [PATCH 2/3] Switch to using have_button matcher Likely more robust, though i didn't actually encounter any flakiness here. Mostly just addressing the TODO comment. --- spec/system/volunteers/index_spec.rb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/spec/system/volunteers/index_spec.rb b/spec/system/volunteers/index_spec.rb index 6d2b2d8e58..89a104dfdb 100644 --- a/spec/system/volunteers/index_spec.rb +++ b/spec/system/volunteers/index_spec.rb @@ -305,18 +305,14 @@ pending "is disabled by default" context "when none is selected" do - it "is enabled" do # TODO: Flaky. Fix this test + it "is enabled" do visit volunteers_path find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click find("[data-select-all-target='button']").click select "None", from: "supervisor_volunteer_supervisor_id" - button = find("[data-disable-form-target='submitButton']") - - expect(button.disabled?).to be false - expect(button[:class].include?("deactive-btn")).to be false - expect(button[:class].include?("dark-btn")).to be true - expect(button[:class].include?("btn-hover")).to be true + expect(page).to have_button("Confirm", disabled: false) + expect(page).to have_button("Confirm", class: %w[!deactive-btn dark-btn btn-hover]) end end From 3f993ee88f5701965c04ce8de1d158199dfa4eca Mon Sep 17 00:00:00 2001 From: solebared Date: Fri, 31 May 2024 15:44:13 -0400 Subject: [PATCH 3/3] Grabbag of changes to mitigate possible flakiness Mostly converting find-then-check occurences to use capybara matchers instead. --- app/views/volunteers/index.html.erb | 2 +- spec/system/volunteers/index_spec.rb | 70 +++++++++++----------------- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/app/views/volunteers/index.html.erb b/app/views/volunteers/index.html.erb index 17ceadb0ce..b5c37e0256 100644 --- a/app/views/volunteers/index.html.erb +++ b/app/views/volunteers/index.html.erb @@ -176,7 +176,7 @@ - + Name Email diff --git a/spec/system/volunteers/index_spec.rb b/spec/system/volunteers/index_spec.rb index 89a104dfdb..3a13357aaf 100644 --- a/spec/system/volunteers/index_spec.rb +++ b/spec/system/volunteers/index_spec.rb @@ -36,8 +36,8 @@ visit volunteers_path - expect(page.find("#casa-logo")["src"]).to match "default-logo" - expect(page.find("#casa-logo")["alt"]).to have_content "CASA Logo" + expect(page).to have_selector("#casa-logo[src*='default-logo']") + expect(page).to have_selector("#casa-logo[alt='CASA Logo']") end end @@ -104,7 +104,7 @@ inactive_volunteers.each do |inactive_volunteer| expect(page).to have_text inactive_volunteer.display_name end - expect(page.all("table#volunteers tbody tr").count).to eq inactive_volunteers.count + expect(page).to have_selector("table#volunteers tbody tr", count: inactive_volunteers.count) visit volunteers_path click_on "Supervisor" @@ -112,7 +112,7 @@ assigned_volunteers.each do |assigned_volunteer| expect(page).to have_text assigned_volunteer.display_name end - expect(page.all("table#volunteers tbody tr").count).to eq assigned_volunteers.count + expect(page).to have_selector("table#volunteers tbody tr", count: assigned_volunteers.count) end it "can go to the volunteer edit page from the volunteer list", js: true do @@ -136,7 +136,7 @@ click_on "New Volunteer" expect(page).to have_text("New Volunteer") - expect(page).to have_css("form#new_volunteer") + expect(page).to have_selector("form#new_volunteer") end describe "supervisor column of volunteers table" do @@ -147,9 +147,8 @@ visit volunteers_path click_on "Supervisor" find(:css, "#unassigned-vol-filter").set(true) - supervisor_cell = page.find("tbody .supervisor-column") - expect(supervisor_cell.text).to eq "" + expect(page).to have_selector("tbody .supervisor-column", text: "") end it "displays supervisor's name when volunteer has supervisor", js: true do @@ -159,9 +158,7 @@ sign_in admin visit volunteers_path - supervisor_cell = page.find("tbody .supervisor-column") - - expect(supervisor_cell.text).to eq name + expect(page).to have_selector("tbody .supervisor-column", text: name) end it "is blank when volunteer's supervisor is inactive", js: true do @@ -171,9 +168,8 @@ visit volunteers_path click_on "Supervisor" find(:css, "#unassigned-vol-filter").set(true) - supervisor_cell = page.find("tbody .supervisor-column") - expect(supervisor_cell.text).to eq "" + expect(page).to have_selector("tbody .supervisor-column", text: "") end end @@ -209,8 +205,7 @@ visit volunteers_path volunteers.each_with_index do |volunteer, index| find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click - button = find("[data-select-all-target='buttonLabel']") - expect(button).to have_text "(#{index + 1})" + expect(page).to have_selector("[data-select-all-target='buttonLabel']", text: "#{index + 1})") end end @@ -250,10 +245,10 @@ it "selects all volunteers" do visit volunteers_path find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}") # Wait for data table to be loaded - find("[data-select-all-target='checkboxAll']").click + find("#checkbox-toggle-all").click volunteers.each do |volunteer| - expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be true + expect(page).to have_field("supervisor_volunteer_volunteer_ids_#{volunteer.id}", checked: true) end end @@ -264,11 +259,11 @@ find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").click end - find("[data-select-all-target='checkboxAll']").click - expect(find("[data-select-all-target='checkboxAll']").checked?).to be false + find("#checkbox-toggle-all").click + expect(page).to have_field("checkbox-toggle-all", checked: false) volunteers.each do |volunteer| - expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be false + expect(page).to have_field("supervisor_volunteer_volunteer_ids_#{volunteer.id}", checked: false) end end end @@ -278,17 +273,17 @@ visit volunteers_path find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click - expect(find("[data-select-all-target='checkboxAll']").checked?).to be false - expect(find("[data-select-all-target='checkboxAll']")[:indeterminate]).to eq("true") + expect(page).to have_field("checkbox-toggle-all", checked: false) + expect(find("#checkbox-toggle-all")[:indeterminate]).to eq("true") end it "selects all volunteers" do visit volunteers_path find("#supervisor_volunteer_volunteer_ids_#{volunteers[0].id}").click - find("[data-select-all-target='checkboxAll']").click + find("#checkbox-toggle-all").click volunteers.each do |volunteer| - expect(find("#supervisor_volunteer_volunteer_ids_#{volunteer.id}").checked?).to be true + expect(page).to have_field("supervisor_volunteer_volunteer_ids_#{volunteer.id}", checked: true) end end end @@ -311,8 +306,7 @@ find("[data-select-all-target='button']").click select "None", from: "supervisor_volunteer_supervisor_id" - expect(page).to have_button("Confirm", disabled: false) - expect(page).to have_button("Confirm", class: %w[!deactive-btn dark-btn btn-hover]) + expect(page).to have_button("Confirm", disabled: false, class: %w[!deactive-btn dark-btn btn-hover]) end end @@ -323,11 +317,8 @@ find("[data-select-all-target='button']").click select supervisor.display_name, from: "supervisor_volunteer_supervisor_id" - button = find("[data-disable-form-target='submitButton']") - expect(button.disabled?).to be false - expect(button[:class].include?("deactive-btn")).to be false - expect(button[:class].include?("dark-btn")).to be true - expect(button[:class].include?("btn-hover")).to be true + + expect(page).to have_button("Confirm", disabled: false, class: %w[!deactive-btn dark-btn btn-hover]) end end @@ -339,11 +330,8 @@ select supervisor.display_name, from: "supervisor_volunteer_supervisor_id" select "Choose a supervisor", from: "supervisor_volunteer_supervisor_id" - button = find("[data-disable-form-target='submitButton']") - expect(button.disabled?).to be true - expect(button[:class].include?("deactive-btn")).to be true - expect(button[:class].include?("dark-btn")).to be false - expect(button[:class].include?("btn-hover")).to be false + + expect(page).to have_button("Confirm", disabled: true, class: %w[deactive-btn !dark-btn !btn-hover]) end end end @@ -351,7 +339,6 @@ context "supervisor user" do let(:supervisor) { create(:supervisor, casa_org: organization) } - let(:input_field) { "div#volunteers_filter input" } it "can filter volunteers", js: true do active_volunteers = create_list(:volunteer, 3, :with_assigned_supervisor, casa_org: organization) @@ -365,8 +352,7 @@ visit volunteers_path expect(page).to have_selector(".volunteer-filters") - - expect(page.all("table#volunteers tbody tr").count).to eq 1 + expect(page).to have_selector("table#volunteers tbody tr", count: 1) click_on "Status" find(:css, 'input[data-value="true"]').set(false) @@ -376,7 +362,7 @@ inactive_volunteers.each do |inactive_volunteer| expect(page).to have_text inactive_volunteer.display_name end - expect(page.all("table#volunteers tbody tr").count).to eq inactive_volunteers.count + expect(page).to have_selector("table#volunteers tbody tr", count: inactive_volunteers.count) end it "can show/hide columns on volunteers table", js: true do @@ -469,12 +455,12 @@ sign_in supervisor visit volunteers_path - page.find(input_field).set("Test") + page.fill_in("Search:", with: "Test") visit supervisors_path visit volunteers_path - input_search = page.find(input_field) - expect(input_search.value).to eq("") + + expect(page).to have_selector("#volunteers_filter input", text: "") end end end