Skip to content

Commit

Permalink
v1.4.2 (#149)
Browse files Browse the repository at this point in the history
* chore(docs): remove references to old API including createTestEnvFile (closes #143)
* build(deps): bump lodash from 4.17.15 to 4.17.19 (#147)
* build(deps): bump lodash from 4.17.15 to 4.17.19 in /examples/basic (#146)
* chore(ci): add node 14 to versions matrix of verify workflow
* chore(ci): add cancel previous runs step
* chore(ci): switch to codecov custom action now this it does not depend on a docker image
* chore(examples): update example dependencies

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
prescottprue and dependabot[bot] authored Jul 22, 2020
1 parent bd94248 commit 10e2be7
Show file tree
Hide file tree
Showing 13 changed files with 2,484 additions and 2,142 deletions.
14 changes: 9 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

- name: Checkout code
uses: actions/checkout@v2

Expand Down Expand Up @@ -94,11 +99,10 @@ jobs:
name: build
path: lib

# Upload to codecov.io. Curl used in place of codecov/codecov-action
# due to long build time. See https://github.com/codecov/codecov-action/issues/21
- name: Upload Coverage
if: steps.check.outputs.changed == 'true'
run: bash <(curl -s https://codecov.io/bash) || echo 'Codecov failed to upload'
- name: Upload Test Coverage
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true

- name: Create Release
if: steps.check.outputs.changed == 'true'
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x]
node-version: [10.x, 12.x, 14.x]
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

- name: Checkout code
uses: actions/checkout@v2

Expand Down Expand Up @@ -59,7 +64,8 @@ jobs:
- name: Size Check
run: $(yarn bin)/size-limit

# Upload to codecov.io. Curl used in place of codecov/codecov-action
# due to long build time. See https://github.com/codecov/codecov-action/issues/21
- name: Upload Coverage
run: bash <(curl -s https://codecov.io/bash) || echo 'Codecov failed to upload'
- name: Upload Test Coverage
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: false

5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
[![License][license-image]][license-url]
[![Code Style][code-style-image]][code-style-url]

> Utilities and cli to help testing Firebase projects with Cypress
> Cypress plugin and custom commands for testing Firebase projects
## What?

- Test environment config generation (including custom auth token) with [`createTestEnvFile`](#createTestEnvFile)
- [Custom cypress commands](https://docs.cypress.io/api/cypress-api/custom-commands.html#Syntax) for auth and database interactions:
- [cy.login][1]
- [cy.logout][4]
Expand All @@ -31,7 +30,7 @@ If you are interested in what drove the need for this checkout [the why section]

**Note:** These instructions assume your tests are in the `cypress` folder (cypress' default). See the [folders section below](#folders) for more info about other supported folders.

1. Install `cypress-firebase` and [`firebase-admin`](https://www.npmjs.org/package/firebase-admin) both: `npm i --save-dev cypress-firebase firebase-admin` or `yarn add -D cypress-firebase firebase-admin --save-dev`
1. Install `cypress-firebase` and [`firebase-admin`](https://www.npmjs.org/package/firebase-admin) both: `yarn add -D cypress-firebase firebase-admin` or `npm i --save-dev cypress-firebase firebase-admin`
1. Go to project setting on firebase console and generate new private key. See how to do so [in the Google Docs](https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/firebase/tutorials/authenticate-with-a-service-account).
1. Add `serviceAccount.json` to your `.gitignore` (THIS IS VERY IMPORTANT TO KEEPING YOUR INFORMATION SECURE!)
1. Save the downloaded file as `serviceAccount.json` in the root of your project (make sure that it is .gitignored) - needed for `firebase-admin` to have read/write access to your DB from within your tests
Expand Down
274 changes: 153 additions & 121 deletions examples/basic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,147 +2,179 @@

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).


## How Was It Made?

### Project Creation

1. `create-react-app basic && cd basic`
1. Add some useful tools: `yarn add lodash` or `npm i --save lodash`

### Add Firebase

1. Install Firebase library: `yarn add firebase` or `npm i --save firebase`
1. Add Firebase config to `src/config.js`:
```js
export const firebase = {
apiKey: "AIzaSyCTUERDM-Pchn_UDTsfhVPiwM4TtNIxots",
authDomain: "redux-firebasev3.firebaseapp.com",
databaseURL: "https://redux-firebasev3.firebaseio.com",
projectId: "redux-firebasev3",
storageBucket: "redux-firebasev3.appspot.com",
messagingSenderId: "823357791673"
}
```

```js
export const firebase = {
apiKey: "AIzaSyCTUERDM-Pchn_UDTsfhVPiwM4TtNIxots",
authDomain: "redux-firebasev3.firebaseapp.com",
databaseURL: "https://redux-firebasev3.firebaseio.com",
projectId: "redux-firebasev3",
storageBucket: "redux-firebasev3.appspot.com",
messagingSenderId: "823357791673",
};
```

1. Add `src/initFirebase.js` - a util to import Firebase and initialize it (supports already initialized Firebase instance on window for testing):

```js
import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'
import 'firebase/firestore' // make sure you add this for firestore
import { firebase as fbConfig } from './config'

let firebaseInstance

export default function initFirebase(initialState, history) {
if (firebaseInstance) {
return firebaseInstance
}
// Handle initializeing firebase app if not already on window (when running tests)
if (window.fbInstance) {
firebaseInstance = window.fbInstance
}
// Init Firebase if an instance doesn't already exist
if (!firebaseInstance) {
firebase.initializeApp(fbConfig)
firebaseInstance = firebase
}
// Return Firebase instance
return firebaseInstance
```js
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/database";
import "firebase/firestore"; // make sure you add this for firestore
import { firebase as fbConfig } from "./config";

let firebaseInstance;

export default function initFirebase(initialState, history) {
if (firebaseInstance) {
return firebaseInstance;
}
```
// Handle initializeing firebase app if not already on window (when running tests)
if (window.fbInstance) {
firebaseInstance = window.fbInstance;
}
// Init Firebase if an instance doesn't already exist
if (!firebaseInstance) {
firebase.initializeApp(fbConfig);
firebaseInstance = firebase;
}
// Return Firebase instance
return firebaseInstance;
}
```

1. Load Firebase data in the home component:

```jsx
import React, { Component } from 'react';
import { invoke, map } from 'lodash';
import logo from './logo.svg';
import initFirebase from './initFirebase'
import Project from './Project'
import './App.css';

const fbInstance = initFirebase()

class App extends Component {
constructor() {
super()
this.state = { loading: false }
}

componentDidMount() {
this.setState({ loading: true })
fbInstance.database()
.ref('projects')
.limitToFirst(10)
.on('value', (snap) => {

```jsx
import React, { Component } from "react";
import { invoke, map } from "lodash";
import logo from "./logo.svg";
import initFirebase from "./initFirebase";
import Project from "./Project";
import "./App.css";

const fbInstance = initFirebase();

class App extends Component {
constructor() {
super();
this.state = { loading: false };
}

componentDidMount() {
this.setState({ loading: true });
fbInstance
.database()
.ref("projects")
.limitToFirst(10)
.on(
"value",
(snap) => {
this.setState({
projects: snap.val(),
loading: false
})
}, (err) => {
loading: false,
});
},
(err) => {
this.setState({
loading: false,
error: invoke(err, 'toString') || err
})
})
}

render() {
const { loading, projects } = this.state
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
{
loading
? <div>Loading...</div>
: !projects
? <div>Projects not found</div>
: map(projects, (project, projectKey) =>
<Project
key={`Project-${projectKey}`}
project={project}
projectId={projectKey}
/>
)
}
</header>
</div>
error: invoke(err, "toString") || err,
});
}
);
}
}

export default App;
```
render() {
const { loading, projects } = this.state;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
{loading ? (
<div>Loading...</div>
) : !projects ? (
<div>Projects not found</div>
) : (
map(projects, (project, projectKey) => (
<Project
key={`Project-${projectKey}`}
project={project}
projectId={projectKey}
/>
))
)}
</header>
</div>
);
}
}

export default App;
```

### Add Cypress Testing

1. Add `.env` that looks like so (to skip warnings due to Cypress deps being out of date):
```
SKIP_PREFLIGHT_CHECK=true
```
1. Install Cypress: `yarn add --dev cypress` or `npm i --save-dev cypress`
1. Install deps for testing: `yarn add --dev cypress-firebase firebase-tools-extra cross-env` or `npm i --save-dev cypress-firebase firebase-tools-extra cross-env`
1. Run `cypress open` to scaffold out Cypress project and open Cypress UI
1. Close the Cypress UI and remove the `cypress/examples` folder
1. Add npm scripts:
```json
"build:testConfig": "cypress-firebase createTestEnvFile",
"test": "npm run build:testConfig && cross-env CYPRESS_baseUrl=http://localhost:3000 cypress run",
"test:ui": "npm run build:testConfig && cross-env CYPRESS_baseUrl=http://localhost:3000 cypress open",
```
1. Add custom commands and Firebase initialization to `cypress/support/commands.js`:
```js
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';
import 'firebase/firestore';
import { attachCustomCommands } from 'cypress-firebase';
const fbConfig = {
// your firebase config
}
window.fbInstance = firebase.initializeApp(fbConfig);
// add cy.login, cy.logout, cy.callRtdb, and cy.callFirestore
attachCustomCommands({ Cypress, cy, firebase })
```

```
SKIP_PREFLIGHT_CHECK=true
```

1. Install `cypress-firebase` and [`firebase-admin`](https://www.npmjs.org/package/firebase-admin) both: `npm i --save-dev cypress-firebase firebase-admin` or `yarn add -D cypress-firebase firebase-admin`
1. Go to project setting on firebase console and generate new private key. See how to do so [in the Google Docs](https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/firebase/tutorials/authenticate-with-a-service-account).
1. Add `serviceAccount.json` to your `.gitignore` (THIS IS VERY IMPORTANT TO KEEPING YOUR INFORMATION SECURE!)
1. Save the downloaded file as `serviceAccount.json` in the root of your project (make sure that it is .gitignored) - needed for `firebase-admin` to have read/write access to your DB from within your tests
1. Add the following your custom commands file (`cypress/support/commands.js`):

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

1. Make sure that you load the custom commands file in an `cypress/support/index.js` like so:

```js
import "./commands";
```

**NOTE**: This is a pattern which is setup by default by Cypress, so this file may already exist

1. Setup plugin adding following your plugins file (`cypress/plugins/index.js`):

```js
const admin = require("firebase-admin");
const cypressFirebasePlugin = require("cypress-firebase").plugin;

module.exports = (on, config) => {
const extendedConfig = cypressFirebasePlugin(on, config, admin);

// Add other plugins/tasks such as code coverage here

return extendedConfig;
};
```
Loading

0 comments on commit 10e2be7

Please sign in to comment.