Unable to read values from .env.local file in latest Cypress version - node.js

I am using latest Cypress version 10.11.0 and I am trying to read username, password from .env.local file in my system using process.env. But some how it not getting the values from the .env.local file ? Could someone please advise ?
Note : As a normal way, I am able to get values if I provide values in cypress.config.js (see below). Since username, password can't expose in config, i need to read it from .env.local file.
env:{
MYBOOKS_USERNAME:"testuser1#test.com",
MYBOOKS_PASSWORD:"Some_password"
},
// cypress.config.js file
const { defineConfig } = require("cypress");
module.exports = defineConfig({
chromeWebSecurity: false,
viewportWidth :1920,
viewportHeight:1080,
responseTimeout: 60000,
fixturesFolder: 'cypress/fixtures',
screenshotsFolder: 'cypress/screenshots',
videosFolder: 'cypress/videos',
numTestsKeptInMemory: 10,
video:false,
e2e: {
setupNodeEvents(on, config) {
require("cypress-grep/src/plugin")(config),
// implement node event listeners here
on('before:browser:launch', (browser, launchOptions ) => {
console.log("Print browser name: "+browser.name);
if (browser.name === 'chrome' || browser.name === 'chrome' && browser.isHeadless) {
launchOptions.args.push('--disable-features=SameSiteByDefaultCookies')
return launchOptions
}
});
on('task', {
logAtConsole (message) {
console.log('Printing the data using task::', message);
return null
}
});
},
baseUrl: "https://somebookssite-test.com",
specPattern: "cypress/e2e/booksSite/**/*.spec.{js,jsx,ts,tsx}",
},
});
// .env.local file
CYPRESS_MYBOOKS_USERNAME=testuser1#test.com,
CYPRESS_MYBOOKS_PASSWORD=Some_password
// commands.js file
const userName = process.env.MYBOOKS_USERNAME;
const userPassword = process.env.MYBOOKS_PASSWORD;
Cypress.Commands.add('loginRequest', (url) => {
helperFunctions.dynamicEnvironmentSelection();
const apiEndpoint = helperFunctions.getItemFromLocalStorage('apiUrl');
cy.request({
method: 'POST',
url: apiEndpoint + url,
contentType: 'application/json',
body: {
username: userName,
password: userPassword,
}
}).then((resp) => {
helperFunctions.setLoginCookies(resp);
});
});

You could use dotenv to read the .env.local file.
Using the convention for this tool, use key=value format in .env.local.
MYBOOKS_USERNAME="testuser1#test.com"
MYBOOKS_PASSWORD="Some_password"
const { defineConfig } = require('cypress')
const path = require('path')
const dotenv = require('dotenv')
const envLocal = dotenv.config({path: path.resolve(process.cwd(), '.env.local')})
module.exports = defineConfig({
env: {
// non-sensitive env vars hard-coded here
login_url: '/login',
products_url: '/products'
// sensitive env vars read in above from external file
...envLocal
},
Without dotenv
If you change the external file to .env.local.json, then it's possible to read it directly.
{
"MYBOOKS_USERNAME": "testuser1#test.com",
"MYBOOKS_PASSWORD": "Some_password"
}
const { defineConfig } = require('cypress')
const envLocal = require('./.env.local.json')
module.exports = defineConfig({
env: {
// non-sensitive env vars hard-coded here
login_url: '/login',
products_url: '/products'
// sensitive env vars read in above from external file
...envLocal
},

Related

how to upgrade webpack from 3 to 5

I really need someone's help.
In this repo,
https://github.com/ueno-llc/starter-kit-universally.git
I don't know how to upgrade the webpack.
The error is from new webpack.NamedChunksPlugin, new webpack.optimize.CommonsChunkPlugin
I can't fix it by myself...
Can anyone help me for this issue ?
import fs from 'fs';
import _isArray from 'lodash/isArray';
import _get from 'lodash/get';
import appRootDir from 'app-root-dir';
import path from 'path';
import webpack from 'webpack';
import ExtractCssChunks from 'extract-css-chunks-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import ChunkManifestWebpackPlugin from 'chunk-manifest-webpack-plugin';
import NameAllModulesPlugin from 'name-all-modules-plugin';
import config from '../';
import { removeNil } from '../../internal/utils/arrays';
import { ifElse } from '../../internal/utils/logic';
function externals() {
// UENO: Define externals
// We don't want our node_modules to be bundled with any bundle that is
// targetting the node environment, prefering them to be resolved via
// native node module system.
// Some of our node_modules may contain files that depend on our
// webpack loaders, e.g. CSS or SASS.
// For these cases please make sure that the file extensions are
// registered within the following configuration setting.
const whitelist = [
/\.bin/,
'source-map-support/register',
'react-universal-component',
'webpack-flush-chunks',
]
// And any items that have been whitelisted in the config need
// to be included in the bundling process too.
.concat(config('nodeExternalsFileTypeWhitelist') || []);
return fs
.readdirSync(path.resolve(appRootDir.get(), 'node_modules'))
.filter(x => !whitelist.some((w) => {
if (w instanceof RegExp) {
return w.test(x);
}
return x === w;
}))
.reduce((ext, mod) => {
// mark this module as external
// https://webpack.js.org/configuration/externals
ext[mod] = `commonjs ${mod}`;
return ext;
}, {});
}
export default (webpackConfig, buildOptions) => {
const { target, optimize = false, localIdentName } = buildOptions;
const isProd = optimize;
const isDev = !isProd;
const isClient = target === 'client';
const isNode = !isClient;
const ifNode = ifElse(isNode);
const ifClient = ifElse(isClient);
const ifProdClient = ifElse(isProd && isClient);
// Overwrite the externals because apparently `webpack-node-externals` does not
// work well with `webpack-flush-chunks`
if (isNode) {
webpackConfig.externals = [externals()];
}
// Remove ExtractTextPlugin
const etpIndex = webpackConfig.plugins.findIndex(p => p instanceof ExtractTextPlugin);
if (etpIndex > -1) {
webpackConfig.plugins.splice(etpIndex, 1);
}
// Add some plugins for css code splitting
webpackConfig.plugins.push(
...removeNil([
// NamedModulesPlugin, NamedChunksPlugin and NameAllModulesPlugin (see below) are all here to
// deal with chunk hashes.
// See https://medium.com/webpack/predictable-long-term-caching-with-webpack-d3eee1d3fa31
ifClient(new webpack.NamedModulesPlugin()),
ifClient(
new webpack.NamedChunksPlugin((chunk) => {
if (chunk.name) {
return chunk.name;
}
return chunk.mapModules(m => path.relative(m.context, m.request)).join('_');
}),
),
ifClient(new ExtractCssChunks({
filename: isDev ? '[name].js' : '[name]-[contenthash].css',
})),
ifProdClient(new ChunkManifestWebpackPlugin({
filename: '../manifest.json',
manifestVariable: '__WEBPACK_MANIFEST__',
})),
// To make sure chunk hashes stay the same if their contents don’t change
// see: https://webpack.js.org/guides/caching/#module-identifiers
ifClient(new webpack.HashedModuleIdsPlugin()),
// Add vendor code chunk
ifProdClient(
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: '[name]-[chunkhash].js',
// Put all node_modules into one chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#passing-the-minchunks-property-a-function
minChunks: module => module.context && module.context.includes('node_modules'),
}),
),
// Add webpack boilerplate chunk
ifClient(
new webpack.optimize.CommonsChunkPlugin({
name: 'bootstrap', // needed to put webpack bootstrap code before chunks
filename: isDev ? '[name].js' : '[name]-[chunkhash].js',
}),
),
ifClient(new NameAllModulesPlugin()),
// We only want one server chunk
ifNode(
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
),
]),
);
const { rules } = webpackConfig.module;
const moduleRules = [..._get(rules, '0.oneOf', rules)];
// Overwrite css loader ExtractTextPlugin
const cssRule = moduleRules.find(r => r.test.test('.css'));
if (cssRule && _isArray(cssRule.use)) {
// Find plugin
const pluginIndex = cssRule.use.findIndex(u =>
Object.prototype.hasOwnProperty.call(u, 'loader') && /extract-text-webpack-plugin/.test(u.loader));
if (pluginIndex > -1) {
const loaders = ExtractCssChunks.extract({
fallback: 'style-loader',
use: [
`css-loader?modules=1&importLoaders=1&localIdentName=${localIdentName}`,
'postcss-loader',
'sass-loader?outputStyle=expanded',
],
});
cssRule.use.splice(
pluginIndex,
loaders.length,
...loaders,
);
}
}
// Overwrite node_modules css loader ExtractTextPlugin
const nmCssRule = moduleRules.find(r =>
r.test.test('node_modules.css') &&
(!r.exclude || !r.exclude.test('node_modules.css')));
if (nmCssRule && _isArray(nmCssRule.use)) {
// Find plugin
const pluginIndex = nmCssRule.use.findIndex(u =>
Object.prototype.hasOwnProperty.call(u, 'loader') && /extract-text-webpack-plugin/.test(u.loader));
if (pluginIndex > -1) {
const loaders = ExtractCssChunks.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader'],
});
nmCssRule.use.splice(
pluginIndex,
loaders.length,
...loaders,
);
}
}
return webpackConfig;
};
===
I have tried to use webpack.config.js, but still failed...
Please help me :(

Fastify CLI decorators undefined

I'm using fastify-cli for building my server application.
For testing I want to generate some test JWTs. Therefore I want to use the sign method of the fastify-jwt plugin.
If I run the application with fastify start -l info ./src/app.js everything works as expected and I can access the decorators.
But in the testing setup I get an error that the jwt decorator is undefined. It seems that the decorators are not exposed and I just can't find any error. For the tests I use node-tap with this command: tap \"test/**/*.test.js\" --reporter=list
app.js
import { dirname, join } from 'path'
import autoload from '#fastify/autoload'
import { fileURLToPath } from 'url'
import jwt from '#fastify/jwt'
export const options = {
ignoreTrailingSlash: true,
logger: true
}
export default async (fastify, opts) => {
await fastify.register(jwt, {
secret: process.env.JWT_SECRET
})
// autoload plugins and routes
await fastify.register(autoload, {
dir: join(dirname(fileURLToPath(import.meta.url)), 'plugins'),
options: Object.assign({}, opts),
forceESM: true,
})
await fastify.register(autoload, {
dir: join(dirname(fileURLToPath(import.meta.url)), 'routes'),
options: Object.assign({}, opts),
forceESM: true
})
}
helper.js
import { fileURLToPath } from 'url'
import helper from 'fastify-cli/helper.js'
import path from 'path'
// config for testing
export const config = () => {
return {}
}
export const build = async (t) => {
const argv = [
path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'src', 'app.js')
]
const app = await helper.build(argv, config())
t.teardown(app.close.bind(app))
return app
}
root.test.js
import { auth, build } from '../helper.js'
import { test } from 'tap'
test('requests the "/" route', async t => {
t.plan(1)
const app = await build(t)
const token = app.jwt.sign({ ... }) //-> jwt is undefined
const res = await app.inject({
method: 'GET',
url: '/'
})
t.equal(res.statusCode, 200, 'returns a status code of 200')
})
The issue is that your application diagram looks like this:
and when you write const app = await build(t) the app variable points to Root Context, but Your app.js contains the jwt decorator.
To solve it, you need just to wrap you app.js file with the fastify-plugin because it breaks the encapsulation:
import fp from 'fastify-plugin'
export default fp(async (fastify, opts) => { ... })
Note: you can visualize this structure by using fastify-overview (and the fastify-overview-ui plugin together:

Export JSON from i18next to the client

I'm trying to export a JSON locale file from i18next to a link as an API to use on the client. The problem is that it only exports the locale that is specified in "fallbackLng", which is 'en'. How can I make it detect the locale from the "detection_options" so that the right locale is loaded and exported on the API?
// app.js
var detection_options = {
// order and from where user language should be detected
order: [/*'path', 'session', */ 'querystring', 'cookie', 'header'],
// keys or params to lookup language from
lookupQuerystring: 'lng',
lookupCookie: 'i18next',
lookupHeader: 'accept-language',
lookupSession: 'lng',
lookupPath: 'lng',
lookupFromPathIndex: 0,
// cache user language
caches: false,
}
// i18next configuration
const i18next = require('i18next');
const Backend = require('i18next-fs-backend');
const middleware = require('i18next-http-middleware');
i18next.use(Backend)
.use(middleware.LanguageDetector)
.init({
debug: true, // debug option shows that "zh-hant" is loaded correctly when the Chinese site is accessed.
detection: detection_options,
fallbackLng: ['en', 'zh'],
backend: {
loadPath(lng, ns) {
if (lng === 'zh' || lng === 'zh-HK' || lng === 'zh-TW') {
return path.join(__dirname, 'locales/zh-hant.json');
} else if (lng === 'en-US') {
return path.join(__dirname, 'locales/en.json');
}
return path.join(__dirname, 'locales/{{lng}}.json');
}
}
})
app.use(middleware.handle(i18next));
const localeController = require('../controllers/locale');
app.get('/locale', localeController.getLocale);
// locale.js
exports.getLocale = async (req, res, next) => {
var i18next = require('i18next');
res.status(200).json(
i18next.t('tree', { returnObjects: true })
)
}
Use the t function from within the request object, like:
https://github.com/i18next/i18next-http-middleware/issues/51#issuecomment-1094851968

How to set env.development and env.production in Preact app

On react app, you can create .env.production and .env.development and enter different key and values like this.
REACT_APP_API_URL= "xyz"
to pick environment variables automatically based on commands used --> npm start or npm run build.
What is the equivalent process in preact?
It is my solution
env.js in the root of project:
import fs from 'fs';
import dotenv from 'dotenv';
function getAppEnvironment() {
const prefix = "PREACT";
return Object.keys(process.env)
.filter((key) => new RegExp(`^${prefix}_`, 'i').test(key))
.reduce((env, key) => {
env[key] = process.env[key];
return env;
}, {});
}
function resolveFile(file) {
const path = fs.realpathSync(process.cwd());
return `${path}/${file}`;
}
function getEnvFiles(production) {
const key = production ? 'production' : 'development';
return [
resolveFile(".env"),
resolveFile(".env.local"),
resolveFile(`.env.${key}`),
resolveFile(`.env.${key}.local`),
].filter(Boolean);
}
export function getEnvironment(production) {
const dotenvFiles = getEnvFiles(production);
dotenvFiles.forEach((dotenvFile) => {
if (fs.existsSync(dotenvFile)) {
dotenv.config({
path: dotenvFile,
override: true
})
}
});
return getAppEnvironment();
}
export default getEnvironment;
then create or modify your preact.config.js:
import getEnvironment from './env';
export default {
plugins: [],
webpack(config, env, helpers) {
config.plugins.push(
new helpers.webpack.DefinePlugin({
'process.env': JSON.stringify(getEnvironment(env.production))
}),
);
},
};

Using nodejs ssh2 within a web worker

I'm trying to use from a nx project (using #nrwl/node), within a nodeJS API, the ssh2 plugin.
Here's my module:
export const datasetTranferModule = ({ username, password }) => {
var connSettings = {
host: "192.168.1.14",
port: 22,
username,
password
// You can use a key file too, read the ssh2 documentation
};
var SSHClient = require("ssh2").Client;
// do something with SSHClient
return;
};
By changing the default webpack behavior, I didn't manage to get it working:
module.exports = (config, context) => {
const WorkerPlugin = require('worker-plugin')
return {
...config,
node: {
process: true,
global: true
},
plugins: [
new WorkerPlugin({
plugins: [
// A string here will copy the named plugin from your configuration:
'ssh2',
// Or you can specify a plugin directly, only applied to Worker code:
]
})
]
};
};
Is it fine to do it within a worker? If so how to import ssh from the worker?

Resources