class AtspiAppDriver

Test driver for the Atspi-enabled applications. Takes care of boot and shutdown, and provides a handle on the GUI's main UI frame.

Attributes

application[R]
frame[R]

Public Class Methods

new(app_name, app_file: nil, verbose: false) click to toggle source
# File lib/atspi_app_driver.rb, line 40
def initialize(app_name, app_file: nil, verbose: false)
  @app_file = app_file || "bin/#{app_name}"
  @lib_dir = "lib"
  @app_name = app_name
  @pid = nil
  @verbose = verbose
  @frame = nil
  @thread = nil
end

Public Instance Methods

boot(test_timeout: 30, exit_timeout: 10, arguments: []) click to toggle source
# File lib/atspi_app_driver.rb, line 52
def boot(test_timeout: 30, exit_timeout: 10, arguments: [])
  raise "Already booted" if @pid

  spawn_process(arguments)

  @cleanup = false

  @frame = find_and_focus_frame

  @thread = Thread.new do
    wait_for("test to be done", test_timeout) { @cleanup }
    wait_for("pid to go away", exit_timeout) { !@pid }
    kill_process if @pid
  end
end
cleanup() click to toggle source
# File lib/atspi_app_driver.rb, line 74
def cleanup
  status = exit_status
  @pid = nil
  @thread&.join
  status
end
spawn_process(arguments) click to toggle source
# File lib/atspi_app_driver.rb, line 68
def spawn_process(arguments)
  command = "ruby -I#{@lib_dir} #{@app_file} #{arguments.join(' ')}"
  log "About to spawn: `#{command}`"
  @pid = Process.spawn command
end

Private Instance Methods

exit_status() click to toggle source
# File lib/atspi_app_driver.rb, line 130
def exit_status
  return unless @pid

  @cleanup = true
  _, status = Process.wait2 @pid
  status
end
find_and_focus_frame() click to toggle source
# File lib/atspi_app_driver.rb, line 83
def find_and_focus_frame
  @application = wait_for("app to appear", 10) { find_app }
  raise "App not found" unless @application

  frame = @application.get_child_at_index 0
  role = frame.role
  raise "Frame has unexpected role #{role.inspect}" unless role == :frame

  wait_for("frame to be focused", 10) do
    frame.get_state_set.get_states.to_a.include? :active
  end

  frame
end
find_app() click to toggle source
# File lib/atspi_app_driver.rb, line 107
def find_app
  desktop = Atspi.get_desktop(0)
  desktop.each_child do |child|
    return child if child.name == @app_name
  end
  nil
end
kill_process() click to toggle source
# File lib/atspi_app_driver.rb, line 98
def kill_process
  log "About to kill child process #{@pid}"
  Process.kill "KILL", @pid
end
log(message) click to toggle source
# File lib/atspi_app_driver.rb, line 103
def log(message)
  warn message if @verbose
end
wait_for(description, _timeout) { || ... } click to toggle source

TODO: Use timeout

# File lib/atspi_app_driver.rb, line 116
def wait_for(description, _timeout)
  start = Time.now
  result = nil
  # Try for 0.01 * 50 * (50 + 1) / 2 = 12.75 seconds
  50.times do |num|
    result = yield
    break if result

    sleep 0.01 * (num + 1)
  end
  log "Waited #{Time.now - start} seconds for #{description}"
  result
end