Change environment in the test instead of command line arg - javascript

I want to be able to change the environment of a test in the code instead of the command line, example:
http://nightwatchjs.org/gettingstarted#test-settings
nightwatch --env xpto will change to the environment in the config of the nighwatch called xpto.
I want to do that in the test,
For example...
export default {
before : function (client) {
//This is just for explanation.
client.options.setEnvironment("xpto");
},
...
...
There is some kind of function or something to do this?
My case scenario is...
I have a docker image to run the tests and i want to have one environment without user agent and another one with it in the same command...
Then i should just have 2 testsFiles one using the default environment and the other one using the xptoenvironment.
Thanks in advance!

Related

Change .page URL based on environment I need to run the suite in

We have been building our automation suite using our staging environment, but are going live soon and want to be ready to tell the project where to run (staging, production).
The only difference between the sites in the environments is the URL. My question is, from start to finish, how can I set the .page URL via a CLI option?
Right now, I have created an environment config file that holds our staging and production URLS and then I call the data into my test files. This is fine for now, but I will need to create a script with an option to set the environment at runtime without having to do a manual find and replace before kicking it off.
I've looked around online and find, what I believe, to be code snippets and general instructions, but I'm not a dev at heart and go crossed eyed. If I could get an ELI5 for this, that would be awesome.
Example of what I'm doing now:
const env = require('../environment_variables.json')
fixture `blog`
.page `${env.production}`
And then I change production to staging or vice versa manually before kicking off the suite.
Since the project will run from CICD, I would like to be able to do something like this in my CLI and script:
testcafe env=production
The env value will then be set where the .page call is for every test file.
Thanks!
There are different ways of doing this. I've used environment variables successfully in this situation, so I'll share this solution since it will solve your problem.
I create config.json in the root of the project:
{
"baseUrl": {
"dev": "https://dev.com/",
"staging": "https://staging.com/",
"prod": "https://prod.com/"
}
}
Then I create two helper functions somewhere like Helpers/env.js:
import config from '../config';
function getEnv () {
return process.env.TESTCAFE_ENV;
}
function getBaseUrl () {
return config.baseUrl[getEnv()];
}
export { getEnv, getBaseUrl };
Then in my test files in Tests/:
import { getBaseUrl } from '../Helpers/env';
const baseUrl = getBaseUrl();
fixture `Test Suite`
.page(baseUrl);
And that's it. Then when I need to run tests on the dev, I execute:
$ TESTCAFE_ENV=dev testcafe
for staging:
$ TESTCAFE_ENV=staging testcafe
and for production:
$ TESTCAFE_ENV=prod testcafe
In v1.20.0 and later, TestCafe offers a way to specify the baseUrl in the test run configuration. You can use this approach along with environment variables, see the following example:
.testcaferc.js
const BASE_URL_MAP = {
dev: 'https://dev.com/',
staging: 'https://staging.com/',
prod: 'https://prod.com/'
};
module.exports = {
baseUrl: BASE_URL_MAP[process.env.TESTCAFE_ENV]
};
Alternatively, you can use different configuration files for each of the required setups using the --config-file option.

npm-config Environment Variables

I saw that best way to store some secret strings is using config package and environment variables. This is how I set it up.
Created a config folder with 2 files (default.json, custom-environment-variables.json)
In default.json I created this:
{
"passPrivateKey": ""
}
In custom-environment-variables.json I created this:
{
"passPrivateKey": "nodeProject_passPrivateKey"
}
After I set the variable in terminal with this command:
npm config set nodeProject_passPrivateKey=randomKey
When I am reading the variable from terminal with command below it works fine and shows the correct value
npm config get nodeProject_passPrivateKey
However in code I have these lines:
if (!config.get("nodeProject_passPrivateKey")) {
console.error("nodeProject_passPrivateKey has not been set");
}
So yeah the problem is this method config.get() is not reading the value and I am getting the error not set from above. I tried doing everything in vs code as admin, and using config.get on "nodeProject_passPrivateKey" and "passPrivateKey" but the method is still not reading any value.
Why not use dotenv?
You create an .env file where you store all your secrets and you access them through
process.env.myvar

Do I need two files for JS module run with node CLI?

I have a module that exports a method used in JEST test. I want to run it from command line too.
async function doRun() { /* do something */}
exports.doRun = doRun;
This works well from JEST, where I import the module and execute the method. But when I call it with node module.js, it has no effect because the method is not executed within JS body. To fix it I have to add:
doRun().then(() => console.log('finished'));
which makes the code work from CLI but it is executed too in JEST just after import.
Am I right that I need to create new file that imports the module and runs the code just for CLI?
const module = require('module.js')
doRun().then(() => console.log('finished'));
and then run node module_cli.js?
Pretty much, yeah. :-)
Either that, or use an environment variable
async function doRun() { /* do something */}
exports.doRun = doRun;
if (process.env.AUTO_RUN === "Y") {
doRun().then(() => console.log('finished'));
}
and run it like this on *nix:
AUTO_RUN=Y node module.js
...or on Windows according to this it would be:
cmd /V /C "set AUTO_RUN=Y&&node module.js"
You could also use the standard NODE_ENV environment variable. I haven't gotten deep into Jest, but it might set it to "testing" or something like that...

Meteor: Development only code? [duplicate]

I need to use different accounts provider's configurations when the meteor application runs as Development, Test or Production environment.
Since Meteor 1.3 these flags work out of the box:
Meteor.isDevelopment
Meteor.isProduction
Meteor.isTest
Meteor.isAppTest
On the server:
var inDevelopment = function () {
return process.env.NODE_ENV === "development";
};
var inProduction = function () {
return process.env.NODE_ENV === "production";
};
Meteor sets the environment variable NODE_ENV to "development" when you run meteor. In production, you can set the variable to whatever you want, otherwise it will default to "production".
Update: I created a smart package to allow this to work on the client and server.
mrt add allow-env
Just set permission rules in a server file.
allowEnv({
NODE_ENV: 1
});
You can use Meteor.settings coupled with the --settings option used when running meteor run or meteor deploy.
For example, to run in dev mode, create a JSON file, call it meteorConfigDev.json, and put the following in it:
{
"public" : {
"mode" : "dev"
},
"anotherProperty" : "anotherValue"
}
Run your app using
meteor --settings meteorConfigDev.json
On the server and on the client you can access the "mode" using:
Meteor.settings.public.mode //in this case it will be "dev"
Note that settings in "public" are available on both the server and the client whereas everything else (in this case "anotherProperty") is only available on the server.
You can then have different configuration files for your different environments.
Very easy. I am running my app on five (yes, five!) different environments. I simply use a switch statement on the ROOT_URL as shown below for four different environments. Of course, you can use an if-else if you only have two environments. Works on the server. Just make a new file called startup.js and use the code example below. Cheers!
switch (process.env.ROOT_URL) {
case "http://www.production.com/":
BLOCK OF CODE HERE
break;
case "http://www.staging.com/":
BLOCK OF CODE HERE
break;
case "http://www.development.com/":
BLOCK OF CODE HERE
break;
case "http://localhost:3000/":
BLOCK OF CODE HERE
break;
}
In general, the format for a switch statement in javascript is
switch(expression) {
case n:
code block
break;
case n:
code block
break;
default:
default code block
}
UPDATE: Note that Meteor now provides Meteor.absoluteUrl(), which is similar to process.env.ROOT_URL with the addition of extra functionality. See docs.
There is an open pull request at github which would allow for that. Comment/Vote for it, so it is more likely to get included!
A really messy way to accomplish this
https://github.com/possibilities/meteor-environment-hooks
note: the interface is OK IMHO, the implementation is messy

Change default timeout for mocha

If we have a unit test file my-spec.js and running with mocha:
mocha my-spec.js
The default timeout will be 2000 ms. It can be overwritten for partial test with a command line parameter:
mocha my-spec.js --timeout 5000
Is it possible to change the default timeout globally for all tests?
i.e. the default timeout value will be different from 2000 ms when you call:
mocha my-spec.js
By default Mocha will read a file named test/mocha.opts that can contain command line arguments. So you could create such a file that contains:
--timeout 5000
Whenever you run Mocha at the command line, it will read this file and set a timeout of 5 seconds by default.
Another way which may be better depending on your situation is to set it like this in a top level describe call in your test file:
describe("something", function () {
this.timeout(5000);
// tests...
});
This would allow you to set a timeout only on a per-file basis.
You could use both methods if you want a global default of 5000 but set something different for some files.
Note that you cannot generally use an arrow function if you are going to call this.timeout (or access any other member of this that Mocha sets for you). For instance, this will usually not work:
describe("something", () => {
this.timeout(5000); //will not work
// tests...
});
This is because an arrow function takes this from the scope the function appears in. Mocha will call the function with a good value for this but that value is not passed inside the arrow function. The documentation for Mocha says on this topic:
Passing arrow functions (“lambdas”) to Mocha is discouraged. Due to the lexical binding of this, such functions are unable to access the Mocha context.
Just adding to the correct answer you can set the timeout with the arrow function like this:
it('Some test', () => {
}).timeout(5000)
Adding this for completeness. If you (like me) use a script in your package.json file, just add the --timeout option to mocha:
"scripts": {
"test": "mocha 'test/**/*.js' --timeout 10000",
"test-debug": "mocha --debug 'test/**/*.js' --timeout 10000"
},
Then you can run npm run test to run your test suite with the timeout set to 10,000 milliseconds.
In current versions of Mocha, the timeout can be changed globally like this:
mocha.timeout(5000);
Just add the line above anywhere in your test suite, preferably at the top of your spec or in a separate test helper.
In older versions, and only in a browser, you could change the global configuration using mocha.setup.
mocha.setup({ timeout: 5000 });
The documentation does not cover the global timeout setting, but offers a few examples on how to change the timeout in other common scenarios.

Categories