npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ralphsmith80/cypress-firebase

v0.2.8

Published

Utilities to help testing Firebase projects with Cypress.

Downloads

12

Readme

cypress-firebase

NPM version Build Status Dependency Status License Code Style

Utilities and cli to help testing Firebase projects with Cypress

What?

If you are interested in what drove the need for this checkout the why section

Usage

Pre-Setup

Note: Skip cypress install if it already exists within your project

  1. Log into your Firebase console for the first time.
  2. Go to Auth tab of Firebase and create a user for testing purpose
  3. Get the UID of created account. This will be the account which you use to login while running tests (we will call this UID TEST_UID)
  4. Go to project setting on firebase console and generate new private key. See how to do here
  5. Save the downloaded file as serviceAccount.json in the root of your project (for local dev)
  6. Set service account as the SERVICE_ACCOUNT environment variable within your CI (make sure to wrap it in ")
  7. Install Cypress and add it to your package file: npm i --save-dev cypress
  8. Add cypress folder by calling cypress open

Setup

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.

  1. 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.

  2. Install using npm i cypress-firebase --save-dev

  3. 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.

  4. 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 ->",
      "FIREBASE_API_KEY": "<- browser apiKey of your project ->"
    }
  5. 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
    };
    
    firebase.initializeApp(fbConfig);
    
    attachCustomCommands({ Cypress, cy, firebase })
  6. 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

Running

  1. Start your local dev server (usually npm start) - for faster alternative checkout the test built version section
  2. Open cypress test running by running npm run test:open in another terminal window

Test Built Version

Tests 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:

  1. Adding the following npm script:

    "start:dist": "npm run build && firebase serve --only hosting -p 3000",
  2. Run npm run start:dist to build your app and serve it with firebase

  3. In another terminal window, run a test command such as npm run test:open

CI

  1. Run 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)
  2. Set FIREBASE_TOKEN within CI environment variables

Folders

cypress 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"
}

Docs

CLI Commands

createTestEnvFile {#createTestEnvFile}

Create test environment file (cypress.env.json) which contains custom auth token generated using firebase-admin SDK and serviceAccount.json.

Requirements

A service account must be provided. This can be done by setting serviceAccount.json in the root of the project (often used locally since service accounts should be in gitignore), or by setting the SERVICE_ACCOUNT enviroment variable. For different environmets you can prefix with the environment name such as STAGE_SERVICE_ACCOUNT.

Examples
cypress-firebase createTestEnvFile

Custom Cypress Commands

Table of Contents

cy.login

Login to Firebase auth using FIREBASE_AUTH_JWT environment variable which is generated using firebase-admin authenticated with serviceAccount during build:testConfig phase.

Examples
cy.login()

Get current UserId and aliases it for later usage.

  //Assuming there's a uid property at the root level of the user object.
  cy.login().then($auth => cy.wrap($auth).its('uid').as('uid'));
  //Then, later somewhere in the test, use the uid like this,
  cy.get('@uid').then((uid) => { 
  //Your code here.
  }

cy.logout

Log out of Firebase instance

Examples
cy.logout()

cy.callRtdb

Call Real Time Database path with some specified action. Authentication is through FIREBASE_TOKEN since firebase-tools is used (instead of firebaseExtra).

Parameters
  • action String The action type to call with (set, push, update, remove)
  • actionPath String Path within RTDB that action should be applied
  • opts Object Options
    • opts.args Array Command line args to be passed
Examples

Set 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)

cy.callFirestore

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).

Parameters
  • action String The action type to call with (set, push, update, remove)
  • actionPath String Path within RTDB that action should be applied
  • opts Object Options
    • opts.args Array Command line args to be passed
Examples

Basic

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');
  });
});

Why?

It isn't currently 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 included 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!

Projects Using It

fireadmin.io - A Firebase project management tool (here is the source)

Roadmap

  • Fix issue where auth token goes bad after test suite has been open a long time