Class: Fastlane::Saucectl::Suites

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
lib/fastlane/plugin/saucectl/helper/suites.rb

Overview

This class will create test suites based on user specified configuration properties

Constant Summary collapse

UI =
FastlaneCore::UI

Constants included from FileUtils

FileUtils::CLASS_NAME_REGEX, FileUtils::FILE_TYPE_REGEX

Instance Method Summary collapse

Methods included from FileUtils

#find, #read_file, #search_retrieve_test_classes, #syscall

Constructor Details

#initialize(config) ⇒ Suites

Returns a new instance of Suites.



17
18
19
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 17

def initialize(config)
  @config = config
end

Instance Method Details

#android_test_optionsObject



193
194
195
196
197
198
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 193

def android_test_options
  {
    'clearPackageData' => @config[:clear_data],
    'useTestOrchestrator' => @config[:use_test_orchestrator]
  }
end

#check_kindObject



31
32
33
34
35
36
37
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 31

def check_kind
  if @config[:platform].eql?('android')
    UI.user_error!("#{@config[:kind]} is not a supported test framework for android. Use espresso") unless @config[:kind].eql?('espresso')
  else
    UI.user_error!("#{@config[:kind]} is not a supported test framework for iOS. Use xcuitest") unless @config[:kind].eql?('xcuitest')
  end
end

#create_real_device_suitesObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 128

def create_real_device_suites
  if !@config[:test_plan].nil? && @config[:test_distribution].eql?('class')
    test_plan_suites
  elsif @config[:test_distribution] == 'shard'
    shard_real_device_suites
  elsif @config[:test_class].kind_of?(Array)
    custom_test_classes
  else
    test_suites = []
    @config[:devices].each do |device|
      test_distribution_array.each do |test_type|
        test_suites << {
          'name' => suite_name(test_type).downcase,
          'testOptions' => default_test_options(test_type)
        }.merge(real_device_options(device))
      end
    end
    test_suites
  end
end

#create_test_planObject



21
22
23
24
25
26
27
28
29
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 21

def create_test_plan
  check_kind
  if @config[:platform].casecmp('ios').zero?
    is_ios_reqs_satisfied?
    Fastlane::Saucectl::XCTest.new(@config)
  else
    Fastlane::Saucectl::Espresso.new(@config)
  end
end

#create_virtual_device_suitesObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 57

def create_virtual_device_suites
  if @config[:test_distribution] == 'shard'
    shard_virtual_device_suites
  elsif @config[:test_class]
    custom_test_classes
  else
    test_suites = []
    @config[:emulators].each do |emulator|
      test_distribution_array.each do |test_type|
        test_suites << {
          'name' => suite_name(test_type).downcase,
          'testOptions' => default_test_options(test_type)
        }.merge(virtual_device_options(emulator))
      end
    end
    test_suites
  end
end

#custom_test_classesObject



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 114

def custom_test_classes
  test_suites = []
  devices = @config[:devices].nil? ? @config[:emulators] : @config[:devices]
  devices.each do |device|
    device_options = @config[:devices].nil? ? virtual_device_options(device) : real_device_options(device)
    test_classes = @config[:test_class].reject(&:empty?).join(',')
    test_suites << {
      'name' => suite_name(device[:name]).downcase,
      'testOptions' => default_test_options(test_classes.split(','))
    }.merge(device_options)
  end
  test_suites
end

#default_test_options(test_type) ⇒ Object



184
185
186
187
188
189
190
191
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 184

def default_test_options(test_type)
  test_option_type = @config[:test_distribution].eql?('package') ? 'package' : 'class'
  if @config[:platform] == 'android'
    { test_option_type => test_type }.merge(android_test_options)
  else
    { 'class' => test_type }
  end
end

#device_options(device) ⇒ Object



176
177
178
179
180
181
182
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 176

def device_options(device)
  {
    'carrierConnectivity' => device[:carrier_connectivity],
    'deviceType' => device[:device_type].upcase!,
    'private' => device[:private]
  }
end

#is_ios_reqs_satisfied?Boolean

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 39

def is_ios_reqs_satisfied?
  if @config[:test_target].nil? && @config[:test_plan].nil?
    UI.user_error!("❌ For ios you must specify test_target or test_plan")
  end
end

#rdc_options(device) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 160

def rdc_options(device)
  device_type_key = device.key?(:id) ? 'id' : 'name'
  name = device.key?(:id) ? device[:id] : device[:name]

  base_device_hash = {
    device_type_key => name,
    'orientation' => device[:orientation]
  }.merge('options' => device_options(device))

  unless device[:platform_version].nil?
    base_device_hash = base_device_hash.merge({ 'platformVersion' => device[:platform_version] })
  end

  base_device_hash
end

#real_device_options(device) ⇒ Object



156
157
158
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 156

def real_device_options(device)
  { 'devices' => [rdc_options(device)] }
end

#shard_real_device_suitesObject



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 90

def shard_real_device_suites
  test_suites = []
  arr = test_distribution_array
  shards = arr.each_slice((arr.size / @config[:devices].size.to_f).round).to_a
  shards.each_with_index do |suite, i|
    test_suites << {
      'name' => suite_name("shard #{i + 1}").downcase,
      'testOptions' => default_test_options(suite)
    }.merge(real_device_options(@config[:devices][i]))
  end
  test_suites
end

#shard_virtual_device_suitesObject



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 76

def shard_virtual_device_suites
  UI.user_error!("❌ Cannot split #{@config[:test_distribution]}'s across virtual devices with a single emulator. \nPlease specify a minimum of two devices!") if @config[:emulators].size.eql?(1)
  test_suites = []
  arr = test_distribution_array
  shards = arr.each_slice((arr.size / @config[:emulators].size.to_f).round).to_a
  shards.each_with_index do |suite, i|
    test_suites << {
      'name' => suite_name("shard #{i + 1}").downcase,
      'testOptions' => default_test_options(suite)
    }.merge(virtual_device_options(@config[:emulators][i]))
  end
  test_suites
end

#suite_name(test_type) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 49

def suite_name(test_type)
  if ENV['JOB_NAME'].nil? && ENV['BUILD_NUMBER'].nil?
    "#{@config[:kind]}-#{test_type.split('.')[-1]}"
  else
    "#{ENV['JOB_NAME']}-#{ENV['BUILD_NUMBER']}-#{test_type.split('.')[-1]}"
  end
end

#test_distribution_arrayObject



45
46
47
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 45

def test_distribution_array
  @config[:test_class] || create_test_plan.test_distribution
end

#test_plan_suitesObject



103
104
105
106
107
108
109
110
111
112
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 103

def test_plan_suites
  test_suites = []
  @config[:devices].each do |device|
    test_suites << {
      'name' => suite_name(@config[:test_plan].to_s).downcase,
      'testOptions' => default_test_options(test_distribution_array)
    }.merge(real_device_options(device))
  end
  test_suites
end

#virtual_device_options(device) ⇒ Object



149
150
151
152
153
154
# File 'lib/fastlane/plugin/saucectl/helper/suites.rb', line 149

def virtual_device_options(device)
  platform_versions = device[:platform_versions].reject(&:empty?).join(',')
  { 'emulators' => [{ 'name' => device[:name],
                      'orientation' => device[:orientation],
                      'platformVersions' => platform_versions.split(',') }] }
end