Class: Sigh::DeveloperCenter
- Inherits:
-
Object
- Object
- Sigh::DeveloperCenter
show all
- Includes:
- Capybara::DSL
- Defined in:
- lib/sigh/developer_center.rb
Defined Under Namespace
Classes: DeveloperCenterGeneralError, DeveloperCenterLoginError
Constant Summary
collapse
- APPSTORE =
"AppStore"
- ADHOC =
"AdHoc"
- DEVELOPMENT =
"Development"
- DEVELOPER_CENTER_URL =
"https://developer.apple.com/devcenter/ios/index.action"
- PROFILES_URL =
"https://developer.apple.com/account/ios/profile/profileList.action?type=production"
- PROFILES_URL_DEV =
"https://developer.apple.com/account/ios/profile/profileList.action?type=limited"
Instance Method Summary
collapse
Constructor Details
Returns a new instance of DeveloperCenter.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/sigh/developer_center.rb', line 31
def initialize
FileUtils.mkdir_p TMP_FOLDER
Capybara.run_server = false
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
Capybara.current_driver = :poltergeist
Capybara.app_host = DEVELOPER_CENTER_URL
Capybara.register_driver :poltergeist do |a|
conf = ['--debug=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1']
Capybara::Poltergeist::Driver.new(a, {
phantomjs_options: conf,
phantomjs_logger: File.open("#{TMP_FOLDER}/poltergeist_log.txt", "a"),
js_errors: false
})
end
page.driver. = { "Accept-Language" => "en" }
self.login
end
|
Instance Method Details
#create_profile(app_identifier, type) ⇒ Object
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
# File 'lib/sigh/developer_center.rb', line 245
def create_profile(app_identifier, type)
Helper.log.info "Creating new profile for app '#{app_identifier}' for type '#{type}'.".yellow
certificate = code_signing_certificate(type)
create_url = "https://developer.apple.com/account/ios/profile/profileCreate.action"
visit create_url
enterprise = false
begin
wait_for_elements('#type-production')
rescue => ex
wait_for_elements('#type-inhouse') enterprise = true
end
value = (enterprise ? 'inhouse' : 'store')
value = 'limited' if type == DEVELOPMENT
value = 'adhoc' if type == ADHOC
first(:xpath, "//input[@type='radio' and @value='#{value}']").click
click_next
while not page.has_content?"Select App ID" do sleep 1 end
identifiers = all(:xpath, "//option[contains(text(), '.#{app_identifier})')]")
if identifiers.count == 0
puts "Couldn't find App ID '#{app_identifier}'\nonly found the following bundle identifiers:".red
all(:xpath, "//option").each do |current|
puts "\t- #{current.text}".yellow
end
raise "Could not find Apple ID '#{app_identifier}'.".red
else
identifiers.first.select_option
end
click_next
while not page.has_content?"Select certificates" do sleep 1 end
sleep 3
Helper.log.info "Using certificate ID '#{certificate['certificateId']}' from '#{certificate['ownerName']}'"
id = certificate["certificateId"]
certs = all(:xpath, "//input[@type='radio' and @value='[#{id}]']") if type != DEVELOPMENT certs = all(:xpath, "//input[@type='checkbox' and @value='#{id}']") if type == DEVELOPMENT if certs.count != 1
Helper.log.info "Looking for certificate: #{certificate}. Found: #{certs.count}"
raise "Could not find certificate in the list of available certificates."
end
certs.first.click
click_next
if type != APPSTORE
wait_for_elements('.selectAll.column')
sleep 3
first(:xpath, "//div[@class='selectAll column']/input").click click_next
end
wait_for_elements('.distributionType')
profile_name = [app_identifier, type].join(' ')
fill_in "provisioningProfileName", with: profile_name
click_next
wait_for_elements('.row-details')
end
|
#download_profile(profile_id) ⇒ Object
340
341
342
343
344
|
# File 'lib/sigh/developer_center.rb', line 340
def download_profile(profile_id)
download_cert_url = "/account/ios/profile/profileContentDownload.action?displayId=#{profile_id}"
return download_file(download_cert_url)
end
|
#login(user = nil, password = nil) ⇒ bool
Loggs in a user with the given login data on the Dev Center Frontend. You don’t need to pass a username and password. It will Automatically be fetched using the CredentialsManager::PasswordManager. This method will also automatically be called when triggering other actions like #open_app_page
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/sigh/developer_center.rb', line 67
def login(user = nil, password = nil)
begin
Helper.log.info "Login into iOS Developer Center"
user ||= CredentialsManager::PasswordManager.shared_manager.username
password ||= CredentialsManager::PasswordManager.shared_manager.password
result = visit PROFILES_URL
raise "Could not open Developer Center" unless result['status'] == 'success'
if page.has_content?"Member Center"
return true
end
(wait_for_elements(".button.blue").first.click rescue nil)
(wait_for_elements('#accountpassword') rescue nil)
if page.has_content?"Member Center"
return true
end
fill_in "accountname", with: user
fill_in "accountpassword", with: password
all(".button.large.blue.signin-button").first.click
begin
if page.has_content?"Select Team" select_team
end
rescue => ex
Helper.log.debug ex
raise DeveloperCenterLoginError.new("Error loggin in user #{user}. User is on multiple teams and we were unable to correctly retrieve them.")
end
begin
wait_for_elements('.ios.profiles.gridList')
visit PROFILES_URL rescue => ex
Helper.log.debug ex
if page.has_content?"Getting Started"
raise "There was no valid signing certificate found. Please log in and follow the 'Getting Started guide' on '#{current_url}'".red
else
raise DeveloperCenterLoginError.new("Error logging in user #{user} with the given password. Make sure you entered them correctly.")
end
end
Helper.log.info "Login successful"
true
rescue => ex
error_occured(ex)
end
end
|
#maintain_app_certificate(app_identifier, type) ⇒ Object
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
# File 'lib/sigh/developer_center.rb', line 184
def maintain_app_certificate(app_identifier, type)
begin
if type == DEVELOPMENT
visit PROFILES_URL_DEV
else
visit PROFILES_URL
end
@list_certs_url = wait_for_variable('profileDataURL')
Helper.log.info "Fetching all available provisioning profiles..."
certs = post_ajax(@list_certs_url)
Helper.log.info "Checking if profile is available. (#{certs['provisioningProfiles'].count} profiles found)"
certs['provisioningProfiles'].each do |current_cert|
if type == DEVELOPMENT
if current_cert['type'] != "iOS Development"
next
end
end
if type != DEVELOPMENT
if not ['iOS Distribution', 'iOS UniversalDistribution'].include?current_cert['type']
next
end
end
details = profile_details(current_cert['provisioningProfileId'])
if details['provisioningProfile']['appId']['identifier'] == app_identifier
if type == APPSTORE and details['provisioningProfile']['deviceCount'] > 0
next end
if type != APPSTORE and details['provisioningProfile']['deviceCount'] == 0
next end
if current_cert['status'] == 'Active'
return download_profile(details['provisioningProfile']['provisioningProfileId']) elsif ['Expired', 'Invalid'].include?current_cert['status']
renew_profile(current_cert['provisioningProfileId'], type) return maintain_app_certificate(app_identifier, type) end
break
end
end
Helper.log.info "Could not find existing profile. Trying to create a new one."
create_profile(app_identifier, type)
return maintain_app_certificate(app_identifier, type)
rescue => ex
error_occured(ex)
end
end
|
#renew_profile(profile_id, type) ⇒ Object
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
# File 'lib/sigh/developer_center.rb', line 317
def renew_profile(profile_id, type)
certificate = code_signing_certificate type
details_url = "https://developer.apple.com/account/ios/profile/profileEdit.action?type=&provisioningProfileId=#{profile_id}"
Helper.log.info "Renewing provisioning profile '#{profile_id}' using URL '#{details_url}'"
visit details_url
Helper.log.info "Using certificate ID '#{certificate['certificateId']}' from '#{certificate['ownerName']}'"
wait_for_elements('.selectCertificates')
certs = all(:xpath, "//input[@type='radio' and @value='#{certificate["certificateId"]}']")
if certs.count == 1
certs.first.click
click_next
wait_for_elements('.row-details')
click_on "Done"
else
Helper.log.info "Looking for certificate: #{certificate}. Found: #{certs}"
raise "Could not find certificate in the list of available certificates."
end
end
|
#run(app_identifier, type, cert_name = nil) ⇒ Object
170
171
172
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/sigh/developer_center.rb', line 170
def run(app_identifier, type, cert_name = nil)
cert = maintain_app_certificate(app_identifier, type)
type_name = type
type_name = "Distribution" if type == APPSTORE cert_name ||= "#{type_name}_#{app_identifier}.mobileprovision" cert_name += '.mobileprovision' unless cert_name.include?'mobileprovision'
output_path = TMP_FOLDER + cert_name
File.write(output_path, cert)
return output_path
end
|
#select_team ⇒ Object
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/sigh/developer_center.rb', line 127
def select_team
team_id = ENV["SIGH_TEAM_ID"]
team_id = nil if team_id.to_s.length == 0
unless team_id
Helper.log.info "You can store you preferred team using the environment variable `SIGH_TEAM_ID`".green
Helper.log.info "Your ID belongs to the following teams:".green
end
available_options = []
teams = find("div.input").all('.team-value') teams.each_with_index do |val, index|
current_team_id = '"' + val.find("input").value + '"'
team_text = val.find(".label-primary").text
description_text = val.find(".label-secondary").text
description_text = "(#{description_text})" unless description_text.empty? index_text = (index + 1).to_s + "."
available_options << [index_text, current_team_id, team_text, description_text].join(" ")
end
unless team_id
puts available_options.join("\n").green
team_index = ask("Please select the team number you would like to access: ".green)
team_id = teams[team_index.to_i - 1].find(".radio").value
end
team_button = first(:xpath, "//input[@type='radio' and @value='#{team_id}']") if team_button
team_button.click
else
Helper.log.fatal "Could not find given Team. Available options: ".red
puts available_options.join("\n").yellow
raise DeveloperCenterLoginError.new("Error finding given team #{team_id}.".red)
end
all(".button.large.blue.submit").first.click
result = visit PROFILES_URL
raise "Could not open Developer Center" unless result['status'] == 'success'
end
|