Class: Aaet::Android

Inherits:
Locators show all
Defined in:
lib/aaet/android/android.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Locators

#activity, #click, #displayed?, #element_center, #enter, #fa, #fe, #get_center, #get_text, #get_window_size, #long_press, #press, #pull_to_refresh, #random_tap, #swipe_down, #swipe_left, #swipe_right, #swipe_up, #tap, #tap2, #type

Constructor Details

#initialize(settings) ⇒ Android

Returns a new instance of Android.



10
11
12
13
14
15
16
17
18
# File 'lib/aaet/android/android.rb', line 10

def initialize settings
  generate_instance_variables nil, settings
  self.uuid = device[:uuid]
  self.dir = output_dir
  self.log = "exception-#{process}.log"
  self.exception_pattern = "FATAL EXCEPTION"
  self.redis = Aaet::Redis.new process
  remove_status_bar_and_notifications #show only the application in the window
end

Instance Attribute Details

#dirObject

Returns the value of attribute dir.



8
9
10
# File 'lib/aaet/android/android.rb', line 8

def dir
  @dir
end

#exception_patternObject

Returns the value of attribute exception_pattern.



8
9
10
# File 'lib/aaet/android/android.rb', line 8

def exception_pattern
  @exception_pattern
end

#logObject

Returns the value of attribute log.



8
9
10
# File 'lib/aaet/android/android.rb', line 8

def log
  @log
end

#redisObject

Returns the value of attribute redis.



8
9
10
# File 'lib/aaet/android/android.rb', line 8

def redis
  @redis
end

#uuidObject

Returns the value of attribute uuid.



8
9
10
# File 'lib/aaet/android/android.rb', line 8

def uuid
  @uuid
end

Instance Method Details

#adb_type(string) ⇒ Object

Force type keyboard when opened…



106
107
108
# File 'lib/aaet/android/android.rb', line 106

def adb_type string
  %x(adb -s #{uuid} shell input text "#{string}\n")
end

#back_buttonObject



57
58
59
60
# File 'lib/aaet/android/android.rb', line 57

def back_button
  puts "\nClicking Android Back Button!!!\n".red
  Appium::Common.back
end

#close_keyboardObject



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/aaet/android/android.rb', line 62

def close_keyboard
  #http://appium.readthedocs.io/en/latest/en/commands/device/keys/hide-keyboard/
  if keyboard_open?
    puts "\nClosing keyboard!!!\n"
    #back_button
    driver.hide_keyboard rescue nil
    sleep 1
    if keyboard_open? #sometimes keyboard doesn't close so try again...
      #back_button
      driver.hide_keyboard rescue nil
    end
  end
end

#close_permissions_dialog(act) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/aaet/android/android.rb', line 81

def close_permissions_dialog act
  if permission_dialog_displayed? act
    if act == "com.android.internal.app.ChooserActivity"
      back_button
    else
      puts "\nDetected Android Permissions/Chooser Dialog. Closing...\n".yellow
      fe({id: 'com.android.packageinstaller:id/permission_deny_button'}).click
    end
    sleep 1
  end
end

#cpuObject



127
128
129
130
131
# File 'lib/aaet/android/android.rb', line 127

def cpu
  cpu = %x(adb -s #{uuid} shell top -n 1 -d 1 | grep #{caps_appPackage} | awk '{print $3}').strip.chomp("%").to_i
  puts "Cpu: #{cpu}%"
  cpu
end

#dialog_buttonObject



39
40
41
# File 'lib/aaet/android/android.rb', line 39

def dialog_button
  ({id: "android:id/button1"})
end

#generate_instance_variables(parent, hash) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/aaet/android/android.rb', line 20

def generate_instance_variables(parent, hash)
  #turn options/settings nested hash into instance variables
  hash.each do |key, value|
    if value.is_a?(Hash)
      generate_instance_variables(key, value)
      self.class.send(:attr_accessor, key.to_sym)
      self.instance_variable_set("@#{key}", value)
    else
      if parent.nil?
        self.class.send(:attr_accessor, "#{key}".to_sym)
        self.instance_variable_set("@#{key}", value)
      else
        self.class.send(:attr_accessor, "#{parent}_#{key}".to_sym)
        self.instance_variable_set("@#{parent}_#{key}", value)
      end
    end
  end
end

#is_textfield?(locator) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/aaet/android/android.rb', line 93

def is_textfield? locator
  "android.widget.EditText" == locator
end

#keyboard_open?Boolean

Returns:

  • (Boolean)


97
98
99
100
101
102
103
# File 'lib/aaet/android/android.rb', line 97

def keyboard_open?
  #http://appium.readthedocs.io/en/latest/en/commands/device/keys/is-keyboard-shown/
  driver.is_keyboard_shown
  #%x(adb shell dumpsys input_method)[/mInputShown=\w+/i].split('=')[1] == 'true'
  #for iOS
  #driver.find_element(:xpath, '//UIAKeyboard').displayed?
end

#kill_emulator(emulator) ⇒ Object



151
152
153
# File 'lib/aaet/android/android.rb', line 151

def kill_emulator emulator
  system("adb -s #{emulator} emu kill")
end

#kill_everythingObject



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/aaet/android/android.rb', line 155

def kill_everything
  pid = Process.getpgid(Process.pid)
  Signal.trap('TERM') { Process.kill('TERM', -pid); exit }
  Signal.trap('INT' ) { Process.kill('INT',  -pid); exit }
  reset_status_bar
  sleep 1
  Process.kill("HUP", appium_pid)
  Process.kill("SIGKILL", @logcat_pid)
  #kill_process "#{uuid} logcat -v threadtime"
  #kill_emulator uuid if options_emulator and options_kill_emulator
end

#kill_process(process_name) ⇒ Object



147
148
149
# File 'lib/aaet/android/android.rb', line 147

def kill_process process_name
  `ps -ef | grep #{process_name} | awk '{print $2}' | xargs kill >> /dev/null 2>&1`
end

#logcatObject



133
134
135
136
# File 'lib/aaet/android/android.rb', line 133

def logcat
  %x(adb -s #{uuid} logcat -c)
  @logcat_pid = spawn("adb -s #{uuid} logcat *:E -v long", :out=>"#{dir}/#{log}")
end

#memoryObject



121
122
123
124
125
# File 'lib/aaet/android/android.rb', line 121

def memory
  memory = (%x(adb -s #{uuid} shell dumpsys meminfo | grep #{caps_appPackage} | awk '{print $1}').strip.split.last.to_i * 0.001).round(2)
  puts "Memory: #{memory} MB"
  memory
end

#permission_dialog_displayed?(act) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
79
# File 'lib/aaet/android/android.rb', line 76

def permission_dialog_displayed? act
  android_activities = ['.permission.ui.GrantPermissionsActivity', 'com.android.internal.app.ChooserActivity']
  android_activities.any?  { |a| a.include? act } rescue false
end

#process_running?(pid) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
141
142
143
144
145
# File 'lib/aaet/android/android.rb', line 138

def process_running? pid
  begin
    Process.getpgid(pid)
    true
  rescue Errno::ESRCH
    false
  end
end

#remove_status_bar_and_notificationsObject



43
44
45
46
47
48
49
50
51
# File 'lib/aaet/android/android.rb', line 43

def remove_status_bar_and_notifications
  unless options_cloud
    #https://android.gadgethacks.com/how-to/hide-navigation-status-bars-your-galaxy-s8-for-even-more-screen-real-estate-no-root-needed-0177297/
    puts "\nRemoving Top Status Bar from Device...\n".yellow
    %x(adb -s #{uuid} shell 'settings put global policy_control immersive.status=*')
    %x(adb -s #{uuid} shell 'appops set android POST_NOTIFICATION ignore')
    sleep 1
  end
end

#reset_status_barObject



53
54
55
# File 'lib/aaet/android/android.rb', line 53

def reset_status_bar
  %x(adb -s #{uuid} shell settings put global policy_control null*) rescue nil #put status bar back...
end

#start_logObject



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/aaet/android/android.rb', line 167

def start_log
  unless options_cloud
    logcat
    Process.fork do
      f = File.open("#{dir}/#{log}", "r")
      f.seek(0,IO::SEEK_END)
      while true
        break unless process_running? @logcat_pid
        select([f])
        if f.gets =~ /#{exception_pattern}/
          redis.app_crashed true
          puts "\n*******************  #{exception_pattern} DETECTED  *******************\nSHUTTING DOWN...\n".red
          sleep 3
          break
        end
      end
      f.close
      #binding.pry
      kill_everything
    end
  end
end

#system_statsObject



110
111
112
113
114
115
116
117
118
119
# File 'lib/aaet/android/android.rb', line 110

def system_stats
  unless options_cloud
    x = %x(adb -s #{uuid} shell top -n 1 -d 1 | grep System).split(",")
    user = x.find { |x| x.include? "User" }.match(/User (.*)%/)[1].to_i rescue 0
    sys  = x.find { |x| x.include? "System" }.match(/System (.*)%/)[1].to_i rescue 0
    # iow  = x.find { |x| x.include? "IOW" }.match(/IOW (.*)%/)[1].to_i
    # irq  = x.find { |x| x.include? "IRQ" }.match(/IRQ (.*)%/)[1].to_i
    { app_mem: memory, app_cpu: cpu, user: user, sys: sys }
  end
end