class NewmanScenario::Scenario
Constants
- DEBUG
- DEFAULT_CUSTOM_SCENARIOS_FILE_PATH
- DEFAULT_LAST_SCENARIO_FILE_PATH
Attributes
default_api_key[RW]
default_collection_id[RW]
default_custom_scenarios_file_path[RW]
default_environments[RW]
default_last_scenario_file_path[RW]
api_key[RW]
collection_id[RW]
custom_collection_file_path[RW]
environments[RW]
last_scenario_file_path[RW]
Public Class Methods
configure(default_api_key: nil, default_collection_id: nil, default_environments: nil, default_custom_scenarios_file_path: nil, default_last_scenario_file_path: nil)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 28 def configure(default_api_key: nil, default_collection_id: nil, default_environments: nil, default_custom_scenarios_file_path: nil, default_last_scenario_file_path: nil) self.default_api_key = default_api_key || prompt.mask('Postman API Key (https://YOURPOSTMAN.postman.co/settings/me/api-keys):', value: ENV['POSTMAN_API_KEY'].to_s) collections = nil environments = nil if prompt.yes?('Using workspace?') workspaces = fetch_postman('/workspaces', api_key: self.default_api_key).parsed_response&.fetch('workspaces', nil) || [] workspaces = workspaces.map { |workspace| workspace.slice('name', 'id').values }.to_h workspace = prompt.select('Workspace', workspaces) workspace = fetch_postman("/workspaces/#{workspace}", api_key: self.default_api_key).parsed_response&.fetch('workspace', nil) || {} collections = workspace['collections'] environments = workspace['environments'] end collections ||= fetch_postman('/collections', api_key: self.default_api_key).parsed_response&.fetch('collections', nil) || [] collections = collections.map { |collection| collection.slice('name', 'id').values }.to_h self.default_collection_id = default_collection_id || prompt.select('Postman Collection', collections, default: 1) self.default_environments = default_environments unless self.default_environments environments ||= fetch_postman('/environments', api_key: self.default_api_key).parsed_response&.fetch('environments', nil) || [] environments = environments.map { |environment| environment.slice('name', 'id').values }.to_h environment_ids = prompt.multi_select('Environment', environments) self.default_environments = environments.select { |_, id| environment_ids.include?(id) } end self.default_custom_scenarios_file_path = default_custom_scenarios_file_path || prompt.ask('Custom scenarios file path:', value: DEFAULT_CUSTOM_SCENARIOS_FILE_PATH) self.default_last_scenario_file_path = default_last_scenario_file_path || prompt.ask('Last scenario file path:', value: DEFAULT_LAST_SCENARIO_FILE_PATH) if (env_path = prompt.ask('Save to: [enter to not save]', value: '.env')) envs = { POSTMAN_API_KEY: self.default_api_key, NEWMAN_SCENARIO_COLLECTION_ID: self.default_collection_id, NEWMAN_SCENARIO_ENVIRONMENTS: self.default_environments.to_json, NEWMAN_SCENARIO_CUSTOM_COLLECTION_FILE_PATH: self.default_custom_scenarios_file_path, NEWMAN_SCENARIO_LAST_SCENARIO_FILE_PATH: self.default_last_scenario_file_path, } existing_lines = [] if File.exists?(env_path) existing_lines = File.readlines(env_path).reject { |line| envs.keys.include?(line.split(':').first.to_sym) } else existing_lines = [] end File.open(env_path, 'w+') do |file| existing_lines.each { |line| file.puts line } file.puts "POSTMAN_API_KEY: #{self.default_api_key}" file.puts "NEWMAN_SCENARIO_COLLECTION_ID: #{self.default_collection_id}" file.puts "NEWMAN_SCENARIO_ENVIRONMENTS: #{self.default_environments.to_json}" file.puts "NEWMAN_SCENARIO_CUSTOM_COLLECTION_FILE_PATH: #{self.default_custom_scenarios_file_path}" file.puts "NEWMAN_SCENARIO_LAST_SCENARIO_FILE_PATH: #{self.default_last_scenario_file_path}" end end end
fetch_postman(url_path, expected_response_codes: [200], api_key: nil)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 77 def fetch_postman(url_path, expected_response_codes: [200], api_key: nil) puts "fetching #{url_path}" if DEBUG response = HTTParty.get("https://api.getpostman.com#{url_path}", headers: { 'X-Api-Key' => api_key}) raise Error, "Invalid response code: #{response.code}" unless expected_response_codes.include?(response.code) response end
new(collection_id: nil, environments: nil, api_key: nil, custom_collection_file_path: nil, last_scenario_file_path: nil)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 98 def initialize(collection_id: nil, environments: nil, api_key: nil, custom_collection_file_path: nil, last_scenario_file_path: nil) self.collection_id ||= self.class.default_collection_id raise ConfigurationError, 'Missing Collection Id' unless self.collection_id self.environments ||= self.class.default_environments self.environments ||= JSON.parse(ENV['NEWMAN_SCENARIO_ENVIRONMENTS'], symbolize_names: true) if ENV['NEWMAN_SCENARIO_ENVIRONMENTS'] raise ConfigurationError, 'Missing Environment Ids' unless self.environments self.api_key ||= self.class.default_api_key raise ConfigurationError, 'Missing Postman API Key' unless self.api_key self.custom_collection_file_path ||= self.class.default_custom_scenarios_file_path raise ConfigurationError, 'Missing Custom collection file path' unless self.custom_collection_file_path self.last_scenario_file_path ||= self.class.default_last_scenario_file_path raise ConfigurationError, 'Missing Last scenario file path' unless self.last_scenario_file_path rescue ConfigurationError => e prompt.warn e if prompt.yes?('Configure?') self.class.configure retry end end
Private Class Methods
prompt()
click to toggle source
# File lib/newman_scenario/scenario.rb, line 87 def prompt @prompt ||= TTY::Prompt.new end
Public Instance Methods
run(environment_name: nil, scenario_name: nil, bail: true, no_prompt: false)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 122 def run(environment_name: nil, scenario_name: nil, bail: true, no_prompt: false) return if `which newman`.empty? && !prompt_to_install_newman environment = environments[environment_name.to_sym] if environment_name environment ||= prompt.select('Environment', environments, default: 1) load_postman_environment(environment, no_prompt: no_prompt) collection = JSON.parse(File.read("/tmp/postman-collection-#{collection_id}.json"), symbolize_names: true)[:collection] unless File.exist?(last_scenario_file_path) && (!scenario_name && prompt.yes?('Replay last scenario?')) scenarii = read_from_json_file(custom_collection_file_path) || {} scenario_name ||= prompt.select('Scenario', ['Custom Scenario'] + scenarii.keys.sort) scenario_requests = (scenario_name == 'Custom Scenario' && []) || scenarii[scenario_name] if scenario_requests.empty? scenario_requests = [] extract_all_requests = lambda do |item, prefix| request_name = "#{prefix.empty? ? '' : "#{prefix}/" }#{item[:name]}" request_names = [request_name] + (item[:item]&.map { |child_item| extract_all_requests.call(child_item, request_name) } || []) request_names end all_request_names = extract_all_requests.call(collection, '') loop do scenario_requests.delete('duplicate') scenario_requests += prompt.multi_select('Requests (type to filter prefix, choose duplicate to perform action multiple times)', ['duplicate'] + all_request_names, cycle: true, filter: true) break unless scenario_requests.include?('duplicate') end if prompt.yes?('Save this custom scenario?') name = prompt.ask('Name?') new_or_overwrite = !scenarii.key?(name) || !prompt.no?('This scenario exist, overwrite it?') if new_or_overwrite prompt.ok "Adding/Updating #{name} to scenarii" scenarii[name] = scenario_requests write_to_json_file(custom_collection_file_path, scenarii, pretty: true) end end end find_request = lambda do |request_path, items| item = items.find { |i| i[:name] == request_path.last } if item item else child_item = items.find { |i| i[:name] == request_path.first } if child_item request_path = request_path.drop(1) if request_path.empty? child_item else find_request.call(request_path, child_item[:item]) end end end end requests = scenario_requests.map do |scenario_request| find_request.call(scenario_request.split('/'), collection[:item]) end new_collection = { collection: { info: { name: scenario_name, schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json' }, item: requests } } write_to_json_file(last_scenario_file_path, new_collection) end exec("newman run #{last_scenario_file_path} -e /tmp/postman-environment-#{environment}.json#{bail ? ' --bail' : ''}") end
Private Instance Methods
cmd(command)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 192 def cmd(command) prompt.ok "Running: #{command}" `#{command}` end
fetch_postman_to_file(url_path, file_path, expected_response_codes: [200])
click to toggle source
# File lib/newman_scenario/scenario.rb, line 230 def fetch_postman_to_file(url_path, file_path, expected_response_codes: [200]) response = self.class.fetch_postman(url_path, expected_response_codes: expected_response_codes, api_key: api_key) File.open(file_path, 'w+') do |file| file.puts response.body end end
load_postman_environment(environment, no_prompt: false)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 209 def load_postman_environment(environment, no_prompt: false) reload = if no_prompt false else !prompt.no?('Refetch postman config?') end if File.file?("/tmp/postman-environment-#{environment}.json") && !reload prompt.ok "reusing env /tmp/postman-environment-#{environment}.json" else prompt.ok "fetching environment #{environment}" fetch_postman_to_file("/environments/#{environment}", "/tmp/postman-environment-#{environment}.json") end if File.file?('/tmp/postman-collection.json') && !reload prompt.ok 'reusing collection /tmp/postman-collection.json' else prompt.ok "fetching collection #{collection_id}" fetch_postman_to_file("/collections/#{collection_id}", "/tmp/postman-collection-#{collection_id}.json") end end
prompt()
click to toggle source
# File lib/newman_scenario/scenario.rb, line 197 def prompt @prompt ||= TTY::Prompt.new end
prompt_to_install_newman()
click to toggle source
# File lib/newman_scenario/scenario.rb, line 201 def prompt_to_install_newman prompt.warn 'missing newman command line' return false unless prompt.yes?('Install newman?') prompt.ok 'installing newman: brew install newman' cmd('brew install newman') end
read_from_json_file(file, symbolize_names: false)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 247 def read_from_json_file(file, symbolize_names: false) return unless File.file?(file) JSON.parse(File.read(file), symbolize_names: symbolize_names) end
write_to_json_file(file, hash, pretty: false)
click to toggle source
# File lib/newman_scenario/scenario.rb, line 237 def write_to_json_file(file, hash, pretty: false) data = if pretty JSON.pretty_generate(hash) else hash.to_json end open(file, 'w') { |f| f.puts data } end