SurfCustomCalabash 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +68 -4
  4. data/SurfCustomCalabash.gemspec +3 -3
  5. data/bin/SurfCustomCalabash +54 -0
  6. data/bin/surf-calabash-console.rb +62 -0
  7. data/bin/surf-calabash-gen.rb +17 -0
  8. data/bin/surf-calabash-helpers.rb +34 -0
  9. data/lib/SurfCustomCalabash/CommonMethods.rb +3 -3
  10. data/lib/SurfCustomCalabash/DroidMethods.rb +2 -1
  11. data/lib/SurfCustomCalabash/IosMethods.rb +2 -2
  12. data/lib/SurfCustomCalabash/version.rb +1 -1
  13. data/sources/Backdoors list b/data/sources/Backdoors → list +0 -0
  14. data/sources/Gemfile +27 -0
  15. data/sources/Scripts/and.sh +5 -0
  16. data/sources/Scripts/ca.sh +5 -0
  17. data/sources/Scripts/ci.sh +5 -0
  18. data/sources/Scripts/data +7 -0
  19. data/sources/Scripts/fa.sh +6 -0
  20. data/sources/Scripts/fi.sh +5 -0
  21. data/sources/Scripts/get_apk.rb +68 -0
  22. data/sources/Scripts/get_scenarios.rb +193 -0
  23. data/sources/Scripts/import_scenarios.rb +172 -0
  24. data/sources/Scripts/ios.sh +5 -0
  25. data/sources/Scripts/parallel_android_smoke.sh +4 -0
  26. data/sources/Scripts/parallel_android_test.sh +4 -0
  27. data/sources/Scripts/ra.sh +12 -0
  28. data/sources/Scripts/ri.sh +9 -0
  29. data/sources/Scripts/smoke_and.sh +5 -0
  30. data/sources/Scripts/smoke_ios.sh +5 -0
  31. data/sources/Scripts/ta.sh +5 -0
  32. data/sources/Scripts/ti.sh +5 -0
  33. data/sources/Scripts/to_exec.sh +19 -0
  34. data/sources/Scripts/update.sh +24 -0
  35. data/sources/Scripts/update_exec.rb +96 -0
  36. data/sources/TestFolder/small.gif +0 -0
  37. data/sources/ci/JenkinsfileUiTestAndroid.groovy +22 -0
  38. data/sources/ci/JenkinsfileUiTestIos.groovy +23 -0
  39. data/sources/config/cucumber.yml +24 -0
  40. data/sources/features/android/pages/standard/DroidCommon.rb +33 -0
  41. data/sources/features/android/pages/standard/Init_android.rb +8 -0
  42. data/sources/features/android/pages/test.rb +43 -0
  43. data/sources/features/android/support/app_life_cycle_hooks.rb +147 -0
  44. data/sources/features/android/support/log_hooks_and.rb +40 -0
  45. data/sources/features/android/support/video_hooks_and.rb +110 -0
  46. data/sources/features/ios/pages/standard/Init_ios.rb +5 -0
  47. data/sources/features/ios/pages/standard/IosCommon.rb +30 -0
  48. data/sources/features/ios/pages/test.rb +37 -0
  49. data/sources/features/ios/support/01_launch.rb +194 -0
  50. data/sources/features/ios/support/log_hooks_ios.rb +40 -0
  51. data/sources/features/ios/support/video_hooks_ios.rb +58 -0
  52. data/sources/features/net/net.rb +28 -0
  53. data/sources/features/net/screentest_api.rb +186 -0
  54. data/sources/features/scenarios/eng.feature +8 -0
  55. data/sources/features/scenarios/rus.feature +8 -0
  56. data/sources/features/step_definitions/test.rb +43 -0
  57. data/sources/features/support/credentials.rb +11 -0
  58. data/sources/features/support/env.rb +8 -0
  59. data/sources/features/support/hooks.rb +21 -0
  60. data/sources/features/support/localization.rb +8 -0
  61. data/sources/find_id.rb +95 -0
  62. data/sources/group_steps.rb +39 -0
  63. data/sources/irbrcs/android/irbrc +105 -0
  64. data/sources/irbrcs/ios/irbrc +132 -0
  65. data/sources/start.sh +134 -0
  66. metadata +63 -6
  67. data/bin/console +0 -14
  68. 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,5 @@
1
+ #!/bin/bash
2
+
3
+ echo "===== RUNNING TEST SUITE IOS ====================="
4
+ cucumber -p ios
5
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ echo "===== PARLLEL RUNNING SMOKE SUITE ANDROID====================="
4
+ parallel_calabash -a L.apk -o '-p android -f pretty -f html -o outputs/report.html -t @smoke' features/ --concurrent
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ echo "===== PARLLEL RUNNING TEST SUITE ANDROID====================="
4
+ parallel_calabash -a L.apk -o '-p android -f pretty -f html -o reports/'<%= ENV['DEVICE_INFO']%>'.html -t @test' features/ --concurrent
@@ -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,9 @@
1
+ #!/bin/bash
2
+
3
+
4
+ echo "===== RUNNING SIGNING ====================="
5
+
6
+
7
+ yes | calabash-ios setup
8
+
9
+
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ echo "===== RUNNING SMOKE SUITE ANDROID====================="
4
+ calabash-android run L.apk -p android -p html_report -t @smoke
5
+
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ echo "===== RUNNING SMOKE SUITE IOS ====================="
4
+ cucumber -p ios -p html_report -t @smoke
5
+
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ echo "===== RUNNING TEST SUITE ANDROID====================="
4
+ calabash-android run L.apk -p android -t @$1
5
+
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ echo "===== RUNNING TEST SUITE IOS ====================="
4
+ cucumber -p ios -t @$1
5
+
@@ -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