lib/produce/developer_center.rb in produce-0.1.3 vs lib/produce/developer_center.rb in produce-0.1.4

- old
+ new

@@ -1,226 +1,51 @@ -require 'credentials_manager/password_manager' -require 'open-uri' -require 'openssl' +require 'fastlane_core/developer_center/developer_center' -require 'capybara' -require 'capybara/poltergeist' -require 'phantomjs/poltergeist' - -module Produce +module FastlaneCore class DeveloperCenter - # This error occurs only if there is something wrong with the given login data - class DeveloperCenterLoginError < StandardError - end - - # This error can occur for many reaons. It is - # usually raised when a UI element could not be found - class DeveloperCenterGeneralError < StandardError - end - - # Types of certificates - APPSTORE = "AppStore" - ADHOC = "AdHoc" - DEVELOPMENT = "Development" - - include Capybara::DSL - - DEVELOPER_CENTER_URL = "https://developer.apple.com/devcenter/ios/index.action" APPS_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleList.action" CREATE_APP_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleCreate.action" - - - 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 - - # Since Apple has some SSL errors, we have to configure the client properly: - # https://github.com/ariya/phantomjs/issues/11239 - Capybara.register_driver :poltergeist do |a| - conf = ['--debug=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1'] - Capybara::Poltergeist::Driver.new(a, { - phantomjs: Phantomjs.path, - phantomjs_options: conf, - phantomjs_logger: File.open("#{TMP_FOLDER}/poltergeist_log.txt", "a"), - js_errors: false - }) - end - - page.driver.headers = { "Accept-Language" => "en" } - - self.login - end - - # 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} - # @param user (String) (optional) The username/email address - # @param password (String) (optional) The password - # @return (bool) true if everything worked fine - # @raise [DeveloperCenterGeneralError] General error while executing - # this action - # @raise [DeveloperCenterLoginError] Login data is wrong - 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 APPS_URL - raise "Could not open Developer Center" unless result['status'] == 'success' - - if page.has_content?"Member Center" - # Already logged in - return true - end - - (wait_for_elements(".button.blue").first.click rescue nil) # maybe already logged in - - (wait_for_elements('#accountpassword') rescue nil) # when the user is already logged in, this will raise an exception - - if page.has_content?"Member Center" - # Already logged in - 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" # If the user is not on multiple teams - select_team - end - rescue => ex - Helper.log.debug ex - raise DeveloperCenterLoginError.new("Error loggin in user #{user}. User is on multiple teams and we couldn't select the one specified.") - end - - begin - wait_for_elements('.toolbar-button.add.navLink') - visit APPS_URL # again, since after the login, the dev center loses the GET value - 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 - - def select_team - team_id = Config.val(:team_id) if Config.has_key?(:team_id) - team_name = Config.val(:team_name) if Config.has_key?(:team_name) - - if team_id == nil and team_name == nil - Helper.log.info "You can store you preferred team using the environment variable `PRODUCE_TEAM_ID` or `PRODUCE_TEAM_NAME`".green - Helper.log.info "Your ID belongs to the following teams:".green - end - - available_options = [] - - teams = find("div.input").all('.team-value') # Grab all the teams data - 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? # Include the team description if any - index_text = (index + 1).to_s + "." - - available_options << [index_text, current_team_id, team_text, description_text].join(" ") - end - - if team_name - # Search for name - found_it = false - all("label.label-primary").each do |current| - if current.text.downcase.gsub(/\s+/, "") == team_name.downcase.gsub(/\s+/, "") - current.click # select the team by name - found_it = true - end - end - - unless found_it - available_teams = all("label.label-primary").collect { |a| a.text } - raise DeveloperCenterLoginError.new("Could not find Team with name '#{team_name}'. Available Teams: #{available_teams}".red) - end - else - # Search by ID/Index - 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}']") # Select the desired team - 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 - end - - all(".button.large.blue.submit").first.click - - result = visit APPS_URL - raise "Could not open Developer Center" unless result['status'] == 'success' - end - - def run + def run(config) + @config = config create_new_app rescue => ex error_occured(ex) end def create_new_app if app_exists? - Helper.log.info "App '#{Config.val(:app_name)}' already exists, nothing to do on the Dev Center".green + Helper.log.info "App '#{@config[:app_name]}' already exists, nothing to do on the Dev Center".green ENV["CREATED_NEW_APP_ID"] = nil # Nothing to do here else - Helper.log.info "Creating new app '#{Config.val(:app_name)}' on the Apple Dev Center".green + Helper.log.info "Creating new app '#{@config[:app_name]}' on the Apple Dev Center".green visit CREATE_APP_URL - wait_for_elements("*[name='appIdName']").first.set Config.val(:app_name) - wait_for_elements("*[name='explicitIdentifier']").first.set Config.val(:bundle_identifier) + wait_for_elements("*[name='appIdName']").first.set @config[:app_name] + wait_for_elements("*[name='explicitIdentifier']").first.set @config[:bundle_identifier] click_next - sleep 3 # sometimes this takes a while and we don't want to timeout + sleep 5 # sometimes this takes a while and we don't want to timeout + if all(".form-error").count > 0 + error = all(".form-error").collect { |a| a.text }.join("\n") + raise error.red + end + wait_for_elements("form[name='bundleSubmit']") # this will show the summary of the given information click_next - sleep 3 # sometimes this takes a while and we don't want to timeout + sleep 5 # sometimes this takes a while and we don't want to timeout wait_for_elements(".ios.bundles.confirmForm.complete") click_on "Done" raise "Something went wrong when creating the new app - it's not listed in the App's list" unless app_exists? ENV["CREATED_NEW_APP_ID"] = Time.now.to_s - Helper.log.info "Finished creating new app '#{Config.val(:app_name)}' on the Dev Center".green + Helper.log.info "Finished creating new app '#{@config[:app_name]}' on the Dev Center".green end return true end @@ -230,59 +55,16 @@ visit APPS_URL wait_for_elements("td[aria-describedby='grid-table_identifier']").each do |app| identifier = app['title'] - return true if identifier.to_s == Config.val(:bundle_identifier).to_s + return true if identifier.to_s == @config[:bundle_identifier].to_s end false end def click_next wait_for_elements('.button.small.blue.right.submit').last.click - end - - def error_occured(ex) - snap - raise ex # re-raise the error after saving the snapshot - end - - def snap - path = "Error#{Time.now.to_i}.png" - save_screenshot(path, :full => true) - system("open '#{path}'") - end - - def wait_for(method, parameter, success) - counter = 0 - result = method.call(parameter) - while !success.call(result) - sleep 0.2 - - result = method.call(parameter) - - counter += 1 - if counter > 100 - Helper.log.debug caller - raise DeveloperCenterGeneralError.new("Couldn't find '#{parameter}' after waiting for quite some time") - end - end - return result - end - - def wait_for_elements(name) - method = Proc.new { |n| all(name) } - success = Proc.new { |r| r.count > 0 } - return wait_for(method, name, success) - end - - def wait_for_variable(name) - method = Proc.new { |n| - retval = page.html.match(/var #{n} = "(.*)"/) - retval[1] unless retval == nil - } - success = Proc.new { |r| r != nil } - return wait_for(method, name, success) end end end