SurfCustomCalabash 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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