Skip to content

Commit e142af2

Browse files
authored
v0.2.0-alpha.5 (#28)
* fix(core): update `peerDependencies` to include firebase-tools v7 * fix(buildRtdbCommand): include preceding slash if it doesn't already exist on action path * fix(createTestEnvFile): move `createTestEnvFile` to its own file in src * fix(run): only include `envName` if argument is provided * fix(commands): switch `cy.logout` to use `onAuthStateChanged` - #20
1 parent d492441 commit e142af2

File tree

7 files changed

+206
-217
lines changed

7 files changed

+206
-217
lines changed

cmds/createTestEnvFile.js

Lines changed: 2 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -2,171 +2,10 @@
22
* createTestEnvFile commander component
33
* To use add require('../cmds/deploy.js')(program) to your commander.js based node executable before program.parse
44
*/
5-
6-
const chalk = require('chalk');
7-
const fs = require('fs');
8-
const pickBy = require('lodash/pickBy');
9-
const get = require('lodash/get');
10-
const size = require('lodash/size');
11-
const keys = require('lodash/keys');
12-
const isUndefined = require('lodash/isUndefined');
13-
const {
14-
envVarBasedOnCIEnv,
15-
getServiceAccount,
16-
getEnvPrefix,
17-
getCypressFolderPath,
18-
readJsonFile
19-
} = require('../lib/utils');
20-
const {
21-
DEFAULT_CONFIG_FILE_NAME,
22-
DEFAULT_TEST_ENV_FILE_NAME
23-
} = require('../lib/constants');
24-
const {
25-
FIREBASE_CONFIG_FILE_PATH,
26-
TEST_ENV_FILE_PATH
27-
} = require('../lib/filePaths');
285
const logger = require('../lib/logger');
6+
const createTestEnvFile = require('../lib/createTestEnvFile');
297

30-
/**
31-
* @param {functions.Event} event - Function event
32-
* @param {functions.Context} context - Functions context
33-
* @return {Promise}
34-
*/
35-
function createTestEnvFile(envName) {
36-
const envPrefix = getEnvPrefix(envName);
37-
// Get UID from environment (falls back to cypress/config.json for local)
38-
const uid = envVarBasedOnCIEnv('TEST_UID');
39-
const varName = `${envPrefix}TEST_UID`;
40-
const testFolderPath = getCypressFolderPath();
41-
const configPath = `${testFolderPath}/${DEFAULT_CONFIG_FILE_NAME}`;
42-
// Throw if UID is missing in environment
43-
if (!uid) {
44-
/* eslint-disable */
45-
const errMsg = `${chalk.cyan(
46-
varName
47-
)} is missing from environment. Confirm that ${chalk.cyan(
48-
configPath
49-
)} contains either ${chalk.cyan(varName)} or ${chalk.cyan('TEST_UID')}.`;
50-
/* eslint-enable */
51-
return Promise.reject(new Error(errMsg));
52-
}
53-
54-
// Get project from .firebaserc
55-
const firebaserc = readJsonFile(FIREBASE_CONFIG_FILE_PATH);
56-
57-
const currentCypressEnvSettings = readJsonFile(TEST_ENV_FILE_PATH);
58-
59-
const FIREBASE_PROJECT_ID =
60-
get(currentCypressEnvSettings, 'FIREBASE_PROJECT_ID') ||
61-
envVarBasedOnCIEnv(`${envPrefix}FIREBASE_PROJECT_ID`) ||
62-
get(
63-
firebaserc,
64-
`projects.${envName}`,
65-
get(firebaserc, 'projects.default', '')
66-
);
67-
68-
logger.info(
69-
`Generating custom auth token for Firebase project with projectId: ${chalk.cyan(
70-
FIREBASE_PROJECT_ID
71-
)}`
72-
);
73-
74-
// Get service account from local file falling back to environment variables
75-
const serviceAccount = getServiceAccount(envName);
76-
77-
// Confirm service account has all parameters
78-
const serviceAccountMissingParams = pickBy(serviceAccount, isUndefined);
79-
if (size(serviceAccountMissingParams)) {
80-
const errMsg = `Service Account is missing parameters: ${keys(
81-
serviceAccountMissingParams
82-
).join(', ')}`;
83-
return Promise.reject(new Error(errMsg));
84-
}
85-
86-
// Remove firebase- prefix
87-
const cleanedProjectId = FIREBASE_PROJECT_ID.replace('firebase-', '');
88-
89-
// Handle service account not matching settings in config.json (local)
90-
if (
91-
envName !== 'local' &&
92-
serviceAccount.project_id !== FIREBASE_PROJECT_ID
93-
) {
94-
/* eslint-disable no-console */
95-
logger.warn(
96-
`project_id in service account (${chalk.cyan(
97-
serviceAccount.project_id
98-
)}) does not match associated project in .firebaserc (${chalk.cyan(
99-
FIREBASE_PROJECT_ID
100-
)})`
101-
);
102-
/* eslint-enable no-console */
103-
}
104-
105-
const admin = require('firebase-admin'); // eslint-disable-line global-require
106-
107-
// Initialize Firebase app with service account
108-
const appFromSA = admin.initializeApp(
109-
{
110-
credential: admin.credential.cert(serviceAccount),
111-
databaseURL: `https://${cleanedProjectId}.firebaseio.com`
112-
},
113-
'withServiceAccount'
114-
);
115-
116-
// Create auth token
117-
return appFromSA
118-
.auth()
119-
.createCustomToken(uid, { isTesting: true })
120-
.then(customToken => {
121-
/* eslint-disable no-console */
122-
logger.success(
123-
`Custom token generated successfully, writing to ${chalk.cyan(
124-
DEFAULT_TEST_ENV_FILE_NAME
125-
)}`
126-
);
127-
/* eslint-enable no-console */
128-
// Remove firebase app
129-
appFromSA.delete();
130-
131-
// Create config object to be written into test env file by combining with existing config
132-
const newCypressConfig = Object.assign({}, currentCypressEnvSettings, {
133-
TEST_UID: envVarBasedOnCIEnv('TEST_UID'),
134-
FIREBASE_PROJECT_ID,
135-
FIREBASE_API_KEY:
136-
envVarBasedOnCIEnv('FIREBASE_API_KEY') ||
137-
get(firebaserc, `ci.createConfig.${envName}.firebase.apiKey`, ''),
138-
FIREBASE_AUTH_JWT: customToken
139-
});
140-
141-
const stageProjectId = envVarBasedOnCIEnv('STAGE_FIREBASE_PROJECT_ID');
142-
const stageApiKey = envVarBasedOnCIEnv('STAGE_FIREBASE_API_KEY');
143-
144-
if (stageProjectId) {
145-
newCypressConfig.STAGE_FIREBASE_PROJECT_ID = stageProjectId;
146-
newCypressConfig.STAGE_FIREBASE_API_KEY = stageApiKey;
147-
}
148-
149-
// Write config file to cypress.env.json
150-
fs.writeFileSync(
151-
TEST_ENV_FILE_PATH,
152-
JSON.stringify(newCypressConfig, null, 2)
153-
);
154-
155-
logger.success(
156-
`${chalk.cyan(DEFAULT_TEST_ENV_FILE_NAME)} updated successfully`
157-
);
158-
return customToken;
159-
})
160-
.catch(err => {
161-
/* eslint-disable no-console */
162-
logger.error(
163-
`Custom token could not be generated for uid: ${chalk.cyan(uid)}`,
164-
err.message || err
165-
);
166-
/* eslint-enable no-console */
167-
return Promise.reject(err);
168-
});
169-
}
8+
console.log('create test', typeof createTestEnvFile);
1709

17110
/**
17211
* @name createTestEnvFile

cmds/run.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
1-
/**
2-
* run commander component
3-
* To use add require('../cmds/run.js')(program) to your commander.js based node executable before program.parse
4-
*/
5-
61
const chalk = require('chalk');
72
const { runCommand } = require('../lib/utils');
83
const logger = require('../lib/logger');
4+
const createTestEnvFile = require('../lib/createTestEnvFile');
95

106
/**
117
* @name run
12-
* @description Deploy to Firebase only on build branches (master, stage, prod)
8+
* @description Build test configuration file then run cypress run command
139
* @param {String} envName
1410
*/
1511
module.exports = function run(program) {
1612
program
1713
.command('run [envName]')
18-
.description(
19-
'Build configuration file containing a token for authorizing a firebase instance'
20-
)
21-
.action((envArg) => {
22-
const envName = typeof envArg === 'string' ? envArg : 'local';
23-
return runCommand({ command: `cypress-firebase createTestEnvFile ${envName}` })
14+
.description('Build test configuration file then run cypress run command')
15+
.action(envArg => {
16+
return createTestEnvFile(envArg)
2417
.then(() => {
25-
logger.info(`Starting test run for environment: ${chalk.cyan(envName)}`);
26-
return runCommand({ command: 'npx', args: ['cypress', 'run', '--env', `envName=${envName}`] });
18+
logger.info(
19+
`Starting test run for environment: ${chalk.cyan(envArg)}`
20+
);
21+
const defaultArgs = ['cypress', 'run'];
22+
return runCommand({
23+
command: 'npx',
24+
args: envArg
25+
? defaultArgs.concat(['--env', `envName=${envArg}`])
26+
: defaultArgs
27+
});
2728
})
2829
.then(() => process.exit(0))
29-
.catch((err) => {
30+
.catch(err => {
3031
logger.error(`Run could not be completed:\n${err.message}`);
3132
process.exit(1);
3233
return Promise.reject(err);

package-lock.json

Lines changed: 25 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cypress-firebase",
3-
"version": "0.2.0-alpha.4",
3+
"version": "0.2.0-alpha.5",
44
"description": "Utilities to help testing Firebase projects with Cypress.",
55
"main": "lib/index.js",
66
"module": "lib/index.js",
@@ -21,13 +21,13 @@
2121
"cypress-firebase": "./bin/cypress-firebase"
2222
},
2323
"peerDependencies": {
24-
"firebase-tools": "^6"
24+
"firebase-tools": "^6 || ^7"
2525
},
2626
"dependencies": {
2727
"chalk": "^2.4.2",
2828
"commander": "^2.19.0",
2929
"figures": "^3.0.0",
30-
"firebase-admin": "^8.0.0",
30+
"firebase-admin": "^8.1.0",
3131
"firebase-tools-extra": "0.1.0-alpha.2",
3232
"lodash": "^4.17.11"
3333
},

src/attachCustomCommands.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,17 @@ export default function({ Cypress, cy, firebase }) {
4646
*/
4747
Cypress.Commands.add('logout', () => {
4848
cy.log('Confirming user is logged out...');
49-
if (!firebase.auth().currentUser) {
50-
cy.log('Current user already logged out.');
51-
} else {
52-
cy.log('Current user exists, logging out...');
53-
firebase.auth().signOut();
54-
}
49+
return new Promise((resolve, reject) => {
50+
firebase.auth().onAuthStateChanged(auth => {
51+
if (!auth) {
52+
resolve();
53+
}
54+
});
55+
firebase
56+
.auth()
57+
.signOut()
58+
.catch(reject);
59+
});
5560
});
5661

5762
/**

0 commit comments

Comments
 (0)