SurfCustomCalabash 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +68 -4
- data/SurfCustomCalabash.gemspec +3 -3
- data/bin/SurfCustomCalabash +54 -0
- data/bin/surf-calabash-console.rb +62 -0
- data/bin/surf-calabash-gen.rb +17 -0
- data/bin/surf-calabash-helpers.rb +34 -0
- data/lib/SurfCustomCalabash/CommonMethods.rb +3 -3
- data/lib/SurfCustomCalabash/DroidMethods.rb +2 -1
- data/lib/SurfCustomCalabash/IosMethods.rb +2 -2
- data/lib/SurfCustomCalabash/version.rb +1 -1
- data/sources/Backdoors list b/data/sources/Backdoors → list +0 -0
- data/sources/Gemfile +27 -0
- data/sources/Scripts/and.sh +5 -0
- data/sources/Scripts/ca.sh +5 -0
- data/sources/Scripts/ci.sh +5 -0
- data/sources/Scripts/data +7 -0
- data/sources/Scripts/fa.sh +6 -0
- data/sources/Scripts/fi.sh +5 -0
- data/sources/Scripts/get_apk.rb +68 -0
- data/sources/Scripts/get_scenarios.rb +193 -0
- data/sources/Scripts/import_scenarios.rb +172 -0
- data/sources/Scripts/ios.sh +5 -0
- data/sources/Scripts/parallel_android_smoke.sh +4 -0
- data/sources/Scripts/parallel_android_test.sh +4 -0
- data/sources/Scripts/ra.sh +12 -0
- data/sources/Scripts/ri.sh +9 -0
- data/sources/Scripts/smoke_and.sh +5 -0
- data/sources/Scripts/smoke_ios.sh +5 -0
- data/sources/Scripts/ta.sh +5 -0
- data/sources/Scripts/ti.sh +5 -0
- data/sources/Scripts/to_exec.sh +19 -0
- data/sources/Scripts/update.sh +24 -0
- data/sources/Scripts/update_exec.rb +96 -0
- data/sources/TestFolder/small.gif +0 -0
- data/sources/ci/JenkinsfileUiTestAndroid.groovy +22 -0
- data/sources/ci/JenkinsfileUiTestIos.groovy +23 -0
- data/sources/config/cucumber.yml +24 -0
- data/sources/features/android/pages/standard/DroidCommon.rb +33 -0
- data/sources/features/android/pages/standard/Init_android.rb +8 -0
- data/sources/features/android/pages/test.rb +43 -0
- data/sources/features/android/support/app_life_cycle_hooks.rb +147 -0
- data/sources/features/android/support/log_hooks_and.rb +40 -0
- data/sources/features/android/support/video_hooks_and.rb +110 -0
- data/sources/features/ios/pages/standard/Init_ios.rb +5 -0
- data/sources/features/ios/pages/standard/IosCommon.rb +30 -0
- data/sources/features/ios/pages/test.rb +37 -0
- data/sources/features/ios/support/01_launch.rb +194 -0
- data/sources/features/ios/support/log_hooks_ios.rb +40 -0
- data/sources/features/ios/support/video_hooks_ios.rb +58 -0
- data/sources/features/net/net.rb +28 -0
- data/sources/features/net/screentest_api.rb +186 -0
- data/sources/features/scenarios/eng.feature +8 -0
- data/sources/features/scenarios/rus.feature +8 -0
- data/sources/features/step_definitions/test.rb +43 -0
- data/sources/features/support/credentials.rb +11 -0
- data/sources/features/support/env.rb +8 -0
- data/sources/features/support/hooks.rb +21 -0
- data/sources/features/support/localization.rb +8 -0
- data/sources/find_id.rb +95 -0
- data/sources/group_steps.rb +39 -0
- data/sources/irbrcs/android/irbrc +105 -0
- data/sources/irbrcs/ios/irbrc +132 -0
- data/sources/start.sh +134 -0
- metadata +63 -6
- data/bin/console +0 -14
- data/bin/setup +0 -8
@@ -0,0 +1,193 @@
|
|
1
|
+
require_relative 'import_scenarios'
|
2
|
+
|
3
|
+
class GetScenarios
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@user_data = Scenarios.new("..")
|
7
|
+
end
|
8
|
+
|
9
|
+
# получить название всех сценариев из папки scenarios
|
10
|
+
def get_all_scenarios_name
|
11
|
+
@lines = Array.new
|
12
|
+
all_scenarios = Array.new
|
13
|
+
|
14
|
+
# путь до папки с фича файлами
|
15
|
+
file_names = Dir["./**/*.feature"]
|
16
|
+
|
17
|
+
# проходимся по всем файлам
|
18
|
+
file_names.each do |name|
|
19
|
+
|
20
|
+
# записываем все строки файла в массив
|
21
|
+
text=File.open(name).read
|
22
|
+
text.gsub!(/\r\n?/, "\n")
|
23
|
+
text.each_line do |line|
|
24
|
+
@lines.push(line)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# получаем все названия сценариев
|
29
|
+
@lines.each do |x|
|
30
|
+
if x.match(/Сценарий:/)
|
31
|
+
x.sub!(/Сценарий:/,'')
|
32
|
+
all_scenarios.push(x.strip)
|
33
|
+
elsif x.match(/Структура сценария:/)
|
34
|
+
x.sub!(/Структура сценария:/,'')
|
35
|
+
all_scenarios.push(x.strip)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# Kernel.puts all_scenarios.count
|
39
|
+
return all_scenarios
|
40
|
+
end
|
41
|
+
|
42
|
+
# получить все не закомментрованные сценарии
|
43
|
+
def get_all_work_scenarios
|
44
|
+
all_work_scenarios = Array.new
|
45
|
+
get_all_scenarios_name.each do |x|
|
46
|
+
all_work_scenarios.push(x) unless x.match(/#/)
|
47
|
+
end
|
48
|
+
# Kernel.puts all_work_scenarios
|
49
|
+
# p all_work_scenarios.count
|
50
|
+
return all_work_scenarios
|
51
|
+
end
|
52
|
+
|
53
|
+
# получить все закомментированные сценарии
|
54
|
+
def get_all_comment_scenarios
|
55
|
+
all_comment_scenarios = Array.new
|
56
|
+
scenarios_name = Array.new
|
57
|
+
get_all_scenarios_name.each do |x|
|
58
|
+
all_comment_scenarios.push(x) if x.match(/#/)
|
59
|
+
end
|
60
|
+
|
61
|
+
all_comment_scenarios.each do |x|
|
62
|
+
x.sub!(/#/,'')
|
63
|
+
scenarios_name.push(x.strip)
|
64
|
+
end
|
65
|
+
|
66
|
+
Kernel.puts scenarios_name
|
67
|
+
p scenarios_name.count
|
68
|
+
return scenarios_name
|
69
|
+
end
|
70
|
+
|
71
|
+
# получить все сценарии с одинаковым именем
|
72
|
+
def show_all_duplicate_scenarios
|
73
|
+
if get_all_scenarios_name.duplicate.reject { |c| c.empty? }.any?
|
74
|
+
Kernel.puts "В репозитории найдены сценарии с одинаковыми названиями:"
|
75
|
+
Kernel.puts get_all_scenarios_name.duplicate
|
76
|
+
else
|
77
|
+
Kernel.puts "В репозитории нет сценариев с одинаковыми названиями"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# получаем все названия и ключи сценариев автотестов из джиры
|
82
|
+
def get_scenarios_name_from_jira
|
83
|
+
# @user_data = Scenarios.new("..")
|
84
|
+
jql = "project%20=%20#{@user_data.key}%20AND%20issuetype%20=%20Test%20AND%20\"Test%20Type\"%20=%20Cucumber"
|
85
|
+
fields = "summary"
|
86
|
+
max_results = "500"
|
87
|
+
url = "https://jira.surfstudio.ru/rest/api/2/search?jql=#{jql}&fields=#{fields}&maxResults=#{max_results}"
|
88
|
+
|
89
|
+
response = RestClient.get url, {:Authorization => @user_data.auth}
|
90
|
+
|
91
|
+
parse_response = JSON.parse(response.body)
|
92
|
+
|
93
|
+
summary = {}
|
94
|
+
|
95
|
+
parse_response['issues'].each {|x| summary[x['key']] = x['fields'].values[0]}
|
96
|
+
# Kernel.puts summary
|
97
|
+
# Kernel.puts summary.count
|
98
|
+
return summary
|
99
|
+
end
|
100
|
+
|
101
|
+
# получаем все сценарии которых нет в джире
|
102
|
+
def get_all_scenarios_not_exists_in_jira
|
103
|
+
get_all_work_scenarios.sort - get_scenarios_name_from_jira.values.sort
|
104
|
+
end
|
105
|
+
|
106
|
+
# получаем все названия сценариев и их ключи которые есть в джире, но нет в репозитории
|
107
|
+
def get_all_scenarios_not_exists_in_repo
|
108
|
+
Hash[get_scenarios_name_from_jira.to_a - get_scenarios_name_from_jira.extract_subhash(get_all_work_scenarios).to_a]
|
109
|
+
end
|
110
|
+
|
111
|
+
def show_all_scenarios_not_exists_in_repo
|
112
|
+
Kernel.puts get_all_scenarios_not_exists_in_repo.values
|
113
|
+
end
|
114
|
+
|
115
|
+
# выводит в консоль информацию о недостающих или лишних тестах в джире
|
116
|
+
def show_difference_tests
|
117
|
+
if get_all_scenarios_not_exists_in_jira.any?
|
118
|
+
Kernel.puts "В jira не хватает #{get_all_scenarios_not_exists_in_jira.count} сценариев, которые есть в репозитории:"
|
119
|
+
Kernel.puts get_all_scenarios_not_exists_in_jira
|
120
|
+
Kernel.puts "\n"
|
121
|
+
end
|
122
|
+
if get_all_scenarios_not_exists_in_repo.any?
|
123
|
+
Kernel.puts "В jira найдены #{get_all_scenarios_not_exists_in_repo.count} сценариев, которых нет в репозитории:"
|
124
|
+
Kernel.puts get_all_scenarios_not_exists_in_repo.values
|
125
|
+
Kernel.puts "\n"
|
126
|
+
end
|
127
|
+
unless get_all_scenarios_not_exists_in_repo.any? || get_all_scenarios_not_exists_in_jira.any?
|
128
|
+
Kernel.puts "В jira есть все сценарии из репозитория и нет лишних"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# создаем тест в репозитории в джире
|
133
|
+
def create_cucumber_test(test_name)
|
134
|
+
# user_data = Scenarios.new("..")
|
135
|
+
url = "https://jira.surfstudio.ru/rest/api/2/issue/"
|
136
|
+
body = {"fields"=>{"project"=>{"key"=>@user_data.key},
|
137
|
+
"summary"=>test_name,
|
138
|
+
"issuetype"=>{"name"=>"Test"},
|
139
|
+
"assignee"=>{"name"=>@user_data.login},
|
140
|
+
"customfield_10200"=>{"value"=>"Cucumber"}}}
|
141
|
+
|
142
|
+
response = RestClient.post url, body.to_json,
|
143
|
+
{:Authorization => @user_data.auth,
|
144
|
+
content_type: :json,
|
145
|
+
accept: :json}
|
146
|
+
return JSON.parse(response.body)['key']
|
147
|
+
end
|
148
|
+
|
149
|
+
# создаем все недостающие тесты в джире
|
150
|
+
def create_all_missing_test
|
151
|
+
Kernel.puts "Созданы сценарии:" if get_all_scenarios_not_exists_in_jira.any?
|
152
|
+
get_all_scenarios_not_exists_in_jira.each do |name|
|
153
|
+
Kernel.puts "#{create_cucumber_test(name)} #{name}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# удаляем тест из jira
|
158
|
+
def delete_issues_by_key(key)
|
159
|
+
# user_data = Scenarios.new("..")
|
160
|
+
url = "https://jira.surfstudio.ru/rest/api/2/issue/#{key}"
|
161
|
+
response = RestClient.delete url,{:Authorization => @user_data.auth}
|
162
|
+
response.code
|
163
|
+
end
|
164
|
+
|
165
|
+
# удаляем тесты, которые есть в джира, но нет в репо
|
166
|
+
def delete_all_waste_tests
|
167
|
+
get_all_scenarios_not_exists_in_repo.each do |k, v|
|
168
|
+
Kernel.puts "Сценарий: #{v} успешно удален" if delete_issues_by_key(k) == 204
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# find duplicate in array
|
174
|
+
class Array
|
175
|
+
def duplicate
|
176
|
+
duplicate = Array.new
|
177
|
+
duplicate.push(self.uniq.
|
178
|
+
map { | e | [self.count(e), e] }.
|
179
|
+
select { | c, _ | c > 1 }.
|
180
|
+
sort.reverse.
|
181
|
+
map { | _, e | "#{e}" })
|
182
|
+
|
183
|
+
return duplicate
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# extract subhash from hash
|
188
|
+
class Hash
|
189
|
+
def extract_subhash(extract)
|
190
|
+
self.select{|k, v| extract.include?(v)}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
require_relative 'get_scenarios'
|
5
|
+
|
6
|
+
class Scenarios
|
7
|
+
|
8
|
+
# path - путь до папки с автотестами, пример - /Users/hripunov/autotests/labirint-test/
|
9
|
+
def initialize(path)
|
10
|
+
# хэш со всеми данными из файла scripts/data
|
11
|
+
@all_data = get_all_data
|
12
|
+
|
13
|
+
# логин в джире
|
14
|
+
@login = @all_data['login']
|
15
|
+
|
16
|
+
# пароль в джире
|
17
|
+
@password = @all_data['jira_pass']
|
18
|
+
|
19
|
+
# ключ проекта в формате LABIOS
|
20
|
+
@key = @all_data['project_key']
|
21
|
+
|
22
|
+
# путь до папки с автотестами
|
23
|
+
@path = path
|
24
|
+
|
25
|
+
# токен в джире
|
26
|
+
@auth = 'Basic ' + Base64.encode64( "#{@login}:#{@password}" ).chomp
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :path, :auth, :key, :login
|
30
|
+
|
31
|
+
# для импорта необходимо запустить метод import_scenarios
|
32
|
+
# импортирует все сценарии из проекта в репозиторий тестов, перемещая тесты в соответствующие папки
|
33
|
+
def import_scenarios
|
34
|
+
# через api xray больше нельзя создавать новые сценрарии, только обновлять существующие
|
35
|
+
# поэтому сначала создаем недостающие сценарии в джира через ее api
|
36
|
+
new_scenarios = GetScenarios.new
|
37
|
+
if new_scenarios.get_all_scenarios_not_exists_in_jira.any?
|
38
|
+
Kernel.puts "Будут созданы #{new_scenarios.get_all_scenarios_not_exists_in_jira.count} новых сценариев:"
|
39
|
+
Kernel.puts new_scenarios.get_all_scenarios_not_exists_in_jira
|
40
|
+
new_scenarios.create_all_missing_test
|
41
|
+
end
|
42
|
+
|
43
|
+
file_names = Dir["#{@path}features/scenarios/**/*.feature"]
|
44
|
+
file_names.each do |file_name|
|
45
|
+
p file_name
|
46
|
+
|
47
|
+
response = import_feature_files(file_name)
|
48
|
+
parse_response = JSON.parse(response.body)
|
49
|
+
Kernel.puts(parse_response)
|
50
|
+
test_key = []
|
51
|
+
parse_response.each{|x| test_key << x['key']}
|
52
|
+
|
53
|
+
p test_key
|
54
|
+
|
55
|
+
folder_name = File.basename(file_name, ".feature")
|
56
|
+
|
57
|
+
p folder_name
|
58
|
+
|
59
|
+
folderid = get_folderid_by_name(folder_name)
|
60
|
+
|
61
|
+
# если папки в репозитории нет - создаем ее
|
62
|
+
if folderid.to_s.empty?
|
63
|
+
cur_folder = File.basename(File.dirname(file_name))
|
64
|
+
if cur_folder == 'scenarios'
|
65
|
+
cur_id = get_id_auto_folders
|
66
|
+
else
|
67
|
+
cur_id = get_folderid_by_name(cur_folder)
|
68
|
+
if cur_id.nil?
|
69
|
+
create_folder(cur_folder, get_id_auto_folders)
|
70
|
+
cur_id = get_folderid_by_name(cur_folder)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
p cur_folder
|
74
|
+
create_folder(folder_name, cur_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
folderid = get_folderid_by_name(folder_name)
|
78
|
+
|
79
|
+
if !test_key.empty?
|
80
|
+
move_tests(folderid, test_key)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# считываем данные пользователя из файла
|
86
|
+
def get_all_data
|
87
|
+
Hash[*File.read("#{@path}scripts/data").split(/[, \n]+/)]
|
88
|
+
end
|
89
|
+
|
90
|
+
# получаем id папки с авотестами в репозитории
|
91
|
+
def get_id_auto_folders
|
92
|
+
url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testrepository/#{@key}/folders"
|
93
|
+
|
94
|
+
response = RestClient.get url, {:Authorization => @auth}
|
95
|
+
# Kernel.puts(response)
|
96
|
+
|
97
|
+
parse_response = JSON.parse(response.body)
|
98
|
+
id_auto = parse_response['folders'].select {|x| x["name"] == "Auto"}[0]['id']
|
99
|
+
Kernel.puts(id_auto)
|
100
|
+
return id_auto
|
101
|
+
end
|
102
|
+
|
103
|
+
def create_folder(name, root_id)
|
104
|
+
url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testrepository/#{@key}/folders/#{root_id}"
|
105
|
+
response = RestClient.post url, {:name => name}.to_json,
|
106
|
+
{:Authorization => @auth,
|
107
|
+
content_type: :json,
|
108
|
+
accept: :json}
|
109
|
+
# Kernel.puts(response)
|
110
|
+
return response
|
111
|
+
end
|
112
|
+
|
113
|
+
# получаем список папок с фичами
|
114
|
+
def get_directories_name
|
115
|
+
dir_name = "#{@path}features/scenarios"
|
116
|
+
all_folders = Dir.entries(dir_name).select {|entry| File.directory? File.join(dir_name, entry) and !(entry =='.' || entry == '..') }
|
117
|
+
all_folders.sort
|
118
|
+
end
|
119
|
+
|
120
|
+
# ищем id папки в репозитории по ее имени
|
121
|
+
def get_folderid_by_name(name)
|
122
|
+
url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testrepository/#{@key}/folders"
|
123
|
+
|
124
|
+
@folder_id = nil
|
125
|
+
|
126
|
+
response = RestClient.get url, {:Authorization => @auth}
|
127
|
+
# Kernel.puts(response)
|
128
|
+
parse_response = JSON.parse(response.body)
|
129
|
+
|
130
|
+
auto = {}
|
131
|
+
parse_response['folders'].each{|x| x["name"] == "Auto" ? auto.update(x) : false}
|
132
|
+
|
133
|
+
ind = auto['folders'].index{|x| x['name'] == name}
|
134
|
+
|
135
|
+
if !ind.nil?
|
136
|
+
@folder_id = auto['folders'][ind]['id']
|
137
|
+
end
|
138
|
+
|
139
|
+
if @folder_id.to_s.empty?
|
140
|
+
auto['folders'].each_with_index do |(x, y), ind|
|
141
|
+
x['folders'].index{|x| x["name"] == name}.nil? ? false : ind_sub = x["folders"].index{|x| x["name"] == name}
|
142
|
+
if !ind_sub.nil?
|
143
|
+
@folder_id = auto['folders'][ind]['folders'][ind_sub]['id']
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
p @folder_id
|
148
|
+
return @folder_id
|
149
|
+
end
|
150
|
+
|
151
|
+
# имортируем фича файл
|
152
|
+
def import_feature_files(file_name)
|
153
|
+
url = "https://jira.surfstudio.ru/rest/raven/1.0/import/feature?projectKey=#{@key}"
|
154
|
+
|
155
|
+
RestClient.post url, { :multipart => true,
|
156
|
+
:file => File.new(file_name, 'rb')},
|
157
|
+
{ :Authorization => @auth}
|
158
|
+
end
|
159
|
+
|
160
|
+
# перемещаем выгруженные сценарии в нужную папку
|
161
|
+
def move_tests(folderid, tests)
|
162
|
+
# https://jira.surfstudio.ru/rest/raven/1.0/folderStructure/moveTests?destinationId=1757
|
163
|
+
url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testrepository/#{@key}/folders/#{folderid}/tests"
|
164
|
+
p url
|
165
|
+
p tests
|
166
|
+
response = RestClient.put url, {:add => tests}.to_json,
|
167
|
+
{:Authorization => @auth,
|
168
|
+
content_type: :json,
|
169
|
+
accept: :json}
|
170
|
+
Kernel.puts(response)
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
password=12345678
|
4
|
+
alias=my
|
5
|
+
|
6
|
+
echo "===== RUNNING SIGNING ====================="
|
7
|
+
|
8
|
+
static_param="{\"keystore_location\":\"my.keystore\",\"keystore_password\":\"12345678\",\"keystore_alias\":\"my\"}"
|
9
|
+
echo $static_param > /.calabash_settings
|
10
|
+
calabash-android resign L.apk
|
11
|
+
|
12
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
echo "enter json name with tests form file name.json in root dir in format <name>"
|
3
|
+
|
4
|
+
read json
|
5
|
+
|
6
|
+
echo "\nвведите код прогона TEST-EXECUTION в формате <BZN-344>"
|
7
|
+
echo "\nenter exec key TEST-EXECUTION in format <KEYPROJ-344>"
|
8
|
+
|
9
|
+
read code
|
10
|
+
|
11
|
+
|
12
|
+
username=$(head -n 2 ./Scripts/user | tail -n 1)
|
13
|
+
password=$(head -n 3 ./Scripts/user | tail -n 1)
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
curl -H "Content-Type: application/json" -X POST -u $username:$password --data @$json.json https://jira.surfstudio.ru/rest/raven/1.0/api/testexec/$code/test
|