class UIRecorder

Created by Yi MIN<minsparky@gmail.com> Copyright © 2017 Yi MIN. All rights reserved.

Example of screen page elememts tree:

                        tree_node             ----Hash  deep 0  path = 0
                            |
                 _______children________      ----Array
                /   /   /   |   \   \   \
               o   o   o    o   o    o   o    ----Hash  deep 1  path = 0/0 0/1 0/2 0/3 0/4 0/5 0/6 
              /             |       / \   \
       ___children___       c      c   c  c   ----Array
      /   /  |   \   \     / \    /\   |  |
     o   o   o    o   o   o  o   o o   o  o   ----Hash  deep 2  path = 0/0/0 0/0/1 0/0/2 0/0/3 0/0/4 0/0/5 
    /                              |      |
children                           c      c   ----Array
 / |                               |      |
o  o                               o      o   ----Hash  deep = 3  path = 0/0/0/0 0/0/0/1

Constants

VERSION

Attributes

driver[RW]
element_count[RW]
exclude_type[RW]
keyboard_path[R]
page_hash[RW]
save_file_path[RW]
skip_keyboard[RW]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/uirecorder.rb, line 26
def initialize(opts = {})
  @driver = opts.fetch :driver
  @driver_type = opts.fetch :driver_type, @driver.class  #Support WDA, later for Appium/Selenium
  @page_hash = opts.fetch :page_hash, nil
  @save_file_path = opts.fetch :save_file_path, nil
  @skip_keyboard = opts.fetch :skip_keyboard, true
  @exclude_type = opts.fetch :exclude_type, []
  @show_invisible_element = opts.fetch :show_invisible_element, false
  @show_inaccessible_element = opts.fetch :show_inaccessible_element, false  # Has bug, to be fixed in wda_lib
  @custom_page_file = opts.fetch :custom_page_file, './template.yml'
  @keyboard_path = ''
  @logger = Logger.new('./tmp/uirecorder.log', 0, 1 * 1024 * 1024) # Start the log over whenever the log exceeds 1 megabytes in size.
end

Public Instance Methods

check_status() click to toggle source
# File lib/uirecorder.rb, line 101
def check_status
  case @driver_type.to_s
  when 'WDA'
    return (@driver.status['status'] == 0)? true : false
  when 'Appium'
  when 'Selenium'
  else
    return true
  end
end
current_page(visible = true, accessible = false) click to toggle source
# File lib/uirecorder.rb, line 52
def current_page(visible = true, accessible = false)
  visible = !@show_invisible_element
  accessible = @show_inaccessible_element
  @logger.debug "Getting current page UI elements..."
  case @driver_type.to_s
  when 'WDA'
    begin
      page = @driver.source(nil, accessible, visible)
      page.delete('sessionId')
      page.delete('status')
    rescue => e
      @logger.error "Failed to get current page's elements, error: #{e}"
    end
    File.open('./tmp/page_elements_tmp.yml', 'wb') do |f|
      f.write(page.to_yaml)
    end
    return page
  when 'Appium'
  when 'Selenium'
  when 'String'
    begin
      page = YAML.load_file(@driver)
    rescue => e
      @logger.error "Failed to load page's elements from #{@driver}, error: #{e}"
    end        
    return page
  else 
  end
end
init_tree_parser() click to toggle source
# File lib/uirecorder.rb, line 40
def init_tree_parser
  @parsed_nodes = Hash.new
  @children_tree = Array.new
  @parent_node = Array.new
  @children_node_index = 0
  @deep_level = 0
  @path = ''
  @parse_count = 1
  @total_elements_count = 0
  @saved_elements_count = 0
end
last_page() click to toggle source
# File lib/uirecorder.rb, line 98
def last_page
end
new_suggested_name() click to toggle source
# File lib/uirecorder.rb, line 82
def new_suggested_name
  @suggested_name.nil?? use_element_label_as_screen_name : @suggested_name = "#{rand(1..100)}.yml"
end
next_page() click to toggle source
# File lib/uirecorder.rb, line 95
def next_page
end
record_page(page_file_name = nil, parser = nil) click to toggle source
# File lib/uirecorder.rb, line 127
def record_page(page_file_name = nil, parser = nil)
  if check_status
    @page_elements = current_page
    @driver_type = parser unless parser.nil?
    case @driver_type.to_s
    when 'WDA'
      init_tree_parser
      @page_elements = @page_elements['value']['tree'] # Get elements tree
      wda_dup_node(@page_elements)
    when 'Appium'
    when 'Selenium'
    end
    page_hash = Digest::SHA256.hexdigest(@parsed_nodes.keys.join('/'))
    @parsed_nodes.merge!('total_elements_count' => @total_elements_count, 'page_hash' => page_hash, 'element_count' => @saved_elements_count)
    if !page_file_name.nil?
      @save_file_path = page_file_name
    else
      @save_file_path = refine_save_file_name
    end
    @logger.debug "Saving elements tree to #{page_file_name}"
    File.open(@save_file_path, 'wb') do |f|
      f.write(@parsed_nodes.to_yaml)
    end
    @logger.debug "Current page UI elements are saved in #{page_file_name}"
  else
    @logger.debug "#{@driver_type} device is not available, please check it!"
  end
end
refine_save_file_name() click to toggle source
# File lib/uirecorder.rb, line 112
def refine_save_file_name
  while @save_file_path.nil?
    puts "You haven't given the name for this screen, does #{use_element_label_as_screen_name} sounds good for you?\n(Yes/No) or give yours:"
    input_name = $stdin.gets.chomp
    case input_name.downcase
    when 'yes', 'y'
      @save_file_path = @suggested_name
    when 'no', 'n'
      use_element_label_as_screen_name
    else 
      @save_file_path = input_name
    end
  end
end
use_element_label_as_screen_name() click to toggle source
# File lib/uirecorder.rb, line 86
def use_element_label_as_screen_name
  node_key = @parsed_nodes.keys.sample
  while @parsed_nodes[node_key]['label'].nil? && @parsed_nodes[node_key]['name'].nil?
    node_key = @parsed_nodes.keys.sample
  end
  @suggested_name = @parsed_nodes[node_key]['label'] || @parsed_nodes[node_key]['name']
  @suggested_name = @suggested_name.downcase.gsub(' ','_').gsub(',','').gsub('(#', '').gsub(')', '').gsub(/[\x00\/\\:\*\?\'\"<>\|\s]/, '_')
end