I’ve got an application which I want to dust the bit-rot off of and update to have something other than a stock HTML interface. Not that the application needs anything particularly fancy however the awesome open source contributations to the React Material UI makes it easy to apply that look and feel to the system, so why not?

First up I think I want to write some automated tests to ensure I don’t break anything. Probably not the best idea to update the dependnecies first. It’s been a while since I’ve booted up this service, I should really remember to put instructions in the README files. The application stack is Sinatra-ActiveRecord so that makes life simple. Ran rake db:migrate to ensure everything was up to date and I’m good to go. Hmm, application uses Google auth. That will be a pain to automate. Google’s auth system doesn’t play nice with automated testing bots at all making life rather difficult.

Boom! Well, I guess that is why I need automated tests. Sometimes things are left accidently broken. I like the stack traces with the line numbers like -6. Looks like the cause of the explosion is a missing local variable. Should be easy enough to fix. Alrighty, original condition restored. Now to begin testing the application. I think I’ll time box the test.

First step in testing the system will be deal with the Google Credentials. I really wish I could create the two test accounts I need for automated verification through offical channels. Sigh, all well. On to automation! Simple Gemfile:

# frozen_string_literal: true
source "https://rubygems.org"

gem "selenium-webdriver", "3.0.4"
gem "pry", "0.10.4"
gem "cucumber", "2.4.0"
gem "rspec", "3.5.0"

Running cucumber --init is great because the command generates the directory skelaton…but misses creating a base feature file. So onto finding an example! Don’t go to the Cucumber Github Project, they don’t have it there. What!? They have a Pro feature now? That is really stupid. So Feature Introduction is a good example. Access control features always start out so generic:

Feature: Access system for authroized users only
	Only authorized users should be able to access the system

Scenario: Unauthorized user is asked to authorize
	Given I am an unauthorized user
	When I attempt to access the dashboard
	Then I am asked to authenticate

I usually insult the URL for the application from hardcording the browser boostrap process. Don’t be bitter when implementing OAuth. Seriously though, having implemented several OAuth clients at this point it’s always disappointing. Lucky for me this round of testing has worked out really well! It worked out of the box; although the bigger problem was I assumed OAuth was broken because I’ve seen it broken too many times already. The system I’m working with explicitly restricts access to known people…because I haven’t built out any social network management system. So I need to ensure the user is invited. Alrighty, recorded that in the project read me and it works like a charm. To get the auth flow correct with Google I have the following:

Given(/^I am an unauthorized user$/) do

When(/^I attempt to access the dashboard$/) do
	browser.navigate.to gifty_url + "/dashboard"

Then(/^I am asked to authenticate$/) do
	sleep 2
	expect( browser.current_url ).to start_with( "https://accounts.google.com" )

Given(/^I am an authorized user$/) do
	@user = OpenStruct.new({
		:email => "{redacted}@gmail.com",
		:secret => "{redacted}",
		:name => OpenStruct.new({ :common_name => "Roy", :surname => "Irmgard" })

When(/^I authenticate with Google$/) do
	sleep 2
	browser.find_element( :id, "Email" ).send_keys( @user.email )
	browser.find_element( :id, "next" ).click

	sleep 2
	browser.find_element( :id, "Passwd" ).send_keys( @user.secret )
	browser.find_element( :id, "signIn" ).click

	sleep 2
	browser.find_element( :id, "submit_approve_access" ).click

Then(/^I should be at the dashboard$/) do
	browser.find_element( :id, "gifty-dashboard" )

I’m not sure if the delays are actually nessecary, however I remember seeing failures from Google often and I would rather not deal with suprious failures. The only part which could trip me up is if the id attributes of the elements change. The delays add a bit of a human element from their side. Now that I’ve got the basic auth flow down I can begin recording features of the application. Good enough for now; time to move onto my next tasks.