class Fastlane::Actions::AndroidReporterAction

Public Class Methods

authors() click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 273
def self.authors
  ["Yazan Tarifi"]
end
available_options() click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 286
def self.available_options
  [
    FastlaneCore::ConfigItem.new(
        key: :avd_name,
        env_name: "ANDROID_REPORTER_AVD_NAME",
        description: "Add Android Emulator Name to Start it before Execute the Commands",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :android_sdk_path,
        env_name: "ANDROID_REPORTER_ANDROID_SDK",
        description: "Add Android SDK Full Path",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :gradle_task_testing_name,
        env_name: "ANDROID_TESTING_GRADLE_TASK",
        description: "Add Android UI Testing Task Name",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :generate_adb_file,
        env_name: "ANDROID_REPORTER_ADB_REPORT FILE",
        description: "This Option will Generate Adb Logcat Report File",
        optional: true,
        type: Boolean
    ),
    FastlaneCore::ConfigItem.new(
        key: :generate_gradle_files,
        env_name: "ANDROID_REPORTER_GRADLE_REPORT FILE",
        description: "This Option will Generate Gradle Report File (Success File, Error File)",
        optional: true,
        type: Boolean
    ),
    FastlaneCore::ConfigItem.new(
        key: :is_slack_upload_reports_enabled,
        env_name: "ANDROID_REPORT_FILES_SLACK_UPLOAD_ENABLED",
        description: "This Option will Check if Slack Upload Files Enabled or Not",
        optional: true,
        type: Boolean
    ),
    FastlaneCore::ConfigItem.new(
        key: :slack_api_key,
        env_name: "SLACK_API_TOKEN",
        description: "Add Slack Api Key",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :slack_channel_name,
        env_name: "SLACK_CHANNEL_NAME",
        description: "Add Slack Channel Name for Bot to Send Messages on this Channel",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :tests_branch_name,
        env_name: "TESTS_BRANCH_NAME",
        description: "Add Branch TO Run Tests on Target Git Branch",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :target_lane_name,
        env_name: "TARGET_LANE_NAME",
        description: "Target Lane Name To Execute Once Tests Task Successfully Built",
        optional: true,
        type: String,
        sensitive: true
    ),
    FastlaneCore::ConfigItem.new(
        key: :version_name_line_number,
        env_name: "VERSION_NAME_LINE_NUMBER",
        description: "Target Lane Name To Execute Once Tests Task Successfully Built",
        optional: true,
        type: String,
        sensitive: true
    )
  ]
end
description() click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 269
def self.description
  "Open Android Emulators Then Generate Report File From Tests then Upload the File To Slack"
end
details() click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 281
def self.details
  # Optional:
  "This Plugin Will Run Android Emulators from a List of Avd Names then Generate Gradle, Tests Report Files and Upload Them To Slack Channel"
end
is_supported?(platform) click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 376
def self.is_supported?(platform)
  # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example)
  # See: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform
  #
  [:android].include?(platform)
  true
end
return_value() click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 277
def self.return_value
  # If your method provides a return value, you can describe here what it does
end
run(params) click to toggle source
# File lib/fastlane/plugin/android_reporter/actions/android_reporter_action.rb, line 11
def self.run(params)
  UI.message("The Android Reporter Plugin Working !!")

  # Create Variables
  avd_name = params[:avd_name]
  android_sdk_path = params[:android_sdk_path]
  generate_adb_file = params[:generate_adb_file]
  generate_gradle_files = params[:generate_gradle_files]
  gradle_task_testing_name = params[:gradle_task_testing_name]
  is_slack_enabled = params[:is_slack_upload_reports_enabled]
  slack_api_key = params[:slack_api_key]
  time = Time.now.to_s
  time = DateTime.parse(time).strftime("%d/%m/%Y %H:%M")
  isLogcatFileUploaded = false
  isGradleDebugFileUploaded = false
  isGradleErrorFileUploaded = false
  buildName = "Current Build"

  # 1. Checkout git to Current Branch to Run Tests on the Current Branch
  if params[:tests_branch_name].to_s.length > 0
      begin
          sh("git fetch")
          sh("git checkout ", params[:tests_branch_name].string)
      rescue => error
          UI.error("Something Error with Git Commands")
      end
  end

  # 2. Get Build Version From Gradle.Props File
  if params[:version_name_line_number].to_s.length > 0
      UI.message("Step Read Version Name of the Build")
      line_num = params[:version_name_line_number].to_i
      text=File.open('gradle.properties').read
      text.gsub!(/\r\n?/, "\n")
      text.each_line.with_index do |line, index|
        if (index + 1) == line_num
          buildName = line
        end
      end
  end

  # 3. Split The String and Get the Value Without Key
  if params[:version_name_line_number].to_s.length > 0
      buildName = buildName.split('=', -1)
      buildName = buildName[1]
      UI.message("Current Build Name : " + buildName)
  end

  # 4. Send Slack Message from Android Reporter Bot That Testing Task Has been Started ....
  if is_slack_enabled
      UI.message("Slack Messages Bot Started .... [Configuration Step]")
      Slack.configure do |config|
         config.token = slack_api_key
      end
         client = Slack::Web::Client.new
         begin
            client.chat_postMessage(
                  channel: "#" + params[:slack_channel_name],
                  text:   " ================================================================================== \n" +
                          " New UI Testing Task Started For Current Release : " + time + " \n " +
                          " Current Branch Build : " + sh("git rev-parse --abbrev-ref HEAD") +
                          " Current Build Version : " + buildName +
                          " ================================================================================== \n",
                  as_user: true
            )

            UI.message("Slack Build Task Message Result : [Send First Task Message] ")
         rescue => error
            UI.error("Something Error with Slack Configuration : [Failed Send First Task Message]")
            puts error.backtrace
         end
  end

  # 5. List All Available AVD's in The Device
  # 6. Run the Target AVD Name From Params
  if params[:avd_name].to_s.length > 0
      Thread.new do
         UI.message("Android Reporting Started to Run AVD : (" + avd_name + ")")
         sh(android_sdk_path + "/tools/bin/avdmanager", "list", "avd")
         sh("cd", android_sdk_path)
         sh(android_sdk_path + "/emulator/emulator", "-avd", avd_name)
      end
  end

  # 7. Clear the Logcat Server Before Start
  if params[:generate_adb_file]
      Process.fork do
         sh("adb logcat -c")
      end
  end

  # 8. Start Clean Task with Target UI Task
  # 9. If Gradle Task Success then Will Generate ADB Log File then Kill Server Connection inside ADB
  begin
    UI.message([
         "Android Reporting Started to Run Gradle Testing Task ...",
         "Gradle Tasks : [Clean , Build , " + gradle_task_testing_name + "]"
    ])
    if params[:gradle_task_testing_name].to_s.length > 0
        sh("./gradlew clean")
        gradle_task_result = sh("./gradlew " + gradle_task_testing_name)
        if gradle_task_result
            UI.message("Gradle Task Finished Successfully ...")
            if params[:generate_adb_file]
                  UI.message([
                     "Android Reporter Started to Save Logcat Logs From ADB Connection Server",
                     "ADB Reporting File : [logcat.txt]"
                  ])
            else
              UI.message("Gradle Task Tests Failed ...")
            end
        end

        Thread.new do
              Process.fork do
                 sh("adb logcat -d > logcat.txt kill-server")
                 begin
                     UI.message("Slack Messages Bot Upload Files Tasks Started ....")
                     if(File.exist?("logcat.txt"))
                           UI.message("logcat.txt File exists ...")
                           client.files_upload(
                               channels: "#" + params[:slack_channel_name],
                               as_user: true,
                               file: Faraday::UploadIO.new('logcat.txt', 'text/plain'),
                               title: "Android UI Testing (ADB Logcat Result)",
                               filename: "logcat.txt",
                               initial_comment: "Current UI Testing Build Result File Report [logcat.txt]"
                           )

                           isLogcatFileUploaded = true
                           UI.message("Slack Step Upload [logcat.txt]")
                     else
                           isLogcatFileUploaded = false
                           UI.error("File does not exist [logcat.txt]")
                     end
                 rescue => error
                     if error
                           UI.error("Something Error with Slack Upload File : [Step Upload Logcat.txt File to Slack]")
                     end
                           puts error.message
                           puts error.backtrace
                 end
              end
        end

  end
  rescue => error
    UI.error("Gradle Task Finished With Error ...")
    puts error.backtrace
  end

  # 10. Generate Gradle Tasks (Failed and Success Files)
  if params[:generate_gradle_files]
       Process.fork do
          sh("./gradlew build > android-logs.txt 2> android-error-logs.txt")
          UI.message([
              "Android Reporting Started to Generate Gradle Reports Files",
              "Gradle Success Debug File : android-logs.txt",
              "Gradle Failed Debug File : android-error-logs.txt"
          ])
       end
  end

  # 11. Check Slack Option if Enabled or Not To Print The Message
  if is_slack_enabled
      UI.message("Slack Configuration Status : Started ...")
  else
      UI.message("Slack Configuration Status : Disabled ...")
  end

  # 12. Upload Files to Slack if The Build Failed
  if gradle_task_result == false
      if is_slack_enabled
          begin
            if(File.exist?("android-logs.txt"))
               UI.message("android-logs.txt File exists ...")
               client.files_upload(
                    channels: "#" + params[:slack_channel_name],
                    as_user: true,
                    file: Faraday::UploadIO.new('android-logs.txt', 'text/plain'),
                    title: "Android UI Testing (Gradle Debug File Result)",
                    filename: "android-logs.txt",
                    initial_comment: "Current UI Testing Build Result File Report [Gradle Debug Result]"
               )

               isGradleDebugFileUploaded = true
               UI.message("Slack Step Upload [android-logs.txt]")
            else
               isGradleDebugFileUploaded = false
               UI.error("File does not exist [android-logs.txt]")
            end
          rescue => error
               if error
                   UI.error("Something Error with Slack Upload File : [Step Upload Logcat.txt File to Slack]")
               end
                   puts error.message
                   puts error.backtrace
          end

          begin
            if(File.exist?("android-error-logs.txt"))
               UI.message("android-error-logs.txt File exists ...")
               client.files_upload(
                     channels: "#" + params[:slack_channel_name],
                     as_user: true,
                     file: Faraday::UploadIO.new('android-error-logs.txt', 'text/plain'),
                     title: "Android UI Testing (Gradle Error File Result)",
                     filename: "android-error-logs.txt",
                     initial_comment: "Current UI Testing Build Result File Report [Gradle Error Result]"
               )

               isGradleErrorFileUploaded = true
               UI.message("Slack Step Upload [android-error-logs.txt]")
            else
               isGradleErrorFileUploaded = false
               UI.error("File does not exist [android-error-logs.txt]")
            end
          rescue => error
            if error
              UI.error("Something Error with Slack Upload File : [Step Upload Logcat.txt File to Slack]")
            end
            puts error.message
            puts error.backtrace
          end

          # 13. Send Message With Files Summery
          slackFinalMessageContent = "Files Status : With Time : " + time + " : \n"
          if isGradleDebugFileUploaded
              slackFinalMessageContent += "Gradle Debug File Uploaded \n"
          end

          if isGradleErrorFileUploaded
              slackFinalMessageContent += "Gradle Error File Uploaded \n"
          end

          if isLogcatFileUploaded
              slackFinalMessageContent += "Logcat ADB Logging File Uploaded \n"
          end

          client.chat_postMessage(channel: "#" + params[:slack_channel_name], text: slackFinalMessageContent, as_user: true)

      end

  end

  # 14. If the Gradle Task Success Then Run Specific Lane Else Send Slack Message The Build Failed
  if gradle_task_result
     if params[:target_lane_name].to_s.length > 0
           client.chat_postMessage(channel: "#" + params[:slack_channel_name], text: "Testing Result Success : [Fastlane Will Execute this Lane (" + params[:target_lane_name] + ") To Send Build]", as_user: true)
           sh("fastlane", params[:target_lane_name])
     end
  else
     UI.message("Gradle Task Result Failed ...")
     client.chat_postMessage(channel: "#" + params[:slack_channel_name], text: "Testing Result Failed : Gradle Testing Task Failed Logs File Should be Uploaded", as_user: true)
  end

end