Cypress technique to bypass OAuth2 in Rails

Shumnan Sun
Cypress.io Thailand
4 min readNov 26, 2021

Use cypress-on-rails gem to mock and bypass authentication via App Command.

Problem

Solution

Install cypress-on-rails as a ready-to-use package that allow test script to access app command for mocking OAuth2. Then bypass authentication system provided by OmniAuth and Devise sign-in with mocked data. This process bypass without accessing GUI, which reduce execution time significantly

1) Pre-requisite

Clone repository from railsfriend:cy_on_rails_initial

2) Install cypress-on-rails Gem

Add this gem into Gemfile

group :development do
# Add to development Gem


gem 'cypress-on-rails'
end

Then execute bundle installation command

bundle install

Setup cypress-on-rails by execute this command

rails g cypress_on_rails:install

3) Add TypeScript configuration

Create tsconfig.json as TypeScript configuration file.

Warning: The tsconfig.json need to be in project root or it always failed to load some method.

More detail can be read from TypeScript official Document

{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["node", "cypress"]
},
"include": ["**/*.ts"]
}

Create cypress/support/index.d.ts as as main TS file. These declaration would allow to use command generated from cypress_on_rails

/// <reference types="cypress" />

declare namespace
Cypress {
interface Chainable<Subject = any> {
app(route: string, options: any): void;
appCommands(params: { name: string; options: any }): Promise<any>;
appScenario(name: any, options?: object): Promise<any>;
appEval(code: any): Promise<any>;
appFactories(option: any): Promise<any>;
appFixtures(option: any): Promise<any>;
}
}

4) Add app command to mock OAuth2

Create app command file in Test Helper module at cypress/app_commands/google_oauth2_mock.rb

module TestHelpers
class GoogleOAuth2Mock
def self
.run(auth)
new.run(auth)
end

def
run(auth)
OmniAuth.config.mock_auth[:google_oauth2] =
OmniAuth::AuthHash.new(auth) # From OmniAuth
end
end
end

TestHelpers::GoogleOAuth2Mock.run(command_options)

The the file name can be called as method as the following format

cy.app(‘google_oauth2_mock’, <mocked_auth_json_object>)

Ensure the configure are uncomment and enabled
config/environments/development.rb

Note: File name depending on using environment

OmniAuth.config.test_mode = true

5) Create auth mock data

Create cypress/fixtures/correct_user.json as test data

{
"provider": "google_oauth2",
"uid": "123456789012345678901",
"name": "mocked_name",
"info": {
"email": "mocked.name@gmail.com"
}
}

6) Implement Keyword file to call created app commands

Create cypress/integration/Bypass.feature as feature file

Feature: Bypass

Scenario: TC_00002 Bypass login to Railsfriends
Given bypass login
Then sign out displayed on menu bar

Create cypress/integration/Bypass/Bypass.ts as keyword file.
This file will call the commaned created sin Step 4

/// <reference types="cypress" />
// Above line needed as indicator for Cypress

// Import Cucumber prefix
import
{Given, Then} from 'cypress-cucumber-preprocessor/steps';
import Common from "../Common";

// Keyword need to be called by Feature files
Given('bypass login', () => {
cy.fixture('correct_user').then((user_json)=>{
cy.app('google_oauth2_mock', user_json)
})
cy.visit('/')
cy.get('a').contains('Sign in with GoogleOauth2').click()
});

Then('sign out displayed on menu bar', () => {
Common.signOutDisplayed()
});

The follow code is custom command in cypress

cy.app('<command_name>', <params>)

7) Execute the test with GUI

Start railsfriend app

rails s

Start Cypress GUI

cypress open

Click on Bypass.feature then Cypress will bypass Sign in step.
Result in when script Sign in with GoogleOauth2, page will be redirected as authntication success immediatly

Summary

Using cypress-on-rails extend Cypress to access and interact with the app with app_command. Combine this with a built-in mock feature in omniauth. These allow the test script to mock the authentication instantly with only a one-time setup for each strategy.

--

--

Shumnan Sun
Cypress.io Thailand

Develop Test and Deploy. Interesting in develop pipeline. Still young in information analysis and A.I.