Class: Browserctl::Recording

Inherits:
Object
  • Object
show all
Defined in:
lib/browserctl/recording.rb

Constant Summary collapse

RECORDINGS_DIR =
File.join(Dir.tmpdir, "browserctl-recordings")
STATE_FILE =
File.expand_path("~/.browserctl/active_recording")
RECORDABLE =
%w[open_page goto fill click screenshot evaluate].freeze

Class Method Summary collapse

Class Method Details

.activeObject



31
32
33
# File 'lib/browserctl/recording.rb', line 31

def self.active
  File.exist?(STATE_FILE) ? File.read(STATE_FILE).strip : nil
end

.append(cmd, **attrs) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/browserctl/recording.rb', line 35

def self.append(cmd, **attrs)
  name = active
  return unless name
  return unless RECORDABLE.include?(cmd.to_s)
  # ref-based interactions have no replayable selector — skip them
  return if %w[click fill].include?(cmd.to_s) && attrs[:selector].nil?

  attrs = attrs.except(:value) if cmd.to_s == "fill"

  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



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/browserctl/recording.rb', line 49

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
  ruby
ensure
  FileUtils.rm_f(log) if log
end

.start(name) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/browserctl/recording.rb', line 15

def self.start(name)
  FileUtils.mkdir_p(RECORDINGS_DIR)
  FileUtils.mkdir_p(File.dirname(STATE_FILE))
  File.write(STATE_FILE, name)
  FileUtils.rm_f(log_path(name))
  name
end

.stopObject



23
24
25
26
27
28
29
# File 'lib/browserctl/recording.rb', line 23

def self.stop
  name = active
  raise "no active recording — run: browserctl record start <name>" unless name

  File.unlink(STATE_FILE)
  name
end