Skip to content

Prune redundant slow system specs; convert non-JS ones to request specs#1577

Open
maebeale wants to merge 1 commit into
mainfrom
maebeale/prune-redundant-slow-tests
Open

Prune redundant slow system specs; convert non-JS ones to request specs#1577
maebeale wants to merge 1 commit into
mainfrom
maebeale/prune-redundant-slow-tests

Conversation

@maebeale
Copy link
Copy Markdown
Collaborator

@maebeale maebeale commented Jun 6, 2026

What is the goal of this PR and why is this important?

The RSpec system suite booted real headless Chrome (selenium_chrome_headless) for many specs that only visited a page and asserted static content. That's the slowest possible way to test rendering that doesn't involve JavaScript, and it was a meaningful drag on suite time without providing coverage a faster layer couldn't.

This PR speeds up the suite by moving that coverage down to request specs, and removes dead test files that never ran.

How did you approach the change?

  • Converted 9 browser-booting, non-JS system specs to request specs, deleting each system file only after the request version passed:
    • faq_specrequests/faqs_spec (added the New FAQ / Edit admin-control link assertions)
    • sectors_controller_specrequests/sectors_spec (added published/name filter tests — the filtering logic was previously only checked at the system layer; the request spec just asserted 200 OK)
    • login_spec → new requests/login_spec
    • person_views_community_news_specrequests/home_spec
    • person_views_story_idea_specrequests/story_ideas_spec
    • person_views_workshop_variation_idea_specrequests/workshop_variation_ideas_spec
    • person_views_workshop_log_specrequests/workshop_logs_spec (added an entire GET /show context that didn't exist)
    • organization_sectors_specrequests/organizations_spec (sector truncation + populations-served page)
    • stories_specrequests/stories_spec (added empty-state message + combined title/body search)
  • Link-vs-plain-text assertions are preserved by parsing the response with Capybara.string(response.body) and using have_link / have_text — full fidelity, no browser.
  • Deleted 17 spec/system/*_test.rb files. RSpec only loads *_spec.rb, so these never executed (dead since ~Feb). 7 fully duplicated loaded specs; the other 10 covered flows whose success paths are already covered by request specs and whose unique JS bits were dormant. Removing them stops them masquerading as coverage.

Net: 27 → 18 system specs, all of which genuinely need a browser (Stimulus, TomSelect, Turbo streams, accept_confirm, file upload/download). The new request examples run in ~18s vs. booting Chrome per example.

UI Testing Checklist

  • N/A — test-only change; no application code or UI modified.

Anything else to add?

  • No production code changed — only specs added/removed.
  • The converted request specs add coverage that was previously missing (sector filtering, workshop-log show page, stories empty state + body search).

The system suite booted real headless Chrome for many specs that only
rendered static pages, making the suite slow without adding coverage a
faster layer couldn't provide. This moves that coverage down to request
specs and removes dead test files that never ran.

- Convert 9 browser-booting, non-JS system specs to request specs
  (faqs, sectors, login, home/community-news, story ideas, workshop
  variation ideas, workshop logs, organization sectors, stories). Each
  conversion preserves the original assertions — including link-vs-text
  checks via Capybara.string(response.body) — and adds coverage that was
  previously missing (sector filtering, workshop-log show, stories empty
  state and body search).
- Delete 17 spec/system/*_test.rb files: RSpec only loads *_spec.rb, so
  these never executed. Their flows are either already covered by request
  specs or were dormant; removing them stops them masquerading as coverage.

Remaining system specs all genuinely require a browser (Stimulus,
TomSelect, Turbo streams, accept_confirm, file upload/download).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 6, 2026 21:44

get story_idea_url(story_idea)

page = Capybara.string(response.body)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Capybara.string(response.body) lets request specs keep the system spec's have_link/have_text assertions (link vs. plain text by role) without booting a browser. This is the pattern that made the conversions faithful.

expect(response).to be_successful
end

context "filtering" do
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: These filter tests are new coverage, not just a port — the request spec previously only asserted 200 OK, so the published/name filtering logic had no fast-layer test.

clear_enqueued_jobs
end

describe "GET /show" do
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: There was no GET /show context here before; the deleted system spec was the only place workshop-log show rendering (org/creator links, external title, workshop chip) was tested.

it "shows the generic error" do
log_in(user.email, "wrong_password")

expect(response).to have_http_status(:unprocessable_content)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Devise re-renders the form with 422 on bad credentials (it does not redirect), unlike the inactive-user path above which redirects. Mirrors actual app behavior.

expect(response.body).not_to include(story_in_other_org.title)
end

it "shows the empty-state message when no stories match" do
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: The stories index is turbo-frame lazy-loaded, so these hit it with the Turbo-Frame header to get the story list into the body — empty state and body-query search were not covered before.

@maebeale maebeale marked this pull request as ready for review June 6, 2026 21:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR speeds up the test suite by removing system specs that didn’t need a real browser (and deleting dead _test.rb files that RSpec never executed), while preserving the same assertions by moving coverage down to request specs (often via Capybara.string(response.body)).

Changes:

  • Converted non-JS, rendering-focused system specs to request specs (keeping link-vs-text expectations where relevant).
  • Added/expanded request-spec coverage for filtering and empty states (e.g., sectors filtering, stories empty state + combined title/body search, workshop log show cases).
  • Deleted redundant/dead system spec files (including *_test.rb files that never ran under RSpec).

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
spec/system/stories_spec.rb Removed non-JS system coverage; replaced by request specs.
spec/system/sectors_controller_spec.rb Removed system-level sectors index/filter coverage; moved to request spec.
spec/system/person_views_workshop_variation_idea_spec.rb Removed show-page link/text assertions; moved to request spec.
spec/system/person_views_workshop_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_views_workshop_logs_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_views_workshop_log_spec.rb Removed show-page link/text + title assertions; moved to request spec.
spec/system/person_views_story_idea_spec.rb Removed show-page link/text assertions; moved to request spec.
spec/system/person_views_popular_resources_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_views_featured_workshops_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_views_community_news_spec.rb Removed non-JS home-page section assertions; moved to request spec.
spec/system/person_submits_workshop_variation_idea_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_submits_workshop_log_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_submits_workshop_idea_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_submits_story_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_searches_workshop_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_searches_resources_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_registers_for_event_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_filters_workshops_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_downloads_resources_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_changes_password_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_bookmarks_workshop_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/person_adds_event_to_calendar_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/system/organization_sectors_spec.rb Removed org sector display assertions; moved to request spec.
spec/system/login_spec.rb Removed non-JS login system spec; replaced with request spec.
spec/system/faq_spec.rb Removed non-JS FAQ system spec; replaced with request spec coverage.
spec/system/event_registrations_test.rb Deleted dead _test.rb system file (never executed by RSpec).
spec/requests/workshop_variation_ideas_spec.rb Added show-page link-vs-text assertions via Capybara.string.
spec/requests/workshop_logs_spec.rb Added comprehensive GET /show contexts for workshop logs via request spec.
spec/requests/story_ideas_spec.rb Added show-page link-vs-text assertions via Capybara.string.
spec/requests/stories_spec.rb Added empty-state + combined title/body query coverage for turbo-frame index results.
spec/requests/sectors_spec.rb Added request-level assertions validating published/name filtering behavior.
spec/requests/organizations_spec.rb Added request-level coverage for sector truncation + populations-served sector distribution.
spec/requests/login_spec.rb New request spec covering inactive, invalid-credential, and successful login flows.
spec/requests/home_spec.rb Added signed-in home-page assertions for key sections.
spec/requests/faqs_spec.rb Added admin-controls visibility assertions for FAQ index.

Comment on lines +73 to +76
it "shows the New FAQ admin control" do
get faqs_path
expect(response.body).to include("New FAQ")
end
Comment on lines +118 to +122
it "hides admin controls" do
get faqs_path
expect(response.body).not_to include("New FAQ")
expect(response.body).not_to include(edit_faq_path(published_faq))
end
Comment on lines +139 to +143
it "hides admin controls" do
get faqs_path
expect(response.body).not_to include("New FAQ")
expect(response.body).not_to include(edit_faq_path(public_faq))
end
Comment on lines +115 to +117
expected_counts.each do |_sector_name, count|
expect(page).to have_content("#{count} #{count == 1 ? 'person' : 'people'}")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants