fastlane-plugin-saucectl 0.1.3.pre → 0.1.6.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,168 @@
1
+ require "find"
2
+ require "open3"
3
+ require "json"
4
+ require_relative "file_utils"
5
+
6
+ module Fastlane
7
+ module Saucectl
8
+ # This class is responsible for creating test execution plans for ios applications and will distribute tests
9
+ # that will be be executed via the cloud provider.
10
+ #
11
+ class XCTest
12
+ include FileUtils
13
+ UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
14
+ TEST_FUNCTION_REGEX = /(test+[A-Z][a-zA-Z]+)[(][)]/.freeze
15
+
16
+ def initialize(config)
17
+ @config = config
18
+ end
19
+
20
+ def test_plan_exists?
21
+ File.exist?(Dir["**/#{@config[:test_plan]}.xctestplan"][0])
22
+ rescue StandardError
23
+ false
24
+ end
25
+
26
+ def valid_test_plan?
27
+ File.exist?(Dir["**/#{@config[:test_plan]}.xctestplan"][0])
28
+ rescue StandardError
29
+ UI.user_error!("#{@config[:test_plan]} was not found in workspace")
30
+ end
31
+
32
+ def fetch_test_plan
33
+ plan_path = Dir["**/#{@config[:test_plan]}.xctestplan"][0]
34
+ selected = File.read(plan_path)
35
+ JSON.parse(selected)["testTargets"][0]
36
+ end
37
+
38
+ def fetch_target_from_test_plan
39
+ fetch_test_plan["target"]["name"]
40
+ end
41
+
42
+ def test_data
43
+ if test_plan_exists?
44
+ valid_test_plan?
45
+ if fetch_test_plan.include?("skippedTests")
46
+ strip_skipped(all_tests)
47
+ else
48
+ fetch_selected_tests
49
+ end
50
+ else
51
+ all_tests
52
+ end
53
+ end
54
+
55
+ def test_target
56
+ @config[:test_target].nil? ? fetch_target_from_test_plan : @config[:test_target]
57
+ end
58
+
59
+ def test_distribution
60
+ test_distribution_check
61
+ tests_arr = []
62
+
63
+ test_distribution = @config[:test_plan].nil? ? @config[:test_distribution] : 'testPlan'
64
+ case test_distribution
65
+ when 'testCase', 'testPlan'
66
+ test_data.each do |type|
67
+ type[:tests].each { |test| tests_arr << "#{test_target}.#{type[:class]}/#{test}" }
68
+ end
69
+ else
70
+ test_data.each do |type|
71
+ tests_arr << "#{test_target}.#{type[:class]}"
72
+ end
73
+ end
74
+ tests_arr.uniq
75
+ end
76
+
77
+ def test_distribution_check
78
+ return @config[:test_distribution] if @config[:test_distribution].kind_of?(Array)
79
+
80
+ distribution_types = %w[class testCase shard]
81
+ unless distribution_types.include?(@config[:test_distribution]) || @config[:test_distribution].nil?
82
+ UI.user_error!("#{@config[:test_distribution]} is not a valid method of test distribution. \n Supported types for iOS: \n #{distribution_types}")
83
+ end
84
+ end
85
+
86
+ def fetch_selected_tests
87
+ ui_tests = []
88
+ fetch_test_plan["selectedTests"].each do |test|
89
+ test_case = test.gsub('/', ' ').split
90
+ ui_tests << { class: test_case[0], tests: [test_case[1].gsub(/[()]/, "").to_s] }
91
+ end
92
+ ui_tests
93
+ end
94
+
95
+ def strip_skipped(all_tests)
96
+ enabled_ui_tests = []
97
+ skipped_tests = fetch_disabled_tests
98
+ all_tests.each do |tests|
99
+ tests[:tests].each do |test|
100
+ unless skipped_tests.to_s.include?(test)
101
+ enabled_ui_tests << { class: tests[:class].to_s, tests: [test] }
102
+ end
103
+ end
104
+ end
105
+ enabled_ui_tests
106
+ end
107
+
108
+ def fetch_disabled_tests
109
+ skipped = fetch_test_plan["skippedTests"]
110
+ ui_tests = []
111
+ skipped.each do |item|
112
+ if item.include?('/')
113
+ test_case = item.gsub('/', ' ').split
114
+ ui_tests << sort_ui_tests(test_case[0], test_case[1])
115
+ else
116
+ ui_tests << scan_test_class(item)
117
+ end
118
+ end
119
+ ui_tests
120
+ end
121
+
122
+ def sort_ui_tests(cls, test_case)
123
+ { class: cls, tests: test_case.gsub(/[()]/, "").to_s }
124
+ end
125
+
126
+ def all_tests
127
+ test_details = []
128
+ test_dir = Dir["**/#{test_target}"][0]
129
+ search_retrieve_test_classes(test_dir).each do |f|
130
+ next unless File.basename(f) =~ CLASS_NAME_REGEX
131
+
132
+ test_details << { class: File.basename(f).gsub(FILE_TYPE_REGEX, ""), tests: tests_from(f) }
133
+ end
134
+
135
+ strip_empty(test_details)
136
+ end
137
+
138
+ def scan_test_class(cls)
139
+ test_details = []
140
+ test_dir = Dir["**/#{test_target}"][0]
141
+ search_retrieve_test_classes(test_dir).each do |f|
142
+ next unless File.basename(f) =~ /#{cls}/
143
+
144
+ test_details << { class: File.basename(f).gsub(FILE_TYPE_REGEX, ""), tests: tests_from(f) }
145
+ end
146
+
147
+ strip_empty(test_details)
148
+ end
149
+
150
+ def tests_from(path)
151
+ stdout, = find(path, "func")
152
+ test_cases = []
153
+ stdout.split.each do |line|
154
+ test_cases << line.match(TEST_FUNCTION_REGEX).to_s.gsub(/[()]/, "") if line =~ TEST_FUNCTION_REGEX
155
+ end
156
+ test_cases
157
+ end
158
+
159
+ def strip_empty(test_details)
160
+ tests = []
161
+ test_details.each do |test|
162
+ tests << test unless test[:tests].size.zero?
163
+ end
164
+ tests
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,12 @@
1
+ ---
2
+ platform_error: "No platform specified, set using: platform: 'android'"
3
+ app_path_error: "No App path given, set using: app_path: 'path/to/my/testApp.apk'"
4
+ file_error: "No file path given, set using: app_path: 'path/to/my/testApp.apk'"
5
+ app_name_error: "No App name given, set using: app_name: 'testApp.apk'"
6
+ test_runner_app_error: "No Test runner application given, set using: test_runner_app: 'testRunnerApp.apk'"
7
+ region_error: "$region is an invalid region. Supported regions are 'us' and 'eu'"
8
+ sauce_username_error: "No sauce labs username provided, set using: sauce_username: 'sauce user name', or consider setting your credentials as environment variables."
9
+ sauce_api_key_error: "No sauce labs access key provided, set using: sauce_access_key: '1234' or consider setting your credentials as environment variables."
10
+ supported_regions: ['us', 'eu']
11
+ accepted_file_types: ['.apk', '.aab', '.ipa', '.zip']
12
+ missing_file_name: "Please specify the name of the app that you wish to query on sauce storage"
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module Saucectl
3
+ VERSION = "0.1.6.pre"
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ require 'fastlane'
2
+
3
+ module Fastlane
4
+ module Saucectl
5
+ UI = FastlaneCore::UI
6
+ # Return all .rb files inside the "actions" and "helper" directory
7
+ def self.all_classes
8
+ Dir[File.expand_path('**/actions/*_action.rb', File.dirname(__FILE__))]
9
+ end
10
+ end
11
+ end
12
+
13
+ # By default we want to import all available actions and helpers
14
+ # A plugin can contain any number of actions and plugins
15
+ Fastlane::Saucectl.all_classes.each do |current|
16
+ require current
17
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-saucectl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3.pre
4
+ version: 0.1.6.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Hamilton
@@ -169,7 +169,29 @@ email: ian.ross.hamilton@gmail.com
169
169
  executables: []
170
170
  extensions: []
171
171
  extra_rdoc_files: []
172
- files: []
172
+ files:
173
+ - LICENSE
174
+ - README.md
175
+ - lib/fastlane/plugin/saucectl.rb
176
+ - lib/fastlane/plugin/saucectl/actions/delete_from_storage_action.rb
177
+ - lib/fastlane/plugin/saucectl/actions/disabled_tests_action.rb
178
+ - lib/fastlane/plugin/saucectl/actions/install_saucectl_action.rb
179
+ - lib/fastlane/plugin/saucectl/actions/sauce_apps_action.rb
180
+ - lib/fastlane/plugin/saucectl/actions/sauce_config_action.rb
181
+ - lib/fastlane/plugin/saucectl/actions/sauce_devices_action.rb
182
+ - lib/fastlane/plugin/saucectl/actions/sauce_runner_action.rb
183
+ - lib/fastlane/plugin/saucectl/actions/sauce_upload_action.rb
184
+ - lib/fastlane/plugin/saucectl/helper/api.rb
185
+ - lib/fastlane/plugin/saucectl/helper/config.rb
186
+ - lib/fastlane/plugin/saucectl/helper/espresso.rb
187
+ - lib/fastlane/plugin/saucectl/helper/file_utils.rb
188
+ - lib/fastlane/plugin/saucectl/helper/installer.rb
189
+ - lib/fastlane/plugin/saucectl/helper/runner.rb
190
+ - lib/fastlane/plugin/saucectl/helper/storage.rb
191
+ - lib/fastlane/plugin/saucectl/helper/suites.rb
192
+ - lib/fastlane/plugin/saucectl/helper/xctest.rb
193
+ - lib/fastlane/plugin/saucectl/strings/messages.yml
194
+ - lib/fastlane/plugin/saucectl/version.rb
173
195
  homepage: https://github.com/ianrhamilton/fastlane-plugin-saucectl
174
196
  licenses:
175
197
  - MIT
@@ -183,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
205
  requirements:
184
206
  - - ">="
185
207
  - !ruby/object:Gem::Version
186
- version: '2.6'
208
+ version: '2.5'
187
209
  required_rubygems_version: !ruby/object:Gem::Requirement
188
210
  requirements:
189
211
  - - ">"
@@ -193,5 +215,7 @@ requirements: []
193
215
  rubygems_version: 3.3.7
194
216
  signing_key:
195
217
  specification_version: 4
196
- summary: Test your iOS and and Android apps at scale using Sauce Labs toolkit.
218
+ summary: Simplify the set up, configuration, upload, and execution of espresso and
219
+ XCUITest on the Sauce Labs platform by utilizing fastlane which will enable you
220
+ to test your iOS and Android apps at scale
197
221
  test_files: []