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,24 @@
1
+ #!/usr/bin/env bash
2
+
3
+ echo "введите название фича файла с обновленными тестами из папки features/scenarios/name.feature в формате <name>"
4
+ echo "enter feature file name with updated tests from dir features/scenarios/name.feature in format <name>"
5
+
6
+ read path
7
+
8
+ index=0
9
+ while read line; do
10
+ array[$index]="$line"
11
+ index=$(($index+1))
12
+ done < ./Scripts/data
13
+
14
+ first_string="${array[0]}"
15
+ username=${first_string/login /}
16
+
17
+ second_string="${array[1]}"
18
+ password=${second_string/jira_pass /}
19
+
20
+ third_string="${array[2]}"
21
+ code=${third_string/project_key /}
22
+
23
+
24
+ curl -H "Content-Type: multipart/form-data" -u $username:$password -F "file=@features/scenarios/$path.feature" https://jira.surfstudio.ru/rest/raven/1.0/import/feature?projectKey=$code
@@ -0,0 +1,96 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+ require 'base64'
4
+
5
+
6
+ class Execution
7
+
8
+ # path - path to dir with autotests, пример - /Users/user_name/autotests/project-test/
9
+ def initialize(path)
10
+
11
+ # hash with data from file scripts/data
12
+ @all_data = get_all_data
13
+
14
+ # login in jira
15
+ @login = @all_data['login']
16
+
17
+ # pass in jira
18
+ @password = @all_data['jira_pass']
19
+
20
+ # project key
21
+ @key = @all_data['project_key']
22
+
23
+ # path to dir with autotests
24
+ @path = path
25
+
26
+ @auth = 'Basic ' + Base64.encode64( "#{@login}:#{@password}" ).chomp
27
+ end
28
+
29
+ attr_accessor :path
30
+
31
+ # read user data from file
32
+ def get_all_data
33
+ Hash[*File.read("#{@path}scripts/data").split(/[, \n]+/)]
34
+ end
35
+
36
+ def get_test_execution(test_exec)
37
+
38
+ key_arr = []
39
+
40
+ for i in 1..2
41
+ url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testexec/#{test_exec}/test?page=#{i}"
42
+
43
+ response = RestClient.get url, {:Authorization => @auth}
44
+ # Kernel.puts(response)
45
+ parse_response = JSON.parse(response.body)
46
+
47
+ # Kernel.puts(parse_response)
48
+
49
+ parse_response.each do |keys|
50
+ key_arr << keys['key']
51
+ end
52
+ end
53
+
54
+ Kernel.puts(key_arr.sort)
55
+
56
+ $test_keys = key_arr.sort
57
+ end
58
+
59
+
60
+ def delete_test_from_execution(test_exec)
61
+
62
+ p "Start Delete"
63
+ # begin
64
+ url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testexec/#{test_exec}/test"
65
+ response = RestClient.post url, {:remove => $test_keys}.to_json,
66
+ {:Authorization => @auth,
67
+ content_type: :json,
68
+ accept: :json}
69
+ end
70
+
71
+ def add_test_to_execution(test_exec)
72
+
73
+ p "Start Update"
74
+
75
+ url = "https://jira.surfstudio.ru/rest/raven/1.0/api/testexec/#{test_exec}/test"
76
+ response = RestClient.post url, {:add => $test_keys}.to_json,
77
+ {:Authorization => @auth,
78
+ content_type: :json,
79
+ accept: :json}
80
+
81
+ end
82
+
83
+ def update_test_execution(test_exec)
84
+ get_test_execution(test_exec)
85
+ begin
86
+ delete_test_from_execution(test_exec)
87
+ rescue
88
+ p "Timeout error"
89
+ p "Retrying Attempt"
90
+ delete_test_from_execution(test_exec)
91
+ end
92
+
93
+ add_test_to_execution(test_exec)
94
+ end
95
+
96
+ end
@@ -0,0 +1,22 @@
1
+ @Library('surf-lib@version-3.0.0-SNAPSHOT') // https://bitbucket.org/surfstudio/jenkins-pipeline-lib/
2
+ import ru.surfstudio.ci.pipeline.ui_test.UiTestPipelineAndroid
3
+
4
+ //init
5
+ def pipeline = new UiTestPipelineAndroid(this)
6
+ pipeline.init()
7
+
8
+ //configuration
9
+ pipeline.sourceRepoUrl = "TODO add repo source code app"
10
+ pipeline.jiraProjectKey = "TODO add key project in jira"
11
+ pipeline.testBranch = "master" // branch with tests
12
+ pipeline.defaultTaskKey = "TODO add key test execution in jira" //task for run periodically
13
+ pipeline.projectForBuild = “TODO add name project for build in jenkins”
14
+
15
+
16
+ //customization
17
+ pipeline.cronTimeTrigger = "00 02 * * *"
18
+ pipeline.notificationEnabled = false
19
+ pipeline.buildGradleTask = "clean assembleQa"
20
+
21
+ //run
22
+ pipeline.run()
@@ -0,0 +1,23 @@
1
+ @Library('surf-lib@version-3.0.0-SNAPSHOT') // https://bitbucket.org/surfstudio/jenkins-pipeline-lib/
2
+ import ru.surfstudio.ci.pipeline.ui_test.UiTestPipelineiOS
3
+
4
+ //init
5
+ def pipeline = new UiTestPipelineiOS(this)
6
+ pipeline.init()
7
+
8
+ //configuration
9
+ pipeline.sourceRepoUrl = "TODO add repo source code app"
10
+ pipeline.jiraProjectKey = "TODO add key project in jira"
11
+ pipeline.testBranch = "master" // branch with tests
12
+ pipeline.defaultTaskKey = "TODO add key test execution in jira" //task for run periodically
13
+ pipeline.testDeviceName = "iPhone 11"
14
+ pipeline.testOSVersion = "com.apple.CoreSimulator.SimRuntime.iOS-13-3"
15
+ pipeline.testiOSSDK = "iphonesimulator13.2"
16
+ pipeline.projectForBuild = "test"
17
+
18
+ //customization
19
+ pipeline.cronTimeTrigger = "01 04 * * *"
20
+ pipeline.notificationEnabled = false
21
+
22
+ //run
23
+ pipeline.run()
@@ -0,0 +1,24 @@
1
+ # config/cucumber.yml
2
+ ##YAML Template
3
+
4
+ android: PLATFORM=android -r features/support -r features/android/support -r features/android -r features/step_definitions -r features/android/pages -r features/android/pages/standard
5
+ ios: PLATFORM=ios -r features/support -r features/ios/support -r features/step_definitions -r features/ios/pages
6
+ <%
7
+ date = Time.now.strftime('%d_%m-%H:%M:%S')
8
+ default_report = "./output_#{date}_.html"
9
+ default_json = "./output_#{date}.json"
10
+ default_allure = "./output_#{date}.html"
11
+ default_rerun = "./rerun_#{date}.txt"
12
+ %>
13
+
14
+ common: NO_STOP='1'
15
+ rerun_out: -f rerun -o ./reports/<%= default_rerun %>
16
+ html_report: -f html -o ./reports/<%= default_report %>
17
+ json_report: -f json -o ./reports/<%= ENV['DEVICE_INFO']%>.json
18
+ json_xray: -f json -o ./reports/<%= ENV['DEVICE_INFO']%>_<%= ENV['ADB_DEVICE_ARG']%>.json
19
+
20
+
21
+ run: -p common -p rerun_out -p html_report -p json_report -p allure_report -p json_xray
22
+
23
+
24
+
@@ -0,0 +1,33 @@
1
+ require 'calabash-android'
2
+ require 'SurfCustomCalabash/DroidMethods'
3
+
4
+ class DroidCommon
5
+
6
+ # system methods
7
+ def initialize(driver)
8
+ @driver = driver
9
+ end
10
+
11
+ def method_missing (sym, *args, &block)
12
+ @driver.send sym, *args, &block
13
+ end
14
+
15
+ def self.element(name, &block)
16
+ define_method(name.to_s, &block)
17
+ end
18
+
19
+ class << self
20
+ alias :value :element
21
+ alias :action :element
22
+ alias :trait :element
23
+ end
24
+
25
+ # custom methods
26
+ def go_back
27
+ sleep(1.5)
28
+ press_back_button
29
+ sleep(1)
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,8 @@
1
+ require_relative 'DroidCommon'
2
+
3
+ def init_android
4
+ $test = Test.new(self)
5
+ # write here creating new class instances like example above this line
6
+ end
7
+
8
+
@@ -0,0 +1,43 @@
1
+ require_relative 'standard/DroidCommon.rb'
2
+ # all screens your application screens should be like this. Inheritance from DroidCommon is essential!
3
+
4
+ class Test < DroidCommon
5
+ def initialize(driver)
6
+
7
+ @driver = driver
8
+
9
+ ##### elements on the screen #######
10
+
11
+ # elements locators and their x-platform nickname should be like that
12
+
13
+ @trait = "* id:'feed_rv'"
14
+
15
+ @auth_field = "* id:'auth_fld'"
16
+
17
+ @main_ok_button = "* id:'feed_vote_tutorial_go_btn'"
18
+
19
+ end
20
+
21
+ # all elements above should have getter for mention them from step definitions
22
+ attr_reader *Test.new(self).instance_variables.map {|s| s[1..-1]}
23
+
24
+ # another way to describe elements
25
+
26
+ def tape
27
+ "* id:'feed_rv'"
28
+ end
29
+
30
+ #### methods ###########
31
+
32
+ def authorize(data)
33
+ tap_on(@auth_field)
34
+ wait_for_keyboard
35
+ enter_text(data)
36
+ end
37
+
38
+ def test
39
+ tap_on(@main_ok_button)
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,147 @@
1
+ require 'calabash-android/operations'
2
+ require 'calabash-android/management/app_installation'
3
+ require 'calabash-android/cucumber'
4
+ require 'cucumber'
5
+ require 'json'
6
+ require_relative '../../../features/net/screentest_api'
7
+ require 'fileutils'
8
+
9
+ Before do |scenario|
10
+
11
+ ENV['SCREENSHOT_PATH'] = './reports/'
12
+
13
+ @scenario_name = scenario.name
14
+
15
+ @start_record = true
16
+ @start_log = true
17
+
18
+ scenario_tags = scenario.source_tag_names
19
+
20
+ reinstall_apps if scenario_tags.include?('@reinstall')
21
+
22
+ clear_app_data if scenario_tags.include?('@clear')
23
+
24
+ skip_this_scenario('Сценарий только для iOS') if scenario_tags.include?('@skip')
25
+
26
+ if scenario_tags.include?('@screentest')
27
+ clear_file_with_stack_trace
28
+ create_feature(@scenario_name)
29
+ end
30
+
31
+ @start_record = true if scenario_tags.include?('@record')
32
+
33
+ start_test_server_in_background
34
+
35
+ @video_capture = nil
36
+
37
+ # start video record
38
+ if @start_record
39
+ @video_capture = AndroidVideoCapture.new
40
+ @video_capture.start_capture
41
+ @need_convert = false
42
+ # set video quality: low, medium, high
43
+ @video_capture.quality = "low"
44
+ end
45
+
46
+ @write_log = nil
47
+
48
+ # start write logs
49
+ if @start_log
50
+ @write_log = AndroidLogs.new
51
+ @write_log.start_log
52
+ end
53
+ end
54
+
55
+ def file_name(ext)
56
+ "android_#{Time.now.strftime('%d_%m-%H:%M:%S')}.#{ext}"
57
+ end
58
+
59
+ def create_folder
60
+ model = %x(adb devices -l | awk 'NR==2{print $5}')
61
+ model.slice! "model:"
62
+
63
+ @path = "#{ENV['SCREENSHOT_PATH']}#{@scenario_name}_#{model}_#{Time.now.strftime('%d_%m-%H:%M:%S')}/"
64
+ # Dir.mkdir(@path) unless File.directory?(@path)
65
+ FileUtils.mkdir_p @path
66
+ end
67
+
68
+ def convert
69
+ convert_file = "video_#{file_name('mp4')}"
70
+ @video_capture.convert_video(@video_capture.video_file, convert_file)
71
+ delete_file(@video_capture.video_file)
72
+ @video_capture.video_file = convert_file
73
+ end
74
+
75
+ def embed_video
76
+ unless @video_capture.nil?
77
+ @video_capture.acquire_capture
78
+ if File.exist?(@video_capture.video_file)
79
+ convert if @need_convert
80
+ embed(@video_capture.video_file, 'video/mp4', "video #{@video_capture.video_file}")
81
+ FileUtils.mv(@video_capture.video_file, @path)
82
+ @video_capture.video_file = @path + @video_capture.video_file
83
+ end
84
+ end
85
+ end
86
+
87
+ def delete_file(file_name)
88
+ if File.exist?(file_name)
89
+ File.delete(file_name)
90
+ end
91
+ end
92
+
93
+ def embed_logs
94
+ unless @write_log.nil?
95
+ if File.exist?(@write_log.log_file)
96
+ embed(@write_log.log_file, 'log/txt', "log #{@write_log.log_file}")
97
+ FileUtils.mv(@write_log.log_file, @path)
98
+ end
99
+ end
100
+ end
101
+
102
+ After do |scenario|
103
+
104
+ @video_capture.stop_capture unless @video_capture.nil?
105
+
106
+ @write_log.stop_log unless @write_log.nil?
107
+
108
+ scenario_tags = scenario.source_tag_names
109
+
110
+ if scenario_tags.include?('@record') && scenario.passed?
111
+ create_folder
112
+ embed_video
113
+ elsif scenario.passed?
114
+ @video_capture.dispose_capture unless @video_capture.nil?
115
+ delete_file(@write_log.log_file) unless @write_log.nil?
116
+ delete_file(@video_capture.video_file) unless @video_capture.nil?
117
+ end
118
+
119
+ if scenario.failed?
120
+
121
+ create_folder
122
+
123
+ mark_feature_as_not_finished if scenario.source_tag_names.include?('@screentest')
124
+
125
+ pretty = JSON.pretty_generate(query("*"))
126
+ parsed = JSON.parse(pretty)
127
+
128
+ for i in 0..query("*").count-1
129
+ id = parsed[i]['id'].to_s
130
+ text = parsed[i]['text'].to_s
131
+ if id != ''
132
+ File.open("#{@path}id_#{file_name('txt')}", 'a', crlf_newline: true) { |f| f.puts(id.encode(crlf_newline: true))}
133
+ end
134
+ if text != ''
135
+ File.open("#{@path}text_#{file_name('txt')}", 'a', crlf_newline: true) { |f| f.puts(text.encode(crlf_newline: true))}
136
+ end
137
+ end
138
+
139
+ screenshot(prefix: @path, name: "#{file_name('png')}")
140
+ embed_video
141
+ embed_logs
142
+ end
143
+
144
+ send_video(@video_capture.video_file) if scenario.source_tag_names.include?('@record')
145
+ shutdown_test_server
146
+
147
+ end
@@ -0,0 +1,40 @@
1
+ require 'open3'
2
+ require 'timeout'
3
+ require 'process'
4
+ require 'calabash-android/operations'
5
+ require 'calabash-android/env'
6
+
7
+ def adb_command
8
+ "\"#{Calabash::Android::Dependencies.adb_path}\""
9
+ end
10
+
11
+ class AndroidLogs
12
+
13
+ def initialize
14
+ @log_file = "#{ENV['SCREENSHOT_PATH']}log_#{Time.now.strftime('%d_%m-%H:%M:%S')}.txt"
15
+ end
16
+
17
+ attr_reader :log_file
18
+
19
+ def start_log
20
+ package = package_name('L.apk')
21
+ pid_app = %x{adb shell ps | grep #{package} | tr -s [:space:] ' ' | cut -d' ' -f2}
22
+ @logcat = Open3.popen2e("adb logcat | grep #{pid_app}")
23
+ @pid = @logcat[2].pid
24
+ end
25
+
26
+ def stop_log
27
+ %x{ps | grep logcat | grep -v grep | cut -d' ' -f1 | awk '{print $1}' | xargs kill -2}
28
+
29
+ begin
30
+ Timeout.timeout(30) { File.open(@log_file, 'w') { |f| f << @logcat[1].readlines.join("\n") } }
31
+ rescue Timeout::Error
32
+ Kernel.puts("Error write log file")
33
+ @logcat[0].close
34
+ @logcat[1].close
35
+ end
36
+
37
+ @logcat[0].close
38
+ @logcat[1].close
39
+ end
40
+ end