# This file is copied to spec/ when you run 'rails generate rspec:install' ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) ENV["NOTIFICATION_CREDENTIAL_PUBLIC_KEY"] = ENV["NOTIFICATION_CREDENTIAL_PUBLIC_KEY"].gsub("\\n", "\n") require 'rspec/rails' require 'rspec/autorun' require 'webmock/rspec' require 'sidekiq/testing' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} RSpec.configure do |config| # ## Mock Framework # # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: # # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures # config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. # config.use_transactional_fixtures = true # If true, the base class of anonymous controllers will be inferred # automatically. This will be the default behavior in future versions of # rspec-rails. config.infer_base_class_for_anonymous_controllers = false # Means you can tag tests with just a symbol config.treat_symbols_as_metadata_keys_with_true_values = true # Exclude visual diffs if ENV["BUILDBOX_PULL_REQUEST"] != "true" && ENV["BUILDBOX_BRANCH"] != "master" config.filter_run_excluding :visual end ## Visual Specs config.before(:suite, :visual) do WebMock.allow_net_connect! start_browser_stack_server start_forked_rails_server end config.after(:suite, :visual) do begin terminate_forked_rails_server terminate_browser_stack_server ensure WebMock.disable_net_connect! FileUtils.rm_rf(current_sha.to_s) end end config.before(:all, :visual) do @driver = setup_selenium end config.after(:all, :visual) do begin ensure @driver.quit end end # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = "random" # Clean up the database config.before(:suite) do DatabaseCleaner.strategy = :truncation DatabaseCleaner.clean_with(:truncation) clean_redis end config.before(:each) do DatabaseCleaner.start # Disable Notifications Trigger.stub(:post_json) # Disable mailchimp MailchimpClient.stub(:add_to_feature_list) end config.after(:each) do DatabaseCleaner.clean clean_redis end config.include Devise::TestHelpers, :type => :controller end def clean_redis $redis.connections.each do |name, connection| if connection.is_a? Array connection.each {|connection| connection.flushdb } else connection.flushdb end end end def synchronous_sidekiq! before{ Sidekiq::Testing.inline! } after{ Sidekiq::Testing.disable! } end def disable_elastic_search! before do ElasticSearcher.methods(false).each do |method| ElasticSearcher.stub(method) end end end def disable_hipchat! before do Hipchat.methods(false).each do |method| Hipchat.stub(method) end end end ## Visual Specs def setup_selenium caps = Selenium::WebDriver::Remote::Capabilities.new caps["browser"] = "firefox" caps["browser_version"] = "31.0" caps["os"] = "OS X" caps["os_version"] = "Mavericks" caps["resolution"] = "1600x1200" caps["browserstack.debug"] = "true" caps["name"] = "Testing Selenium 2 with Ruby on BrowserStack" caps["browserstack.local"] = "true" Selenium::WebDriver.for(:remote, :url => ENV["BROWSER_STACK_URL"], :desired_capabilities => caps) end def start_browser_stack_server @browser_stack_pid = spawn("BrowserStackLocal -forcelocal #{ENV["BROWSER_STACK_KEY"]}", err: '/dev/null', out: '/dev/null') end def terminate_browser_stack_server Process.kill('SIGTERM', @browser_stack_pid) if @browser_stack_pid end def start_forked_rails_server # Start forked Ruby server unless system("curl 127.0.0.1:3000", err: '/dev/null', out: '/dev/null') @server_pid = Bundler.with_clean_env { spawn "bundle exec rails s", err: '/dev/null', out: '/dev/null' } tries = 0 sleep 1 until system("curl 127.0.0.1:3000", err: '/dev/null', out: '/dev/null') || (tries+=1) > 30 end end def terminate_forked_rails_server Process.kill('SIGTERM', @server_pid) if @server_pid end def master_sha @master_sha ||= `git rev-parse --short HEAD^`.strip # @master_sha ||= `git rev-parse --short origin/master`.strip end def current_sha @current_sha ||= `git rev-parse --short HEAD`.strip end def shots_bucket s3 = AWS::S3.new(access_key_id: ENV["BUGSNAG_WEBSITE_AWS_ACCESS_KEY"], secret_access_key: ENV["BUGSNAG_WEBSITE_AWS_SECRET_KEY"]) s3.buckets['bugsnag-shots'] end def page_path(area, page_name) File.join(current_sha, area, page_name) end def previous_screenshot_path(area, page_name) File.join(page_path(area, page_name), "previous.png") end def master_sha_path(area, page_name) File.join(master_sha, area, page_name) end def current_screenshot_path(area, page_name) File.join(page_path(area, page_name), "current.png") end def diff_screenshot_path(area, page_name) File.join(page_path(area, page_name), "diff.png") end def save_shot(area, page_name, driver) FileUtils.mkdir_p page_path(area, page_name) driver.save_screenshot(previous_screenshot_path(area, page_name)) end def save_shots_to_aws(area, page_name) bucket = shots_bucket # Save screenshots to S3 bucket.objects[Pathname.new(previous_screenshot_path(area, page_name))].write(File.open(previous_screenshot_path(area, page_name))) # Download master's screenshot to our SHA File.open(previous_screenshot_path(area, page_name), "wb") do |file| bucket.objects[Pathname.new(File.join(master_sha_path(area, page_name), "current.png"))].read do |chunk| file.write(chunk) end end if File.exist?(current_screenshot_path(area, page_name)) # Create diff screenshot system("compare -metric PAE ./#{current_screenshot_path(area, page_name)} ./#{previous_screenshot_path(area, page_name)} ./#{diff_screenshot_path(area, page_name)}", err: '/dev/null', out: '/dev/null') # Save base/diff screenshots bucket.objects[Pathname.new(current_screenshot_path(area, page_name))].write(File.open(current_screenshot_path(area, page_name))) bucket.objects[Pathname.new(diff_screenshot_path(area, page_name))].write(File.open(diff_screenshot_path(area, page_name))) end end # This enables mongoid logging :-) enable if you want lots of text in your shell #Mongoid.logger = Logger.new($stdout) #Moped.logger = Logger.new($stdout) def map_models(object) if object.is_a? Array object.map { |obj| yield obj } else yield object end end def for_each_model(object) if object.is_a? Array object.map { |obj| yield obj } else yield object end end