Module: Capybara::Storyboard
- Defined in:
- lib/capybara/storyboard.rb,
lib/capybara/storyboard/context.rb,
lib/capybara/storyboard/session.rb,
lib/capybara/storyboard/version.rb,
lib/capybara/storyboard/test_helper.rb,
lib/capybara/storyboard/configuration.rb,
lib/capybara/storyboard/page_stability.rb,
lib/capybara/storyboard/policies/env_policy.rb,
lib/capybara/storyboard/policies/target_list_policy.rb,
sig/capybara/storyboard.rbs
Overview
Automatic Capybara screenshots for RSpec system specs, gated by a replaceable policy (see Capybara::Storyboard.policy).
Defined Under Namespace
Modules: PageStability, Policies, TestHelper Classes: Configuration, Context, Error, Session
Constant Summary collapse
- VERSION =
'0.1.0'
Class Method Summary collapse
-
.clear_output! ⇒ Object
Empties the output root once per process so a run's screenshots never mix with stale files left by a previous run.
-
.configuration ⇒ Object
The single Configuration holding user overrides (output root, policy).
-
.configure {|configuration| ... } ⇒ Object
Yields the Configuration for block-style setup: Capybara::Storyboard.configure { |config| config.output_dir = ... }.
-
.default_policy ⇒ Object
The single place that builds the default policy.
-
.normalize_test_path(path) ⇒ Object
Normalizes a test file path to a base-relative string so that target list entries and Context#test_file compare equal regardless of leading
./, absolute vs relative form, or surrounding whitespace/newlines. -
.policy ⇒ Object
An object responding to #call(context) -> Boolean.
- .policy=(value) ⇒ Object
-
.rails_root_or_pwd ⇒ Object
The single place that resolves the base directory: Rails.root when available (the gem stays Rails-optional), else the current directory.
-
.reset_configuration! ⇒ Object
Drops every override (output_dir and policy) in one shot, restoring the gem's defaults.
-
.reset_output_cleared! ⇒ Object
Test-hygiene helper mirroring reset_configuration! / reset_policy!: clears the run-once flag so clear_output! can be exercised again within the same process (a real run never needs this).
-
.reset_policy! ⇒ Object
Equivalent to
self.policy = nil; named for readableafterhooks that prevent a custom policy from leaking into later examples.
Class Method Details
.clear_output! ⇒ Object
Empties the output root once per process so a run's screenshots never mix with stale files left by a previous run. Meant to be wired into a before(:suite) hook by the host app (see the README); not called automatically, so nothing is registered on RSpec just by requiring the gem.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/capybara/storyboard.rb', line 44 def clear_output! # Run-once guard: idempotent even if the before(:suite) hook fires more # than once (e.g. one hook per RSpec process under parallel_tests). return if @output_cleared # Arm gate: same bare-SCREENSHOTS probe as default_policy's own gate # (EnvPolicy ignores its argument, so call(nil) is context-free). We # deliberately do NOT use configuration.policy here: a custom policy # assumes a per-example Context and may read the target list (raising # when SCREENSHOT_TESTS_FILE is bad). A suite-wide clear must key off # the global arm state alone, never per-example data. return unless Policies::EnvPolicy.new.call(nil) # Honor the run-once contract BEFORE touching the filesystem: if the # delete fails, we must not keep retrying (and re-deleting) on later # registrations of the same hook. @output_cleared = true # Resolve the root against the shared base so a relative output_dir # (kept relative by Configuration) maps to a single absolute target. root = configuration.output_dir.(rails_root_or_pwd) return unless safe_to_clear?(root) # First run / nothing captured yet: silently skip. Session#ensure_dir! # lazily recreates the tree on the first capture, so a missing root is # not an error. return unless root.exist? FileUtils.rm_rf(root) end |
.configuration ⇒ Object
The single Configuration holding user overrides (output root, policy).
16 17 18 |
# File 'lib/capybara/storyboard.rb', line 16 def configuration @configuration ||= Configuration.new end |
.configure {|configuration| ... } ⇒ Object
Yields the Configuration for block-style setup:
Capybara::Storyboard.configure { |config| config.output_dir = ... }
22 23 24 |
# File 'lib/capybara/storyboard.rb', line 22 def configure yield(configuration) end |
.default_policy ⇒ Object
The single place that builds the default policy. Internal API, public
only so Configuration#policy can call it without send; use policy.
When SCREENSHOTS is unset the mechanism is disarmed: return EnvPolicy alone WITHOUT touching the target list. This honors the "disabled -> nothing happens" contract even when SCREENSHOT_TESTS_FILE points at a missing file (its existence check must not blow up a disarmed suite).
When armed: no target list configured (neither ENV set) -> EnvPolicy alone, preserving the gist's "SCREENSHOTS=1 captures everything". A target list configured (even an empty file) -> EnvPolicy AND TargetListPolicy; an empty set then means "explicitly zero targets".
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/capybara/storyboard.rb', line 127 def default_policy env = Policies::EnvPolicy.new # env.call(nil) probes the bare SCREENSHOTS switch (same gate # clear_output! uses), inlined here so we can reuse this exact `env` # instance as the return value below instead of building a second one. # Disarmed -> skip reading/validating the target list entirely. return env unless env.call(nil) raw_targets = raw_target_list return env if raw_targets.nil? # Drop blank entries BEFORE normalizing: an empty string normalizes to # "." (the base dir), which is not blank and would leak into the set. targets = raw_targets.map { |path| path.to_s.strip }.compact_blank.map { |path| normalize_test_path(path) } target = Policies::TargetListPolicy.new(targets) # Composition style: a plain lambda. A proc responds to #call, so it # satisfies the #call(context) -> Boolean policy contract, and it can # still be replaced wholesale via #policy=. ->(context) { env.call(context) && target.call(context) } end |
.normalize_test_path(path) ⇒ Object
Normalizes a test file path to a base-relative string so that target
list entries and Context#test_file compare equal regardless of leading
./, absolute vs relative form, or surrounding whitespace/newlines.
Shared by default_policy (list side) and TargetListPolicy#call
(context side) so both sides always agree on the canonical form.
96 97 98 99 100 101 102 |
# File 'lib/capybara/storyboard.rb', line 96 def normalize_test_path(path) base = rails_root_or_pwd Pathname(path.to_s.strip) .(base) .relative_path_from(base) .to_s end |
.policy ⇒ Object
An object responding to #call(context) -> Boolean. Assign nil (or call reset_policy!) to restore the default. Delegated to the Configuration so there is a single source of truth.
77 78 79 |
# File 'lib/capybara/storyboard.rb', line 77 def policy configuration.policy end |
.policy=(value) ⇒ Object
81 82 83 |
# File 'lib/capybara/storyboard.rb', line 81 def policy=(value) configuration.policy = value end |
.rails_root_or_pwd ⇒ Object
The single place that resolves the base directory: Rails.root when available (the gem stays Rails-optional), else the current directory. Session#default_output_root joins its own subpath onto this.
107 108 109 110 111 112 113 |
# File 'lib/capybara/storyboard.rb', line 107 def rails_root_or_pwd if defined?(Rails) && Rails.respond_to?(:root) && Rails.root Rails.root else Pathname(Dir.pwd) end end |
.reset_configuration! ⇒ Object
Drops every override (output_dir and policy) in one shot, restoring the
gem's defaults. Handy in after hooks so a customized run never leaks
into later examples.
29 30 31 |
# File 'lib/capybara/storyboard.rb', line 29 def reset_configuration! @configuration = nil end |
.reset_output_cleared! ⇒ Object
Test-hygiene helper mirroring reset_configuration! / reset_policy!: clears the run-once flag so clear_output! can be exercised again within the same process (a real run never needs this).
36 37 38 |
# File 'lib/capybara/storyboard.rb', line 36 def reset_output_cleared! @output_cleared = nil end |
.reset_policy! ⇒ Object
Equivalent to self.policy = nil; named for readable after hooks that
prevent a custom policy from leaking into later examples.
87 88 89 |
# File 'lib/capybara/storyboard.rb', line 87 def reset_policy! configuration.reset_policy! end |