deliver 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/bin/deliver +58 -13
- data/lib/assets/DeliverfileDefault +0 -5
- data/lib/deliver.rb +1 -1
- data/lib/deliver/app.rb +7 -6
- data/lib/deliver/app_metadata.rb +8 -148
- data/lib/deliver/app_metadata_screenshots.rb +153 -0
- data/lib/deliver/deliver_process.rb +24 -0
- data/lib/deliver/deliverer.rb +19 -0
- data/lib/deliver/deliverfile/deliverfile_creator.rb +1 -1
- data/lib/deliver/deliverfile/dsl.rb +7 -3
- data/lib/deliver/itunes_connect/itunes_connect.rb +72 -0
- data/lib/deliver/itunes_connect/itunes_connect_additional.rb +90 -0
- data/lib/deliver/itunes_connect/itunes_connect_app_icon.rb +35 -0
- data/lib/deliver/itunes_connect/itunes_connect_app_rating.rb +68 -0
- data/lib/deliver/itunes_connect/itunes_connect_helper.rb +83 -0
- data/lib/deliver/itunes_connect/itunes_connect_login.rb +61 -0
- data/lib/deliver/itunes_connect/itunes_connect_new_version.rb +57 -0
- data/lib/deliver/itunes_connect/itunes_connect_reader.rb +60 -0
- data/lib/deliver/itunes_connect/itunes_connect_submission.rb +222 -0
- data/lib/deliver/version.rb +1 -1
- metadata +12 -5
- data/lib/deliver/commands/init.rb +0 -10
- data/lib/deliver/commands/run.rb +0 -24
- data/lib/deliver/itunes_connect.rb +0 -552
data/lib/deliver/commands/run.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
command :run do |c|
|
4
|
-
c.syntax = 'deliver'
|
5
|
-
c.description = 'Run a deploy process using the Deliverfile in the current folder'
|
6
|
-
c.option '--force', 'Runs a deployment without verifying any information (PDF file). This can be used for build servers.'
|
7
|
-
c.option '--beta', 'Runs a deployment to beta build on iTunes Connect'
|
8
|
-
c.option '--skip-deploy', 'Skips deployment on iTunes Connect'
|
9
|
-
c.action do |args, options|
|
10
|
-
path = (Deliver::Helper.fastlane_enabled?? './fastlane' : '.')
|
11
|
-
Dir.chdir(path) do # switch the context
|
12
|
-
if File.exists?(deliver_path)
|
13
|
-
# Everything looks alright, use the given Deliverfile
|
14
|
-
options.default :beta => false, :skip_deploy => false
|
15
|
-
Deliver::Deliverer.new(deliver_path, force: options.force, is_beta_ipa: options.beta, skip_deploy: options.skip_deploy)
|
16
|
-
else
|
17
|
-
Deliver::Helper.log.warn("No Deliverfile found at path '#{deliver_path}'.")
|
18
|
-
if agree("Do you want to create a new Deliverfile at the current directory? (y/n)", true)
|
19
|
-
Deliver::DeliverfileCreator.create(enclosed_directory)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,552 +0,0 @@
|
|
1
|
-
require 'capybara'
|
2
|
-
require 'capybara/poltergeist'
|
3
|
-
require 'fastimage'
|
4
|
-
require 'credentials_manager/password_manager'
|
5
|
-
|
6
|
-
|
7
|
-
module Deliver
|
8
|
-
# Everything that can't be achived using the {Deliver::ItunesTransporter}
|
9
|
-
# will be scripted using the iTunesConnect frontend.
|
10
|
-
#
|
11
|
-
# Every method you call here, might take a time
|
12
|
-
class ItunesConnect
|
13
|
-
# This error occurs only if there is something wrong with the given login data
|
14
|
-
class ItunesConnectLoginError < StandardError
|
15
|
-
end
|
16
|
-
|
17
|
-
# This error can occur for many reaons. It is
|
18
|
-
# usually raised when a UI element could not be found
|
19
|
-
class ItunesConnectGeneralError < StandardError
|
20
|
-
end
|
21
|
-
|
22
|
-
include Capybara::DSL
|
23
|
-
|
24
|
-
ITUNESCONNECT_URL = "https://itunesconnect.apple.com/"
|
25
|
-
APP_DETAILS_URL = "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/[[app_id]]"
|
26
|
-
|
27
|
-
BUTTON_STRING_NEW_VERSION = "New Version"
|
28
|
-
BUTTON_STRING_SUBMIT_FOR_REVIEW = "Submit for Review"
|
29
|
-
BUTTON_ADD_NEW_BUILD = 'Click + to add a build before you submit your app.'
|
30
|
-
|
31
|
-
WAITING_FOR_REVIEW = "Waiting For Review"
|
32
|
-
PROCESSING_TEXT = "Processing"
|
33
|
-
|
34
|
-
def initialize
|
35
|
-
super
|
36
|
-
|
37
|
-
DependencyChecker.check_dependencies
|
38
|
-
|
39
|
-
Capybara.run_server = false
|
40
|
-
Capybara.default_driver = :poltergeist
|
41
|
-
Capybara.javascript_driver = :poltergeist
|
42
|
-
Capybara.current_driver = :poltergeist
|
43
|
-
Capybara.app_host = ITUNESCONNECT_URL
|
44
|
-
|
45
|
-
# Since Apple has some SSL errors, we have to configure the client properly:
|
46
|
-
# https://github.com/ariya/phantomjs/issues/11239
|
47
|
-
Capybara.register_driver :poltergeist do |a|
|
48
|
-
conf = ['--debug=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1']
|
49
|
-
Capybara::Poltergeist::Driver.new(a, {
|
50
|
-
phantomjs_options: conf,
|
51
|
-
phantomjs_logger: File.open("/tmp/poltergeist_log.txt", "a"),
|
52
|
-
js_errors: false
|
53
|
-
})
|
54
|
-
end
|
55
|
-
|
56
|
-
page.driver.headers = { "Accept-Language" => "en" }
|
57
|
-
|
58
|
-
self.login
|
59
|
-
end
|
60
|
-
|
61
|
-
# Loggs in a user with the given login data on the iTC Frontend.
|
62
|
-
# You don't need to pass a username and password. It will
|
63
|
-
# Automatically be fetched using the {CredentialsManager::PasswordManager}.
|
64
|
-
# This method will also automatically be called when triggering other
|
65
|
-
# actions like {#open_app_page}
|
66
|
-
# @param user (String) (optional) The username/email address
|
67
|
-
# @param password (String) (optional) The password
|
68
|
-
# @return (bool) true if everything worked fine
|
69
|
-
# @raise [ItunesConnectGeneralError] General error while executing
|
70
|
-
# this action
|
71
|
-
# @raise [ItunesConnectLoginError] Login data is wrong
|
72
|
-
def login(user = nil, password = nil)
|
73
|
-
begin
|
74
|
-
Helper.log.info "Logging into iTunesConnect"
|
75
|
-
|
76
|
-
user ||= CredentialsManager::PasswordManager.shared_manager.username
|
77
|
-
password ||= CredentialsManager::PasswordManager.shared_manager.password
|
78
|
-
|
79
|
-
result = visit ITUNESCONNECT_URL
|
80
|
-
raise "Could not open iTunesConnect" unless result['status'] == 'success'
|
81
|
-
|
82
|
-
(wait_for_elements('#accountpassword') rescue nil) # when the user is already logged in, this will raise an exception
|
83
|
-
|
84
|
-
if page.has_content?"My Apps"
|
85
|
-
# Already logged in
|
86
|
-
return true
|
87
|
-
end
|
88
|
-
|
89
|
-
fill_in "accountname", with: user
|
90
|
-
fill_in "accountpassword", with: password
|
91
|
-
|
92
|
-
begin
|
93
|
-
(wait_for_elements(".enabled").first.click rescue nil) # Login Button
|
94
|
-
wait_for_elements('.homepageWrapper.ng-scope')
|
95
|
-
|
96
|
-
if page.has_content?"My Apps"
|
97
|
-
# Everything looks good
|
98
|
-
else
|
99
|
-
raise ItunesConnectLoginError.new("Looks like your login data was correct, but you do not have access to the apps.")
|
100
|
-
end
|
101
|
-
rescue => ex
|
102
|
-
Helper.log.debug(ex)
|
103
|
-
raise ItunesConnectLoginError.new("Error logging in user #{user} with the given password. Make sure you entered them correctly.")
|
104
|
-
end
|
105
|
-
|
106
|
-
Helper.log.info "Successfully logged into iTunesConnect"
|
107
|
-
|
108
|
-
true
|
109
|
-
rescue => ex
|
110
|
-
error_occured(ex)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Opens the app details page of the given app.
|
115
|
-
# @param app (Deliver::App) the app that should be opened
|
116
|
-
# @return (bool) true if everything worked fine
|
117
|
-
# @raise [ItunesConnectGeneralError] General error while executing
|
118
|
-
# this action
|
119
|
-
# @raise [ItunesConnectLoginError] Login data is wrong
|
120
|
-
def open_app_page(app)
|
121
|
-
begin
|
122
|
-
verify_app(app)
|
123
|
-
|
124
|
-
Helper.log.info "Opening detail page for app #{app}"
|
125
|
-
|
126
|
-
visit APP_DETAILS_URL.gsub("[[app_id]]", app.apple_id.to_s)
|
127
|
-
|
128
|
-
wait_for_elements('.page-subnav')
|
129
|
-
sleep 3
|
130
|
-
|
131
|
-
if current_url.include?"wa/defaultError" # app could not be found
|
132
|
-
raise "Could not open app details for app '#{app}'. Make sure you're using the correct Apple ID and the correct Apple developer account (#{CredentialsManager::PasswordManager.shared_manager.username}).".red
|
133
|
-
end
|
134
|
-
|
135
|
-
true
|
136
|
-
rescue => ex
|
137
|
-
error_occured(ex)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# This method will fetch the current status ({Deliver::App::AppStatus})
|
142
|
-
# of your app and return it. This method uses a headless browser
|
143
|
-
# under the hood, so it might take some time until you get the result
|
144
|
-
# @param app (Deliver::App) the app you want this information from
|
145
|
-
# @raise [ItunesConnectGeneralError] General error while executing
|
146
|
-
# this action
|
147
|
-
# @raise [ItunesConnectLoginError] Login data is wrong
|
148
|
-
def get_app_status(app)
|
149
|
-
begin
|
150
|
-
verify_app(app)
|
151
|
-
|
152
|
-
open_app_page(app)
|
153
|
-
|
154
|
-
if page.has_content?WAITING_FOR_REVIEW
|
155
|
-
# That's either Upload Received or Waiting for Review
|
156
|
-
if page.has_content?"To submit a new build, you must remove this version from review"
|
157
|
-
return App::AppStatus::WAITING_FOR_REVIEW
|
158
|
-
else
|
159
|
-
return App::AppStatus::UPLOAD_RECEIVED
|
160
|
-
end
|
161
|
-
elsif page.has_content?BUTTON_STRING_NEW_VERSION
|
162
|
-
return App::AppStatus::READY_FOR_SALE
|
163
|
-
elsif page.has_content?BUTTON_STRING_SUBMIT_FOR_REVIEW
|
164
|
-
return App::AppStatus::PREPARE_FOR_SUBMISSION
|
165
|
-
else
|
166
|
-
raise "App status not yet implemented"
|
167
|
-
end
|
168
|
-
rescue Exception => ex
|
169
|
-
error_occured(ex)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
# This method will fetch the version number of the currently live version
|
174
|
-
# of your app and return it. This method uses a headless browser
|
175
|
-
# under the hood, so it might take some time until you get the result
|
176
|
-
# @param app (Deliver::App) the app you want this information from
|
177
|
-
# @raise [ItunesConnectGeneralError] General error while executing
|
178
|
-
# this action
|
179
|
-
# @raise [ItunesConnectLoginError] Login data is wrong
|
180
|
-
def get_live_version(app)
|
181
|
-
begin
|
182
|
-
verify_app(app)
|
183
|
-
|
184
|
-
open_app_page(app)
|
185
|
-
|
186
|
-
begin
|
187
|
-
return first(".status.ready").text.split(" ").first
|
188
|
-
rescue
|
189
|
-
Helper.log.debug "Could not fetch version number of the live version for app #{app}."
|
190
|
-
return nil
|
191
|
-
end
|
192
|
-
rescue => ex
|
193
|
-
error_occured(ex)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
#####################################################
|
200
|
-
# @!group Constructive/Destructive Methods
|
201
|
-
#####################################################
|
202
|
-
|
203
|
-
# This method creates a new version of your app using the
|
204
|
-
# iTunesConnect frontend. This will happen directly after calling
|
205
|
-
# this method.
|
206
|
-
# @param app (Deliver::App) the app you want to modify
|
207
|
-
# @param version_number (String) the version number as string for
|
208
|
-
# the new version that should be created
|
209
|
-
def create_new_version!(app, version_number)
|
210
|
-
begin
|
211
|
-
current_version = get_live_version(app)
|
212
|
-
|
213
|
-
verify_app(app)
|
214
|
-
open_app_page(app)
|
215
|
-
|
216
|
-
if page.has_content?BUTTON_STRING_NEW_VERSION
|
217
|
-
|
218
|
-
if current_version == version_number
|
219
|
-
# This means, this version is already live on the App Store
|
220
|
-
raise "Version #{version_number} is already created, submitted and released on iTC. Please verify you're using a new version number."
|
221
|
-
end
|
222
|
-
|
223
|
-
click_on BUTTON_STRING_NEW_VERSION
|
224
|
-
|
225
|
-
Helper.log.info "Creating a new version (#{version_number})"
|
226
|
-
|
227
|
-
all(".fullWidth.nobottom.ng-isolate-scope.ng-pristine").last.set(version_number.to_s)
|
228
|
-
click_on "Create"
|
229
|
-
|
230
|
-
while not page.has_content?"Prepare for Submission"
|
231
|
-
sleep 1
|
232
|
-
Helper.log.debug("Waiting for 'Prepare for Submission'")
|
233
|
-
end
|
234
|
-
else
|
235
|
-
Helper.log.warn "Can not create version #{version_number} on iTunesConnect. Maybe it was already created."
|
236
|
-
Helper.log.info "Check out '#{current_url}' what's the latest version."
|
237
|
-
|
238
|
-
begin
|
239
|
-
created_version = first(".status.waiting").text.split(" ").first
|
240
|
-
if created_version != version_number
|
241
|
-
raise "Some other version ('#{created_version}') was created instead of the one you defined ('#{version_number}')"
|
242
|
-
end
|
243
|
-
rescue => ex
|
244
|
-
# Can not fetch the version number of the new version (this happens, when it's e.g. 'Developer Rejected')
|
245
|
-
unless page.has_content?version_number
|
246
|
-
raise "Some other version was created instead of the one you defined ('#{version_number}')."
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
true
|
252
|
-
rescue => ex
|
253
|
-
error_occured(ex)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
# def update_app_icon!(app, path)
|
258
|
-
# raise "App icon not found at path '#{path}'" unless File.exists?(path)
|
259
|
-
# size = FastImage.size(path)
|
260
|
-
# raise "App icon must have the resolution of 1024x1024px" unless (size[0] == 1024 and size[1] == 1024)
|
261
|
-
|
262
|
-
# begin
|
263
|
-
# verify_app(app)
|
264
|
-
# open_app_page(app)
|
265
|
-
|
266
|
-
# Capybara.ignore_hidden_elements = false
|
267
|
-
|
268
|
-
# icon_area = first(:xpath, "//div[@url='tempPageContent.appIconDisplayUrl']")
|
269
|
-
# delete_button = icon_area.first(".deleteButton")
|
270
|
-
# input = icon_area.first(:xpath, ".//input[@type='file']")
|
271
|
-
|
272
|
-
|
273
|
-
# Capybara.ignore_hidden_elements = true
|
274
|
-
# first(:button, "Save").click
|
275
|
-
|
276
|
-
# rescue => ex
|
277
|
-
# error_occured(ex)
|
278
|
-
# end
|
279
|
-
# end
|
280
|
-
|
281
|
-
|
282
|
-
# This will put the latest uploaded build as a new beta build
|
283
|
-
def put_build_into_beta_testing!(app, version_number)
|
284
|
-
begin
|
285
|
-
verify_app(app)
|
286
|
-
open_app_page(app)
|
287
|
-
|
288
|
-
Helper.log.info("Choosing the latest build on iTunesConnect for beta distribution")
|
289
|
-
|
290
|
-
click_on "Prerelease"
|
291
|
-
|
292
|
-
wait_for_preprocessing
|
293
|
-
|
294
|
-
if all(".switcher.ng-binding").count == 0
|
295
|
-
raise "Could not find beta build on '#{current_url}'. Make sure it is available there"
|
296
|
-
end
|
297
|
-
|
298
|
-
if first(".switcher.ng-binding")['class'].include?"checked"
|
299
|
-
Helper.log.warn("Beta Build seems to be already active. Take a look at '#{current_url}'")
|
300
|
-
return true
|
301
|
-
end
|
302
|
-
|
303
|
-
first(".switcher.ng-binding").click
|
304
|
-
if page.has_content?"Are you sure you want to start testing"
|
305
|
-
click_on "Start"
|
306
|
-
end
|
307
|
-
|
308
|
-
|
309
|
-
return true
|
310
|
-
rescue => ex
|
311
|
-
error_occured(ex)
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
# This will choose the latest uploaded build on iTunesConnect as the production one
|
316
|
-
# After this method, you still have to call submit_for_review to actually submit the
|
317
|
-
# whole update
|
318
|
-
# @param app (Deliver::App) the app you want to choose the build for
|
319
|
-
# @param version_number (String) the version number as string for
|
320
|
-
def put_build_into_production!(app, version_number)
|
321
|
-
begin
|
322
|
-
verify_app(app)
|
323
|
-
open_app_page(app)
|
324
|
-
|
325
|
-
Helper.log.info("Choosing the latest build on iTunesConnect for release")
|
326
|
-
|
327
|
-
click_on "Prerelease"
|
328
|
-
|
329
|
-
wait_for_preprocessing
|
330
|
-
|
331
|
-
################# Apple is finished processing the ipa file #################
|
332
|
-
|
333
|
-
Helper.log.info("Apple finally finished processing the ipa file")
|
334
|
-
open_app_page(app)
|
335
|
-
|
336
|
-
begin
|
337
|
-
first('a', :text => BUTTON_ADD_NEW_BUILD).click
|
338
|
-
wait_for_elements(".buildModalList")
|
339
|
-
sleep 5
|
340
|
-
rescue
|
341
|
-
if page.has_content?"Upload Date"
|
342
|
-
# That's fine, the ipa was already selected
|
343
|
-
return true
|
344
|
-
else
|
345
|
-
raise "Could not find Build Button. It looks like the ipa file was not properly uploaded."
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
if page.all('td', :text => version_number).count > 1
|
350
|
-
Helper.log.fatal "There were multiple submitted builds found. Don't know which one to choose. Just choosing the top one for now"
|
351
|
-
end
|
352
|
-
|
353
|
-
result = page.first('td', :text => version_number).first(:xpath,"./..").first(:css, ".small").click
|
354
|
-
click_on "Done" # Save the modal dialog
|
355
|
-
click_on "Save" # on the top right to save everything else
|
356
|
-
|
357
|
-
error = page.has_content?BUTTON_ADD_NEW_BUILD
|
358
|
-
raise "Could not put build itself onto production. Try opening '#{current_url}'" if error
|
359
|
-
|
360
|
-
return true
|
361
|
-
rescue => ex
|
362
|
-
error_occured(ex)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
# Submits the update itself to Apple, this includes the app metadata and the ipa file
|
367
|
-
# This can easily cause exceptions, which will be shown on iTC.
|
368
|
-
# @param app (Deliver::App) the app you want to submit
|
369
|
-
# @param perms (Hash) information about content rights, ...
|
370
|
-
def submit_for_review!(app, perms = nil)
|
371
|
-
begin
|
372
|
-
verify_app(app)
|
373
|
-
open_app_page(app)
|
374
|
-
|
375
|
-
Helper.log.info("Submitting app for Review")
|
376
|
-
|
377
|
-
if not page.has_content?BUTTON_STRING_SUBMIT_FOR_REVIEW
|
378
|
-
if page.has_content?WAITING_FOR_REVIEW
|
379
|
-
Helper.log.info("App is already Waiting For Review")
|
380
|
-
return true
|
381
|
-
else
|
382
|
-
raise "Couldn't find button with name '#{BUTTON_STRING_SUBMIT_FOR_REVIEW}'"
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
click_on BUTTON_STRING_SUBMIT_FOR_REVIEW
|
387
|
-
sleep 4
|
388
|
-
|
389
|
-
errors = (all(".pagemessage.error") || []).count > 0
|
390
|
-
raise "Some error occured when submitting the app for review: '#{current_url}'" if errors
|
391
|
-
|
392
|
-
wait_for_elements(".savingWrapper.ng-scope.ng-pristine")
|
393
|
-
wait_for_elements(".radiostyle")
|
394
|
-
sleep 3
|
395
|
-
|
396
|
-
if page.has_content?"Content Rights"
|
397
|
-
# Looks good.. just a few more steps
|
398
|
-
|
399
|
-
perms ||= {
|
400
|
-
export_compliance: {
|
401
|
-
encryption_updated: false,
|
402
|
-
cryptography_enabled: false,
|
403
|
-
is_exempt: false
|
404
|
-
},
|
405
|
-
third_party_content: {
|
406
|
-
contains_third_party_content: false,
|
407
|
-
has_rights: false
|
408
|
-
},
|
409
|
-
advertising_identifier: {
|
410
|
-
use_idfa: false,
|
411
|
-
serve_advertisement: false,
|
412
|
-
attribute_advertisement: false,
|
413
|
-
attribute_actions: false,
|
414
|
-
limit_ad_tracking: false
|
415
|
-
}
|
416
|
-
}
|
417
|
-
|
418
|
-
basic = "//*[@itc-radio='submitForReviewAnswers"
|
419
|
-
checkbox = "//*[@itc-checkbox='submitForReviewAnswers"
|
420
|
-
|
421
|
-
#####################
|
422
|
-
# Export Compliance #
|
423
|
-
#####################
|
424
|
-
if page.has_content?"Export"
|
425
|
-
|
426
|
-
if not perms[:export_compliance][:encryption_updated] and perms[:export_compliance][:cryptography_enabled]
|
427
|
-
raise "encryption_updated must be enabled if cryptography_enabled is enabled!"
|
428
|
-
end
|
429
|
-
|
430
|
-
begin
|
431
|
-
encryption_updated_control = all(:xpath, "#{basic}.exportCompliance.encryptionUpdated.value' and @radio-value='#{perms[:export_compliance][:encryption_updated]}']//input")
|
432
|
-
encryption_updated_control[0].trigger('click') if encryption_updated_control.count > 0
|
433
|
-
first(:xpath, "#{basic}.exportCompliance.usesEncryption.value' and @radio-value='#{perms[:export_compliance][:cryptography_enabled]}']//input").trigger('click')
|
434
|
-
first(:xpath, "#{basic}.exportCompliance.isExempt.value' and @radio-value='#{perms[:export_compliance][:is_exempt]}']//input").trigger('click')
|
435
|
-
rescue
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
##################
|
440
|
-
# Content Rights #
|
441
|
-
##################
|
442
|
-
if page.has_content?"Content Rights"
|
443
|
-
if not perms[:third_party_content][:contains_third_party_content] and perms[:third_party_content][:has_rights]
|
444
|
-
raise "contains_third_party_content must be enabled if has_rights is enabled".red
|
445
|
-
end
|
446
|
-
|
447
|
-
begin
|
448
|
-
first(:xpath, "#{basic}.contentRights.containsThirdPartyContent.value' and @radio-value='#{perms[:third_party_content][:contains_third_party_content]}']//input").trigger('click')
|
449
|
-
first(:xpath, "#{basic}.contentRights.hasRights.value' and @radio-value='#{perms[:third_party_content][:has_rights]}']//input").trigger('click')
|
450
|
-
rescue
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
##########################
|
455
|
-
# Advertising Identifier #
|
456
|
-
##########################
|
457
|
-
if page.has_content?"Advertising Identifier"
|
458
|
-
first(:xpath, "#{basic}.adIdInfo.usesIdfa.value' and @radio-value='#{perms[:advertising_identifier][:use_idfa]}']//a").click rescue nil
|
459
|
-
|
460
|
-
if perms[:advertising_identifier][:use_idfa]
|
461
|
-
if perms[:advertising_identifier][:serve_advertisement]
|
462
|
-
first(:xpath, "#{checkbox}.adIdInfo.servesAds.value']//a").click
|
463
|
-
end
|
464
|
-
if perms[:advertising_identifier][:attribute_advertisement]
|
465
|
-
first(:xpath, "#{checkbox}.adIdInfo.tracksInstall.value']//a").click
|
466
|
-
end
|
467
|
-
if perms[:advertising_identifier][:attribute_actions]
|
468
|
-
first(:xpath, "#{checkbox}.adIdInfo.tracksAction.value']//a").click
|
469
|
-
end
|
470
|
-
if perms[:advertising_identifier][:limit_ad_tracking]
|
471
|
-
first(:xpath, "#{checkbox}.adIdInfo.limitsTracking.value']//a").click
|
472
|
-
end
|
473
|
-
end
|
474
|
-
end
|
475
|
-
|
476
|
-
|
477
|
-
Helper.log.info("Filled out the export compliance and other information on iTC".green)
|
478
|
-
|
479
|
-
click_on "Submit"
|
480
|
-
sleep 5
|
481
|
-
|
482
|
-
if page.has_content?WAITING_FOR_REVIEW
|
483
|
-
# Everything worked :)
|
484
|
-
Helper.log.info("Successfully submitted App for Review".green)
|
485
|
-
return true
|
486
|
-
else
|
487
|
-
raise "So close, it looks like there went something wrong with the actual deployment. Checkout '#{current_url}'".red
|
488
|
-
end
|
489
|
-
else
|
490
|
-
raise "Something is missing here.".red
|
491
|
-
end
|
492
|
-
return false
|
493
|
-
rescue => ex
|
494
|
-
error_occured(ex)
|
495
|
-
end
|
496
|
-
end
|
497
|
-
|
498
|
-
|
499
|
-
private
|
500
|
-
def verify_app(app)
|
501
|
-
raise ItunesConnectGeneralError.new("No valid Deliver::App given") unless app.kind_of?Deliver::App
|
502
|
-
raise ItunesConnectGeneralError.new("App is missing information (apple_id not given)") unless (app.apple_id || '').to_s.length > 5
|
503
|
-
end
|
504
|
-
|
505
|
-
def error_occured(ex)
|
506
|
-
snap
|
507
|
-
raise ex # re-raise the error after saving the snapshot
|
508
|
-
end
|
509
|
-
|
510
|
-
def snap
|
511
|
-
path = "Error#{Time.now.to_i}.png"
|
512
|
-
save_screenshot(path, :full => true)
|
513
|
-
system("open '#{path}'")
|
514
|
-
end
|
515
|
-
|
516
|
-
# Since Apple takes for ages, after the upload is properly processed, we have to wait here
|
517
|
-
def wait_for_preprocessing
|
518
|
-
started = Time.now
|
519
|
-
|
520
|
-
# Wait, while iTunesConnect is processing the uploaded file
|
521
|
-
while page.has_content?"Uploaded"
|
522
|
-
# iTunesConnect is super slow... so we have to wait...
|
523
|
-
Helper.log.info("Sorry, we have to wait for iTunesConnect, since it's still processing the uploaded ipa file\n" +
|
524
|
-
"If this takes longer than 45 minutes, you have to re-upload the ipa file again.\n" +
|
525
|
-
"You can always open the browser page yourself: '#{current_url}'\n" +
|
526
|
-
"Passed time: ~#{((Time.now - started) / 60.0).to_i} minute(s)")
|
527
|
-
sleep 60
|
528
|
-
visit current_url
|
529
|
-
sleep 10
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
|
-
def wait_for_elements(name)
|
534
|
-
counter = 0
|
535
|
-
results = all(name)
|
536
|
-
while results.count == 0
|
537
|
-
# Helper.log.debug "Waiting for #{name}"
|
538
|
-
sleep 0.2
|
539
|
-
|
540
|
-
results = all(name)
|
541
|
-
|
542
|
-
counter += 1
|
543
|
-
if counter > 100
|
544
|
-
Helper.log.debug page.html
|
545
|
-
Helper.log.debug caller
|
546
|
-
raise ItunesConnectGeneralError.new("Couldn't find element '#{name}' after waiting for quite some time")
|
547
|
-
end
|
548
|
-
end
|
549
|
-
return results
|
550
|
-
end
|
551
|
-
end
|
552
|
-
end
|