kraken-mobile 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +8 -0
- data/README.md +169 -0
- data/bin/kraken-mobile +91 -0
- data/bin/kraken-mobile-calabash-android.rb +85 -0
- data/bin/kraken-mobile-generate.rb +19 -0
- data/bin/kraken-mobile-helpers.rb +48 -0
- data/bin/kraken-mobile-setup.rb +50 -0
- data/calabash-android-features-skeleton/my_first.feature +11 -0
- data/calabash-android-features-skeleton/step_definitions/kraken_steps.rb +1 -0
- data/calabash-android-features-skeleton/support/app_installation_hooks.rb +25 -0
- data/calabash-android-features-skeleton/support/app_life_cycle_hooks.rb +10 -0
- data/calabash-android-features-skeleton/support/env.rb +1 -0
- data/lib/kraken-mobile.rb +29 -0
- data/lib/kraken-mobile/constants.rb +25 -0
- data/lib/kraken-mobile/helpers/command_helper.rb +38 -0
- data/lib/kraken-mobile/helpers/devices_helper/adb_helper.rb +157 -0
- data/lib/kraken-mobile/helpers/devices_helper/manager.rb +43 -0
- data/lib/kraken-mobile/helpers/feature_analyzer.rb +28 -0
- data/lib/kraken-mobile/helpers/feature_grouper.rb +48 -0
- data/lib/kraken-mobile/helpers/reporter.rb +381 -0
- data/lib/kraken-mobile/models/device.rb +32 -0
- data/lib/kraken-mobile/protocols/file_protocol.rb +126 -0
- data/lib/kraken-mobile/runners/calabash/android/android_runner.rb +130 -0
- data/lib/kraken-mobile/runners/calabash/android/apk_signer.rb +14 -0
- data/lib/kraken-mobile/runners/calabash/android/cucumber.rb +27 -0
- data/lib/kraken-mobile/runners/calabash/android/kraken_hooks.rb +15 -0
- data/lib/kraken-mobile/runners/calabash/android/kraken_steps.rb +3 -0
- data/lib/kraken-mobile/runners/calabash/android/monkey_helper.rb +139 -0
- data/lib/kraken-mobile/runners/calabash/android/operations.rb +44 -0
- data/lib/kraken-mobile/runners/calabash/android/steps/communication_steps.rb +57 -0
- data/lib/kraken-mobile/runners/calabash/monkey/monkey_runner.rb +113 -0
- data/lib/kraken-mobile/runners/runner.rb +18 -0
- data/lib/kraken-mobile/version.rb +5 -0
- data/reporter/assets/css/bootstrap.min.css +6 -0
- data/reporter/assets/css/dataTables.bootstrap.min.css +1 -0
- data/reporter/assets/css/feature_index.css +449 -0
- data/reporter/assets/css/font-awesome.min.css +4 -0
- data/reporter/assets/css/responsive.dataTables.min.css +1 -0
- data/reporter/assets/css/scenario_index.css +461 -0
- data/reporter/assets/fonts/FontAwesome.otf +0 -0
- data/reporter/assets/fonts/fontawesome-webfont.eot +0 -0
- data/reporter/assets/fonts/fontawesome-webfont.svg +2671 -0
- data/reporter/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/reporter/assets/fonts/fontawesome-webfont.woff +0 -0
- data/reporter/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/reporter/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/reporter/assets/fonts/glyphicons-halflings-regular.svg +288 -0
- data/reporter/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/reporter/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/reporter/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/reporter/assets/images/kraken.png +0 -0
- data/reporter/assets/js/Chart.min.js +14 -0
- data/reporter/assets/js/bootstrap.min.js +7 -0
- data/reporter/assets/js/d3.chart.min.js +7 -0
- data/reporter/assets/js/d3.v3.min.js +5 -0
- data/reporter/assets/js/dataTables.bootstrap.min.js +8 -0
- data/reporter/assets/js/dataTables.responsive.min.js +26 -0
- data/reporter/assets/js/first-sankey.js +292 -0
- data/reporter/assets/js/gitgraph.min.js +10 -0
- data/reporter/assets/js/html5shiv.min.js +4 -0
- data/reporter/assets/js/jquery-3.2.1.min.js +4 -0
- data/reporter/assets/js/jquery.dataTables.min.js +167 -0
- data/reporter/assets/js/respond.min.js +5 -0
- data/reporter/assets/js/sankey.js +512 -0
- data/reporter/feature_report.html.erb +274 -0
- data/reporter/index.html.erb +711 -0
- data/reporter/scenario_report.html.erb +174 -0
- metadata +169 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module KrakenMobile
|
2
|
+
module Models
|
3
|
+
class Device
|
4
|
+
|
5
|
+
#-------------------------------
|
6
|
+
# Fields
|
7
|
+
#-------------------------------
|
8
|
+
attr_accessor :id
|
9
|
+
attr_accessor :model
|
10
|
+
attr_accessor :position
|
11
|
+
attr_accessor :config
|
12
|
+
|
13
|
+
#-------------------------------
|
14
|
+
# Constructors
|
15
|
+
#-------------------------------
|
16
|
+
def initialize(id, model, position, config = {})
|
17
|
+
@id = id
|
18
|
+
@model = model
|
19
|
+
@position = position
|
20
|
+
@config = config
|
21
|
+
end
|
22
|
+
|
23
|
+
#-------------------------------
|
24
|
+
# Helpers
|
25
|
+
#-------------------------------
|
26
|
+
def screenshot_prefix
|
27
|
+
@id.gsub('.', '_').gsub(/:(.*)/, '').to_s + '_'
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'kraken-mobile/helpers/devices_helper/manager'
|
2
|
+
require 'kraken-mobile/constants'
|
3
|
+
require 'calabash-android/operations'
|
4
|
+
require 'digest'
|
5
|
+
|
6
|
+
module KrakenMobile
|
7
|
+
module Protocol
|
8
|
+
module FileProtocol
|
9
|
+
def readSignal(channel, content, timeout)
|
10
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
11
|
+
device_id = channel_to_device_id(channel)
|
12
|
+
Timeout::timeout(timeout, RuntimeError) do
|
13
|
+
sleep(1) until devices_helper.read_file_content(KrakenMobile::Constants::DEVICE_INBOX_NAME, device_id) == content
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def readLastSignal(channel)
|
18
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
19
|
+
device_id = channel_to_device_id(channel)
|
20
|
+
devices_helper.read_file_content(KrakenMobile::Constants::DEVICE_INBOX_NAME, device_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def readAnySignal(channel, timeout)
|
24
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
25
|
+
device_id = channel_to_device_id(channel)
|
26
|
+
Timeout::timeout(timeout, RuntimeError) do
|
27
|
+
sleep(1) until devices_helper.read_file_content(KrakenMobile::Constants::DEVICE_INBOX_NAME, device_id) != ""
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def readSignalWithKeyworkd(channel, keyword, timeout)
|
32
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
33
|
+
device_id = channel_to_device_id(channel)
|
34
|
+
Timeout::timeout(timeout, RuntimeError) do
|
35
|
+
sleep(1) until devices_helper.read_file_content(KrakenMobile::Constants::DEVICE_INBOX_NAME, device_id).include?(keyword)
|
36
|
+
return devices_helper.read_file_content(KrakenMobile::Constants::DEVICE_INBOX_NAME, device_id)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def writeSignal(channel, content)
|
41
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
42
|
+
device_id = channel_to_device_id(channel)
|
43
|
+
devices_helper.write_content_to_file(content, KrakenMobile::Constants::DEVICE_INBOX_NAME, device_id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def writeSignalToAll(content)
|
47
|
+
devices_manager = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]})
|
48
|
+
devices_manager.connected_devices.each do |device|
|
49
|
+
devices_manager.device_helper.write_content_to_file(content, KrakenMobile::Constants::DEVICE_INBOX_NAME, device.id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def writeSignalToAnyDevice(content)
|
54
|
+
devices_manager = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]})
|
55
|
+
device = devices_manager.connected_devices.sample
|
56
|
+
devices_manager.device_helper.write_content_to_file(content, KrakenMobile::Constants::DEVICE_INBOX_NAME, device.id)
|
57
|
+
device
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_setup channel, scenario
|
61
|
+
devices_manager = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]})
|
62
|
+
device_id = channel_to_device_id(channel)
|
63
|
+
scenario_id = build_scenario_id(scenario)
|
64
|
+
devices_manager.device_helper.write_content_to_file "ready_#{scenario_id}", KrakenMobile::Constants::KRAKEN_CONFIGURATION_FILE_NAME, device_id
|
65
|
+
ordered_tags = ordered_feature_tags scenario
|
66
|
+
while true
|
67
|
+
compare_criteria = devices_manager.connected_devices.count >= ordered_tags.count ? ordered_tags.count : devices_manager.connected_devices.count
|
68
|
+
break if devices_ready_start(devices_manager, scenario_id).count >= compare_criteria
|
69
|
+
sleep(1)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def end_setup channel, scenario
|
74
|
+
devices_manager = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]})
|
75
|
+
device_id = channel_to_device_id(channel)
|
76
|
+
scenario_id = build_scenario_id(scenario)
|
77
|
+
devices_manager.device_helper.write_content_to_file "end_#{scenario_id}", KrakenMobile::Constants::KRAKEN_CONFIGURATION_FILE_NAME, device_id
|
78
|
+
ordered_tags = ordered_feature_tags scenario
|
79
|
+
while true
|
80
|
+
compare_criteria = devices_manager.connected_devices.count >= ordered_tags.count ? ordered_tags.count : devices_manager.connected_devices.count
|
81
|
+
break if devices_ready_to_finish(devices_manager, scenario_id).count >= compare_criteria
|
82
|
+
sleep(1)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# helpers
|
87
|
+
def build_scenario_id scenario
|
88
|
+
location = scenario.location.to_s
|
89
|
+
index_of_line_number_start = location.index(":")
|
90
|
+
real_location = location[0..index_of_line_number_start-1]
|
91
|
+
Digest::SHA256.hexdigest(real_location)
|
92
|
+
end
|
93
|
+
|
94
|
+
def feature_tags scenario
|
95
|
+
tag_objects = scenario.feature.children.map { |e| e.tags if e.tags }.compact
|
96
|
+
tags = []
|
97
|
+
tag_objects.each do |tag_object|
|
98
|
+
names = tag_object.map { |tag| tag.name if tag.name }
|
99
|
+
tags.concat names
|
100
|
+
end
|
101
|
+
tags.uniq.select{ |tag| tag.start_with? "@user" }.sort
|
102
|
+
end
|
103
|
+
|
104
|
+
def ordered_feature_tags scenario
|
105
|
+
tags = feature_tags scenario
|
106
|
+
ordered_tags = []
|
107
|
+
tags.count.times do |index|
|
108
|
+
if tags[index].include? "@user#{index+1}"
|
109
|
+
ordered_tags << tags[index]
|
110
|
+
else
|
111
|
+
break
|
112
|
+
end
|
113
|
+
end
|
114
|
+
ordered_tags
|
115
|
+
end
|
116
|
+
|
117
|
+
def devices_ready_start devices_manager, scenario_id
|
118
|
+
devices_manager.connected_devices.select { |device| devices_manager.device_helper.read_file_content(KrakenMobile::Constants::KRAKEN_CONFIGURATION_FILE_NAME, device.id) == "ready_#{scenario_id}" }
|
119
|
+
end
|
120
|
+
|
121
|
+
def devices_ready_to_finish devices_manager, scenario_id
|
122
|
+
devices_manager.connected_devices.select { |device| devices_manager.device_helper.read_file_content(KrakenMobile::Constants::KRAKEN_CONFIGURATION_FILE_NAME, device.id) == "end_#{scenario_id}" }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'kraken-mobile/helpers/devices_helper/manager'
|
2
|
+
require 'kraken-mobile/helpers/feature_grouper'
|
3
|
+
require 'kraken-mobile/helpers/reporter'
|
4
|
+
require 'kraken-mobile/runners/runner'
|
5
|
+
require 'kraken-mobile/constants'
|
6
|
+
require 'kraken-mobile/runners/calabash/android/apk_signer.rb'
|
7
|
+
require 'parallel'
|
8
|
+
require 'digest'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'erb'
|
11
|
+
|
12
|
+
module KrakenMobile
|
13
|
+
module Runner
|
14
|
+
class CalabashAndroidRunner < KrakenRunner
|
15
|
+
BASE_COMMAND = "calabash-android run"
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
super(options)
|
19
|
+
default_runner = KrakenMobile::Constants::CALABASH_ANDROID
|
20
|
+
@devices_manager = DevicesHelper::Manager.new({runner: default_runner, config_path: @options[:config_path]})
|
21
|
+
@adb_helper = @devices_manager.device_helper
|
22
|
+
@execution_id = Digest::SHA256.hexdigest("#{Time.now.to_f}")
|
23
|
+
@reporter = KrakenMobile::Reporter.new(@execution_id, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
#-------------------------------
|
27
|
+
# Hooks
|
28
|
+
#-------------------------------
|
29
|
+
def before_all
|
30
|
+
Dir.mkdir(KrakenMobile::Constants::REPORT_PATH) unless File.exists?(KrakenMobile::Constants::REPORT_PATH)
|
31
|
+
Dir.mkdir("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}")
|
32
|
+
devices_id_list = []
|
33
|
+
@devices_manager.connected_devices.each_with_index do |device, index|
|
34
|
+
height, width = @adb_helper.screen_size device.id
|
35
|
+
sdk_version = @adb_helper.sdk_version device.id
|
36
|
+
devices_id_list << { user: (index+1), id: device.id, model: device.model, screen_height: height, screen_width: width, sdk: sdk_version }
|
37
|
+
Dir.mkdir("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}")
|
38
|
+
end
|
39
|
+
file = open("#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{KrakenMobile::Constants::REPORT_DEVICES_FILE_NAME}.json", 'w')
|
40
|
+
file.puts(devices_id_list.to_json)
|
41
|
+
file.close
|
42
|
+
source_dir = File.expand_path("../../../../../../reporter/assets/", __FILE__)
|
43
|
+
FileUtils.cp_r(source_dir, "#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/")
|
44
|
+
end
|
45
|
+
|
46
|
+
def before_execution process_number
|
47
|
+
device = @devices_manager.connected_devices[process_number]
|
48
|
+
raise "There is no device for process #{process_number}" unless device
|
49
|
+
@adb_helper.create_file KrakenMobile::Constants::DEVICE_INBOX_NAME, device.id
|
50
|
+
@adb_helper.create_file KrakenMobile::Constants::KRAKEN_CONFIGURATION_FILE_NAME, device.id
|
51
|
+
end
|
52
|
+
|
53
|
+
def after_execution process_number
|
54
|
+
device = @devices_manager.connected_devices[process_number]
|
55
|
+
raise "There is no device for process #{process_number}" unless device
|
56
|
+
@adb_helper.delete_file KrakenMobile::Constants::DEVICE_INBOX_NAME, device.id
|
57
|
+
@adb_helper.delete_file KrakenMobile::Constants::KRAKEN_CONFIGURATION_FILE_NAME, device.id
|
58
|
+
end
|
59
|
+
|
60
|
+
#-------------------------------
|
61
|
+
# Execution
|
62
|
+
#-------------------------------
|
63
|
+
def run_in_parallel
|
64
|
+
ensure_apks_signed
|
65
|
+
before_all
|
66
|
+
feature_folder = @options[:feature_folder]
|
67
|
+
devices_connected = @devices_manager.connected_devices
|
68
|
+
groups = FeatureGrouper.file_groups(feature_folder, devices_connected.size)
|
69
|
+
threads = groups.size
|
70
|
+
puts "Running with #{threads} threads: #{groups}"
|
71
|
+
test_results = Parallel.map_with_index(
|
72
|
+
groups,
|
73
|
+
:in_threads => threads,
|
74
|
+
:start => lambda { |group, index|
|
75
|
+
before_execution(index)
|
76
|
+
},
|
77
|
+
:finish => lambda { |group, index, _|
|
78
|
+
after_execution(index)
|
79
|
+
}
|
80
|
+
) do |group, index|
|
81
|
+
run_tests(group, index, @options)
|
82
|
+
@reporter.generate_device_report devices_connected[index]
|
83
|
+
end
|
84
|
+
@reporter.generate_general_report
|
85
|
+
end
|
86
|
+
|
87
|
+
def run_tests(test_files, process_number, options)
|
88
|
+
command = build_execution_command(process_number, options[:apk_path], test_files)
|
89
|
+
puts "\n****** PROCESS #{process_number} STARTED ******\n\n"
|
90
|
+
@command_helper.execute_command(process_number, command)
|
91
|
+
puts "\n****** PROCESS #{process_number} COMPLETED ******\n\n"
|
92
|
+
end
|
93
|
+
|
94
|
+
#-------------------------------
|
95
|
+
# Helpers
|
96
|
+
#-------------------------------
|
97
|
+
def build_execution_command process_number, general_apk, test_files
|
98
|
+
device = @devices_manager.connected_devices[process_number]
|
99
|
+
raise "Theres not a device for process #{process_number}" unless device
|
100
|
+
apk_path = device.config["apk_path"] ? device.config["apk_path"] : general_apk
|
101
|
+
raise "Invalid apk path" unless apk_path
|
102
|
+
cucumber_options = "--format pretty --format json -o #{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/#{KrakenMobile::Constants::REPORT_FILE_NAME}.json"
|
103
|
+
execution_command = @command_helper.build_command [BASE_COMMAND, apk_path, cucumber_options, *test_files, "--tags @user#{device.position}"]
|
104
|
+
env_variables = {
|
105
|
+
AUTOTEST: '1',
|
106
|
+
ADB_DEVICE_ARG: device.id,
|
107
|
+
DEVICE_INFO: device.model,
|
108
|
+
TEST_PROCESS_NUMBER: (process_number+1).to_s,
|
109
|
+
SCREENSHOT_PATH: "#{KrakenMobile::Constants::REPORT_PATH}/#{@execution_id}/#{device.id}/#{device.screenshot_prefix}",
|
110
|
+
PROTOCOL: @options[:protocol],
|
111
|
+
RUNNER: KrakenMobile::Constants::CALABASH_ANDROID
|
112
|
+
}
|
113
|
+
env_variables[:CONFIG_PATH] = @options[:config_path] if @options[:config_path]
|
114
|
+
env_variables[:PROPERTIES_PATH] = @options[:properties_path] if @options[:properties_path]
|
115
|
+
exports = @command_helper.build_export_env_command env_variables
|
116
|
+
exports + @command_helper.terminal_command_separator + execution_command
|
117
|
+
end
|
118
|
+
|
119
|
+
def ensure_apks_signed
|
120
|
+
checked_apks = {}
|
121
|
+
@devices_manager.connected_devices.each do |device|
|
122
|
+
apk_path = device.config["apk_path"] ? device.config["apk_path"] : @options[:apk_path]
|
123
|
+
next if checked_apks[apk_path] # Dont check already checked apks
|
124
|
+
raise "APK is not signed, you can resign the app by running kraken-mobile resign #{apk_path}" if !KrakenMobile::CalabashAndroid::ApkSigner.is_apk_signed? apk_path
|
125
|
+
checked_apks[apk_path] = apk_path
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'calabash-android/helpers'
|
2
|
+
require 'calabash-android/java_keystore'
|
3
|
+
|
4
|
+
module KrakenMobile
|
5
|
+
module CalabashAndroid
|
6
|
+
module ApkSigner
|
7
|
+
def self.is_apk_signed? apk_path
|
8
|
+
keystores = JavaKeystore.get_keystores
|
9
|
+
apk_fingerprint = fingerprint_from_apk(apk_path)
|
10
|
+
keystores.select { |k| k.fingerprint == apk_fingerprint}.any?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'calabash-android/cucumber'
|
2
|
+
require 'calabash-android/operations'
|
3
|
+
require 'kraken-mobile/runners/calabash/android/kraken_hooks'
|
4
|
+
require 'kraken-mobile/runners/calabash/android/operations'
|
5
|
+
require 'kraken-mobile/runners/calabash/android/monkey_helper'
|
6
|
+
require 'kraken-mobile/constants'
|
7
|
+
require 'kraken-mobile/protocols/file_protocol'
|
8
|
+
|
9
|
+
def requested_protocol
|
10
|
+
case ENV["PROTOCOL"]
|
11
|
+
when KrakenMobile::Constants::FILE_PROTOCOL
|
12
|
+
KrakenMobile::Protocol::FileProtocol
|
13
|
+
else
|
14
|
+
raise "Invalid Kraken protocol."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
World(Calabash::Android::ColorHelper)
|
19
|
+
World(Calabash::Android::Operations)
|
20
|
+
World(KrakenMobile::CalabashAndroid::Operations)
|
21
|
+
World(KrakenMobile::CalabashAndroid::MonkeyHelper)
|
22
|
+
World(requested_protocol())
|
23
|
+
|
24
|
+
AfterConfiguration do
|
25
|
+
require 'calabash-android/calabash_steps'
|
26
|
+
require 'kraken-mobile/runners/calabash/android/kraken_steps'
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'calabash-android/management/adb'
|
2
|
+
require 'calabash-android/operations'
|
3
|
+
|
4
|
+
Before do |scenario|
|
5
|
+
install_app_with_calabash()
|
6
|
+
@scenario_tags = scenario.source_tag_names
|
7
|
+
end
|
8
|
+
|
9
|
+
After do |scenario|
|
10
|
+
@scenario_tags = scenario.source_tag_names
|
11
|
+
end
|
12
|
+
|
13
|
+
AfterStep do |scenario|
|
14
|
+
screenshot_embed
|
15
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'calabash-android/monkey_helpers'
|
2
|
+
require 'kraken-mobile/constants'
|
3
|
+
|
4
|
+
module KrakenMobile
|
5
|
+
module CalabashAndroid
|
6
|
+
module MonkeyHelper
|
7
|
+
|
8
|
+
# Runs inteligent monkey
|
9
|
+
def run_intelligent_monkey channel, number_of_events
|
10
|
+
device_id = channel_to_device_id channel
|
11
|
+
logger = open("./#{device_id}.txt", 'w')
|
12
|
+
number_of_events.times do |i|
|
13
|
+
handle_random_action channel, logger
|
14
|
+
end
|
15
|
+
logger.close
|
16
|
+
end
|
17
|
+
|
18
|
+
# Runs adb monkey
|
19
|
+
def run_monkey channel, number_of_events
|
20
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
21
|
+
device_id = channel_to_device_id channel
|
22
|
+
height, width = devices_helper.screen_size device_id
|
23
|
+
start_monkey
|
24
|
+
actions = [:move, :down, :up]
|
25
|
+
number_of_events.times do |i|
|
26
|
+
monkey_touch(actions.sample, rand(5..(width-5)) , rand(5..(height-5)))
|
27
|
+
end
|
28
|
+
kill_existing_monkey_processes
|
29
|
+
end
|
30
|
+
|
31
|
+
# Runs monkey in an speciic part of the screen
|
32
|
+
def run_small_monkey channel, number_of_events, height_start, height_end, width_start, width_end
|
33
|
+
devices_helper = DevicesHelper::Manager.new({runner: ENV["RUNNER"], config_path: ENV["CONFIG_PATH"]}).device_helper
|
34
|
+
device_id = channel_to_device_id channel
|
35
|
+
height, width = devices_helper.screen_size device_id
|
36
|
+
start_monkey
|
37
|
+
actions = [:move, :down, :up]
|
38
|
+
numb_height_start = (height*(height_start/100.0)).to_i+5
|
39
|
+
numb_height_end = (height*(height_end/100.0)).to_i-5
|
40
|
+
numb_width_start = (width*(width_start/100.0)).to_i+5
|
41
|
+
numb_width_end = (width*(width_end/100.0)).to_i-5
|
42
|
+
number_of_events.times do |i|
|
43
|
+
pos_x = rand(numb_width_start..numb_width_end)
|
44
|
+
pos_y = rand(numb_height_start..numb_height_end)
|
45
|
+
monkey_touch(actions.sample,pos_x,pos_y)
|
46
|
+
end
|
47
|
+
kill_existing_monkey_processes
|
48
|
+
end
|
49
|
+
|
50
|
+
###########################################
|
51
|
+
############## Events #####################
|
52
|
+
###########################################
|
53
|
+
def handle_random_action channel, logger
|
54
|
+
begin
|
55
|
+
Timeout::timeout(KrakenMobile::Constants::MONKEY_DEFAULT_TIMEOUT, RuntimeError) do
|
56
|
+
arr = [method(:enter_last_signal_in_random_input), method(:send_random_signal), method(:random_click)]
|
57
|
+
arr.sample.call(channel, logger)
|
58
|
+
end
|
59
|
+
rescue => e
|
60
|
+
puts "#{ENV['TEST_PROCESS_NUMBER']}> e"
|
61
|
+
logger.puts(e)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def random_click channel, logger
|
66
|
+
elements = query("*")
|
67
|
+
element = elements.sample if elements
|
68
|
+
return if !element
|
69
|
+
x = element["rect"]["x"]
|
70
|
+
y = element["rect"]["y"]
|
71
|
+
begin
|
72
|
+
perform_action(random_touch_action, x, y)
|
73
|
+
puts "#{ENV['TEST_PROCESS_NUMBER']}> random_click - Coordinates: #{x},#{y}"
|
74
|
+
logger.puts("random_click - Coordinates: #{x},#{y}")
|
75
|
+
rescue => e
|
76
|
+
puts "#{ENV['TEST_PROCESS_NUMBER']}> #{e}"
|
77
|
+
logger.puts(e)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def enter_last_signal_in_random_input channel, logger
|
82
|
+
last_signal = readLastSignal(channel)
|
83
|
+
enter_text_in_random_input last_signal, logger
|
84
|
+
puts "#{ENV['TEST_PROCESS_NUMBER']}> enter_last_signal_in_random_input - Signal: #{last_signal}"
|
85
|
+
logger.puts("enter_last_signal_in_random_input - Signal: #{last_signal}")
|
86
|
+
end
|
87
|
+
|
88
|
+
def enter_text_in_random_input text, logger
|
89
|
+
return if input_texts.count <= 0
|
90
|
+
input = input_texts.sample
|
91
|
+
x = input["rect"]["x"]
|
92
|
+
y = input["rect"]["y"]
|
93
|
+
perform_action(random_touch_action, x, y)
|
94
|
+
enter_text text
|
95
|
+
end
|
96
|
+
|
97
|
+
def send_random_signal channel, logger
|
98
|
+
return if app_texts.count <= 0
|
99
|
+
text = app_texts.sample
|
100
|
+
# TODO Remove all special characters
|
101
|
+
text.slice!("(")
|
102
|
+
text.slice!(")")
|
103
|
+
text.slice!("'")
|
104
|
+
text.slice!("\"")
|
105
|
+
send_signal_method = [method(:writeSignalToAnyDevice), method(:writeSignalToAll)]
|
106
|
+
ans = send_signal_method.sample.call(text)
|
107
|
+
if ans
|
108
|
+
puts "#{ENV['TEST_PROCESS_NUMBER']}> send_random_signal to #{ans.id} - Signal: #{text}"
|
109
|
+
logger.puts("send_random_signal to #{ans.id} - Signal: #{text}")
|
110
|
+
else
|
111
|
+
puts "#{ENV['TEST_PROCESS_NUMBER']}> send_random_signal - Signal: #{text}"
|
112
|
+
logger.puts("send_random_signal - Signal: #{text}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def random_touch_action
|
117
|
+
actions = ["touch_coordinate"]
|
118
|
+
actions.sample
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
def app_texts
|
123
|
+
query("*", "text").select{ |e| !e["error"]}
|
124
|
+
end
|
125
|
+
|
126
|
+
def buttons
|
127
|
+
query("android.support.v7.widget.AppCompatButton")
|
128
|
+
end
|
129
|
+
|
130
|
+
def enter_text text
|
131
|
+
perform_action('keyboard_enter_text', text) if keyboard_visible?
|
132
|
+
end
|
133
|
+
|
134
|
+
def input_texts
|
135
|
+
query("android.support.v7.widget.AppCompatEditText")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|