Module: Dommy::Rails::BrowserSpec
- Defined in:
- lib/dommy/rails/browser_spec.rb
Overview
Test-integration helper that runs application JavaScript against the real Rails app, bridging request-style specs to the lightweight test browser. Include it in a Minitest test or RSpec example group to get a ‘browser` (a `javascript: true` Dommy::Rack::Session bound to the Rails Rack app):
browser.visit todos_path
browser.click "li.todo"
assert browser.has_css?("li.todo.is-completed")
External ‘<script>`s and `fetch` resolve through the Rails app itself (Propshaft / Sprockets / controllers), sharing the session cookie jar. The browser is disposed at teardown, and any uncaught JS error / unhandled rejection fails the test (strict by default) unless wrapped in `allow_js_errors`.
Class Method Summary collapse
-
.included(base) ⇒ Object
Auto-wire teardown: RSpec example groups get an ‘after` hook (the example is passed so we can save artifacts on failure); Minitest tests use `after_teardown` (defined below).
Instance Method Summary collapse
-
#after_teardown ⇒ Object
Minitest teardown hook (no-op outside Minitest).
-
#allow_js_errors ⇒ Object
Suppress strict JS-error failure for errors raised inside the block (they stay in ‘browser.js_errors`).
-
#browser ⇒ Object
Memoized JS-enabled session bound to the app.
- #browser_started? ⇒ Boolean
-
#dommy_browser_after(failed:, label: nil, exception: nil) ⇒ Object
On a failed example, write debugging artifacts (page HTML + trace + visible text) before disposing, then run the normal teardown.
-
#dommy_browser_app ⇒ Object
The Rack app the browser drives.
-
#dommy_browser_teardown ⇒ Object
Dispose the browser and fail if uncaught JS errors were collected.
-
#dommy_failures_dir ⇒ Object
Directory failure artifacts are written under (override per host).
Class Method Details
.included(base) ⇒ Object
Auto-wire teardown: RSpec example groups get an ‘after` hook (the example is passed so we can save artifacts on failure); Minitest tests use `after_teardown` (defined below).
25 26 27 28 29 30 31 32 |
# File 'lib/dommy/rails/browser_spec.rb', line 25 def self.included(base) if base.respond_to?(:after) base.after do |example| dommy_browser_after(failed: example.exception ? true : false, label: example.full_description, exception: example.exception) end end end |
Instance Method Details
#after_teardown ⇒ Object
Minitest teardown hook (no-op outside Minitest).
35 36 37 38 39 40 41 |
# File 'lib/dommy/rails/browser_spec.rb', line 35 def after_teardown failures = respond_to?(:failures) ? self.failures : [] dommy_browser_after(failed: !failures.empty?, label: (name if respond_to?(:name)), exception: failures.first) ensure super if defined?(super) end |
#allow_js_errors ⇒ Object
Suppress strict JS-error failure for errors raised inside the block (they stay in ‘browser.js_errors`). For specs that intentionally trigger one.
78 79 80 81 82 83 |
# File 'lib/dommy/rails/browser_spec.rb', line 78 def allow_js_errors @dommy_allow_js_errors = true yield ensure dommy_browser_ack_js_errors end |
#browser ⇒ Object
Memoized JS-enabled session bound to the app. Lazily requires the dommy-rack + QuickJS integration so the dependency is only needed when a browser spec actually runs.
63 64 65 66 67 68 69 |
# File 'lib/dommy/rails/browser_spec.rb', line 63 def browser @dommy_browser ||= begin require "dommy/js/quickjs/rack" ::Dommy::Rack::Session.new(dommy_browser_app, javascript: true, trace: true, trace_dom: true, trace_snapshots: true) end end |
#browser_started? ⇒ Boolean
74 |
# File 'lib/dommy/rails/browser_spec.rb', line 74 def browser_started? = !@dommy_browser.nil? |
#dommy_browser_after(failed:, label: nil, exception: nil) ⇒ Object
On a failed example, write debugging artifacts (page HTML + trace + visible text) before disposing, then run the normal teardown. Shared by the RSpec and Minitest hooks.
46 47 48 49 |
# File 'lib/dommy/rails/browser_spec.rb', line 46 def dommy_browser_after(failed:, label: nil, exception: nil) dommy_save_failure_artifacts(label, exception: exception) if failed && browser_started? dommy_browser_teardown end |
#dommy_browser_app ⇒ Object
The Rack app the browser drives. Defaults to the Rails application; override ‘dommy_browser_app` to point elsewhere.
53 54 55 56 57 58 |
# File 'lib/dommy/rails/browser_spec.rb', line 53 def dommy_browser_app return ::Rails.application if defined?(::Rails) && ::Rails.respond_to?(:application) raise "Dommy::Rails::BrowserSpec needs a Rack app: define #dommy_browser_app " \ "(Rails.application was not available)." end |
#dommy_browser_teardown ⇒ Object
Dispose the browser and fail if uncaught JS errors were collected. Call from a Minitest #teardown / RSpec after hook (the integration modules wire this automatically).
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/dommy/rails/browser_spec.rb', line 88 def dommy_browser_teardown return unless browser_started? pending = browser.js_errors[(@dommy_browser_acked || 0)..] || [] browser.dispose_js @dommy_browser = nil return if @dommy_allow_js_errors || pending.empty? raise dommy_browser_js_error(pending) end |
#dommy_failures_dir ⇒ Object
Directory failure artifacts are written under (override per host).
72 |
# File 'lib/dommy/rails/browser_spec.rb', line 72 def dommy_failures_dir = ::File.join("tmp", "dommy", "failures") |