Class: Aaet::Common

Inherits:
Locators show all
Defined in:
lib/aaet/common/common_methods.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) ⇒ Common

Returns a new instance of Common.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 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

Instance Attribute Details

#applitoolsObject

Returns the value of attribute applitools.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def applitools
  @applitools
end

#countObject

Returns the value of attribute count.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def count
  @count
end

#dirObject

Returns the value of attribute dir.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def dir
  @dir
end

#executeObject

Returns the value of attribute execute.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def execute
  @execute
end

#parserObject

Returns the value of attribute parser.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def parser
  @parser
end

#redisObject

Returns the value of attribute redis.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def redis
  @redis
end

#testsObject

Returns the value of attribute tests.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def tests
  @tests
end

#uuidObject

Returns the value of attribute uuid.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def uuid
  @uuid
end

#wait_for_elementObject

Returns the value of attribute wait_for_element.



12
13
14
# File 'lib/aaet/common/common_methods.rb', line 12

def wait_for_element
  @wait_for_element
end

Instance Method Details

#accept_dialogObject



251
252
253
254
# 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) ⇒ Object



136
137
138
139
140
# 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?Boolean

Returns:

  • (Boolean)


498
499
500
501
502
503
504
505
506
507
508
509
510
# 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) ⇒ Boolean

Returns:

  • (Boolean)


521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# 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) ⇒ Object

TODO: Return boolean if replay step is displayed… use this to debug replay values



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# 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?Boolean

Returns:

  • (Boolean)


272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# 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) ⇒ Boolean

Returns:

  • (Boolean)


512
513
514
515
516
517
518
519
# 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_elementsObject



104
105
106
# File 'lib/aaet/common/common_methods.rb', line 104

def clicked_elements
  redis.get_list "clicked"
end

#close_keyboardObject



234
235
236
# File 'lib/aaet/common/common_methods.rb', line 234

def close_keyboard
  execute.close_keyboard if execute.keyboard_open?
end

#collect_chaos_performance(body) ⇒ Object



300
301
302
# File 'lib/aaet/common/common_methods.rb', line 300

def collect_chaos_performance body
  redis.update_list "chaos", body
end

#crawlerObject



552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
# File 'lib/aaet/common/common_methods.rb', line 552

def crawler
  print_debug "\n#{uuid}: Starting!!!\n".green

  take_screenshot?
  relaunch_app?
  

  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_countObject



264
265
266
# File 'lib/aaet/common/common_methods.rb', line 264

def dialog_count
  redis.hget("dialog", "count").to_i
end

#dialog_displayed?Boolean

Returns:

  • (Boolean)


247
248
249
# File 'lib/aaet/common/common_methods.rb', line 247

def dialog_displayed?
  displayed? execute.dialog_button
end

#diff_actvity_elements(old_page, new_page) ⇒ Object



417
418
419
420
421
# 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_clickObject



423
424
425
# 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) ⇒ Object



437
438
439
440
441
442
443
444
445
446
# 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) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 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) ⇒ Object



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# 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) ⇒ Object



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# 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) ⇒ Boolean

Returns:

  • (Boolean)


131
132
133
134
# 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_countObject



260
261
262
# File 'lib/aaet/common/common_methods.rb', line 260

def increment_dialog_count
  redis.hincr("dialog","count")
end

#is_test?Boolean

Returns:

  • (Boolean)


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# 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

#loginObject



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/aaet/common/common_methods.rb', line 82

def 
  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?Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
# File 'lib/aaet/common/common_methods.rb', line 74

def 
  print_debug "#{uuid}: Checking if on Login page..."
   = config[:loginPage] rescue {}
  if .any?
     if (activity == [0][:activity])
  end
end

#md5_page_sourceObject



216
217
218
219
220
# 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

#monkeyObject



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/aaet/common/common_methods.rb', line 304

def monkey
  
  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

#new_activity(current_activity) ⇒ Object



395
396
397
398
399
400
401
# 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) ⇒ Boolean

Returns:

  • (Boolean)


116
117
118
119
120
121
122
123
124
# 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) ⇒ Boolean

Returns:

  • (Boolean)


210
211
212
213
214
# 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


70
71
72
# File 'lib/aaet/common/common_methods.rb', line 70

def print_debug string
  puts string if options_debug
end

#relaunch_appObject



187
188
189
190
191
192
# 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?Boolean

Returns:

  • (Boolean)


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# 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_elementObject



268
269
270
# File 'lib/aaet/common/common_methods.rb', line 268

def remove_clicked_element
  redis.lpop "clicked"
end

#replayObject



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# 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?
    

    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_countObject



256
257
258
# File 'lib/aaet/common/common_methods.rb', line 256

def reset_dialog_count
  redis.hset("dialog","count", 0)
end

#screenshot_exists?(md5) ⇒ Boolean

Returns:

  • (Boolean)


182
183
184
185
# 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_logObject



108
109
110
# File 'lib/aaet/common/common_methods.rb', line 108

def start_log
  execute.start_log
end

#stop_logObject



112
113
114
# File 'lib/aaet/common/common_methods.rb', line 112

def stop_log
  execute.stop_log
end

#store_accessibility_labels(body) ⇒ Object



432
433
434
435
# 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) ⇒ Object



99
100
101
102
# 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) ⇒ Object



427
428
429
430
# 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

#stringObject



222
223
224
225
226
227
228
229
230
231
232
# 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?Boolean

Returns:

  • (Boolean)


172
173
174
175
176
177
178
179
180
# 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_openObject



238
239
240
241
242
243
244
245
# 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) ⇒ Object



403
404
405
406
407
408
409
410
411
412
413
414
415
# 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) ⇒ Object



126
127
128
129
# 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_screenObject



95
96
97
# 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_actionsObject



288
289
290
291
292
293
294
295
296
297
298
# 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