How to run rails request specs on a cloud deployment? - ruby-on-rails

I am new to rails testing. Two days of running down leads with Google has turned up no solutions for what ought to be a frequent need.
If I write request (integration) specs to use a Selenium or other browser-based driver, is it possible to redirect the test's i/o to a staging deployment on a cloud server (in my case Heroku)?
If so, how? If not, what prevents this from working?
So far I have been using rspec/capybara, but would switch to anything of similar power if necessary.

You can use Capybara with Selenium driver, and set Capybara.app_host to specify the IP of you staging app server. While doing so you can turn off Capybara local rack with Capybara.run_server = false
Remote testing will allow you only to perform human kind of action and test the returned generated HTML/JS/Json etc .. but no access to controller, view, or any other app internal objects.
On thing you could do (I never tried, but I don't see why it wouldn't work) is to set-up your database.yml test configuration to remotely access you staging database, allowing you to control the database during your tests. It's not really secure so you may want to do that over a SSH tunnel , or a similar solution.

Related

What is the most accurate way to check if you are in rails server process for the needs of Hyperstack

Hyperstack is an isomorphic framework where same code can run server or client side. So there are specific cases where depending on where some piece of code gets executed (server or client side) different things should be accomplished (client synchronization etc.).
The problem is that relying on the default check if
defined?(Rails::Server)
depends on the webserver you are running and the enclosing environment.
For example i run on puma (in docker for development and in Ubuntu server for production) and even in that case defined?(Rails::Server) works fine in development but not in production. This reveals that server execution detection depends not only on the actual server you are running on, but also on the method used to start it (e.x. rails s VS puma start)
Additional information can be found here:
Detect if application was started as HTTP server or not (rake task, rconsole etc)
https://gitter.im/ruby-hyperloop/chat?at=59d60f2201110b72317cd61c
https://hyperstack-org.slack.com/archives/CHRQ5U8HL/p1557262851049900
Is there a standard way to check whether something in Rails is executing on the server process/thread (not in browser, some sort of client, console, migration, rake task etc.) without relying on some hack to identify or declare what server we deploy on (puma, thin, nginx etc.)?
You can use the RUBY_ENGINE guard to see if the code is running in Opal or not.
if RUBY_ENGINE == 'opal'
# I am on the client
end
This is very useful in your Isomorphic models to exclude parts of the model's methods from existing on the client. Also very useful for using added Gem methods which make no sense in the client code.

How can I use VCR with Rails 5.1 system tests?

Many things on the web seem to suggest that VCR can be used with Capybara.
I have three problems.
This doesn't make much sense to me, because the test driver and the application code don't share memory.
I'm not finding full recipes on how to set this up.
I'm finding bits and pieces of how people have set this up, but it's outside of the context of rails 5.1, which does the capybara setup behind the scenes.
How do I configure a Rails 5.1 app, Capybara, and VCR to work together for system tests?
(My headless browser is phantomjs, driven by poltergeist. But I don't need to intercept requests from the browser, only server-side requests. If I needed to intercept from the browser I would probably use a full http proxy server, like puffing-billy.)
I'm assuming you mean Rails 5.1 since Rails 5 doesn't have system tests.
The copy of the application Capybara runs for testing is run in a separate thread, not a separate process. This means they do have access to the same memory, and loaded classes
There is nothing special required for configuring WebMock or VCR beyond what their READMEs already provide
The setup of Capybara and how Rails handles it is irrelevant to the configuration of WebMock or VCR. Additionally, even when using Rails 5.1 system tests all of the normal Capybara configuration options are still usable.
That all being said, there are a couple of things to be aware of here. Firstly, WebMock/VCR can only deal with requests made by your app (not from the browser which you stated you don't need) and it's generally better to use faked services (if possible) rather than WebMock/VCR when doing end to end system tests since there is less interference with the code under test.
If this doesn't answer your issues, post a question with a specific issue you're having, the code that's causing your issue, and the error you're getting.

testing with selenium not able to log in

It's the first test im writing that requires :js => true so I installed selenium.
I am always able to login with some credentials I create before but unable to log in when I run them through selenium.
A sanity check to see if I'm still creating my user (recruiter)
puts "RECRUITER NAME => #{Recruiter.first.email}"
returns
RECRUITER NAME => company1#test.com
I always set my password to "testtesttest"
But it always fails to login.
Is it using a different (empty?) database? Am I missing some settings that are required?
Note => Logging in with the exact same file works flawless if I remove :js => true. But somehow it breaks on this step.
When performing js tests the app being tested runs in a different thread than the test, which means they no longer share the same database connection - see https://github.com/jnicklas/capybara#transactions-and-database-setup. There are ways to force the two threads to share the connection, but it ends up being flaky on some edge cases and limiting what database access you can do at specific times in your test, and really isn't something a beginner wants to deal with. The better/easiest solution is to disable transactional testing and use truncation or deletion to manage the database state. The easiest way to do that is to use database_cleaner and setup a config that will swap to the needed strategy for each test - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example

Rails: test mailgun on localhost

I have a Rails app running on Heroku that uses Mailgun to process incoming emails. I haven't been able to figure how I can debug my email processing locally (on localhost) instead of having to push everything up to heroku every time I make a change. (this is just a test app - I'm the only one using it)
Is it possible to work with Mailgun locally? If so, how do I go about it?
Thank you in advance
Mailgun gives you the option to store a message for later retrieval. If you configure it that way, you'll be able to fetch messages from development for processing without having to set up a publicly-accessible webhook for Mailgun to hit.
But I'm assuming you have production configured with an HTTP endpoint, and it's no fun to do things differently between environments. There are a few tools that will let you set up a public endpoint that routes to localhost:
ngrok, which I've used to good effect to test Twilio. You can set up a permanent subdomain so you don't have to constantly change your Mailgun configuration.
UltraHook, which I haven't personally used, but looks the same.
Localtunnel which looks easiest to start up, but like you get a different host at every boot.
If you have a permanent publicly-accessible server, you can also maintain your own tunnel.
mailgun provides a sandbox that you can use for localhost the only downside to this is that you have to add the test email to valid recipient.
using this gem might be another possible solution:
https://github.com/ryanb/letter_opener/ or https://github.com/fgrehm/letter_opener_web for more advanced features
follow installation from repo
mail will open in new tab

How to test sending emails from asp.net on development machine?

How do I accomplish this? The SMTP class throws error on dev machine about not finding an SMTP server. Is there a way to test sending emails on development machine?
Shawn,
Straight from my web.config:
<smtp deliveryMethod="SpecifiedPickupDirectory">
<network host="ignored" />
<specifiedPickupDirectory pickupDirectoryLocation="c:\email_c#" />
</smtp>
this works fine insofar as being able to review the 'emails' that get saved into the pickupDirectoryLocation directory.
Give it a try...
You can dump the files on disk, by configuring System.Net.Mail.SmtpClient to use a deliveryMethod of type SpecifiedPickupDirectory, I found an example on SO
I know this is an old thread, but I just stumbled upon this service:
http://mailtrap.io/
Which is friggin brilliant. It serves as a dummy SMTP server for your app, and doesn't actually send the emails, but allows you to easily view them in the browser (or via API).
It's killer.
There's a couple possible reasons for this.
1) Is your code configured to use local SMTP server during development and you've upgraded to windows 7? There's no longer a SMTP server available on your localhost. Find and download smtp4dev to allow your localhost to trap the sent Emails.
2) If you are using a remote SMTP server, check your windows firewall to confirm that you are allowed to send outgoing mail. If you are, then confirm that your machine/username has rights to send mail via that server. A quick telnet:25 to the server should let you know if your connection is refused or not.
Assuming by "test sending emails" you mean sending test emails instead of formal/unit testing, I like to use smtp4dev:
http://smtp4dev.codeplex.com/
As the page explains, it's a dummy SMTP server, basically intercepting your outgoing messages from your app, allowing you to examine those messages and make sure everything works as you expect. It's a Windows app, which hopefully isn't an issue if you're developing for ASP.NET.
I usually do this by creating a wrapper class for the SmtpClient, then mocking out the wrapper in my tests. This removes the actual mail client/server dependencies from my unit tests. The wrapper itself is relatively thin so I don't feel the need to create tests for it. Usually I do my integration level testing for things like this as exploratory tests in my staging environment. The staging environment typically uses a production mail server, but with "fake" data -- e.g., customer email addresses replaced with my own.
Having said that, I would expect the client to work without errors even on your development system unless your mail server is protected by a firewall or something that would prevent your dev system talking to it. Can you give more detail on what the error you are experiencing?
Without seeing the exception there's not much we can do. As long as the details on your dev machine are pointing to a proper smtp server and have the correct credentials then your code won't be the issue and you should look further down the chain. I had an exception of the target machine refusing the request despite everything else being right. After spending ages double and triple checking the credentials, sending from our server etc I tracked the bug down to McAfee blocking email port 25...

Resources