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,28 @@
1
+ require 'rest-client'
2
+
3
+ # we use API-method for a clearing state
4
+
5
+ def delete_all_posts_from_profile
6
+
7
+ token = $user[:accesstoken]
8
+ user_id = $user[:userid]
9
+
10
+ response_posts = RestClient.get 'https://test/users/' + user_id + '/posts?filter=0&limit=100&offset=0',
11
+ {'access-token' => token}
12
+
13
+ post_id = Array.new
14
+ post_id.clear
15
+
16
+ list_post = JSON.parse(response_posts.body)
17
+ post_items = list_post['items']
18
+ post_items.each {|value| post_id << value['id']}
19
+
20
+ for i in 0..post_id.length - 1
21
+
22
+ RestClient.delete 'https://test/posts/' + post_id[i].to_s,
23
+ {'access-token' => token}
24
+
25
+ sleep(1.5)
26
+ end
27
+
28
+ end
@@ -0,0 +1,186 @@
1
+ require 'rest-client'
2
+ require 'csv'
3
+ require 'base64'
4
+ require 'benchmark'
5
+ require 'json'
6
+
7
+ $main_big_boom_address = "https://snaptest.ps.surfstudio.ru/api/"
8
+ $api_mark_as_not_finished = "mark_not_finished/"
9
+ $api_create_execution = "create_execution/"
10
+ $api_create_feature = "create_feature/"
11
+ $api_create_step = "create_step/"
12
+ $api_compare = "compare/"
13
+ $api_add_video = "add_video/"
14
+ $stack_trace_file_name = "stacktrace.log"
15
+
16
+ #запрос POST возвращающий весь response
17
+ def request_post(address, json = {})
18
+ begin
19
+ headers = {content_type: :json, accept: :json, Authorization: $token}
20
+ RestClient::Request.execute(
21
+ :url => $main_big_boom_address + address,
22
+ :method => :post,
23
+ :headers => headers,
24
+ :payload => json.to_json,
25
+ :verify_ssl => false
26
+ )
27
+ rescue RestClient::ExceptionWithResponse => e
28
+ if e.http_code == 401
29
+ fail("Указан недействительный Api-Key")
30
+ else
31
+ print(e.http_body)
32
+ fail("Запрос завершился не успешно: #{e.http_code}")
33
+ end
34
+ end
35
+ end
36
+
37
+ # формируем json и отправляем post запрос create_execution, полученный execution_id сохраняем в глобальную переменную
38
+ def create_execution_base(execution_name, device, app_version, os_version)
39
+ object = {
40
+ 'execution_name' => execution_name.to_s,
41
+ 'device' => device.to_s,
42
+ 'app_version' => app_version.to_s,
43
+ 'os_version' => os_version.to_s
44
+ }
45
+ get_execution_data = request_post($api_create_execution, object)
46
+ execution_data = JSON.parse(get_execution_data)
47
+ $execution_id = execution_data['execution_id']
48
+ end
49
+
50
+ # формируем json и отправляем post запрос create_feature, полученный feature_id сохраняем в глобальную переменную
51
+ def create_feature_base(execution_id, feature_name)
52
+ object = {
53
+ 'execution_id' => execution_id,
54
+ 'feature_name' => feature_name.to_s
55
+ }
56
+ get_feature_data = request_post($api_create_feature, object)
57
+ feature_data = JSON.parse(get_feature_data)
58
+ $feature_id = feature_data['feature_id']
59
+ end
60
+
61
+ # временный запрос для фикса бд
62
+ def fix_ids
63
+ object = {}
64
+ get_api_key
65
+ fix_ids = request_post($api_fix_image_paths, object)
66
+ end
67
+
68
+
69
+ # формируем json и отправляем post запрос create_step, полученный step_id сохраняем в глобальную переменную
70
+ def create_step_base(feature_id, step_name, device, resolution)
71
+ object = {
72
+ 'feature_id' => feature_id,
73
+ 'step_name' => step_name.to_s,
74
+ 'device' => device.to_s,
75
+ 'resolution' => resolution
76
+ }
77
+ get_step_data = request_post($api_create_step, object)
78
+ body_step_data = JSON.parse(get_step_data)
79
+ $step_id = body_step_data['step_id']
80
+ end
81
+
82
+ # формируем json и отправляем post запрос mark feature as not finished
83
+ def compare_base(step_id, screenshot)
84
+ object = {
85
+ 'step_id' => step_id,
86
+ 'photo' => screenshot.to_s,
87
+ }
88
+ request_post($api_compare, object)
89
+ end
90
+
91
+ # формируем json и отправляем post запрос mark feature as not finished
92
+ def video_base(feature_id, video)
93
+ object = {
94
+ 'feature_id' => feature_id,
95
+ 'video' => video.to_s,
96
+ }
97
+ request_post($api_add_video, object)
98
+ end
99
+
100
+ # формируем json и отправляем post запрос помечающий фичу как not finished
101
+ def mark_feature_as_not_finished(feature_id = $feature_id)
102
+ begin
103
+ stack_trace = File.readlines($stack_trace_file_name).drop(1)
104
+ rescue
105
+ stack_trace = "file with stack trace not found"
106
+ end
107
+ object = {
108
+ 'feature_id' => feature_id,
109
+ 'stack_trace' => stack_trace.to_s
110
+ }
111
+ request_post($api_mark_as_not_finished, object)
112
+ end
113
+
114
+ # создаём прогон с передаваемым названием и сохраняем его id в глобальную переменную
115
+ def create_execution(execution_name)
116
+ get_api_key
117
+ $main.get_device_data
118
+ $execution_id = create_execution_base(execution_name, $device_name, $app_version, $os_version)
119
+ end
120
+
121
+ # создаём фичу с передаваемым названием и сохраняем его id в глобальную переменную
122
+ def create_feature(execution_id = $execution_id, feature_name)
123
+ $feature_id = create_feature_base(execution_id, feature_name)
124
+ end
125
+
126
+ # создаём шаг, делаем скриншот с устройства и запускаем процесс сравнения на сервере
127
+ def create_test_step(step_name)
128
+ create_step(step_name)
129
+ screenshot_path = take_screenshot(step_name)
130
+ img_base64 = file_to_base64(screenshot_path)
131
+ File.delete(screenshot_path)
132
+ compare(img_base64)
133
+ end
134
+
135
+ # создаём шаг в созданном прогоне с передаваемым названием и сохраняем его id в глобальную переменную
136
+ def create_step(feature_id = $feature_id, step_name)
137
+ $step_id = create_step_base(feature_id, step_name, $device_name, $resolution)
138
+ end
139
+
140
+ # запускаем процесс сравнения на бэке, отправляем айди шага и скриншот для сравнения
141
+ def compare(step_id = $step_id, screenshot)
142
+ compare_base(step_id, screenshot)
143
+ end
144
+
145
+ # создаём шаг, делаем скриншот с устройства и запускаем процесс сравнения на сервере
146
+ def send_video(feature_id = $feature_id, video_path)
147
+ sleep(2)
148
+ video_base64 = file_to_base64(video_path)
149
+ video_base(feature_id, video_base64)
150
+ #File.delete(video_path)
151
+ end
152
+
153
+ # достаём из файла api key и сохраняем его в глобальную переменную
154
+ def get_api_key
155
+ file_path = "./api_key.txt"
156
+ if File.exist?(file_path)
157
+ file = File.new("./api_key.txt","r:UTF-8")
158
+ api_key = file.readlines
159
+ $token = "Api-Key #{api_key[0]}"
160
+ file.close
161
+ else
162
+ fail("Файл с Api Key не найден.")
163
+ end
164
+ end
165
+
166
+ # сделать скриншот и записать его куда надо
167
+ def take_screenshot(name)
168
+ path = './reports/'
169
+ name = "#{name}.png"
170
+ screenshot_path = screenshot(:prefix => path, :name => name)
171
+ end
172
+
173
+ # на входе получаем фото или видео и кодируем его в base64
174
+ def file_to_base64(file_path)
175
+ base64_file =
176
+ File.open(file_path, "rb") do |file|
177
+ Base64.strict_encode64(file.read)
178
+ end
179
+ return base64_file
180
+ end
181
+
182
+
183
+ # очищаем файл в котором находится весь вывод, если этот файл существует
184
+ def clear_file_with_stack_trace
185
+ File.open($stack_trace_file_name, 'w'){ |file| file.truncate(0) } if File.exists?($stack_trace_file_name)
186
+ end
@@ -0,0 +1,8 @@
1
+
2
+ #all your scenarios should be here
3
+ Feature:
4
+ @android @reinstall
5
+ Scenario: Test
6
+ When I start the application
7
+ And I use gmail for authorization
8
+
@@ -0,0 +1,8 @@
1
+ #language: ru
2
+
3
+ #all your scenarios should be here
4
+ Функция:
5
+ @android @reinstall
6
+ Сценарий: Тест
7
+ Когда Я запускаю приложение
8
+ И Я использую Gmail для авторизации
@@ -0,0 +1,43 @@
1
+ #language: ru
2
+ # Definitions or Ruby for all steps in Gherkin
3
+
4
+ И (/^Я запускаю приложение$/) do
5
+ wait_for do
6
+ !query('*').empty?
7
+ end
8
+ end
9
+
10
+
11
+ And (/^I start the application$/) do
12
+ wait_for do
13
+ !query('*').empty?
14
+ end
15
+
16
+ end
17
+
18
+ Тогда(/^Я использую Gmail для авторизации$/) do
19
+ $user = CREDENTIALS[:twitter]
20
+ $test.wait_element($test.auth_field)
21
+ end
22
+
23
+
24
+ Тогда(/^Я использую Gmail для авторизации$/) do
25
+ $user = CREDENTIALS[:twitter]
26
+ $test.wait_element($test.auth_field)
27
+ $test.authorize("#{$user[:token].to_s}%#{$user[:number].to_s}")
28
+ end
29
+
30
+
31
+ And(/^I use gmail for authorization$/) do
32
+ $user = CREDENTIALS[:twitter]
33
+ $test.wait_element($test.auth_field)
34
+ $test.authorize("#{$user[:token].to_s}%#{$user[:number].to_s}")
35
+ end
36
+
37
+ И(/^Я авторизуюсь от разных пользователей$/) do
38
+ if ENV['PLATFORM'] == 'ios'
39
+ steps %Q{И Я авторизуюсь под пользователем для ios}
40
+ elsif ENV['PLATFORM'] == 'android'
41
+ steps %Q{И Я авторизуюсь под пользователем для android}
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ # Some hard-coded user-data for authorization e.g.
2
+ CREDENTIALS = {
3
+
4
+ test_gmail: {
5
+ network: "test.testikov@gmail.com | Test",
6
+ number: 3,
7
+ token: "test",
8
+ accesstoken: "test",
9
+ userid: "482"
10
+ }
11
+ }
@@ -0,0 +1,8 @@
1
+ if ENV['PLATFORM'] == 'ios'
2
+ require 'calabash-cucumber/cucumber'
3
+ require_relative '../ios/pages/standard/IosCommon'
4
+ elsif ENV['PLATFORM'] == 'android'
5
+ require 'calabash-android/cucumber'
6
+ require_relative '../../features/android/pages/standard/DroidCommon'
7
+ end
8
+
@@ -0,0 +1,21 @@
1
+ #On the start execution we should create all Page objects.
2
+
3
+ if ENV['PLATFORM'] == 'ios'
4
+
5
+ Before do |scenario|
6
+ init_ios
7
+ end
8
+
9
+ elsif ENV['PLATFORM'] == 'android'
10
+
11
+ Before do |scenario|
12
+ init_android
13
+ end
14
+
15
+ else Kernel.puts('Error in hooks.rb file!')
16
+
17
+ end
18
+
19
+
20
+
21
+
@@ -0,0 +1,8 @@
1
+ LOCALE = {
2
+ rus: {
3
+ content_in_feed_world: "Международный"
4
+ },
5
+ eng: {
6
+ content_in_feed_world: "International"
7
+ }
8
+ }
@@ -0,0 +1,95 @@
1
+ class Find
2
+
3
+ def find_id_dev(path)
4
+
5
+ sub_lines = Array.new
6
+
7
+ # path to dir with r-files
8
+ file_names = Dir["#{path}/**/R.java"]
9
+
10
+ file_names.each do |name|
11
+ Kernel.puts(name)
12
+
13
+ lines = Array.new
14
+ text=File.open(name).read
15
+ text.gsub!(/\r\n?/, "\n")
16
+ text.each_line do |line|
17
+ lines.push(line)
18
+ end
19
+
20
+ if !lines.index{|x| x.match(/public static final class id {/)}.nil?
21
+
22
+ start_push = false
23
+ lines.each do |x|
24
+ if !x.match(/public static final class id {/).nil?
25
+ start_push = true
26
+ elsif !x.match(/\s}/).nil?
27
+ start_push = false
28
+ end
29
+ if start_push and x.match(/public static final class id {/).nil? and x.match(/}/).nil?
30
+ x.sub! /.*int/, ''
31
+ x.sub! /\=.*/, ''
32
+ sub_lines.push(x.strip)
33
+ end
34
+ end
35
+ sub_lines.uniq!
36
+ end
37
+ end
38
+
39
+ p sub_lines.length
40
+ return sub_lines
41
+ end
42
+
43
+ def find_id_test(path)
44
+ sub_lines = Array.new
45
+
46
+ file_names = Dir["#{path}/**/*.rb"]
47
+ file_names.each do |name|
48
+
49
+ Kernel.puts(name)
50
+
51
+ lines = Array.new
52
+ text=File.open(name).read
53
+ text.gsub!(/\r\n?/, "\n")
54
+ text.each_line do |line|
55
+ lines.push(line)
56
+ end
57
+
58
+ if !lines.index{|x| x.match(/def initialize/)}.nil?
59
+
60
+ start_push = false
61
+ lines.each do |x|
62
+ if !x.match(/\@/).nil?
63
+ start_push = true
64
+ elsif !x.match(/end}/).nil?
65
+ start_push = false
66
+ end
67
+ if start_push and !x.match(/@/).nil? and
68
+ !x.match(/\* id/).nil? and
69
+ x.match(/CONTAINS/).nil? and
70
+ x.match(/\.widget/).nil? and
71
+ x.match(/\.BEGINSWITH/).nil? and
72
+ x.match(/text:/).nil? and
73
+ x.sub! /.*\* id:'/, ''
74
+ x.sub! /'".*/, ''
75
+ x.sub! /' index:.*/, ''
76
+ sub_lines.push(x.strip)
77
+ end
78
+ end
79
+
80
+ sub_lines.uniq!
81
+ end
82
+ end
83
+
84
+ p sub_lines.length
85
+ return sub_lines
86
+ end
87
+
88
+ def get_miss_id(dev_path, test_path)
89
+ miss_id = find_id_test(test_path) - find_id_dev(dev_path)
90
+
91
+ File.open("miss_id.txt", "w+") do |f|
92
+ miss_id.each{|x| f.puts(x)}
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,39 @@
1
+ require 'json'
2
+
3
+ class GroupScenarios
4
+
5
+ # get all failed scenarios
6
+ def parse_json(json_file)
7
+ file = File.read(json_file)
8
+ data_hash = JSON.parse(file)
9
+
10
+ failed_steps = Hash.new
11
+
12
+ data_hash.each do |feature|
13
+ feature['elements'].each do |scenarios|
14
+ scenarios['steps'].each do |steps|
15
+ if steps['result']['status'] == 'failed'
16
+ hash_key = scenarios['name']
17
+ failed_steps[hash_key] = steps['name']
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ return failed_steps
24
+ end
25
+
26
+ def group_failed_scenarios(json_file, output_file)
27
+ group_hash = parse_json(json_file).group_by{ |k, v| v}
28
+ File.open(output_file, "w:UTF-8") do |file|
29
+ group_hash.each do |step, values|
30
+ count = values.count
31
+ file.puts("\nНа шаге '#{step}' упало #{count} сценария:")
32
+ values.each do |element|
33
+ element.delete(step)
34
+ file.puts(" #{element[0]}")
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end