Jest set TZ env variable PER test - javascript

I am running into an issue where I want to run some of my tests under different time zones.
After following a few links i found that you can set the TZ env var before calling jest in your package.json or command line like so:
{
...
"test": "TZ=America/Sao_Paulo jest"
...
}
But this doesn't scale properly say if i want to test both America/Sao_Paulo & Asia/Shanghai...I'd have to do something like this...
{
...
"test": "TZ=America/Sao_Paulo jest & TZ=Asia/Shanghai jest"
...
}
I've also tried the approach with setting the timezone by manipulating process.env.TZ in beforeEach of each test BUT...it never actually picks up on the env when it goes runs my suites.

OK I went around the houses a bit but ended up creating a custom bash script called handleTests.sh and also renaming my test file to toUTCDate_test.ts instead of toUTCDate.test.ts to avoid jest picking it up and running it.
My package.json now looks like:
{
...
"test": "./handleTests.sh"
...
}
Make sure you run chmod +x ./handleTests.sh
handleTests.sh
# run jest like normal...
jest
# run toUTCDate tests, note _test in the file name...
# this is to dodge jest's auto-run and run only on our own terms.
for TZ in America/Los_Angeles America/Sao_Paulo Asia/Shanghai
do
TZ=$TZ jest --testRegex toUTCDate_test
done

Related

Package.json variable not being picked up

I have the following functionality that locally loads some products out of stock depending on the command run in the terminal:
const updates = process.env.option === "oos" ? oosUpdates : insUpdates
log.info("updates: ", JSON.stringify(updates))
const result = await loadUpdateVariants(cache, updates as UpdateType[])
In my package.json I have:
"update:oos": "ts-node src/loaders/mock/update-variants.ts --option oos",
"update:ins": "ts-node src/loaders/mock/update-variants.ts --option ins"
however when I run yarn update:oos I am getting the instock products meaning that this process.env.option === "oos" is not working out correctly.
process.env gives you access to environment variables. If you want to use environment variables, you can set them like this:
"update:oos": "OPTION=oos ts-node src/loaders/mock/update-variants.ts",
"update:ins": "OPTION=ins ts-node src/loaders/mock/update-variants.ts"
This is the "vanilla" (without any extra dependencies) approach - but may encounter issues on Windows. If you want your command to work well cross-platform, you might consider using cross-env

Fail Gatsby build if environment variable missing

I have experimented with adding environment variables to my Gatsby project using .env.development and .env.production files and it's working great.
I would like to have my builds fail if one of the environment variables is missing, however I can't seem to see how to enable this functionality.
I have read through the Gatsby environment variables documentation, but can't seem to see how this would work? is this possible?
I believe it uses dotenv/webpack define plugin under the hood.
I’m sure there are other ways to do this, but with some quick tests, this approach seems to be working well for me.
In your gatsby-config.js file, you can choose to explicitly require the dotenv, so you can use those environment variables in your config.
I added the following, and now the Gatsby build will fail unless the specified environment variables are present.
// Load the environment variables, per
// https://www.gatsbyjs.org/docs/environment-variables/#server-side-nodejs
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
})
function checkEnv(envName) {
if (typeof process.env[envName] === 'undefined' || process.env[envName] === '') {
throw `Missing required environment variables: ${envName}`
}
}
try {
checkEnv('NODE_ENV')
checkEnv('EXAMPLE_MISSING_ENV')
checkEnv('EXAMPLE_API_KEY')
} catch (e) {
throw new Error(e)
}
// The rest of the config file
I could imagine customizing this further, ex. logging a warning for a variable with a fallback versus throwing an error for one that is required by your content sourcing plugin or theme. Hope this is helpful as a starting point!
I couldn't find built-in solution for this on Gatsby neither. You may do it manually, but still not too easy.
First problem: If you wanna load your environment from file while running npm script; it can not be loaded right away. But you may trigger a script file, and it can load this environment variables before your check.
lets say build.sh on root directory of project :
source ./.env.development # this line will set env variables
if [ "$API_KEY" = 927349872349798 ] ; then
npm run build
fi
Another problem rises; some developers might want to run it on windows maybe. So better use famous cross-env package.
npm i cross-env
Then everything is ready, add your secure-build :
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,json,md}\"",
"start": "npm run develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1",
"secure-build": "cross-env-shell \"./build.sh\""
},
And run it :
npm run secure-build
This solution looks too much for me as we created a build.sh and install a new package. Maybe there is cleaner solution. I am not Gatsby Guru after all.
I added env checking to the onPreInit life cycle hook in gatsby-node.ts:
const envVariablesList = [
"ENV1",
"ENV2",
"ENV3",
];
function envVarChecker(vars: string[]): string | undefined {
return vars.find(
(item) => process.env[item] === undefined || process.env[item] === ""
);
}
export const onPreInit: GatsbyNode["onPreInit"] = ({ actions }) => {
const emptyEnv = envVarChecker(envVariablesList);
if (emptyEnv !== undefined) {
throw new Error(`Env variable: ${emptyEnv} is empty!`);
}
};
It fails build almost at the very beginning (during pre-bootstrap phase) if any of the declared variables is missing

Protractor Flake guidance needed to rerun failed test cases

Please correct my understanding for the below:
I've installed protractor flake
From the website we have 2 sets of
code
My assumption
I'm pretty sure the B part needs to be given in configuration.js file
of my protractor project but the A part where exactly should it be written.
As a separate file should i write it and then require them in the spec file which i'm running.I need exact steps as to achieve the above
The usage section which starts with below:
**var protractorFlake = require('protractor-flake')
// OR using es6 modules/typescript
import protractorFlake = require('protractor-flake')**
and ends with **process.exit(status)**
and the parsers section which starts with
module.exports = { till return [...failedSpecs]
As per the documentation,
Add dependency
npm i protractor-flake
# or globally for easier cli usage
npm i -g protractor-flake
Running tests
Option 1: Via the CLI:
# protractor-flake <protractor-flake-options> -- <options to be passed to protractor>
protractor-flake --parser standard --max-attempts=3 -- path/to/protractor.conf.js
Assuming that your conf.js file is in root directory.
Available command line options.
color?: string | boolean
choose color from here or set false to disable coloring
Usage : protractor-flake --parser standard --color=magenta --max-attempts=3 -- conf.js
protractorArgs?: string[]
protractorPath?: string: protractor location like this 'node_modules/.bin/protractor',
Usage : protractor-flake --parser standard --protractorPath=node_modules/.bin/protractor --max-attempts=3 -- conf.js
parser?: string: the name of one of the included parsers
Usage : protractor-flake --parser standard --color=magenta --max-attempts=3 -- conf.js
You can refer other options from here
Option 2: Programmatically
Create file in your root directory as flake and copy below snippet.
flake is a node script that uses protractor-flake to re-run failed tests. Note
that it reruns tests at the file level, so if one test fails, it will rerun all
the tests in that file.
Thanks Brian Ray to this repository
#!/usr/bin/env node
/**
*
* usage:
* `./flake conf.js [other protractor args]`
*/
const protractorFlake = require('protractor-flake');
// skip first two passed args (node and self)
let protractorArgs = process.argv.splice(2);
console.log(protractorArgs);
protractorFlake({
protractorPath: 'node_modules/.bin/protractor',
maxAttempts: 3,
parser: 'standard',
nodeBin: 'node',
protractorArgs: protractorArgs
}, (status, output) => {
process.exit(status);
});
After creating this file, for avoiding permission error's just run chmod +x ./flake
To run your test cases
./flake conf.js
If you are keeping specs in a test suite, just pass after conf.js.
./flake conf.js --suite smoke_test
Before you are running, check these Caveats

Cypress: run only one test

I want to toggle only running one test, so I don't have to wait for my other tests to see the result of one test.
Currently, I comment out my other tests, but this is really annoying.
Is there a way to toggle only running one test in Cypress?
to run only one file
cypress run --spec path/to/file.spec.js
or using glob patterns:
cypress run --spec 'path/to/files/*.spec.js'
Note: you need to wrap your glob patterns in single quotes to avoid shell expansion!
to run only one test in a file
You can use a .only as described in the Cypress docs
it.only('only run this one', () => {
// similarly use it.skip(...) to skip a test
})
it('not this one', () => {
})
Also, you can do the same with describe and context blocks
edit:
there's also a nice VSCode extension to make adding/removing .only's easier with keyboard shortcuts. It's called Test Utils (install with ext install chrisbreiding.test-utils). It works with js, coffee, and typescript:
There are multiple ways of achieving this.
You can add .onlyto it or describe see #bkucera answer
You can do it from the terminal as explained in the doc here
npx cypress run --record --spec "cypress/integration/my-spec.js"
npm run cypress -- --record --spec "cypress/integration/my-spec.js"
You can mute not needed test suites and particular cases by prepending x to testrunner methods call (describe, it, etc.)
So it would look like:
// this whole testsuite will be muted
xdescribe('Visit google', () => {
it('should visit google', () => { cy.visit('https://google.com/'); });
});
// this testsuite will run
describe('Visit youtube', () => {
it('should visit youtube', () => { cy.visit('https://youtube.com/'); });
// this testcase will be muted
xit('is not necessary', () => { ... });
});
You can run the test like this.
cypress run --spec **/file.js
The best way to do such kind runs are by using the .only keyword that cypress provide.
To run all the test cases in one describe function from many describe functions add the .only in the required describe.
describe("1st describe", () => {
it("Should check xx", async function(){
});
it("Should check yy", async function(){
});
});
describe.only("2nd describe", () => {
it("Should check xx", async function(){
});
it("Should check yy", async function(){
});
});
describe("3rd describe", () => {
it("Should check xx", async function(){
});
it("Should check yy", async function(){
});
});
So here only the 2nd describe will run.
Similarly if you want to run some test cases in 1 describe add the .only in front of all the test cases that you want to run.
describe("describe statement", () => {
it("Should check xx", async function(){
});
it.only("Should check yy", async function(){
});
it.only("Should check zz", async function(){
});
});
So here the it for yy and zz will run
This is similar to the fit and fdescribe in karma and jasmine that you might be familiar with.
You can skip the test in cypress with it.skip or xit
There is one way I have found to skip tests which I don't need to run (in the current test), and that is to use: this.skip();
it('test page', function () {
// skip this test for now
this.skip();
cy.visit('http://example.com/')
cy.contains('test page').click()
cy.url()
.should('include', '/test-page/')
})
1. it is important to use regular function as second argument of it, this will not be available in arrow function
2. Whole of the test will be skipped no matter where we write this.skip()
My test files have a structure like this path/something.test.jsx and commands npx cypress run --spec path/something.test.jsx gives the following exception in the terminal:
Can't run because no spec files were found.
We searched for any files matching this glob pattern:
...
Surprisingly enough the following works and run the test exactly for one file (providing you have jest installed):
jest path/something.test.jsx
A very easy solution is to prefix your tests in with numbers, as testing frameworks will typically will run tests in alpha/numeric order by default - so if I have to check one spec file - I will copy the contents into a file 0-[file-name].spec and re-run the test command. Once the test completes - you terminate the test run - as you will have the results you were looking for. This answer is targeted at projects where your testing framework is abstracted and as a developer, you do not have all available options for your testing framework. Not the best answer, but it works and is intuitive and super easy to do. I have found this to be a way to avoid adding a bunch of conditional skips() or only() calls that will not make it to production, will have to be removed and you can easily add the file pattern to .gitignore file so these local files do not get checked in.
The best-known solution for that already exists and requires adding just one simple argument in the console.
https://github.com/cypress-io/cypress/tree/develop/npm/grep
Simply run:
npx cypress run --env grep="TestName" --spec "filename"
Cypress .only() function is used only for development.
put .only for the test you want to execute and then run the spec as npx cypress run --spec path/to/your-file.spec.js
To run a specific file through Terminal:
npx cypress run --record --spec "cypress/integration/my-spec.js"
npm run cypress -- --record --spec "cypress/integration/my-spec.js"
You can use this
cypress run -- --spec 'path/to/files/*.spec.js'
or
npm run --spec 'path/to/files/*.spec.js'
It worked for me.
Many thanks
use the #focus keyword in the test scripts when execute using cypress open

grunt and qunit - running a single test

I already have grunt-contrib-qunit set up. My Gruntfile.js includes something like this
qunit: { files: ['test/*.html'] }
Now I can run grunt qunit and all my tests run.
Question: how can I run just one single test without running all of them? Is there a way I can overload the value of files from the command line?
You definitely need to look into grunt-contrib-qunit and grunt-contrib-connect (https://github.com/gruntjs/grunt-contrib-qunit and https://github.com/gruntjs/grunt-contrib-connect) as the tandem will provide you with a headless phantom and a local webserver.
UPDATE - as for running just one specific test, you could write something like this, listing your tests as separate targets for your qunit task:
grunt.initConfig({
qunit: {
justSomething: ['test/justsomething.html'],
justSomethingElse: ['test/justsomethingelse.html'],
all: ['test/*.html']
}
});
Then you can call grunt qunit:justSomething, or grunt qunit:all - this is not specific to qunit, though - see http://gruntjs.com/configuring-tasks
Now, if you would really like to use the target to specify a test name, you would go with something like:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.initConfig({
qunit: {
all: ['test/**/*.html']
}
});
grunt.task.registerTask('foo', 'A sample task that run one test.', function(testname) {
if(!!testname)
grunt.config('qunit.all', ['test/' + testname + '.html']);
grunt.task.run('qunit:all');
});
}
Then call grunt foo:testname.
Yet again, this is not specific to qunit - but rather grunt task writing.
Hope that (finally) helps.

Categories

Resources