How to run cucumber separately from rails? - ruby-on-rails

Hi I am working on ROR project with rails 5 and ruby 2.5.1. I have written test cases in cucumber. When i run cucumber it runs locally i.e it gives the output based on local code but i want to test the remote API. How can i test the remote API without depending on local rails code?. I tried to mention the remote URL as follows:
When(/^I send a GET request to receipt details$/) do
#url = "http://example.com/api/receipts"
end
Then(/^the json response should have main receipt status complete$/) do
header 'login-token', #login_token
header 'user-id', #user_id
response = get #url
response_body = JSON response.body
#id = response_body['data']['id']
expect(response_body['data']['attributes']['status']).to eq('complete')
end
But still it checks for the local routes '/api/receipts'. It doesn't call the URL.
Please help me Thanks in advance.

Related

Is there any way to prevent Rails autocleaning class variables when testing emails?

I testing a Rails application that sends emails in some situations. It's an API.
For the testing, I'm using the Airborne gem, which makes API testing pretty easy. All went correct except when I had to test the email deliveries. I tried the following:
it "blah" do
//Code that makes my API send an email
puts ActionMailer::Base.deliveries.inspect
end
But deliveries array is always empty. I also tried with Emails.deliveries.inspect. Emails is my custom Mailer that inherits ActionMailer::Base.
I ended reading the API documentation of ActionMailer and met the interceptor concept. Interceptors doesn't work in :test delivery method so I switched to :smtp. In fact, the emails are being sent correctly, but I can not access them on the tests to make expectations.
My interceptor code is this right now
initializers/email_interceptor.rb
class EmailInterceptor
##msgs = []
def self.delivering_email(message)
puts message
//Rails.logger.debug "Email being sent: " + message.to_s
##msgs << message
Rails.logger.debug "Actual messages array: #{##msgs}"
end
def self.msgs
##msgs
end
end
ActionMailer::Base.register_interceptor(EmailInterceptor)
All OK. The debug messages print the array being populated correctly. But the variable is cleaned before my test statement is executed.
EDIT: The code above is executed when I run my test suite. But the variable is empty accessed from the test itself.
//test code
puts EmailInterceptor.msgs.inspect
=> []
Is there any way to prevent this behavior?
You may have config.action_mailer.perform_deliveries = false in your test.rb config. It seems like you should really be using config.action_mailer.delivery_method = :test since this will allow ActionMailer::Base.deliveries to be populated, which makes for easier and more reliable testing. Do you really need interceptors for your tests?

Outputting HTTP request/response data with RSpec

I have a rails project that serves a JSON API with tests written in RSpec. Often when running specs (request specs, specifically), I’m interested in seeing some details about the HTTP request/response...i.e. the request URL, request body, and response body, ideally JSON pretty-formatted for readability. This isn't for the purposes of documentation but rather as part of the development / debugging process.
I have a helper method I wrote which does this...you just drop a method call into your spec and it prints this stuff out.
But, seems like it would be better if there was a switch that’s part of the running specs. RSpec has custom formatters which I thought might be the right direction, but in trying to build one, I can't figure out how to get access to the request/response objects like you can from inside of your spec.
How can I access the request/response objects in my custom RSpec formatter? Or, perhaps another way to approach the problem?
Here's an approach:
Assuming a rails project, in spec_helper.rb, define a global "after" hook like so:
config.after(:each) do #runs after each example
if ENV['PRINTHTTP']
#use request/response objects here, e.g. puts response.status
end
end
Then, you can conditionally enable by adding the environmental variable on the command-line:
$ PRINTHTTP=1 rspec

Selenium IDE, Selenium Client, Ruby, Rails 3, session maintenance

I am quite new to Selenium. Currently i am using selenium driver for writing test cases in ruby on rails. In the application, I am required to login and Logout for each test cases. So, I exported each test cases from Selenium IDE to rails 3. I am required to use same browser session for multiple test cases. So I am calling Login test before required test case to be executed in a single ruby file. Is it possible to maintain browser session for consecutive next tests in rails 3 either with Selenium Client or Selenium Webdriver?
I got a solution for this issue for Selenium Client/Webdriver in Ruby on Rails 3. To maintain a session from test script to another script, the only thing you need is session variable. Since I have written different Login script and this script is being called in different other script files, so from this another file I have to access the session variable from Login script.
To access variable from Login script, the code inside is being converted to module.
This is how it worked for me:
----Start-----
------Login.rb-----
module ModuleName
def methodName
----Write particular Login code required through selenium---#
#variable = SELENIUM::CLIENT:DRIVER.new \ #---Create browser instance and store in a variable ---#
return #variable #--Return back the variable from this method
end
end
------File1.rb-----
require Login.rb #---Specify with path---#
include ModuleName
Class File < TestCase #--Extending resp. Test Class
def setup
#local = ModuleName.methodName #--Access Module's method that will return session object.
end
def test_file
--Access this #local in rest of the code--#
end
end
-----End----
This was the tweak to access variable from file1 to file2.
I hope this may help somebody.........

Can't get ActiveMerchant to respond using rails 3 server

I'm using Rails 3.1 and ActiveMerchant 1.17
I'm calling the PaymentExpress gateway, using the correct test credit card details. However, it keeps giving some form of invalid response.
The most I can make out is that the response.params array contains
{"re_co"=>"Zz", "response_text"=>"Error in getting response.", "success"=>"0"}
This is using the local rails server.
I have a hunch that it may be to do with the SSL verify_peer option, though I have no way of proving that, and I have no idea how to configure that option.
This is my code, fairly standard stuff:
credit_card = ActiveMerchant::Billing::CreditCard.new(params[:credit_card])
gateway = ActiveMerchant::Billing::PaymentExpressGateway.new(:login => APP_CONFIG[:dps_username], :password => APP_CONFIG[:dps_password])
response = gateway.authorize total_cents, credit_card
Interestingly, it seems to work fine from the rails console. Are there any steps I should be taking to debug this?
Ok, it turns out the problem wasn't to do with ActiveMerchant at all.
I should have been using
APP_CONFIG['dps_username']
instead of
APP_CONFIG[:dps_username]
Ahh, the simple problems

Sending emails in test mode with ActionMailer in rails 3

I am having a slightly odd problem with sending mail in test mode with Rails 3
It seems that my mailers are not returning anything. For example I have a mailer called UserMailer. Users can make changes that require approval in the app so this has a method called changes_approved that should send the user an email notifying them that their changes have been approved.class
UserMailer < ActionMailer::Base
default :from => "from#example.com"
def changes_approved(user, page)
#user = user
#page = page
mail(:to => user.email, :subject => "Your changes have been approved")
end
end
In my controller I have the following line
UserMailer.changes_approved(#page_revision.created_by, #page_revision.page).deliver
However my tests fail at this point with the error:
undefined method `deliver' for nil:NilClass
When I trigger the same actions on the development site tho (http://localhost:3000 through a browser), the emails are sent out correctly and everything works quite happily
And to add further confusion, I am using devise for authentication and the emails for that seem to be working correctly both in test and development modes. Certainly I am not getting this same error and according to my email-spec tests, everythings working
So this leads me to believe that I have a problem with my mailers rather than my test mail config per se but I have no idea what. Any suggestions would be much appreciated
Thanks
I used https://gist.github.com/1031144
to convert
# Rails 2 method:
UserMailer.should_receive(:deliver_signup)
to
# Cumbersome Rails 3 method:
mailer = mock
mailer.should_receive(:deliver)
UserMailer.should_receive(:signup).and_return(mailer)
I had a similar problem - probably the UserMailer.changes_approved method is being replaced with a mock method, which returns nil (I wasn't using shoulda for that test, but that's my best guess).
My code looked like this (modified to use your example):
UserMailer.expects(:changes_approved).once
I fixed it with an additional stub:
#mailer = stub(:deliver)
UserMailer.expects(:changes_approved).once.returns(#mailer)
The nil is now replaced with #mailer.
To test the delayed action mailer we need to first change the configuration of delayed_job (in config/initializers/delayed_job_config.rb) to
Delayed::Worker.delay_jobs = !Rails.env.test?
and in your tests the expectation should be set to
mock_mail = mock(:mail)
mock_mail.should_receive(:deliver)
UserMailer.should_receive(:changes_approved).with(user, page).and_return(mock_mail)
Well I have found the answer,
it looks like the problem was in the way I was testing these mailers. In each of the controller tests I had a line similar to
UserMailer.should_receive(:changes_approved).with(user, page)
Whilst this test was passing fine, it appeared to break the mailer itself. I have removed this line from the tests and now they pass ok. Subsequent tests against ActionMailer::Base.deliveries.last to check the details of the sent email are correct appear to be ok so I am happy that this line is not neccessary.
If anyone has an explanation as to why this breaks tho, I would be interested to find out
Thanks anyways

Resources