Where to load secrets/.env in intern - intern

I'm setting up our e2e testing service with intern and want to keep my secrets (sauce labs key etc) in a .env file using the npm dotenv library. in order to do that i need to require it somewhere. Where would be the earliest place I can do that? My intern configs all inherit from a base configuration, so i plan to use that for now- but is there somewhere earlier?
for the record, this is a self-contained testing service, not part of another framework and i'm using this library: https://github.com/motdotla/dotenv

In case there is no better point of entry, I'm updating with my own solution which injects the environmental variables prior to loading the intern.js config module:
define( ['intern/dojo/node!dotenv'], function (dotenv) {
dotenv.config();
return { intern config object };
});

Related

Detect whether an npm package can run on browser, node or both

I'm building a NextJs application which uses a set of abstractions to enable code from both react (Component logic etc.) and node (API logic) to utilize same types and classes. The motive here is to make the development process seem seamless across client side and server side.
For example. a call on User.create method of the User class will behave differently based on the runtime environment (ie. browser or node) - on the browser, it will call an api with a POST request and on server it will persist data to a database.
So far this pattern worked just fine, and I like how it all turned out in terms of the code structure. However, for this to work, I have to import modules responsible for working on the server and browser to a single module (which in this case is the User class) this leads to a critical error when trying to resolve dependencies in each module.
For example I'm using firebase-admin in the server to persist data to the Firebase Firestore. But it uses fs which cannot be resolved when the same code runs on the browser.
As a work around I set the resolve alias of firebase-admin to false inside the webpack configuration (given it runs on browser) see code below.
/** next.config.js **/
webpack: (config, { isServer }) => {
if (!isServer) {
// set alias of node specific modules to false
// eg: service dependencies
config.resolve.alias = {
...config.resolve.alias,
'firebase-admin': false,
}
} else {
// set alias of browser only modules to false.
config.resolve.alias = {
...config.resolve.alias,
}
}
While this does the trick, it won't be much long until the process gets really tedious to include all such dependencies within resolve aliases.
So, my approach to this is to write a script that runs prior to npm run dev (or manually) that will read all dependencies in package.json and SOMEHOW identify packages that will not run on a specific runtime environment and add them to the webpack config. In order to this, there should be a way to identify this nature of each dependency which I don't think is something that comes right out of the box from npm or the package itself.
Any suggestion on how this can be achieved is really appreciated. Thanks`

React Testing Library - Global configuration

I need to override default testID attribute in React Testing Library. Using Jest as a testing framework.
For this, I have followed the steps given here at individual test file level.
Is there any way to have this configuration at global (project) level, so that all the test files in the project will adhere to such custom configuration and will not have need to define custom configuration explicitly at test file level?
If using jest you can add the following in file
import { configure } from 'react-testing-library';
configure({
testIdAttribute: 'data-my-test-id',
});
and include that file in the jest.config.js file in the setupFiles property
setupFiles: [
'<rootDir>/path-to-your-configuration-file.js',
]
https://testing-library.com/docs/dom-testing-library/api-configuration/#introduction
import {configure} from '#testing-library/dom'
configure({
testIdAttribute: 'data-my-test-id',
})

How to get environment variables defined in serverless.yml in tests

I am using the serverless framework for running lambda functions on AWS.
In my serverless.yml there are environment variables that are fetched from SSM.
When I write integration tests for the code, I need the code to have the environment variables and I can't find a good way to do this.
I don't want to duplicate all the variables definitions just for the tests, they are already defined in the serverless.yml. Also, some are secrets and I can't commit them to source conrol, so I would have to also repeat them in the ci environment.
Tried using the serverless-jest-plugin but it is not working and not well maintained.
Ideas I had for solutions:
Make the tests exec sls invoke - this will work but would mean that the code cannot be debugged, I won't know the test coverage, and it will be slow.
Parse the serverless.yml myself and export the env variables - possible but rewriting the logic of pulling the SSM variables just for tests seems wrong.
Any ideas?
The solution we ended up using is a serverless plugin called serverless-export-env.
After adding this plugin you can run serverless export-env to export all the resolved environment variables to an .env file. This resolves ssm parameters correctly and made integration testing much simpler for us.
BTW, to get the environment variables set from the .env file use the the dotenv npm package.
Credit to grishezz for finding the solution
You can run node with --require option to inject .env file to a serverless command.
Create .env at the project root with package.json, and list variables in .env.
Install serverless and dotenv in the project by yarn add -D serverless dotenv.
Run a command like node -r dotenv/config ./node_modules/.bin/sls invoke.
Then, you can get environment variables in the handler process.env.XXX.
Are you looking to do mocked unit tests, or something more like integration tests?
In the first case, you don't need real values for the environment variables. Mock your database, or whatever requires environment variables set. This is actually the preferable way because the tests will run super quickly with proper mocks.
If you are actually looking to go with end-to-end/integration kind of approach, then you would do something like sls invoke, but from jest using javascript. So, like regular network calls to your deployed api.
Also, I would recommend not to store keys in serverless.yml. Try the secret: ${env:MY_SECRET} syntax instead (https://serverless.com/framework/docs/providers/aws/guide/variables#referencing-environment-variables), and use environment variables instead. If you have a ci/cd build server, you can store your secrets there.
After searching I did my custom solution
import * as data from './secrets.[stage].json'
if( process.env.NODE_ENV === 'test'){
process.env = Object.assign( data, process.env );
}
//'data' is the object that has the Serverless environment variables
The SLS environment variables in my case at the file secrets.[stage].json
Serverless.yml has
custom:
secrets: ${file(secrets.[stage].json)}

How to set process.env from the file in NodeJS?

I'm new to the Node.JS. I found few articles says we can use .env file to setup the process.env variable, e.g.,
PORT = 8081
but when I run the program in my node, it is still 8080 PORT (by default). The question is how can I setup the env variable in Node without any other 3rd party module's help? (I found there are few 3rd party package to management the env config, but... it is kind confused, different package might have different rule and more complex use cases; I want to start from clear way to study purely nodejs)
Update
I have read Node Environment Setting post on StackOverFlow, but they are refer using 3rd party package, none of them tells the detail steps. (Either windows system environment, or Linux environment variables... but how can I place the setting into my project folder?!)
Dotenv file have become the most popular mode to separate configuratione from app, using system environment variables (see 12factor config).
On node there exists a lot of libraries for loading config from .env file. The most popular is motdotla/dotenv.
You can read a lot of examples on readme file about the usage of this library
Make a config.js file with the following content:
module.exports = {
bar: 'someValue',
foo: 'otherValue'
...
}
Then you can do this in some file:
const config = require('./config');
let foo = config.foo;

Setting release configuration for SPA / webpack

I'm developing a Single Page Application and using Webpack for bundling up the modules.
One of my source files (I'm using TypeScript) has settings and configuration used in the application e.g.
// app-settings.ts
export class AppSettings {
public static ApiUrlPrefix: string = "//localhost/myapi/";
}
Which I then use in my code like:
//some-class.ts
import {AppSettings} from "./app-settings"
export class SomeClass {
contructor() {
var something = AppSettings.ApiUrlPrefix;
}
}
When release time comes, I'm going to want the settings to match the live environment.
What's a good way with either gulp, npm or webpack configs to update the settings file? I've seen the HtmlWebpackPlugin which can take a template and plug in some options, so I guess I'm looking for something similar.
You can also use the webpack.DefinePlugin. The Define plugin allows you to pass "Free Global" or "macro-like" variables into your project that you can use. To use webpack.DefinePlugin simply require() webpack into your project.
Here's the documentation and an example on how to use it.

Resources