test(docs): RSpec + Capybara + Playwright system suite for the dogfood site
Merged
MH
4mo ago+972+972+012345678901234567890123456789-92-92-01234567890123456789
Why
The gem's CI never exercised the /docs app, so the og:image 404 shipped with zero coverage — it was a bug that only manifests through a booted app's asset pipeline (a logical og_image path resolving to the served, digested /assets URL), which no isolated component spec can reach. This gives the dogfood site a real browser suite so that class of regression can't ship again.
Matches the stack you use everywhere else (cosmos / phlex-reactive / pgbus): RSpec + Capybara + Playwright (chromium). Replaces the throwaway minitest test from the fix PR.
What's covered
System specs (real browser + Puma + Propshaft):
seo_meta_tags_spec.rb— the 404 regression guard: visit/, assertog:imageis a/assetsURL, and that visiting it returns 200 (a shared link's image must actually load). Also og/twitter parity + per-page description.docs_chrome_spec.rb— landing hero, a doc page (masthead + Rouge code block), active sidebar link, sidebar navigation.theme_persistence_spec.rb— theme applies in place and survives navigation (docs-nav + localStorage, no flash).
Request specs (no browser — the JS-off invariant):
progressive_enhancement_spec.rb— complete HTML document, sidebar<details open>, server-side active nav, the.mdtwin,llms.txt.
Setup (mirrors the sibling repos)
- Gemfile:
rspec-rails,capybara+capybara-playwright-driver(require: false),rubocop-capybara/rubocop-rspec. package.json:playwright.bin/rspecbinstub. spec/spec_helper.rb,rails_helper.rb(DB-less —use_active_record = false),system_helper.rb;spec/system/support/{playwright,capybara}_setup.rb— Puma server, chromium,HEADLESSenv, a viewport matrix (CAPYBARA_SCREEN) with a:desktop_onlyskip for the always-open-drawer sidebar specs.spec/support/assets.rbprecompiles once before a system/request run, soimage_url(Propshaft'sStaticresolver) resolvesog:image— mirroring the deploy-timeassets:precompilecondition, so the suite is self-sufficient.
CI
docs/config/ci.rbgains aTest: RSpecstep (sobin/ciruns it)..github/workflows/ci.ymlgains a docs-site job: bundle indocs/,setup-bun, cache + install Playwright chromium, runrspec.BUNDLE_FROZEN: "false"(thepath: ".."gemspec digest changes every commit). Commitsdocs/Gemfile.lockfor reproducible installs — un-ignored, since it's a real deployable app (same asphlex-reactive/docs).
Verification
docs:bundle exec rspec→ 15 examples, 0 failures from a clean asset state (CI parity).docs: responsive matrix → desktop 10, mobile 8 (:desktop_onlyskipped).docs:bin/rubocop→ 34 files, no offenses.gem:bundle exec rake→ 714 examples, 0 failures, rubocop clean (untouched).
Refs #48.