Can you run Sapper with NODE_ENV=test - sapper

I'm converting a project from Angular + Node.js server --> Sapper. In relation to e2e tests, there is something I can't understand; can I run Sapper with NODE_ENV env variable set to test? When I run export NODE_ENV=test && sapper dev the variable is always dev. How can I fix this?
My current work-around is to build the application, and then start it with node __sapper__/build, but this is not very nice when developing e2e tests.

Sapper is an open-source project, so we can check how NODE_ENV is set: https://github.com/sveltejs/sapper.
When running sapper dev, the environmental variable NODE_ENV is set in /src/api/dev.ts
(/src/api/dev.ts)
process.env.NODE_ENV = 'development';
where it's hard-coded to development.
The variable can be set to other values (including testing) in
(/src/cli.ts)
178. process.env.NODE_ENV = process.env.NODE_ENV || 'production';
so I surmise you would need sapper prod (or something similar, check it) to use this NODE_ENV.
You should also check it that doesn't beat the purpose of what you're trying to achieve, perhaps sticking to sapper dev is preferable to running in non-dev mode.

Related

Using different URLs for local and CI testing

I want to use Cypress to test locally and on CI at the same time. On CI, I would like to test a production version of my application, which has a different baseUrl than the local version, obviously. I am using the https://github.com/bjowes/cypress-ntlm-auth package to ause windows authentication for the CI, and to do so I have to call cy.ntlm line in my tests. I want to make an IF function that calls the cy.ntlm line ONLY if the baseUrl matches the production one. If the baseUrl is localhost then I would like the cy.ntlm line to be ignored. So my bottom line questions are, how do I let cypress know that I want to use 2 different URLs and how do I pack that into an IF statement? Thank you
You can check the baseUrl to conditionally call cy.ntlm,
const baseUrl = Cypress.config('baseUrl')! // use non-null assertion operator
const isLocal = baseUrl.includes('localhost')
if (!isLocal) {
cy.ntlm(...)
}
When using Typescript with Cypress you will get complaints because Typescript has no idea if you have set the baseUrl configuration or not.
You can overcome that by adding ! after getting the baseUrl value.
Ref Typescript - Non-null assertion operator
I separated the steps to make it clearer.
Assuming your cypress config file has the baseUrl. You can then update the baseUrl using the CLI during run time. For this create two different scripts with the staging and production URL's in your package.json like this:
"scripts": {
"test:local": "cypress run --config baseUrl=https://example.com/staging",
"test:ci": "cypress run --config baseUrl=https://example.com/production"
}
Then to run the scripts in CI use npm run test:ci and for local use npm run test:local.

Heroku NODE_ENV is always "development" despite setting config var to "staging" (NestJS app)

In my Heroku environment where I deploy my NestJS application, I set all my Config Vars through the Heroku UI. I have set my NODE_ENV config var to staging using the Heroku UI. I've even ran this command heroku config:set NODE_ENV=staging -a <my-staging-environment. When I run heroku config -a <my-staging-environment>, I see that NODE_ENV is set to staging, but for whatever reason, when I console.log this variable from my code, it outputs development. Below is some example code where it is logs development as the value for NODE_ENV in my TypeOrm configuration. This is causing the ssl property to not get set to the correct value, and I cannot connect to my Heroku Postgres database because of it. I only intend to set it to development for local development purposes.
require('dotenv').config();
console.log(process.env.NODE_ENV); // outputs "development" - idk where this value is coming from
console.log(process.env.DATABASE_URL); // outputs the correct value that I set in Heroku Config Vars
const typeOrmConfig: TypeOrmModuleOptions = {
type: 'postgres',
url: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV !== 'development' ? { rejectUnauthorized: false } : false, // ternary evaluates to the wrong value
// ... other config options
};
I use dotenv, and I made sure to .gitignore my .env file. I don't recall ever setting this variable to development. The only place I see it set to NODE_ENV=development in my code is in my .env-example file. I do commit this file to source control, but it's just an example file and not a real .env file and it shouldn't actually be being used.
Does anyone have any idea why this is happening?
I have found that it is not a Heroku issue. Rather it is a NestJS/Nx issue.
See:
process.env.NODE_ENV always 'development' when building nestjs app with nrwl nx

How to pass values from command line to cypress spec file?

I have a few different environments in which I am running Cypress tests (i.e. envA, envB, envC)
I run the tests like so:
npm run cypress:open -- --env apiEndpoint=https://app-envA.mySite.com
npm run cypress:open -- --env apiEndpoint=https://app-envB.mySite.com
npm run cypress:open -- --env apiEndpoint=https://app-envC.mySite.com
As you can see, the apiEndpoint varies based on the environment.
In one of my Cypress tests, I am testing a value that changes based on the environment being tested.
For example:
expect(resourceTiming.name).to.eq('https://cdn-envA.net/myPage.html')
As you can see the text envA appears in this assertion.
The issue I'm facing is that if I run this test in envB, it will fail like so:
Expected: expect(resourceTiming.name).to.eq('https://cdn-envB.net/myPage.html')
Actual: expect(resourceTiming.name).to.eq('https://cdn-envA.net/myPage.html')
My question is - how can I update the spec files so that the correct URL is asserted when I run in the different environments?
I am wondering if there's a way to pass a value from the command line to the spec file to tell the spec file which environment I'm in, but I'm not sure if that's possible.
You can directly use the Cypress.env('apiEndpoint') in your assertions, so that whatever you're passing via CLI, your spec files has the same value -
expect(resourceTiming.name).to.eq(Cypress.env('apiEndpoint'))
And if you want to check that when you pass https://app-envA.mySite.com and the url you expect in the spec file is https://cdn-envA.net/myPage.html, You can use:
expect(resourceTiming.name).to.eq(Cypress.env('apiEndpoint').replace('app', 'cdn').replace('mySite.com', 'net') + '/myPage.html')
Your best bet, in my opinion, is to utilize environment configs (envA.json, envB.json, etc)
Keep all of the property names in the configs identical, and then apply the values based on the environment:
// envA.json file
"env": {
"baseUrl": "yourUrlForEnvA.com"
}
// envB.json file
"env": {
"baseUrl": "yourUrlForEnvB.com"
}
That way, you can call Cypress.env('baseUrl') in your test, and no matter what, the right property should be loaded in.
You would call your environment from the command line with the following syntax:
"cypress run --config-file cypress\\config\\envA.json",
This sets up the test run to grab the right config from the start.
Calling the url for login, for example, would be something like:
cy.login(Cypress.env('baseUrl'))
Best of luck to you!

jestjs - how to parametrize test execution from cli in ci?

i have 4 environments :
dev (developers area)
test (test area)
preprod (pre production environment)
production (production environment)
these environments needs different configuration to execute tests (differents urls, usernames, assets, and so on).
how to pass there configurations to jest as a parameter in continous integration?
As you can read here, jest would not permits to pass custom arguments you can use to handle custom configuration loaded at runtime.
i propose a workaround working for me.
create a configuration file, e.g. config.js
edit config.js and exports modules switching for the environment
switch (env) {
case "test":
module.exports = {
baseUrl: 'https://test.website.com'
}
break;
case "production":
module.exports = {
baseUrl: 'https://production.website.com'
}
break;
}
create a javascript files for every environment you need
test-configuration.js
production-configuration.js
edit these files writing in the environment variables
for example test-configuration.js will be
process.env.ENVIRONMENT = "test"
load configuration for your test files as it was a static file
const config = require('./config.js')
use jest setupFiles to add a setupFiles that load the environment variables.
for example, running
jest --setupFiles=./test-configuration.js
jest will load the test-configuration.js file that will set "test" on the "process.env.ENVIRONMENT" variables, so config.js file will "switch" on the "test" environment and all your test will use it.
so now you can (or CI can) loads configuration as needed.
For anyone facing the same issue – can't pass environment url to your custom setup file and tests. The solution might be dumb but it works without modifying the code much.
In package.json modify your scripts to export environment before running jest:
"scripts": {
"test": "jest",
"test:dev": "export ENVIRONMENT=https://dev.environment/ && jest",
"test:prod": "export ENVIRONMENT=https://prod.environment/ && jest"
}
Then you can access your code:
const page = await browser.newPage();
await page.goto(process.env.ENVIRONMENT);
console.log(process.env.ENVIRONMENT);

Node Env not set?

This is a general question though I haven't found where I am going wrong.
Using Windows Server with Azures kudu stand alone to host a local project.
Also using React, Webpack, Redux
Windows environment var is set to production
Package.json has set NODE_ENV=production && etc.. for
both start and build scripts
web.config has iisnode node_env=production
running node I get the node_env is indeed production
However when I build it's giving me the development build when I do something like
if (process.env.NODE_ENV === 'production') {
module.exports = require('./buildProduction.js')
}
else {
module.exports = require('./buildDevelopment.js')
}
What gives?
I came to the same conclusion and searched why this is and thanks to neagtivetwelve for the comment # https://github.com/webpack/webpack/issues/1720
In short setting
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
fixes the issue. Instead of
new webpack.DefinePlugin({
'process.env.NODE_ENV': process.env.NODE_ENV,
}),
Even though I have in the build script to set the session NODE_ENV var and set within the system environment vars I would still get the wrong result until this change was made even though opening node from cmd and typing process.env.NODE_ENV yields the correct result.
Anyway I hope it helps someone else.

Resources