Class: Browserctl::Recording
- Inherits:
-
Object
- Object
- Browserctl::Recording
- Defined in:
- lib/browserctl/recording.rb
Constant Summary collapse
- RECORDINGS_DIR =
File.join(Dir.tmpdir, "browserctl-recordings")
- STATE_FILE =
File.("~/.browserctl/active_recording")
- RECORDABLE =
%w[open_page goto fill click screenshot evaluate].freeze
- SENSITIVE_PARAM_PATTERN =
/\A(token|key|secret|auth|code|access_token|api_key|client_secret|state)\z/ix
Class Method Summary collapse
- .active ⇒ Object
- .append(cmd, **attrs) ⇒ Object
- .generate_workflow(name, output_path: nil) ⇒ Object
- .start(name) ⇒ Object
- .stop ⇒ Object
Class Method Details
.active ⇒ Object
36 37 38 |
# File 'lib/browserctl/recording.rb', line 36 def self.active File.exist?(STATE_FILE) ? File.read(STATE_FILE).strip : nil end |
.append(cmd, **attrs) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/browserctl/recording.rb', line 40 def self.append(cmd, **attrs) name = active return unless name return unless RECORDABLE.include?(cmd.to_s) if %w[click fill].include?(cmd.to_s) && attrs[:selector].nil? record_ref_interaction(name, cmd.to_s, attrs) return end attrs = prepare_attrs(cmd.to_s, attrs) File.open(log_path(name), "a") do |f| f.puts JSON.generate({ cmd: cmd.to_s }.merge(attrs.transform_keys(&:to_s))) end end |
.generate_workflow(name, output_path: nil) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/browserctl/recording.rb', line 57 def self.generate_workflow(name, output_path: nil) log = log_path(name) raise "no recording found for '#{name}'" unless File.exist?(log) lines = File.readlines(log).map { |l| JSON.parse(l, symbolize_names: true) } ruby = build_workflow_ruby(name, lines) File.write(output_path, ruby) if output_path ref_count = lines.count { |l| l[:cmd] == "_ref_interaction" } if ref_count.positive? warn "Warning: #{ref_count} ref-based interaction(s) were captured but cannot be replayed by ref." warn "Search the generated workflow for 'TODO: ref-based' and replace with stable CSS selectors." end ruby ensure FileUtils.rm_f(log) if log end |
.start(name) ⇒ Object
18 19 20 21 22 23 24 25 26 |
# File 'lib/browserctl/recording.rb', line 18 def self.start(name) FileUtils.mkdir_p(RECORDINGS_DIR, mode: 0o700) FileUtils.mkdir_p(File.dirname(STATE_FILE)) File.write(STATE_FILE, name) FileUtils.rm_f(log_path(name)) FileUtils.touch(log_path(name)) File.chmod(0o600, log_path(name)) name end |
.stop ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/browserctl/recording.rb', line 28 def self.stop name = active raise "no active recording — run: browserctl record start <name>" unless name File.unlink(STATE_FILE) name end |