Class: UIRecorder

Inherits:
Object
  • Object
show all
Includes:
WDAUIParser
Defined in:
lib/uirecorder/wda_ui_parser.rb,
lib/uirecorder.rb,
lib/uirecorder/version.rb

Overview

Created by Yi MIN<[email protected]> 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

Defined Under Namespace

Modules: WDAUIParser

Constant Summary collapse

VERSION =
"0.1.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from WDAUIParser

#go_to_path, #keyboard_nodes_rawIdentifier, #path_arr, #path_chop, #tree_node_template, #wda_dup_node

Constructor Details

#initialize(opts = {}) ⇒ UIRecorder

Returns a new instance of UIRecorder.



26
27
28
29
30
31
32
33
34
35
36
37
38
# 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

Instance Attribute Details

#driverObject

Returns the value of attribute driver.



22
23
24
# File 'lib/uirecorder.rb', line 22

def driver
  @driver
end

#element_countObject

Returns the value of attribute element_count.



23
24
25
# File 'lib/uirecorder.rb', line 23

def element_count
  @element_count
end

#exclude_typeObject

Returns the value of attribute exclude_type.



22
23
24
# File 'lib/uirecorder.rb', line 22

def exclude_type
  @exclude_type
end

#keyboard_pathObject (readonly)

Returns the value of attribute keyboard_path.



24
25
26
# File 'lib/uirecorder.rb', line 24

def keyboard_path
  @keyboard_path
end

#page_hashObject

Returns the value of attribute page_hash.



22
23
24
# File 'lib/uirecorder.rb', line 22

def page_hash
  @page_hash
end

#save_file_pathObject

Returns the value of attribute save_file_path.



22
23
24
# File 'lib/uirecorder.rb', line 22

def save_file_path
  @save_file_path
end

#skip_keyboardObject

Returns the value of attribute skip_keyboard.



22
23
24
# File 'lib/uirecorder.rb', line 22

def skip_keyboard
  @skip_keyboard
end

Instance Method Details

#check_statusObject



101
102
103
104
105
106
107
108
109
110
# 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) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 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_parserObject



40
41
42
43
44
45
46
47
48
49
50
# 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_pageObject



98
99
# File 'lib/uirecorder.rb', line 98

def last_page
end

#new_suggested_nameObject



82
83
84
# 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_pageObject



95
96
# File 'lib/uirecorder.rb', line 95

def next_page
end

#record_page(page_file_name = nil, parser = nil) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 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_nameObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# 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_nameObject



86
87
88
89
90
91
92
93
# 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