@@ -57,7 +57,7 @@ def self.run(params)
5757
5858 binary_type = binary_type_from_path ( binary_path )
5959 UI . message ( "📡 Uploading the #{ binary_type } ." )
60- operation = upload_binary ( app_name , binary_path , binary_type , client , timeout )
60+ operation = upload_binary ( client , app_name , binary_path , binary_type , timeout )
6161 UI . message ( "🕵️ Validating upload…" )
6262 release = poll_upload_release_operation ( client , operation , binary_type )
6363
@@ -88,11 +88,12 @@ def self.run(params)
8888 test_devices =
8989 get_value_from_value_or_file ( params [ :test_devices ] , params [ :test_devices_file ] )
9090 if present? ( test_devices )
91- UI . message ( "🤖 Starting automated tests. Note: This feature is in beta." )
91+ test_cases =
92+ string_to_array ( get_value_from_value_or_file ( params [ :test_case_ids ] , params [ :test_case_ids_file ] ) ) &.map { |id | "#{ app_name } /testCases/#{ id } " }
9293 test_password = test_password_from_params ( params )
93- release_test = test_release ( alpha_client , release , test_devices , params [ :test_username ] , test_password , params [ :test_username_resource ] , params [ :test_password_resource ] )
94+ release_tests = test_release ( alpha_client , release , test_devices , test_cases , params [ :test_username ] , test_password , params [ :test_username_resource ] , params [ :test_password_resource ] )
9495 unless params [ :test_non_blocking ]
95- poll_test_finished ( alpha_client , release_test . name )
96+ poll_test_finished ( alpha_client , release_tests )
9697 end
9798 end
9899
@@ -279,7 +280,7 @@ def self.poll_upload_release_operation(client, operation, binary_type)
279280 extract_release ( operation )
280281 end
281282
282- def self . upload_binary ( app_name , binary_path , binary_type , client , timeout )
283+ def self . upload_binary ( client , app_name , binary_path , binary_type , timeout )
283284 options = Google ::Apis ::RequestOptions . new
284285 options . max_elapsed_time = timeout # includes retries (default = no retries)
285286 options . header = {
@@ -359,7 +360,10 @@ def self.distribute_release(client, release, request)
359360 end
360361 end
361362
362- def self . test_release ( alpha_client , release , test_devices , username = nil , password = nil , username_resource = nil , password_resource = nil )
363+ def self . test_release ( alpha_client , release , test_devices , test_cases , username = nil , password = nil , username_resource = nil , password_resource = nil )
364+ if present? ( test_cases ) && ( !username_resource . nil? || !password_resource . nil? )
365+ UI . user_error! ( "Password and username resource names are not supported for the AI testing agent." )
366+ end
363367 if username_resource . nil? ^ password_resource . nil?
364368 UI . user_error! ( "Username and password resource names for automated tests need to be specified together." )
365369 end
@@ -401,37 +405,64 @@ def self.test_release(alpha_client, release, test_devices, username = nil, passw
401405 )
402406 end
403407
408+ UI . message ( "🤖 Starting automated tests. Note: This feature is in beta." )
409+ release_tests = [ ]
410+ if present? ( test_cases )
411+ test_cases . each do |tc |
412+ release_tests . push ( create_release_test ( alpha_client , release . name , device_executions , login_credential , tc ) )
413+ end
414+ else
415+ release_tests . push ( create_release_test ( alpha_client , release . name , device_executions , login_credential ) )
416+ end
417+ release_tests
418+ end
419+
420+ def self . create_release_test ( alpha_client , release_name , device_executions , login_credential , test_case_name = nil )
404421 release_test =
405422 Google ::Apis ::FirebaseappdistributionV1alpha ::GoogleFirebaseAppdistroV1alphaReleaseTest . new (
423+ device_executions : device_executions ,
406424 login_credential : login_credential ,
407- device_executions : device_executions
425+ test_case : test_case_name
408426 )
409- alpha_client . create_project_app_release_test ( release . name , release_test )
427+ alpha_client . create_project_app_release_test ( release_name , release_test )
410428 rescue Google ::Apis ::Error => err
411- UI . crash! ( err )
429+ case err . status_code . to_i
430+ when 404
431+ UI . user_error! ( "Test Case #{ test_case_name } not found" )
432+ else
433+ UI . crash! ( err )
434+ end
412435 end
413436
414- def self . poll_test_finished ( alpha_client , release_test_name )
437+ def self . poll_test_finished ( alpha_client , release_tests )
438+ release_test_names = release_tests . map ( &:name )
415439 TEST_MAX_POLLING_RETRIES . times do
416- UI . message ( "⏳ The automated test results are pending." )
440+ UI . message ( "⏳ #{ release_test_names . size } automated test results are pending." )
417441 sleep ( TEST_POLLING_INTERVAL_SECONDS )
418- release_test = alpha_client . get_project_app_release_test ( release_test_name )
419- if release_test . device_executions . all? { |e | e . state == 'PASSED' }
420- UI . success ( "✅ Passed automated test(s)." )
421- return
422- end
423- release_test . device_executions . each do |de |
424- case de . state
425- when 'PASSED' , 'IN_PROGRESS'
426- next
427- when 'FAILED'
428- UI . test_failure! ( "Automated test failed for #{ device_to_s ( de . device ) } : #{ de . failed_reason } ." )
429- when 'INCONCLUSIVE'
430- UI . test_failure! ( "Automated test inconclusive for #{ device_to_s ( de . device ) } : #{ de . inconclusive_reason } ." )
442+ release_test_names . delete_if do |release_test_name |
443+ release_test = alpha_client . get_project_app_release_test ( release_test_name )
444+ if release_test . device_executions . all? { |e | e . state == 'PASSED' }
445+ true
431446 else
432- UI . test_failure! ( "Unsupported automated test state for #{ device_to_s ( de . device ) } : #{ de . state } ." )
447+ release_test . device_executions . each do |de |
448+ case de . state
449+ when 'PASSED' , 'IN_PROGRESS'
450+ next
451+ when 'FAILED'
452+ UI . test_failure! ( "Automated test failed for #{ device_to_s ( de . device ) } : #{ de . failed_reason } ." )
453+ when 'INCONCLUSIVE'
454+ UI . test_failure! ( "Automated test inconclusive for #{ device_to_s ( de . device ) } : #{ de . inconclusive_reason } ." )
455+ else
456+ UI . test_failure! ( "Unsupported automated test state for #{ device_to_s ( de . device ) } : #{ de . state } ." )
457+ end
458+ end
459+ false
433460 end
434461 end
462+ if release_test_names . empty?
463+ UI . success ( "✅ Passed automated test(s)." )
464+ return
465+ end
435466 end
436467 UI . test_failure! ( "It took longer than expected to process your test, please try again." )
437468 end
@@ -580,6 +611,16 @@ def self.available_options
580611 optional : false ,
581612 default_value : false ,
582613 type : Boolean ) ,
614+ FastlaneCore ::ConfigItem . new ( key : :test_case_ids ,
615+ env_name : "FIREBASEAPPDISTRO_TEST_CASE_IDS" ,
616+ description : "Test Case IDs, separated by commas. Note: This feature is in beta" ,
617+ optional : true ,
618+ type : String ) ,
619+ FastlaneCore ::ConfigItem . new ( key : :test_case_ids_file ,
620+ env_name : "FIREBASEAPPDISTRO_TEST_CASE_IDS_FILE" ,
621+ description : "Path to file with containing Test Case IDs, separated by commas or newlines. Note: This feature is in beta" ,
622+ optional : true ,
623+ type : String ) ,
583624
584625 # Auth
585626 FastlaneCore ::ConfigItem . new ( key : :firebase_cli_token ,
0 commit comments