class Aaet::Common
Attributes
applitools[RW]
count[RW]
dir[RW]
execute[RW]
parser[RW]
redis[RW]
tests[RW]
uuid[RW]
wait_for_element[RW]
Public Class Methods
new(settings)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 14 def initialize settings generate_instance_variables nil, settings #Applitools only runs on crawler mode... if options[:mode] == "crawler" if options_applitools self.applitools = Aaet::ApplitoolEyes.new settings self.tests = applitools.tests print_debug "\nApplitools Tests:".green ap tests if options_debug print_debug "\n" end end self.count = "%03d" % 1 self.redis = Aaet::Redis.new process if caps_platform == "android" self.execute = Aaet::Android.new settings self.parser = Aaet::AndroidParser.new elsif caps_platform == "ios" self.execute = Aaet::Ios.new settings #placeholder for iOS self.parser = Aaet::IosParser.new end self.wait_for_element = 10 self.dir = output_dir if options_cloud self.uuid = "#{cloud_service}-#{caps_deviceName.gsub(" ","_")}" else self.uuid = device[:uuid] end @window_size = driver.manage.window.size.to_a end
Public Instance Methods
accept_dialog()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 251 def accept_dialog #maybe override this with appium capability to auto accept dialogs. Undecieded about it, though... click execute.dialog_button if dialog_displayed? end
applitools_results(results, test)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 136 def applitools_results results, test hash = { test: test, failed: results.failed?, passed: results.passed?, new: results.new?, url: results.url } #redis.update_list "applitools_results", hash redis.update_applitools "applitools_results", hash end
back_locator_displayed?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 498 def back_locator_displayed? locators = config_backLocators.map { |h| h.map { |k,v| v } }.flatten rescue [] false if locators.empty? locators.shuffle.each do |locator| if displayed? locator print_debug "\n#{uuid}: Tapping Back Locator: #{locator}\n".yellow @back_locator = locator return true else return false end end end
been_clicked?(clicked_list, e)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 521 def been_clicked?(clicked_list, e) #add a weighted selection on how many clicks have occured... clicked = clicked_list.find do |x| x[:index] == e[:index] and x[:class] == e[:class] and x[:package] == e[:package] and x[:checkable] == e[:checkable] and #x[:checked] == e[:checked] and x[:clickable] == e[:clickable] and x[:focusable] == e[:focusable] and x[:focused] == e[:focused] and x[:scrollable] == e[:scrollable] and x[:long_clickable] == e[:long_clickable] and #x[:selected] == e[:selected] and x[:bounds] == e[:bounds] and x[:id] == e[:id] and x[:instance] == e[:instance] and x[:clickable] == e[:clickable] and x[:enabled] == e[:enabled] and x[:activity] == e[:activity] end @click_count = clicked[:click_count] rescue 0 begin clicked.any? @has_clicked = true rescue @has_clicked = false false end end
check_replay_element_values(step)
click to toggle source
TODO: Return boolean if replay step is displayed… use this to debug replay values
# File lib/aaet/common/common_methods.rb, line 326 def check_replay_element_values step element_values = [] [:bounds, :id, :accessibilty_label].each do |key| next if step[key].nil? if [:id, :accessibilty_label].include? key element = fe({id: step[key]}) else element = fe({xpath: "//#{step[:class]}[@bounds='#{step[:bounds]}']"}) end next if element.nil? location = element.location size = element.size element_values << { locator_used: key, element: element, location: location.to_h, step_location: step[:location], center: element_center(location, size), step_center: step[:center], step_id: step[:id], step_accessibilty_label: step[:accessibilty_label], step_bounds: step[:bounds] } end element_values end
click_dialog?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 272 def click_dialog? if dialog_displayed? if dialog_count >= 3 print_debug "#{uuid}: Clicking OK on Dialog!!!" accept_dialog reset_dialog_count else print_debug "#{uuid}: Skipping Dialog click..." increment_dialog_count return end else reset_dialog_count end end
clicked_before?(e)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 512 def clicked_before?(e) #center may change if scrolling is enabled. cant use accessibility label because that can change... clicked = clicked_elements.find { |c| c[:id] == e[:id] and c[:size] == e[:size] and c[:center] == e[:center] and c[:activity] == e[:activity] and c[:class] == e[:class] } @click_count = clicked[:click_count] rescue 0 clicked.any? rescue false end
clicked_elements()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 104 def clicked_elements redis.get_list "clicked" end
close_keyboard()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 234 def close_keyboard execute.close_keyboard if execute.keyboard_open? end
collect_chaos_performance(body)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 300 def collect_chaos_performance body redis.update_list "chaos", body end
crawler()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 552 def crawler print_debug "\n#{uuid}: Starting!!!\n".green take_screenshot? relaunch_app? login_page? current_activity = activity print_debug "#{uuid}: Current Activity: #{current_activity}" #binding.pry objects = get_elements current_activity if objects.empty? if current_activity != homeActivity[:activity] execute.back_button else relaunch_app end return end catch(:stop) do print_debug "#{uuid}: Objects Count: #{objects.count}\n" objects.each_with_index do |o,oi| print_debug "\n#{uuid}: INDEX: #{oi}\nOBJECT: #{o}\n" e = get_element_attributes(o) next if e.nil? or dont_click.include? e[:id] print_debug "\n#{uuid}: Using Element: #{e}\n" e[:page_changed] = false if e[:click_count] >= settings[:click_count] if oi == objects.size - 1 if back_locator_displayed? e = get_element_attributes(@back_locator) #reset element to config_backLocators attributes... been_clicked?(clicked_elements, e) e.merge!({click_count: @click_count, activity: o[:activity], page: o[:page]}) #merge object attributes into e. else #this logic will need to change for iOS unless we can create a method to simulate a back button like android has... e = { click_count: 0, class: nil, text: nil, location: nil, center: nil, element: nil, id: "force-tap-back" } e.merge!({activity: o[:activity], page: o[:page]}) #merge object attributes into e. end else print_debug "\n#{uuid}: Skipping Element: #{e}".yellow print_debug "#{uuid}: I've tapped this Locator #{@click_count} times before...\n".yellow next end end e[:clicked] = true #store clicked element in case app crashes when clicked. #TODO: Set rules hash on click counts by locator class. e.g. textfield, button etc... if e[:class] == "android.widget.EditText" #only click textfields once e[:click_count] = 3 else e[:click_count] = e[:click_count] + 1 end if e[:dialog] e[:click_count] = 0 end e[:time] = Time.now store_clicked_element e if e[:id] == "force-tap-back" execute.back_button; sleep 0.2 if e[:page] == md5_page_source #at a last resort relaunch the app... print_debug "\n#{uuid}: Stuck on the same view/page. Getting outta here...\n".red relaunch_app end else click e[:element] end sleep 0.2 e[:typed] = type_if_keyboard_is_open if page_changed? e remove_clicked_element e[:page_changed] = true e[:performance] = Thread.new { execute.system_stats }.value e[:new_activity] = new_activity(e[:activity]) e[:new_page] = md5_page_source store_clicked_element e throw :stop end end end end
dialog_count()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 264 def dialog_count redis.hget("dialog", "count").to_i end
dialog_displayed?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 247 def dialog_displayed? displayed? execute.dialog_button end
diff_actvity_elements(old_page, new_page)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 417 def diff_actvity_elements old_page, new_page a = old_page.map { |x| { id: x[:id], label: x[:accessibilty_label] } }.uniq b = new_page.map { |x| { id: x[:id], label: x[:accessibilty_label] } }.uniq ( b - a ) end
dont_click()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 423 def dont_click config_doNotClick.map { |h| h.map { |k,v| v.values } }.flatten rescue [] end
fix_orientation(rotation)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 437 def fix_orientation rotation #TODO: Since parser.page tells the orientation we can do something with it.... if config[:caps][:caps][:orientation] == "PORTRAIT" orientation = 0 else orientation = 1 end set_orientation = config[:caps][:caps][:orientation].downcase.to_sym driver.rotate(set_orientation) if orientation != rotation end
generate_instance_variables(parent, hash)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 51 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
get_element_attributes(object)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 473 def get_element_attributes object locator = object[:accessibilty_label] || object[:id] #use accessibility label first and then id if available if locator.nil? element = fe({xpath: "//#{object[:class]}[@bounds='#{object[:bounds]}']"}) else element = fe({id: locator}) end return if element.nil? location = element.location rescue nil return if location.nil? or outside_screen_boundaries?(@window_size.to_a, location.to_a) displayed = element.displayed? rescue false return unless displayed size = element.size { location: location.to_h, displayed: displayed, window_size: @window_size, center: element_center(location, size), element: element, size: size.to_h }.merge!(object) end
get_elements(page_objects = parser.page, act)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 448 def get_elements page_objects = parser.page, act print_debug "\n#{uuid}: Getting page elements..." md5 = md5_page_source a = act elements = [] dialog = dialog_displayed? rotation = page_objects[0][:rotation].to_i page_objects.each do |o| next unless (o[:enabled] and o[:clickable]) o[:dialog] = false if o[:dialog].nil? elements << { activity: a, page: md5, dialog_displayed: dialog, rotation: rotation }.merge!(o) end elements = elements.uniq update_element_list a, elements page_text = page_objects.map { |t| t[:text] }.compact.reject { |e| e.empty? } store_page_text([{activity: a, page: md5, text: page_text}]) accessibility_labels = page_objects.map { |l| l[:accessibilty_label] }.compact.reject { |e| e.empty? } store_accessibility_labels([{activity: a, page: md5, text: accessibility_labels}]) objects = [] clicked_list = clicked_elements elements.each { |e| been_clicked?(clicked_list, e); objects << e.merge!({click_count: @click_count, clicked_before: @has_clicked}) } objects.shuffle.sort_by { |x| x[:click_count] } end
has_uploaded?(test)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 131 def has_uploaded? test #redis.list_includes_value "applitools", test redis.list_includes_applitools_value "applitools", test end
increment_dialog_count()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 260 def increment_dialog_count redis.hincr("dialog","count") end
is_test?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 142 def is_test? print_debug "#{uuid}: Checking for Applitool test..." do_not_upload = tests.find_all { |test| test[:name] == "do_not_upload" }[0].select { |loc| loc if loc != :name } rescue [] current_activity_tests = tests.find_all { |test| test[:activity] == activity } rescue [] if displayed?(do_not_upload) #skip if do_not_upload locator displayed... false else if current_activity_tests.empty? false else current_activity_tests.each do |test| #store screenshot name in redis if pushed to applitools so not to get duplicates. locator = Hash[*test.to_a[2]] unless fe(locator).nil? or get_text(test[:text]).nil? test_name = "#{test[:name]}-#{device_resolution}" unless has_uploaded? test_name print_debug "\n#{uuid}: Uploading test '#{test_name}' to Applitools!\n".yellow applitools.upload_to_applitools caps_appPackage, test_name, test[:text] results = applitools.close_eyes applitools_results results, test_name uploaded_to_applitools test_name #TODO: create a method to shutdown after test count matches redis completed test count... #redis.hincr("applicount", "count") end end end end end end
login()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 82 def login puts "#{uuid}: ON THE LOGIN PAGE. I WILL LOGIN NOW!!!" config_loginPage[0][:steps].each do |step| driver.wait(config_loginPage[0][:maxWaitBetweenSteps]) { fe({:"#{step[1]}"=>step[2]}) } print_debug "action: #{step[0]}, locator: :#{step[1]}=>#{step[2]}, text: #{step[3]}" self.send(step[0], fe({:"#{step[1]}"=>step[2]}), step[3]) execute.close_keyboard if execute.keyboard_open? sleep 5 end wait_for_home_screen #set_screen_boudaries end
login_page?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 74 def login_page? print_debug "#{uuid}: Checking if on Login page..." login_hash = config[:loginPage] rescue {} if login_hash.any? login if (activity == login_hash[0][:activity]) end end
md5_page_source()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 216 def md5_page_source print_debug "MD5'ing the Page Source..." #Can also maybe use get_page_class to distinguish between pages... Digest::MD5.hexdigest(get_source) end
monkey()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 304 def monkey login_page? relaunch_app? #binding.pry action = weighted_actions if action == "buttons" b = buttons unless b.empty? print_debug "#{uuid}: Clicking random button...".yellow begin b.sample.click rescue nil end end elsif action == "back" execute.back_button unless activity == homeActivity[:activity] else self.send(action) end sleep 0.3 #TODO: collect_chaos_performance({time: Time.now, performance: Thread.new { execute.system_stats }.value}) end #TODO: Return boolean if replay step is displayed... #use this to debug replay values def check_replay_element_values step element_values = [] [:bounds, :id, :accessibilty_label].each do |key| next if step[key].nil? if [:id, :accessibilty_label].include? key element = fe({id: step[key]}) else element = fe({xpath: "//#{step[:class]}[@bounds='#{step[:bounds]}']"}) end next if element.nil? location = element.location size = element.size element_values << { locator_used: key, element: element, location: location.to_h, step_location: step[:location], center: element_center(location, size), step_center: step[:center], step_id: step[:id], step_accessibilty_label: step[:accessibilty_label], step_bounds: step[:bounds] } end element_values end def replay last_run_steps.each do |step| #take_screenshot #not yet implemented logic yet to store screenshots in new location. relaunch_app? login_page? locator = step[:accessibilty_label] || step[:id] if locator.nil? wait(wait_for_element) { fe({xpath: "//#{step[:class]}[@bounds='#{step[:bounds]}']"}) } rescue nil #will wait if element exists... element = fe({xpath: "//#{step[:class]}[@bounds='#{step[:bounds]}']"}) else wait(wait_for_element) { fe({id: locator}) } rescue nil #will wait if element exists... element = fe({id: locator}) end print_debug "\n#{uuid}: Last Run Step: #{step}\n" print_debug "" #binding.pry #check_replay_element_values step if step[:id] == "force-tap-back" execute.back_button else element.click end if execute.keyboard_open? and step[:typed] print_debug "\n#{uuid}: Typying Last Run Text: #{step[:typed]}\n" type "#{step[:typed]}\n" close_keyboard else type_if_keyboard_is_open end sleep 0.5 #step[:performance] = Thread.new { execute.system_stats }.value #To compare peformance from last test run... end sleep 5 #wait for a crash to happen end def new_activity current_activity if activity == current_activity nil else activity end end def update_element_list act, elements if redis.activity_exists? act old_elements = redis.get_list(act) new_elements = elements diff = diff_actvity_elements(old_elements, new_elements) rescue [] unless diff.empty? redis.del_list activity select_elements = new_elements.select { |e| diff.map { |x| x[:id] }.include? e[:id] } redis.update_list activity, (old_elements + select_elements) end redis.update_activity_count act end end def diff_actvity_elements old_page, new_page a = old_page.map { |x| { id: x[:id], label: x[:accessibilty_label] } }.uniq b = new_page.map { |x| { id: x[:id], label: x[:accessibilty_label] } }.uniq ( b - a ) end def dont_click config_doNotClick.map { |h| h.map { |k,v| v.values } }.flatten rescue [] end def store_page_text body print_debug "\n#{uuid}: Storing Page Text: #{body}\n" redis.update_list "page_text", body end def store_accessibility_labels body print_debug "\n#{uuid}: Storing Accessibility Labels: #{body}\n" redis.update_list "accessibility_labels", body end def fix_orientation rotation #TODO: Since parser.page tells the orientation we can do something with it.... if config[:caps][:caps][:orientation] == "PORTRAIT" orientation = 0 else orientation = 1 end set_orientation = config[:caps][:caps][:orientation].downcase.to_sym driver.rotate(set_orientation) if orientation != rotation end def get_elements page_objects = parser.page, act print_debug "\n#{uuid}: Getting page elements..." md5 = md5_page_source a = act elements = [] dialog = dialog_displayed? rotation = page_objects[0][:rotation].to_i page_objects.each do |o| next unless (o[:enabled] and o[:clickable]) o[:dialog] = false if o[:dialog].nil? elements << { activity: a, page: md5, dialog_displayed: dialog, rotation: rotation }.merge!(o) end elements = elements.uniq update_element_list a, elements page_text = page_objects.map { |t| t[:text] }.compact.reject { |e| e.empty? } store_page_text([{activity: a, page: md5, text: page_text}]) accessibility_labels = page_objects.map { |l| l[:accessibilty_label] }.compact.reject { |e| e.empty? } store_accessibility_labels([{activity: a, page: md5, text: accessibility_labels}]) objects = [] clicked_list = clicked_elements elements.each { |e| been_clicked?(clicked_list, e); objects << e.merge!({click_count: @click_count, clicked_before: @has_clicked}) } objects.shuffle.sort_by { |x| x[:click_count] } end def get_element_attributes object locator = object[:accessibilty_label] || object[:id] #use accessibility label first and then id if available if locator.nil? element = fe({xpath: "//#{object[:class]}[@bounds='#{object[:bounds]}']"}) else element = fe({id: locator}) end return if element.nil? location = element.location rescue nil return if location.nil? or outside_screen_boundaries?(@window_size.to_a, location.to_a) displayed = element.displayed? rescue false return unless displayed size = element.size { location: location.to_h, displayed: displayed, window_size: @window_size, center: element_center(location, size), element: element, size: size.to_h }.merge!(object) end def back_locator_displayed? locators = config_backLocators.map { |h| h.map { |k,v| v } }.flatten rescue [] false if locators.empty? locators.shuffle.each do |locator| if displayed? locator print_debug "\n#{uuid}: Tapping Back Locator: #{locator}\n".yellow @back_locator = locator return true else return false end end end def clicked_before?(e) #center may change if scrolling is enabled. cant use accessibility label because that can change... clicked = clicked_elements.find { |c| c[:id] == e[:id] and c[:size] == e[:size] and c[:center] == e[:center] and c[:activity] == e[:activity] and c[:class] == e[:class] } @click_count = clicked[:click_count] rescue 0 clicked.any? rescue false end def been_clicked?(clicked_list, e) #add a weighted selection on how many clicks have occured... clicked = clicked_list.find do |x| x[:index] == e[:index] and x[:class] == e[:class] and x[:package] == e[:package] and x[:checkable] == e[:checkable] and #x[:checked] == e[:checked] and x[:clickable] == e[:clickable] and x[:focusable] == e[:focusable] and x[:focused] == e[:focused] and x[:scrollable] == e[:scrollable] and x[:long_clickable] == e[:long_clickable] and #x[:selected] == e[:selected] and x[:bounds] == e[:bounds] and x[:id] == e[:id] and x[:instance] == e[:instance] and x[:clickable] == e[:clickable] and x[:enabled] == e[:enabled] and x[:activity] == e[:activity] end @click_count = clicked[:click_count] rescue 0 begin clicked.any? @has_clicked = true rescue @has_clicked = false false end end def crawler print_debug "\n#{uuid}: Starting!!!\n".green take_screenshot? relaunch_app? login_page? current_activity = activity print_debug "#{uuid}: Current Activity: #{current_activity}" #binding.pry objects = get_elements current_activity if objects.empty? if current_activity != homeActivity[:activity] execute.back_button else relaunch_app end return end catch(:stop) do print_debug "#{uuid}: Objects Count: #{objects.count}\n" objects.each_with_index do |o,oi| print_debug "\n#{uuid}: INDEX: #{oi}\nOBJECT: #{o}\n" e = get_element_attributes(o) next if e.nil? or dont_click.include? e[:id] print_debug "\n#{uuid}: Using Element: #{e}\n" e[:page_changed] = false if e[:click_count] >= settings[:click_count] if oi == objects.size - 1 if back_locator_displayed? e = get_element_attributes(@back_locator) #reset element to config_backLocators attributes... been_clicked?(clicked_elements, e) e.merge!({click_count: @click_count, activity: o[:activity], page: o[:page]}) #merge object attributes into e. else #this logic will need to change for iOS unless we can create a method to simulate a back button like android has... e = { click_count: 0, class: nil, text: nil, location: nil, center: nil, element: nil, id: "force-tap-back" } e.merge!({activity: o[:activity], page: o[:page]}) #merge object attributes into e. end else print_debug "\n#{uuid}: Skipping Element: #{e}".yellow print_debug "#{uuid}: I've tapped this Locator #{@click_count} times before...\n".yellow next end end e[:clicked] = true #store clicked element in case app crashes when clicked. #TODO: Set rules hash on click counts by locator class. e.g. textfield, button etc... if e[:class] == "android.widget.EditText" #only click textfields once e[:click_count] = 3 else e[:click_count] = e[:click_count] + 1 end if e[:dialog] e[:click_count] = 0 end e[:time] = Time.now store_clicked_element e if e[:id] == "force-tap-back" execute.back_button; sleep 0.2 if e[:page] == md5_page_source #at a last resort relaunch the app... print_debug "\n#{uuid}: Stuck on the same view/page. Getting outta here...\n".red relaunch_app end else click e[:element] end sleep 0.2 e[:typed] = type_if_keyboard_is_open if page_changed? e remove_clicked_element e[:page_changed] = true e[:performance] = Thread.new { execute.system_stats }.value e[:new_activity] = new_activity(e[:activity]) e[:new_page] = md5_page_source store_clicked_element e throw :stop end end end end end
new_activity(current_activity)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 395 def new_activity current_activity if activity == current_activity nil else activity end end
outside_screen_boundaries?(screen_size, location)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 116 def outside_screen_boundaries?(screen_size, location) if location[0] < 0 or location[1] < 0 true elsif location[0] > screen_size[0] or location[1] > screen_size[1] true else false end end
page_changed?(element)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 210 def page_changed? element changed = md5_page_source != element[:page] print_debug "\n#{uuid} The page has changed!!! Restarting...\n".red if changed changed end
print_debug(string)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 70 def print_debug string puts string if options_debug end
relaunch_app()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 187 def relaunch_app print_debug "#{uuid}: Launching App!!!" `curl -s -X POST #{caps_url}/session/#{driver.session_id}/appium/app/launch` #@new_page = [] sleep 5 end
relaunch_app?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 194 def relaunch_app? print_debug "#{uuid}: Checking to Relaunch app..." act = activity unless redis.activities.any? { |a| a.include? act } if execute.permission_dialog_displayed? act execute.close_permissions_dialog act sleep 2 else execute.back_button unless redis.activities.any? { |a| a.include? activity } relaunch_app end end end end
remove_clicked_element()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 268 def remove_clicked_element redis.lpop "clicked" end
replay()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 353 def replay last_run_steps.each do |step| #take_screenshot #not yet implemented logic yet to store screenshots in new location. relaunch_app? login_page? locator = step[:accessibilty_label] || step[:id] if locator.nil? wait(wait_for_element) { fe({xpath: "//#{step[:class]}[@bounds='#{step[:bounds]}']"}) } rescue nil #will wait if element exists... element = fe({xpath: "//#{step[:class]}[@bounds='#{step[:bounds]}']"}) else wait(wait_for_element) { fe({id: locator}) } rescue nil #will wait if element exists... element = fe({id: locator}) end print_debug "\n#{uuid}: Last Run Step: #{step}\n" print_debug "" #binding.pry #check_replay_element_values step if step[:id] == "force-tap-back" execute.back_button else element.click end if execute.keyboard_open? and step[:typed] print_debug "\n#{uuid}: Typying Last Run Text: #{step[:typed]}\n" type "#{step[:typed]}\n" close_keyboard else type_if_keyboard_is_open end sleep 0.5 #step[:performance] = Thread.new { execute.system_stats }.value #To compare peformance from last test run... end sleep 5 #wait for a crash to happen end
reset_dialog_count()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 256 def reset_dialog_count redis.hset("dialog","count", 0) end
screenshot_exists?(md5)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 182 def screenshot_exists? md5 files = Dir.entries(dir).select { |x| x.include? ".png" } rescue [] files.any? { |x| x.include? md5 } unless files.empty? end
start_log()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 108 def start_log execute.start_log end
stop_log()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 112 def stop_log execute.stop_log end
store_accessibility_labels(body)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 432 def store_accessibility_labels body print_debug "\n#{uuid}: Storing Accessibility Labels: #{body}\n" redis.update_list "accessibility_labels", body end
store_clicked_element(body)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 99 def store_clicked_element body print_debug "\n#{uuid}: Storing clicked element: #{body}\n" redis.update_list "clicked", body end
store_page_text(body)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 427 def store_page_text body print_debug "\n#{uuid}: Storing Page Text: #{body}\n" redis.update_list "page_text", body end
string()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 222 def string #TODO create a CLI option to change which kind of strings are passed chars = Lorem.characters(rand(1..100)) sentence = Faker::Hipster.sentence(1) words = (Faker::Hipster.words(rand(1..10))).shuffle.join(" ") url = Faker::Internet.url mac = Faker::Internet.mac_address #[chars, words, url, mac].sample #Right now just sending hipster text but maybe randomize this in the future... sentence end
take_screenshot?()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 172 def take_screenshot? md5 = md5_page_source unless screenshot_exists? md5 is_test? if options_applitools print_debug "#{uuid}: Taking a screenshot..." screenshot "#{dir}/#{count}_#{md5}.png" count.next! end end
type_if_keyboard_is_open()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 238 def type_if_keyboard_is_open if execute.keyboard_open? print_debug "#{uuid}: Keyboard is open. I will type now..." type "#{string}\n" close_keyboard string end end
update_element_list(act, elements)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 403 def update_element_list act, elements if redis.activity_exists? act old_elements = redis.get_list(act) new_elements = elements diff = diff_actvity_elements(old_elements, new_elements) rescue [] unless diff.empty? redis.del_list activity select_elements = new_elements.select { |e| diff.map { |x| x[:id] }.include? e[:id] } redis.update_list activity, (old_elements + select_elements) end redis.update_activity_count act end end
uploaded_to_applitools(test)
click to toggle source
# File lib/aaet/common/common_methods.rb, line 126 def uploaded_to_applitools test #redis.update_list "applitools", test redis.update_applitools "applitools", test end
wait_for_home_screen()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 95 def wait_for_home_screen Appium::Common.wait_true(wait_for_element) { activity == config[:homeActivity][:activity] } end
weighted_actions()
click to toggle source
# File lib/aaet/common/common_methods.rb, line 288 def weighted_actions #TODO: implement these later... [multi_touch, shake, forcepress, longpress] actions = ["random_tap", "swipe_right", "swipe_left", "pull_to_refresh", "buttons", "back", "swipe_down", "swipe_up"] weights = [45, 15, 15, 10, 5, 5, 3, 2] ps = weights.map { |w| (Float w) / weights.reduce(:+) } weighted_actions = actions.zip(ps).to_h wrs = -> (freq) { freq.max_by { |_, weight| rand ** (1.0 / weight) }.first } action = wrs[weighted_actions] print_debug "#{uuid}: Performing Action: #{action}".yellow action end