Testing JavaScript partials with Rails View Specs

Blog posts   •   Jan 13, 2020 13:15 CET

At Mynewsdesk we use Rails in the backend and React in combination with Redux in the frontend in our main application that our customers use to create and distribute press releases. Rails is responsible for rendering the HTML layout that hosts the React app. This layout file includes a partial that contains various JavaScript variables that we're passing from Rails to React.

When we develop new features, we often put them behind feature flags which are stored in Redis by the flipper gem. Since many feature flags are included in the partial mentioned above, this file is often changed by both frontend and backend developers.

Feature flags that are not set correctly can lead to unexpected bugs in production. To prevent accidental regressions when making changes in the partial we recently added view specs for the partial to ensure two things:

1. The partial should render without any unhandled Ruby exceptions.

In RSpec the view spec might look like this:

describe 'layouts/_env.html.erb' do
  it 'renders'
    expect { render }.not_to raise_error
  end
end

This will catch bugs like undefined local variable or method or undefined method `foo' for nil:NilClass, as sometimes introduced by typos, syntax errors or faulty MacBook Pro keyboards.

2. The partial should contain the expected JavaScript objects which parse without errors in a JavaScript runtime.

We could use expect(rendered).to have_content to look for JavaScript variables that we expect Rails to render. However the matcher have_content is string-based and cannot guarantee that the JavaScript object we're rendering is actually valid JavaScript.

To check for valid JavaScript we use the MiniRacer gem which gives us a V8-based JavaScript context that we can use to evaluate the JavaScript object and compare against a Ruby hash.

let(:js_context) do
  render
  snapshot = MiniRacer::Snapshot.new(rendered)
  MiniRacer::Context.new(snapshot: snapshot)
end

it 'renders feature flags' do
  mnd = js_context.eval("MND")
  expect(mnd["featureFlags"]).to include(
    "featureA" => true,
    "featureB" => false,
  )
end

These specs help us to make changes to our JavaScript partial with confidence.

In this blog post we explain how we use view specs to test JavaScript partials that are rendered by Rails.

Read more »

ReactEurope conference summary!

Blog posts   •   Jul 10, 2015 15:44 CEST

The gang (Emil, Jocke and Woll) visited ReactEurope in Paris on July 2–3. This is a post with thoughts around the conference and rants of how hot it was.

Mynewsdesk Robotwars

Blog posts   •   Jun 18, 2015 09:54 CEST

Mynewsdesk development team tried out Robotwars, where you program robots to fight against each other.

Moving to Heroku

Blog posts   •   Dec 05, 2014 09:22 CET

About Mynewsdesk's Epic Journey to Heroku.

Ember Workshop

Blog posts   •   Oct 16, 2014 21:23 CEST

Nico and Jonas held our second workshop for getting started with Ember.

Fronteers 2014 – The Day That Never Ended

Blog posts   •   Oct 15, 2014 09:49 CEST

The last chapter in our adventure. Thanks to Fronteers & Burger Bar for making this trip awesome!

Maker Space

Blog posts   •   Oct 12, 2014 14:00 CEST

Mynewsdesk moves into the era of Internet of Things by starting a Maker Space

Fronteers 2014 – Day 1

Blog posts   •   Oct 10, 2014 10:23 CEST

Our epic adventure continues as we fight through crowds of developers, wade through coffee rivers, eat cookies (a lot of cookies) and learn new front-end survival skills.

Fronteers 2014 – The Arrival

Blog posts   •   Oct 09, 2014 09:34 CEST

After the plane landed, we took the train from Schiphol airport station, riding it like a wild bull, and got off at this once so important harbor city, the center for all sea based trading coming in and out of Europe. We started our journey with a pitstop at the closest Vlaamse frites place we could find.

A simple https server for development

Blog posts   •   Sep 24, 2014 11:11 CEST

Last day, I had to serve some html pages via HTTPS. But didn't really know any simple solution to do this.

Here is one. A simple wrapper of the python SimpleHTTPServer with support for SSL.

Before running the server, you'll need to create your certificate:

openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes

Now that you have your certificate, create the file srv.py:

#!/usr/bin/python

## Run the following command to generate your certificate file
# openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
import os
import BaseHTTPServer, SimpleHTTPServer
import ssl 
import sys 

cdir = os.getcwd()
os.chdir(cdir)

certFile = os.path.dirname(sys.argv[0]) + '/server.pem'

httpd = BaseHTTPServer.HTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile=certFile, server_side=True)
httpd.serve_forever()

Add this file to your path, or simply call it from wherever you want like that:

	/path/to/srv.py

This will serve the file in your current directory on https://localhost:4443

If you need a non https version to simply serve some static file, you can use the standard python simpleHTTPServer like this:

	python -m SimpleHTTPServer

Last day, I had to serve some html pages via HTTPS. But didn't really know any simple solution to do this. Here is one. A simple wrapper of the python SimpleHTTPServer with support for SSL.

Read more »

About Mynewsdesk Devcorner

Get to know what's happening in the development team of Mynewsdesk.