Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
cypress-firebase
Advanced tools
Utilities and cli to help testing Firebase projects with Cypress
createTestEnvFile
If you are intereted in what drove the need for this checkout the why section
Note: Skip cypress install if it already exists within your project
TEST_UID
)serviceAccount.json
npm i --save-dev cypress
cypress open
Note: These instructions assume your tests are in the cypress
folder (cypress' default). See the folders section below for more info about other supported folders.
Make sure you have firebase-tools
installed (globally or within project). It is used to call to database when using cy.callRtdb
and cy.callFirestore
.
Install using npm i cypress-firebase --save-dev
Add the following to the scripts
section of your package.json
:
"build:testConfig": "cypress-firebase createTestEnvFile",
"test": "npm run build:testConfig cypress run",
"test:open": "npm run build:testConfig cypress open",
"test:stage": "npm run test -- --env envName=stage",
"test:open:stage": "npm run test:open -- --env envName=stage"
Environment variables can be passed through --env
. envName
points to the firebase project within the projects section of .firebaserc
.
Add your config info to cypress/config.json
{
"TEST_UID": "<- uid of the user you want to test as ->",
"FIREBASE_PROJECT_ID": "<- projectId of your project ->"
}
Add the following your custom commands file (cypress/support/commands.js
):
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';
import 'firebase/firestore';
import { attachCustomCommands } from 'cypress-firebase';
const fbConfig = {
// Your config from Firebase Console
};
window.fbInstance = firebase.initializeApp(fbConfig);
attachCustomCommands({ Cypress, cy, firebase })
Setup plugin adding following your plugins file (cypress/plugins/index.js
):
const cypressFirebasePlugin = require('cypress-firebase').plugin
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
// Return extended config (with settings from .firebaserc)
return cypressFirebasePlugin(config)
}
The plugin sets baseUrl
and loads config from .firebaserc
npm start
) - for faster alternative checkout the test built version sectionnpm run test:open
in another terminal windowTests will run faster locally if you tests against the build version of your app instead of your dev version (with hot module reloading and other dev tools). You can do that by:
Adding the following npm script:
"start:dist": "npm run build && firebase serve --only hosting -p 3000",
Run npm run start:dist
to build your app and serve it with firebase
In another terminal window, run a test command such as npm run test:open
firebase login:ci
to generate a CI token for firebase-tools
(this will give your cy.callRtdb
and cy.callFirestore
commands admin access to the DB)FIREBASE_TOKEN
within CI environment variablescypress
is the default folder where config is loaded from, but you can use another folder by specifiying a different setting for the integrationFolder
parameter in cypress.json
:
{
"projectId": "<- your project id ->",
"fixturesFolder": "test/e2e/fixtures",
"integrationFolder": "test/e2e/integration",
"pluginsFile": "test/e2e/plugins/index.js",
"screenshotsFolder": "test/e2e/screenshots",
"videosFolder": "test/e2e/videos",
"supportFile": "test/e2e/support/index.js"
}
Create test environment file (cypress.env.json
) which contains custom auth token generated using firebase-admin
SDK and serviceAccount.json
.
cypress-firebase createTestEnvFile
Login to Firebase auth using FIREBASE_AUTH_JWT
environment variable
which is generated using firebase-admin
authenticated with serviceAccount
during build:testConfig
phase.
cy.login()
Log out of Firebase instance
cy.logout()
Call Real Time Database path with some specified action. Authentication is through FIREBASE_TOKEN
since firebase-tools is used (instead of firebaseExtra).
action
String The action type to call with (set, push, update, remove)actionPath
String Path within RTDB that action should be appliedopts
Object Options
opts.args
Array Command line args to be passedSet data
const fakeProject = { some: 'data' }
cy.callRtdb('set', 'projects/ABC123', fakeProject)
Set Data With Meta
const fakeProject = { some: 'data' }
// Adds createdAt and createdBy (current user's uid) on data
cy.callRtdb('set', 'projects/ABC123', fakeProject, { withMeta: true })
Get/Verify Data
cy.callRtdb('get', 'projects/ABC123')
.then((project) => {
// Confirm new data has users uid
cy.wrap(project)
.its('createdBy')
.should('equal', Cypress.env('TEST_UID'))
})
Other Args
const opts = { args: ['-d'] }
const fakeProject = { some: 'data' }
cy.callRtdb('update', 'project/test-project', fakeProject, opts)
Call Firestore instance with some specified action. Authentication is through serviceAccount.json since it is at the base level. If using delete, auth is through FIREBASE_TOKEN since firebase-tools is used (instead of firebaseExtra).
action
String The action type to call with (set, push, update, remove)actionPath
String Path within RTDB that action should be appliedopts
Object Options
opts.args
Array Command line args to be passedBasic
cy.callFirestore('set', 'project/test-project', 'fakeProject.json')
Recursive Delete
const opts = { recursive: true }
cy.callFirestore('delete', 'project/test-project', opts)
Other Args
const opts = { args: ['-r'] }
cy.callFirestore('delete', 'project/test-project', opts)
Full
describe('Test firestore', () => {
const TEST_UID = Cypress.env('TEST_UID');
const mockAge = 8;
beforeEach(() => {
cy.visit('http://localhost:4200');
});
it('read/write test', () => {
cy.log('Starting test');
cy.callFirestore('set', `testCollection/${TEST_UID}`, {
name: 'axa',
age: 8,
});
cy.callFirestore('get', `testCollection/${TEST_UID}`).then(r => {
cy.wrap(r[0])
.its('id')
.should('equal', TEST_UID);
cy.wrap(r[0])
.its('data.age')
.should('equal', mockAge);
});
cy.log('Ended test');
});
});
It isn't currenlty possible to use Firebase's firebase-admin
SDK directly within Cypress due to dependencies not being able to be loaded into the Browser environment. Since firebase-admin
is nessesary to generate custom token needed to login to Firebase, the usage of it happens outside of Cypress (through cypress-firebase createTestEnvFile
) before booting up.
Instead of a cli tool, the plugin that is include could maybe use firebase-admin
(since cypress plugins is a node environment) - when investigating this, I found it frustrating to get the values back into the test. That said, always open to better ways of solving this, so please reach out with your ideas!
fireadmin.io - A Firebase project management tool (here is the source)
FAQs
Utilities to help testing Firebase projects with Cypress.
The npm package cypress-firebase receives a total of 18,371 weekly downloads. As such, cypress-firebase popularity was classified as popular.
We found that cypress-firebase demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.