Skip to content

Instantly share code, notes, and snippets.

@xenjke
Created January 20, 2017 08:25
Show Gist options
  • Save xenjke/30189fa8d5831cbb03209aecba6d519f to your computer and use it in GitHub Desktop.
Save xenjke/30189fa8d5831cbb03209aecba6d519f to your computer and use it in GitHub Desktop.
RSpec Slack reporter/listener
require_relative 'spec_reporter'
RSpec.configure do |config|
#custom listener
if ENV['REPORT'] == 'slack'
config.reporter.register_listener Listener.new, :start, :example_started, :example_passed, :example_failed, :dump_summary
end
end
require 'json'
class Listener
def initialize
@bot = Reporter.new
@fails_count = 0
@progress = 0
@included = self.included_tests
end
def included_tests
included = RSpec.configuration.filter_manager.inclusions.rules
included.map { |k, v| "#{k}: #{v}" }
end
def start(notification)
@tests_count = notification.count
message = {}
message[:plain_text] = ":arrow_right: Started on: *#{Config.instance.api_url}*"
message[:text] = "#{@tests_count} tests"
message[:color] = '#0071AA' #blue
@bot.send_message(message)
end
def example_started(notification)
notify_frequency = 5*60 #minutes
should_notify = (Time.now - @bot.last_reported_time) > notify_frequency
message = {}
message[:plain_text] = ":arrows_counterclockwise: Still testing: *#{Config.instance.api_url}*"
message[:text] = "#{@progress} out of #{@tests_count} tests passed"
message[:color] = '#0071AA' #blue
@bot.send_message(message) if should_notify
end
def example_passed(notification)
#puts "**This example passed. Neat!**"
@progress += 1
end
def example_failed(notification)
@fails_count += 1
exceptions = notification.exception.to_s.split("\r")
exceptions[0] = "*#{exceptions.first}*"
exception = exceptions.join("\r\n")
text = []
text << "Spec file: #{notification.example.metadata[:location]}"
text << "Test: #{notification.description}"
text << "Failure: #{exception}"
message = {}
message[:plain_text] = ":x: Test failed. #{@fails_count} total."
message[:text] = text.join("\r\n")
message[:color] = '#AA1C2E' #red
@bot.send_message(message)
end
def dump_summary(notification)
failures = notification.failure_count
duration = notification.formatted_duration #(notification.duration / 60).round(2)
message = {}
message[:plain_text] = ":arrow_left: Finished testing: *#{ENV_URL}*"
message[:text] = "#{@progress} passed, #{failures} failures. Took #{duration}"
message[:color] = failures > 0 ? '#AA1C2E' : '#42AA53' #red or green
@bot.send_message(message)
end
end
class Reporter
attr_accessor :last_reported_time
def initialize
@options = {
webhook_url: 'WEBHOOKURL',
username: 'BOTNAME',
channel: 'SLACKCHANNEL',
#icon_url: '',
#icon_emoji: '',
#link_names: '',
#unfurl_links: ''
}
end
def send_message(message)
attachments = []
attachments << {
color: message[:color],
text: message[:text],
pretext: message[:pretext],
mrkdwn_in: ["text"]
}
message = message[:plain_text]
post(message, attachments)
end
def post(message='', attachments=[])
payload = {
text: message,
attachments: attachments
}.to_json
self.last_reported_time = Time.now
begin
RestClient.post(@options[:webhook_url], payload)
rescue => e
log("Was unable to post to slack: #{e}", 'error')
end
end
def jira_attach(file, issue_key)
jira_login = CREDS[:jira][:user]
jira_password = CREDS[:jira][:password]
url = URI.parse("https://#{jira_login}:#{jira_password}@yourjiraurl.atlassian.net/rest/api/2/issue/#{issue_key}/attachments")
begin
puts "Posting '#{file}' to #{issue_key}"
RestClient.post(
url.to_s,
{:file => File.new(file, 'rb')},
{'X-Atlassian-Token': 'nocheck'}
)
rescue => e
puts "Was unable to post to slack: #{e}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment